diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..61536f81 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,272 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# All files +[*] +end_of_line = lf +insert_final_newline = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Code Actions #### + +# Type members +dotnet_hide_advanced_members = false +dotnet_member_insertion_location = with_other_members_of_the_same_kind +dotnet_property_generation_behavior = prefer_auto_properties + +# Symbol search +dotnet_search_reference_assemblies = true + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = always_for_clarity +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_prefer_system_hash_code = true +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_collection_expression = when_types_loosely_match +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = non_public + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = false +dotnet_style_allow_statement_immediately_after_block_experimental = false + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false +csharp_style_var_for_built_in_types = false +csharp_style_var_when_type_is_apparent = false + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true +csharp_style_expression_bodied_constructors = false +csharp_style_expression_bodied_indexers = true +csharp_style_expression_bodied_lambdas = when_on_single_line +csharp_style_expression_bodied_local_functions = when_on_single_line +csharp_style_expression_bodied_methods = false +csharp_style_expression_bodied_operators = false +csharp_style_expression_bodied_properties = true + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true +csharp_style_pattern_matching_over_is_with_cast_check = true +csharp_style_prefer_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true + +# Modifier preferences +csharp_prefer_static_anonymous_function = true +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true +csharp_style_prefer_readonly_struct_member = true + +# Code-block preferences +csharp_prefer_braces = true +csharp_prefer_simple_using_statement = false +csharp_prefer_system_threading_lock = true +csharp_style_namespace_declarations = file_scoped +csharp_style_prefer_method_group_conversion = false +csharp_style_prefer_primary_constructors = true +csharp_style_prefer_top_level_statements = false + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true +csharp_style_prefer_implicitly_typed_lambda_expression = true +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = false +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_prefer_unbound_generic_type_in_nameof = true +csharp_style_prefer_utf8_string_literals = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable + +# 'using' directive preferences +csharp_using_directive_placement = inside_namespace + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false +csharp_style_allow_embedded_statements_on_same_line_experimental = false + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = false +csharp_new_line_before_else = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = none +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_or_internal_const_field_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.private_or_internal_const_field_should_be_pascal_case.symbols = private_or_internal_const_field +dotnet_naming_rule.private_or_internal_const_field_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.severity = suggestion +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.symbols = private_or_internal_field +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.style = underscore_camel_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected +dotnet_naming_symbols.private_or_internal_field.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, method, event +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.private_or_internal_const_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_const_field.applicable_accessibilities = internal, private, protected_internal, private_protected +dotnet_naming_symbols.private_or_internal_const_field.required_modifiers = const + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.underscore_camel_case.required_prefix = _ +dotnet_naming_style.underscore_camel_case.required_suffix = +dotnet_naming_style.underscore_camel_case.word_separator = +dotnet_naming_style.underscore_camel_case.capitalization = camel_case diff --git a/.gitattributes b/.gitattributes index 5fa1ed0e..e4cab669 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,7 +10,7 @@ # default for csharp files. # Note: This is only used by command line ############################################################################### -#*.cs diff=csharp +*.cs diff=csharp ############################################################################### # Set the merge driver for project and solution files @@ -22,27 +22,28 @@ # these files as binary and thus will always conflict and require user # intervention with every merge. To do so, just uncomment the entries below ############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary +*.sln merge=binary +*.csproj merge=binary +*.vbproj merge=binary +*.vcxproj merge=binary +*.vcproj merge=binary +*.dbproj merge=binary +*.fsproj merge=binary +*.lsproj merge=binary +*.wixproj merge=binary +*.modelproj merge=binary +*.sqlproj merge=binary +*.wwaproj merge=binary ############################################################################### # behavior for image files # # image files are treated as binary by default. ############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary +*.jpg binary +*.png binary +*.gif binary +*.ico binary ############################################################################### # diff behavior for common document formats @@ -51,16 +52,16 @@ # is only available from the command line. Turn it on by uncommenting the # entries below. ############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain ############################################################################### # exclude files except those with cs file extension from repository language detection diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/actions/documentation/docfx-build/action.yml b/.github/actions/documentation/docfx-build/action.yml new file mode 100644 index 00000000..4eddad17 --- /dev/null +++ b/.github/actions/documentation/docfx-build/action.yml @@ -0,0 +1,47 @@ +name: 'Generate docs with docfx' +author: 'Pete Sramek' +description: 'Generate documentation using docfx' +inputs: +# Required + artifact-name: + description: 'Name of the artifact to upload after generating documentation' + required: true + docfx-json-manifest: + description: 'Path to the docfx JSON manifest file' + required: true + output-directory: + description: 'Target directory for generated documentation' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: Dotnet Setup + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'testing variables' + shell: bash + run: | + echo "artifact-name: ${{ inputs.artifact-name }}" + echo "docfx-json-manifest: ${{ inputs.docfx-json-manifest }}" + echo "output-directory: ${{ inputs.output-directory }}" + echo "dotnet-sdk-version: ${{ inputs.dotnet_sdk_version }}" + - name: 'Update docfx tool' + run: dotnet tool update -g docfx + shell: bash + - name: 'Generate documentation' + run: docfx build ${{ inputs.docfx-json-manifest }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.artifact-name }} + path: ${{ inputs.output-directory }} \ No newline at end of file diff --git a/.github/actions/documentation/docfx-metadata/action.yml b/.github/actions/documentation/docfx-metadata/action.yml new file mode 100644 index 00000000..bf20df47 --- /dev/null +++ b/.github/actions/documentation/docfx-metadata/action.yml @@ -0,0 +1,66 @@ +name: 'Generate metadata with docfx' +author: 'Pete Sramek' +description: 'Generate metadata using docfx' + +inputs: +# Required + artifact-name: + description: 'Name of the artifact to upload after generating metadata' + required: true + docfx-json-manifest: + description: 'Path to the docfx JSON manifest file' + required: true + temporary-directory: + description: 'Temporary directory for docfx metadata generation' + required: true + output-directory: + description: 'Target directory for generated documentation' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: Dotnet Setup + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Update docfx tool' + run: dotnet tool update -g docfx + shell: bash + - name: 'Delete temporary folder' + shell: bash + run: | + if [ -d "${{ inputs.temporary-directory }}" ]; then + rm -rf "${{ inputs.temporary-directory }}" + fi + - name: 'Delete temporary folder' + shell: bash + run: | + if [ -d "$${{ inputs.output-directory }}" ]; then + rm -rf "${{ inputs.output-directory }}" + fi + - name: 'Generate assembly metadata' + shell: bash + run: docfx metadata ${{ inputs.docfx-json-manifest }} + - name: 'List directory' + shell: bash + run: | + ls + - name: 'Copy metadata to output directory' + shell: bash + run: | + mkdir -p ${{ inputs.output-directory }} + cp -r ${{ inputs.temporary-directory }}/* ${{ inputs.output-directory }} + - name: 'Upload artifact' + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.artifact-name }} + path: ${{ inputs.output-directory }} + \ No newline at end of file diff --git a/.github/actions/git/push-changes/action.yml b/.github/actions/git/push-changes/action.yml new file mode 100644 index 00000000..da323b21 --- /dev/null +++ b/.github/actions/git/push-changes/action.yml @@ -0,0 +1,99 @@ +name: 'Push Changes' +author: 'Pete Sramek' +description: 'Push changes to a specified branch in the repository.' +inputs: + # Required + commit-message: + description: 'The commit message to use when pushing changes.' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + artifact-name: + description: 'Name of the artifact to download before pushing changes. Default: ''''' + required: false + default: '' + working-directory: + description: 'The working directory where the changes will be pushed from. Default ''.''' + required: false + default: '.' + target-branch: + description: 'The branch to push changes to.. Default: ''''' + required: false + default: '' + +runs: + using: "composite" + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Dotnet Setup + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: Download a single artifact + if: ${{ inputs.artifact-name != '' }} + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.artifact-name }} + path: ${{ inputs.working-directory }} + + - name: Stage changes in ${{ inputs.working-directory }} + shell: bash + run: | + git add . + working-directory: ${{ inputs.working-directory }} + + - if: runner.os == 'Windows' + shell: bash + run: | + git config --global core.autocrlf false + git config --global core.eol lf + + - if: runner.os != 'Windows' + shell: bash + run: | + git config --global core.autocrlf true + git config --global core.eol lf + + - name: Create or switch to ${{ inputs.target-branch }} + if: ${{ inputs.target-branch != '' }} + shell: bash + run: | + git fetch origin + git stash push --keep-index + if git show-ref --verify --quiet refs/heads/${{ inputs.target-branch }}; then + echo "Branch ${{ inputs.target-branch }} already exists, switching to it." + git checkout ${{ inputs.target-branch }} --force + git pull origin ${{ inputs.target-branch }} + else + echo "Branch ${{ inputs.target-branch }} does not exist, creating it." + git checkout -b ${{ inputs.target-branch }} origin/${{ inputs.target-branch }} --force || git checkout -b ${{ inputs.target-branch }} --force + git pull origin ${{ inputs.target-branch }} + fi + git stash apply + + - name: Validate changes + id: validate + shell: bash + run: | + set +e + git diff --quiet --exit-code --cached + echo has-changes="$?" >> $GITHUB_OUTPUT + set -e + working-directory: ${{ inputs.working-directory }} + + - name: Push changes to ${{ github.head_ref || github.ref }} + if: ${{ fromJSON(steps.validate.outputs.has-changes) == '1' }} + shell: bash + run: | + git config user.name "$(git log -n 1 --pretty=format:%an)" + git config user.email "$(git log -n 1 --pretty=format:%ae)" + git commit -m '${{ inputs.commit-message }}' + git pull --rebase origin ${{ github.head_ref || github.ref }} + git push + working-directory: ${{ inputs.working-directory }} diff --git a/.github/actions/github/create-release/action.yml b/.github/actions/github/create-release/action.yml new file mode 100644 index 00000000..0b0185ab --- /dev/null +++ b/.github/actions/github/create-release/action.yml @@ -0,0 +1,24 @@ +name: 'Create GitHub release' +author: 'Pete Sramek' +description: 'Create GitHub release.' +inputs: + release-version: + description: 'Version to use for the release.' + required: true + is-preview: + description: 'Is this a preview release?' + required: true + default: 'false' + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Create GitHub release PolylineAlgorithm ${{ env.release-version }}' + shell: bash + env: + GH_TOKEN: ${{ github.token }} + preview-argument: "${{ inputs.is-preview == 'true' && '--prerelease' || '' }}" + run: | + gh release create ${{ env.release-version }} --generate-notes --discussion-category "General" ${{ env.preview-argument }} diff --git a/.github/actions/github/write-file-to-summary/action.yml b/.github/actions/github/write-file-to-summary/action.yml new file mode 100644 index 00000000..ac682f6d --- /dev/null +++ b/.github/actions/github/write-file-to-summary/action.yml @@ -0,0 +1,25 @@ +name: 'Write file to step summary' +author: 'Pete Sramek' +description: 'Writes file contents to step summary.' +inputs: +# Required + file-glob-pattern: + description: 'Search pattern for files to write.' + required: true + +# Optional + working-directory: + description: 'Working directory to search for file.' + required: false + default: ${{ github.workspace }} + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Writing ${{ inputs.file }} to step summary + shell: bash + run: cat ${{ inputs.file }} >> $GITHUB_STEP_SUMMARY + working-directory: ${{ inputs.working-directory }} \ No newline at end of file diff --git a/.github/actions/nuget/publish-package/action.yml b/.github/actions/nuget/publish-package/action.yml new file mode 100644 index 00000000..83d00687 --- /dev/null +++ b/.github/actions/nuget/publish-package/action.yml @@ -0,0 +1,61 @@ +name: 'Publish packages to NuGet feed' +author: 'Pete Sramek' +description: 'Publishes packages in working directory to public NuGet feed' +inputs: +# Required + package-artifact-name: + description: 'Name of the artifact to download and publish' + required: true + nuget-feed-url: + description: 'NuGet feed URL' + required: true + nuget-feed-api-key: + description: 'NuGet feed API key' + required: true + nuget-feed-server: + description: 'NuGet feed server. Allowed values: ''NuGet'', ''AzureArtifacts''' + required: true +# Optional + dotnet-sdk-version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + working-directory: + description: 'Working directory to search for file.' + required: false + default: ${{ github.workspace }} + +runs: + using: composite + + steps: + + - if: ${{ inputs.nuget-feed-server != 'NuGet' && inputs.nuget-feed-server != 'AzureArtifacts' }} + name: 'Validate NuGet feed server type' + shell: bash + run: | + echo "Invalid NuGet feed server type. Allowed values are ''NuGet'' or ''AzureArtifacts''." + exit 1 + + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Download package artifact + uses: actions/download-artifact@v5 + with: + name: ${{ inputs.package-artifact-name }} + + - if: ${{ inputs.nuget-feed-server == 'NuGet' }} + name: 'Publish package to NuGet' + shell: bash + run: | + dotnet nuget push **/*.nupkg --source ${{ inputs.nuget-feed-url }} --api-key ${{ inputs.nuget-feed-api-key }} + working-directory: ${{ env.working-directory }} + + - if: ${{ inputs.nuget-feed-server == 'AzureArtifacts' }} + name: 'Publish package to Azure Artifacts' + shell: bash + run: | + dotnet nuget add source ${{ inputs.nuget-feed-url }} --name nuget-feed --username username --password ${{ inputs.nuget-feed-api-key }} --store-password-in-clear-text + dotnet nuget push **/*.nupkg --source nuget-feed --api-key ${{ inputs.nuget-feed-api-key }} --skip-duplicate + working-directory: ${{ env.working-directory }} \ No newline at end of file diff --git a/.github/actions/source/compile/action.yml b/.github/actions/source/compile/action.yml new file mode 100644 index 00000000..7e6eea46 --- /dev/null +++ b/.github/actions/source/compile/action.yml @@ -0,0 +1,74 @@ +name: 'Compile source code' +author: 'Pete Sramek' +description: 'Compiles source code, uploads build artifacts.' +inputs: +# Required + assembly-version: + description: 'Assembly version.' + required: true + assembly-informational-version: + description: 'Assembly informational version.' + required: true + file-version: + description: 'Assembly file version.' + required: true + treat-warnins-as-error: + description: 'Treat warnings as errors.' + required: true + project-path: + description: 'Search pattern for source code.' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: ''9.x''' + required: false + default: '9.x' + build-configuration: + description: 'Build configuration. Default: ''Release''' + required: false + default: 'Release' + build-platform: + description: 'Build platform. Deafult: ''Any CPU''' + required: false + default: 'Any CPU' + upload-build-artifacts: + description: 'Upload build artifacts, Default: ''true''' + required: false + default: 'true' + build-artifacts-glob-pattern: + description: 'Search pattern for build artifacts. Default: **/bin/*, **/obj/*' + required: false + default: | + **/bin/* + **/obj/* + build-artifacts-name: + description: 'Upload build artifacts, Default: ''build''' + required: false + default: 'build' + +runs: + using: "composite" + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - if: ${{ inputs.treat-warnings-as-error == 'true' }} + name: 'Validate warnings with .NET CLI' + shell: bash + run: dotnet format analyzers --severity warn --verify-no-changes + + - name: 'Build with .NET CLI' + shell: bash + run: dotnet build ${{ inputs.search-glob-pattern }} --configuration ${{ inputs.build-configuration }} /p:Platform="${{ inputs.build-platform }}" /p:Version=${{ inputs.assembly-version }} /p:AssemblyInformationalVersion=${{ inputs.assembly-informational-version }} /p:FileVersion=${{ inputs.file-version }} + + - name: 'Upload build artifacts' + if: ${{ inputs.upload-build-artifacts == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.build-artifacts-name }} + path: ${{ inputs.build-artifacts-glob-pattern }} diff --git a/.github/actions/source/format/action.yml b/.github/actions/source/format/action.yml new file mode 100644 index 00000000..f932a166 --- /dev/null +++ b/.github/actions/source/format/action.yml @@ -0,0 +1,73 @@ +name: 'Format source code' +author: 'Pete Sramek' +description: 'Formats source code using dotnet format tool. Pushes changes to the current branch.' +inputs: +# Required + project-path: + description: 'Path to the project or solution file.' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: ''9.x''' + required: false + default: '9.x' + format-whitespace: + description: 'Format whitespace. Default: ''true''' + required: false + default: 'true' + format-style: + description: 'Format style. Default: ''true''' + required: false + default: 'true' + format-analyzers: + description: 'Format analyzers. Default: ''false''' + required: false + default: 'false' + format-analyzers-diagnostics-parameter: + description: 'Format analyzers diagnostics parameter. Default: ''''' + required: false + default: '' + +runs: + using: "composite" + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - name: Format whitespace + if: ${{ inputs.format-whitespace == 'true' }} + shell: bash + run: | + dotnet format whitespace + working-directory: ${{ github.workspace }} + + - name: Format style + if: ${{ inputs.format-style == 'true' }} + shell: bash + run: | + dotnet format style + working-directory: ${{ github.workspace }} + + - name: 'Set target branch' + if: ${{ inputs.format-analyzers == 'true' && inputs.format-analyzers-diagnostics-parameter != '' }} + id: set-diagnostics-parameter + shell: bash + run: | + echo "format-analyzers-diagnostics-parameter=--diagnostics ${{ inputs.format-analyzers-diagnostics-parameter }}" >> $GITHUB_OUTPUT + + - name: Format analyzers + if: ${{ inputs.format-analyzers == 'true' }} + shell: bash + run: | + dotnet format analyzers ${{ env.format-analyzers-diagnostics-parameter }} + working-directory: ${{ github.workspace }} + + - name: 'Push changes' + uses: './.github/actions/git/push-changes' + with: + commit-message: 'Formatted csharp files' diff --git a/.github/actions/testing/code-coverage/action.yml b/.github/actions/testing/code-coverage/action.yml new file mode 100644 index 00000000..45d257f5 --- /dev/null +++ b/.github/actions/testing/code-coverage/action.yml @@ -0,0 +1,73 @@ +name: 'Test with .NET CLI' +author: 'Pete Sramek' +description: 'Run tests, collects code coverage, logs test results, uploads test artifacts' +inputs: +# Required + test-result-folder: + description: 'Folder where test results are stored' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + +outputs: + code-coverage-report-file: + description: 'Path to the generated code coverage report' + value: ${{ steps.variables.outputs.code-coverage-report-file }} + code-coverage-merge-file: + description: 'Path to the merged code coverage file' + value: ${{ steps.variables.outputs.code-coverage-merge-file }} + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - if: ${{ endsWith(inputs.test-result-folder, '/') }} + name: 'Set TEST_RESULT_FOLDER environment variable' + shell: bash + run: echo "TEST_RESULT_FOLDER=${{ inputs.test-result-folder }}" >> $GITHUB_ENV + + - if: ${{ !endsWith(inputs.test-result-folder, '/') }} + name: 'Set TEST_RESULT_FOLDER environment variable' + shell: bash + run: echo "TEST_RESULT_FOLDER=${{ inputs.test-result-folder }}/" >> $GITHUB_ENV + + - name: 'Set CODE_COVERAGE_REPORT_FOLDER environment variable' + shell: bash + run: echo "CODE_COVERAGE_REPORT_FOLDER=${{ env.TEST_RESULT_FOLDER }}coverage-report/" >> $GITHUB_ENV + + - name: 'Set CODE_COVERAGE_MERGED_FILE environment variable' + shell: bash + run: echo "CODE_COVERAGE_MERGED_FILE=${{ env.CODE_COVERAGE_REPORT_FOLDER }}code-coverage.cobertura.xml" >> $GITHUB_ENV + + - name: 'Set code-coverage-report output' + id: variables + shell: bash + run: | + echo "code-coverage-report-file=${{ env.CODE_COVERAGE_REPORT_FOLDER }}Summary.md" >> $GITHUB_OUTPUT + echo "code-coverage-merge-file=${{ env.CODE_COVERAGE_MERGED_FILE }}" >> $GITHUB_OUTPUT + + - name: 'Update dotnet-coverage tool' + shell: bash + run: dotnet tool update --global dotnet-coverage + + - name: 'Merge code coverage reports' + shell: bash + run: dotnet-coverage merge --output ${{ env.CODE_COVERAGE_MERGED_FILE }} --output-format cobertura "${{ env.TEST_RESULT_FOLDER }}**/*.cobertura.xml" + + - name: 'Update dotnet-reportgenerator-globaltool tool' + shell: bash + run: dotnet tool update --global dotnet-reportgenerator-globaltool + + - name: 'Generate code coverage report' + shell: bash + run: reportgenerator -reports:${{ env.CODE_COVERAGE_MERGED_FILE }} -targetdir:${{ env.CODE_COVERAGE_REPORT_FOLDER }} -reporttypes:"MarkdownSummary" \ No newline at end of file diff --git a/.github/actions/testing/test-report/action.yml b/.github/actions/testing/test-report/action.yml new file mode 100644 index 00000000..aee61285 --- /dev/null +++ b/.github/actions/testing/test-report/action.yml @@ -0,0 +1,60 @@ +name: 'Generate test report with Liquid Test Reports CLI' +author: 'Pete Sramek' +description: 'Run tests, collects code coverage, logs test results, uploads test artifacts' +inputs: +# Required + test-result-folder: + description: 'Folder where test results are stored' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + test-report-filename: + description: 'Filename of the test report. Default: test-report.md' + required: false + default: 'test-report.md' + +outputs: + test-report-file: + description: 'Path to the generated test report' + value: ${{ steps.variables.outputs.test-report-file }} + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - name: Install LiquidTestReports.Cli + shell: bash + run: dotnet tool install --global LiquidTestReports.Cli --prerelease + + - if: ${{ endsWith(inputs.test-result-folder, '/') }} + name: 'Set TEST_RESULT_FOLDER environment variable' + shell: bash + run: echo "TEST_RESULT_FOLDER=${{ inputs.test-result-folder }}" >> $GITHUB_ENV + + - if: ${{ !endsWith(inputs.test-result-folder, '/') }} + name: 'Set TEST_RESULT_FOLDER environment variable' + shell: bash + run: echo "TEST_RESULT_FOLDER=${{ inputs.test-result-folder }}/" >> $GITHUB_ENV + + - name: 'Set TEST_REPORT_FILE environment variable' + shell: bash + run: echo "TEST_REPORT_FILE=${{ env.TEST_RESULT_FOLDER }}${{ inputs.test-report-filename }}" >> $GITHUB_ENV + + - name: 'Set test-report-file output' + id: variables + shell: bash + run: echo "test-report-file=${{ env.TEST_REPORT_FILE }}" >> $GITHUB_OUTPUT + + - name: Generate test report + shell: bash + run: liquid --inputs "Folder=${{ env.TEST_RESULT_FOLDER }};File=**/*.trx;Format=Trx" --output-file ${{ env.TEST_REPORT_FILE }} \ No newline at end of file diff --git a/.github/actions/testing/test/action.yml b/.github/actions/testing/test/action.yml new file mode 100644 index 00000000..52b875a2 --- /dev/null +++ b/.github/actions/testing/test/action.yml @@ -0,0 +1,91 @@ +name: 'Test with .NET CLI' +author: 'Pete Sramek' +description: 'Run tests, collects code coverage, logs test results, uploads test artifacts' +inputs: +# Required + +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: 9.x' + required: false + default: '9.x' + build-configuration: + description: 'Build configuration. Default: Release' + required: false + default: 'Release' + project-path: + description: 'Search pattern for test projects.' + required: true + use-trf-logger: + description: 'Use TRX logger. Default: true' + required: false + default: 'true' + collect-code-coverage: + description: 'Collect code coverage. Default: true' + required: false + default: 'true' + code-coverage-output-format: + description: 'Code coverage output format. Default: cobertura' + required: false + default: 'cobertura' + code-coverage-settings-file: + description: 'Code coverage settings file. Default: ' + required: false + default: '' + upload-test-artifacts: + description: 'Upload test artifacts, Default: true' + required: false + default: 'true' + test-results-directory: + description: 'Search pattern for test artifacts. Default: test-results' + required: false + default: | + 'test-results' + test-artifacts-name: + description: 'Test artifacts name, Default: test-results' + required: false + default: 'test-results' + +runs: + using: composite + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - if: ${{ inputs.use-trf-logger == 'true' }} + name: 'Set TRX_LOGGER_ARGS environment variable' + shell: bash + run: echo "TRX_LOGGER_ARGS=--report-trx" >> $GITHUB_ENV + + - if: ${{ inputs.test-runsettings-path != '' }} + name: 'Set RUN_SETTINGS_ARGS environment variable' + shell: bash + run: echo "RUN_SETTINGS_ARGS=--setttings ${{ inputs.test-runsettings-path }}" >> $GITHUB_ENV + + - if: ${{ inputs.collect-code-coverage == 'true' }} + name: 'Set CODE_COVERAGE_ARGS environment variable' + shell: bash + run: | + echo "CODE_COVERAGE_ARGS=--coverage --coverage-output-format ${{ inputs.code-coverage-output-format}}" >> $GITHUB_ENV + + - if: ${{ inputs.collect-code-coverage == 'true' && inputs.code-coverage-settings-file != ''}} + name: 'Set CODE_COVERAGE_ARGS environment variable' + shell: bash + run: | + echo "CODE_COVERAGE_ARGS=${{ env.CODE_COVERAGE_ARGS }} --coverage-settings ${{ inputs.code-coverage-settings-file }}" >> $GITHUB_ENV + + - name: 'Test with .NET CLI' + shell: bash + run: dotnet test ${{ inputs.test-project-glob-pattern }} --configuration ${{ inputs.build-configuration }} -- ${{ env.CODE_COVERAGE_ARGS }} ${{ env.TRX_LOGGER_ARGS }} --results-directory ${{ inputs.test-results-directory }} + + - name: 'Upload test results' + if: ${{ inputs.upload-test-artifacts == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: '${{ inputs.test-artifacts-name }}' + path: '${{ inputs.test-results-directory }}*' \ No newline at end of file diff --git a/.github/actions/versioning/extract-version/action.yml b/.github/actions/versioning/extract-version/action.yml new file mode 100644 index 00000000..43ad87a9 --- /dev/null +++ b/.github/actions/versioning/extract-version/action.yml @@ -0,0 +1,56 @@ +name: 'Extract version' +author: 'Pete Sramek' +description: 'Determines versions for the build.' +inputs: +# Required + branch-name: + description: 'Branch name.' + required: true +# Optional + default-version: + description: 'Default version to use if no match is found. Default: ''0.0''' + required: false + default: '0.0' + version-format: + description: 'Version format. Default: ''(\d+).(\d+)''' + required: false + default: '(\d+).(\d+)' + dotnet_sdk_version: + description: '.NET SDK version. Default: ''9.x''' + required: false + default: '9.x' +outputs: + version: + description: 'Version extracted from the branch name.' + value: ${{ steps.regex-match.outputs.match }} + +runs: + using: "composite" + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + + - name: 'Extract version from branch name' + id: regex-match + uses: actions-ecosystem/action-regex-match@v2 + with: + text: ${{ inputs.branch-name }} + regex: ${{ inputs.version-format }} + flags: 'g' + + - name: 'Set extracted version output' + if: steps.regex-match.outputs.match != '' + shell: bash + run: | + echo "version=${{ steps.regex-match.outputs.match }}" >> $GITHUB_OUTPUT + + - name: 'Set default version output' + if: steps.regex-match.outputs.match == '' + shell: bash + run: | + echo "version=${{ inputs.default-version }}" >> $GITHUB_OUTPUT diff --git a/.github/actions/versioning/format-version/action.yml b/.github/actions/versioning/format-version/action.yml new file mode 100644 index 00000000..035410fa --- /dev/null +++ b/.github/actions/versioning/format-version/action.yml @@ -0,0 +1,66 @@ +name: 'Format version' +author: 'Pete Sramek' +description: 'Formats versions.' +inputs: +# Required + version: + description: 'Version to use.' + required: true + patch: + description: 'Patch version to append to the formatted version.' + required: true + build-number: + description: 'Build number to append to the formatted version.' + required: true + sha: + description: 'Commit SHA to append to the formatted version.' + required: true + pre-release-tag: + description: 'Pre-release tag to append to the formatted version.' + required: true +# Optional + dotnet_sdk_version: + description: '.NET SDK version. Default: ''9.x''' + required: false + default: '9.x' + +outputs: + friendly-version: + description: 'Formatted friendly version.' + value: ${{ steps.format-version.outputs.friendly-version }} + assembly-version: + description: 'Formatted assembly version.' + value: ${{ steps.format-version.outputs.assembly-version }} + assembly-informational-version: + description: 'Formatted assembly informational version.' + value: ${{ steps.format-version.outputs.assembly-informational-version }} + file-version: + description: 'Formatted file version.' + value: ${{ steps.format-version.outputs.file-version }} + release-version: + description: 'Formatted release version.' + value: ${{ steps.format-version.outputs.release-version }} + +runs: + using: "composite" + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET ${{ inputs.dotnet_sdk_version }}' + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ inputs.dotnet_sdk_version }} + - name: 'Format version' + shell: bash + id: format-version + run: | + echo "friendly-version=${{ inputs.version }}" >> $GITHUB_OUTPUT + echo "assembly-version=${{ inputs.version }}.${{ inputs.patch }}.${{ inputs.build-number }}" >> $GITHUB_OUTPUT + echo "assembly-informational-version=${{ inputs.version }}.${{ inputs.patch }}+${{ inputs.sha }}" >> $GITHUB_OUTPUT + echo "file-version=${{ inputs.version }}.${{ inputs.patch }}.${{ inputs.build-number }}" >> $GITHUB_OUTPUT + if [ -n "${{ inputs.pre-release-tag }}" ]; then + echo "release-version=${{ inputs.version }}.${{ inputs.patch }}-${{ inputs.pre-release-tag }}.${{ inputs.build-number }}" >> $GITHUB_OUTPUT + else + echo "release-version=${{ inputs.version }}.${{ inputs.patch }}.${{ inputs.build-number }}" >> $GITHUB_OUTPUT + fi diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..02a54502 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "dotnet-sdk" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..082c11e9 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,258 @@ +name: Build + +on: + workflow_dispatch: + push: + branches-ignore: + - 'preview/**' + - 'release/**' + paths: + - 'src/**' + +permissions: + actions: read + pages: write + id-token: write + contents: write + +concurrency: + group: build-${{ github.head_ref || github.ref }} + cancel-in-progress: false + +env: + dotnet-sdk-version: '9.x' + build-configuration: 'Release' + build-platform: 'Any CPU' + git-version: '6.0.x' + test-result-directory: 'test-results' + nuget-packages-directory: 'nuget-packages' + +jobs: + workflow-variables: + name: 'Set workflow variables' + runs-on: ubuntu-latest + + outputs: + is-release: ${{ startsWith(github.ref_name, 'release') }} + is-preview: ${{ startsWith(github.ref_name, 'preview') }} + + steps: + - name: 'Set workflow variables' + id: github + run: | + echo "is-release:${{ startsWith(github.ref_name, 'release') }}" + echo "is-preview:${{ startsWith(github.ref_name, 'preview') }}" + + versioning: + name: 'Extract version' + runs-on: ubuntu-latest + outputs: + friendly-version: ${{ steps.format-version.outputs.friendly-version }} + assembly-version: ${{ steps.format-version.outputs.assembly-version }} + assembly-informational-version: ${{ steps.format-version.outputs.assembly-informational-version }} + file-version: ${{ steps.format-version.outputs.file-version }} + release-version: ${{ steps.format-version.outputs.release-version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Extract version from branch name' + id: extract-version + uses: './.github/actions/versioning/extract-version' + with: + branch-name: ${{ github.ref_name }} + - name: 'Create build number' + shell: bash + id: create-build-number + run: | + git fetch --unshallow --filter=tree:0 + build_number=$(git rev-list --count origin/${{ github.ref_name }} ^origin/main) + echo "build-number=$build_number" >> $GITHUB_OUTPUT + - name: 'Create pre-release tag' + shell: bash + id: create-pre-release-tag + env: + build-number: ${{ steps.create-build-number.outputs.build-number }} + run: | + if [[ '${{ needs.workflow-variables.outputs.is-release }}' == 'true' ]]; then + echo "pre-release-tag=" >> $GITHUB_OUTPUT + elif [[ '${{ needs.workflow-variables.outputs.is-preview }}' == 'true' ]]; then + pre_release_tag='preview' + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + else + pre_release_tag=$(echo ${{ github.ref_name }} | tr '/' '-' | tr '.' '-'| tr '_' '-') + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + fi + - name: 'Format version' + id: format-version + uses: ./.github/actions/versioning/format-version + with: + version: ${{ steps.extract-version.outputs.version }} + patch: ${{ github.run_number }} + build-number: ${{ steps.create-build-number.outputs.build-number }} + sha: ${{ github.sha }} + pre-release-tag: ${{ steps.create-pre-release-tag.outputs.pre-release-tag }} + + format: + name: 'Format source code' + runs-on: ubuntu-latest + + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Format source code' + uses: ./.github/actions/source/format + with: + project-path: '**/PolylineAlgorithm.csproj' + + build: + name: 'Compile source code' + needs: [workflow-variables, versioning, format] + runs-on: ubuntu-latest + + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Compile source code' + uses: ./.github/actions/source/compile + with: + project-path: '**/PolylineAlgorithm.csproj' + assembly-version: ${{ env.assembly-version }} + assembly-informational-version: ${{ env.assembly-informational-version }} + file-version: ${{ env.file-version }} + treat-warnins-as-error: ${{ needs.workflow-variables.outputs.is-release }} + + test: + name: 'Run tests' + needs: [build] + runs-on: ubuntu-latest + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Run tests' + uses: ./.github/actions/testing/test + with: + project-path: '**/PolylineAlgorithm.Tests.csproj' + test-results-directory: '${{ runner.temp }}/${{ env.test-result-directory }}/' + code-coverage-settings-file: '${{ github.workspace}}/code-coverage-settings.xml' + + - name: 'Generate test report' + uses: ./.github/actions/testing/test-report + id: test-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write test report summary + run: cat ${{ steps.test-report.outputs.test-report-file }} >> $GITHUB_STEP_SUMMARY + + - name: 'Generate code coverage' + uses: ./.github/actions/testing/code-coverage + id: code-coverage-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write code coverage report summary + run: cat ${{ steps.code-coverage-report.outputs.code-coverage-report-file }} >> $GITHUB_STEP_SUMMARY + + pack: + name: 'Package binaries' + needs: [versioning, build] + runs-on: ubuntu-latest + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + release-version: ${{ needs.versioning.outputs.release-version }} + package-artifact-name: package + outputs: + package-artifact-name: ${{ env.package-artifact-name }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: Download Build + uses: actions/download-artifact@v5 + with: + name: build + + - name: Pack with .NET + run: | + dotnet pack ${{ vars.SRC_DEFAULT_GLOB_PATTERN }} --configuration ${{ env.build-configuration }} /p:Platform="${{ env.build-platform }}" /p:PackageVersion=${{ env.release-version }} /p:Version=${{ env.assembly-version }} /p:AssemblyInformationalVersion=${{ env.assembly-informational-version }} /p:FileVersion=${{ env.file-version }} --output ${{ runner.temp }}/${{ env.nuget-packages-directory }} + + - name: Upload Package + uses: actions/upload-artifact@v4 + with: + name: ${{ env.package-artifact-name }} + path: | + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.nupkg + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.snupkg + + publish-package: + name: 'Publish development package' + needs: [pack] + env: + package-artifact-name: ${{ needs.pack.outputs.package-artifact-name }} + runs-on: ubuntu-latest + environment: 'Development' + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Publish package to Azure Artifact feed' + uses: ./.github/actions/nuget/publish-package + with: + package-artifact-name: ${{ env.package-artifact-name }} + nuget-feed-url: ${{ vars.NUGET_PACKAGE_FEED_URL }} + nuget-feed-api-key: ${{ secrets.NUGET_PACKAGE_FEED_API_KEY }} + nuget-feed-server: 'AzureArtifacts' + working-directory: ${{ runner.temp }}/${{ env.nuget-packages-directory }} + dotnet-sdk-version: ${{ env.dotnet-sdk-version }}' + + generate-assembly-metadata: + name: 'Generate assembly metadata' + needs: [versioning, build] + env: + friendly-version: ${{ needs.versioning.outputs.friendly-version }} + runs-on: ubuntu-latest + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Generate assembly metadata' + uses: ./.github/actions/documentation/docfx-metadata + with: + artifact-name: 'assembly-metadata' + docfx-json-manifest: './api-reference/assembly-metadata.json' + temporary-directory: './api-reference/temp' + output-directory: './api-reference/${{ env.friendly-version }}' + - name: 'Push assembly metadata artifact' + uses: ./.github/actions/git/push-changes + with: + artifact-name: 'assembly-metadata' + commit-message: 'Updated docs for version ${{ env.friendly-version }}' + working-directory: './api-reference/${{ env.friendly-version }}' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 1b11d4ec..00000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,97 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL Advanced" - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - schedule: - - cron: '29 17 * * 3' - -jobs: - analyze: - name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - permissions: - # required for all workflows - security-events: write - - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read - - strategy: - fail-fast: false - matrix: - include: - - language: csharp - build-mode: none - # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 9.0.x - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # 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 - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml deleted file mode 100644 index 0bfc8aa7..00000000 --- a/.github/workflows/dotnet.yml +++ /dev/null @@ -1,28 +0,0 @@ -# This workflow will build a .NET project -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net - -name: .NET - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.0.x - - name: Restore dependencies - run: dotnet restore - - name: Build - run: dotnet build --no-restore - - name: Test - run: dotnet test --no-build --verbosity normal diff --git a/.github/workflows/promote-branch.yml b/.github/workflows/promote-branch.yml new file mode 100644 index 00000000..43e9cdab --- /dev/null +++ b/.github/workflows/promote-branch.yml @@ -0,0 +1,216 @@ +name: 'Promote branch' + +on: + workflow_dispatch: + inputs: + promotion-type: + type: choice + options: + - 'preview' + - 'release' + description: 'Promotion type.' + required: true + base-branch: + type: string + description: 'Base branch to create target from.' + default: 'main' + required: true + +permissions: + actions: read + id-token: write + contents: write + pull-requests: write + +concurrency: + group: 'promote-branch-${{ inputs.promotion-type }}-${{github.ref_name }}' + cancel-in-progress: false + +env: + dotnet-sdk-version: '9.x' + is-development-branch: ${{ startsWith(github.ref_name, 'develop') }} + is-maintenance-branch: ${{ startsWith(github.ref_name, 'support') }} + +jobs: + versioning: + name: 'Extract version' + runs-on: ubuntu-latest + outputs: + friendly-version: ${{ steps.extract-version.outputs.version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Extract version from branch name' + id: extract-version + uses: './.github/actions/versioning/extract-version' + with: + branch-name: ${{ github.ref_name }} + workflow-variables: + name: 'Set workflow variables' + needs: [versioning] + runs-on: ubuntu-latest + outputs: + base-branch: ${{ steps.set-base-branch.outputs.base-branch }} + target-branch: ${{ steps.set-target-branch.outputs.target-branch }} + target-branch-exists: ${{ steps.check-target-branch-exists.outputs.target-branch-exists }} + pull-request-exists: ${{ steps.check-pull-request-exists.outputs.pull-request-exists }} + steps: + - name: 'Set target branch' + id: set-target-branch + run: | + if [[ "${{ inputs.promotion-type }}" == "preview" ]]; then + target_branch="preview/${{ needs.versioning.outputs.friendly-version }}" + elif [[ "${{ inputs.promotion-type }}" == "release" ]]; then + target_branch="release/${{ needs.versioning.outputs.friendly-version }}" + fi + + echo "Setting target branch $target_branch." + + echo "target-branch=$target_branch" >> $GITHUB_OUTPUT + - name: 'Set base branch' + id: set-base-branch + run: | + base_branch=${{ inputs.base-branch }} + + echo "Setting base branch $base_branch." + + echo "base-branch=$base_branch" >> $GITHUB_OUTPUT + - name: 'Check if base branch exists' + id: check-target-branch-exists + env: + target-branch: ${{ steps.set-target-branch.outputs.target-branch }} + run: | + set +e + + git ls-remote --exit-code --heads origin ${{ env.target-branch }} + + if [[ $? -eq 0 ]]; then + echo "Target branch ${{ env.target-branch }} does exist." + target_branch_exists="true" + else + echo "Target branch ${{ env.target-branch }} does not exist." + target_branch_exists="false" + fi + + echo "target-branch-exists=$target_branch_exists" >> $GITHUB_OUTPUT + + set -e + - name: 'Check if base branch exists' + id: check-base-branch-exists + env: + base-branch: ${{ steps.set-base-branch.outputs.base-branch }} + run: | + set +e + + git ls-remote --exit-code --heads origin ${{ env.base-branch }} + + if [[ $? -eq 0 ]]; then + echo "Base branch ${{ env.base-branch }} does exist." + base_branch_exists="true" + else + echo "Base branch ${{ env.base-branch }} does not exist." + base_branch_exists="false" + fi + + echo "base-branch-exists=$base_branch_exists" >> $GITHUB_OUTPUT + + set -e + - name: 'Check if pull request exists exists' + id: check-pull-request-exists + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository_owner }}/${{ github.event.repository.name }} + current-branch: ${{ github.ref_name }} + target-branch: ${{ steps.set-target-branch.outputs.target-branch }} + run: | + pull_request_count=$(gh pr list --head ${{ env.current-branch }} --base ${{ env.target-branch }} --state open --limit 1 --json id --jq '. | length') + + if [[ $pull_request_count -eq 0 ]]; then + echo "Pull request does not exist." + pull_request_exists="false" + else + echo "Pull request does exist." + pull_request_exists="true" + fi + + echo "pull-request-exists=$pull_request_exists" >> $GITHUB_OUTPUT + + validate-promotion: + name: 'Validate promotion' + needs: [ versioning, workflow-variables ] + runs-on: ubuntu-latest + env: + promotion-type: ${{ inputs.promotion-type }} + base-branch: ${{ needs.workflow-variables.outputs.base-branch }} + current-branch: ${{ github.ref_name }} + target-branch: ${{ needs.workflow-variables.outputs.target-branch }} + pull-request-exists: ${{ needs.workflow-variables.outputs.pull-request-exists }} + outputs: + target-branch: ${{ env.target-branch }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Check promotion type' + if: ${{ (env.promotion-type != 'release') && (env.promotion-type != 'preview') }} + run: | + echo "Invalid promotion type ${{ inputs.promotion-type }}" + exit 1 + - name: 'Validate current branch' + if: ${{ (env.is-development-branch == 'false') && (env.is-maintenance-branch == 'false') }} + run: | + echo "Invalid current branch '${{ github.ref_name }}'" + exit 1 + - name: 'Validate default and current branch' + if: ${{ env.base-branch == env.current-branch }} + run: | + echo "Default and current branch cannot be the same." + echo "Default branch is '${{ env.base-branch }}'" + echo "Current branch is '${{ env.current-branch }}'" + exit 1 + + - name: 'Validate target and current branch' + if: ${{ env.target-branch == env.current-branch }} + run: | + echo "Default and target branch cannot be the same." + echo "Default branch is '${{ env.target-branch }}'" + echo "Current branch is '${{ env.current-branch }}'" + exit 1 + + - name: 'Validate pull request' + if: ${{ env.pull-request-exists == 'true' }} + run: | + echo "Pull request exists." + exit 1 + + promote-branch: + name: 'Promote branch ${{ github.ref_name }} to ${{ needs.workflow-variables.outputs.target-branch }}' + needs: [ workflow-variables, validate-promotion ] + runs-on: ubuntu-latest + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Create target branch' + if: ${{ needs.workflow-variables.outputs.target-branch-exists == 'false' }} + run: | + git config user.name "$(git log -n 1 --pretty=format:%an)" + git config user.email "$(git log -n 1 --pretty=format:%ae)" + git fetch origin + git switch ${{ needs.workflow-variables.outputs.base-branch }} + git checkout -b ${{ needs.workflow-variables.outputs.target-branch }} origin/${{ needs.workflow-variables.outputs.target-branch }} || git checkout -b ${{ needs.workflow-variables.outputs.target-branch }} + git push --set-upstream origin ${{ needs.workflow-variables.outputs.target-branch }} + - name: 'Create PR: "Promote ${{ env.current-branch }} to ${{ env.target-branch }}"' + if: ${{ needs.workflow-variables.outputs.pull-request-exists == 'false' }} + env: + GH_TOKEN: ${{ github.token }} + current-branch: ${{ github.ref_name }} + target-branch: ${{ needs.workflow-variables.outputs.target-branch }} + run: | + gh pr create --title "Promote ${{ env.current-branch }} to ${{ env.target-branch }}" --fill --base ${{ env.target-branch }} --head ${{ env.current-branch }} diff --git a/.github/workflows/publish-documentation.yml b/.github/workflows/publish-documentation.yml new file mode 100644 index 00000000..7f9af8e3 --- /dev/null +++ b/.github/workflows/publish-documentation.yml @@ -0,0 +1,85 @@ +name: 'Publish documentation' + +on: + workflow_dispatch: + +permissions: + actions: read + pages: write + id-token: write + +concurrency: + group: publish-docs-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + workflow-variables: + name: 'Workflow variables' + runs-on: ubuntu-latest + + outputs: + github-run-number: ${{ github.run_number }} + + steps: + - name: 'Workflow variables' + id: github + run: | + echo "github-run-number:${{ github.run_number }}" + + versioning: + name: 'Extract version' + needs: [workflow-variables] + runs-on: ubuntu-latest + outputs: + friendly-version: ${{ steps.versioning.outputs.friendly-version }} + + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + with: + fetch-depth: 0 # Ensure the full git history is available for versioning + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Extract version from branch name' + id: versioning + uses: './.github/actions/versioning/extract-version' + with: + branch-name: ${{ github.ref_name }} + + generate-docs: + name: 'Generate documentation' + needs: [workflow-variables, versioning] + runs-on: ubuntu-latest + env: + friendly-version: ${{ needs.versioning.outputs.friendly-version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Generate documentation' + uses: ./.github/actions/documentation/docfx-build + with: + artifact-name: 'documentation' + docfx-json-manifest: './api-reference/api-reference.json' + output-directory: './api-reference/_docs' + + - name: 'Upload artifact' + uses: actions/upload-pages-artifact@v4 + with: + name: github-pages + path: './api-reference/_docs' + + publish-docs: + name: 'Publish documentation' + needs: [workflow-variables, versioning, generate-docs] + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + + - name: 'Deploy to GitHub Pages' + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 00000000..573c5891 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,258 @@ +name: 'Pull Request' + +on: + pull_request: + types: + - opened + - synchronize + - reopened + branches: + - 'preview/**' + - 'release/**' + +permissions: + actions: read + pages: write + id-token: write + contents: write + +concurrency: + group: pull-request-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +env: + dotnet-sdk-version: '9.x' + build-configuration: 'Release' + build-platform: 'Any CPU' + git-version: '6.0.x' + test-result-directory: 'test-results' + nuget-packages-directory: 'nuget-packages' + +jobs: + workflow-variables: + name: 'Set workflow variables' + runs-on: ubuntu-latest + + outputs: + is-release: ${{ startsWith(github.base_ref, 'release') }} + is-preview: ${{ startsWith(github.base_ref , 'preview') }} + + steps: + - name: 'Set workflow variables' + run: | + echo "is-release:${{ startsWith(github.base_ref, 'release') }}" + echo "is-preview:${{ startsWith(github.base_ref, 'preview') }}" + + versioning: + name: 'Extract version from branch' + runs-on: ubuntu-latest + needs: [workflow-variables] + outputs: + friendly-version: ${{ steps.format-version.outputs.friendly-version }} + assembly-version: ${{ steps.format-version.outputs.assembly-version }} + assembly-informational-version: ${{ steps.format-version.outputs.assembly-informational-version }} + file-version: ${{ steps.format-version.outputs.file-version }} + release-version: ${{ steps.format-version.outputs.release-version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Extract version from branch name' + id: extract-version + uses: './.github/actions/versioning/extract-version' + with: + branch-name: ${{ github.base_ref }} + - name: 'Create build number' + shell: bash + id: create-build-number + run: | + git fetch --unshallow --filter=tree:0 + build_number=$(git rev-list --count origin/${{ github.base_ref }} ^origin/main) + echo "build-number=$build_number" >> $GITHUB_OUTPUT + - name: 'Create pre-release tag' + shell: bash + id: create-pre-release-tag + env: + build-number: ${{ steps.create-build-number.outputs.build-number }} + run: | + if [[ '${{ needs.workflow-variables.outputs.is-release }}' == 'true' ]]; then + echo "pre-release-tag=" >> $GITHUB_OUTPUT + elif [[ '${{ needs.workflow-variables.outputs.is-preview }}' == 'true' ]]; then + pre_release_tag='preview' + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + else + pre_release_tag=$(echo ${{ github.base_ref }} | tr '/' '-' | tr '.' '-'| tr '_' '-') + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + fi + - name: 'Format version' + id: format-version + uses: ./.github/actions/versioning/format-version + with: + version: ${{ steps.extract-version.outputs.version }} + patch: ${{ github.run_number }} + build-number: ${{ steps.create-build-number.outputs.build-number }} + sha: ${{ github.sha }} + pre-release-tag: ${{ steps.create-pre-release-tag.outputs.pre-release-tag }} + + build: + name: 'Compile source code' + needs: [workflow-variables, versioning] + runs-on: ubuntu-latest + + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Compile source code' + uses: ./.github/actions/source/compile + with: + project-path: '**/PolylineAlgorithm.csproj' + assembly-version: ${{ env.assembly-version }} + assembly-informational-version: ${{ env.assembly-informational-version }} + file-version: ${{ env.file-version }} + treat-warnins-as-error: ${{ needs.workflow-variables.outputs.is-release }} + + test: + name: 'Run tests' + needs: [build] + runs-on: ubuntu-latest + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Run tests' + uses: ./.github/actions/testing/test + with: + project-path: '**/PolylineAlgorithm.Tests.csproj' + test-results-directory: '${{ runner.temp }}/${{ env.test-result-directory }}/' + code-coverage-settings-file: '${{ github.workspace}}/code-coverage-settings.xml' + + - name: 'Generate test report' + uses: ./.github/actions/testing/test-report + id: test-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write test report summary + run: cat ${{ steps.test-report.outputs.test-report-file }} >> $GITHUB_STEP_SUMMARY + + - name: 'Generate code coverage' + uses: ./.github/actions/testing/code-coverage + id: code-coverage-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write code coverage report summary + run: cat ${{ steps.code-coverage-report.outputs.code-coverage-report-file }} >> $GITHUB_STEP_SUMMARY + + pack: + name: 'Package binaries' + needs: [versioning, build] + runs-on: ubuntu-latest + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + release-version: ${{ needs.versioning.outputs.release-version }} + package-artifact-name: package + outputs: + package-artifact-name: ${{ env.package-artifact-name }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: Download Build + uses: actions/download-artifact@v5 + with: + name: build + + - name: Pack with .NET + run: | + dotnet pack ${{ vars.SRC_DEFAULT_GLOB_PATTERN }} --configuration ${{ env.build-configuration }} /p:Platform="${{ env.build-platform }}" /p:PackageVersion=${{ env.release-version }} /p:Version=${{ env.assembly-version }} /p:AssemblyInformationalVersion=${{ env.assembly-informational-version }} /p:FileVersion=${{ env.file-version }} --output ${{ runner.temp }}/${{ env.nuget-packages-directory }} + + - name: Upload Package + uses: actions/upload-artifact@v4 + with: + name: ${{ env.package-artifact-name }} + path: | + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.nupkg + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.snupkg + + publish-development-package: + name: 'Publish development package' + needs: [pack] + env: + package-artifact-name: ${{ needs.pack.outputs.package-artifact-name }} + runs-on: ubuntu-latest + environment: 'Development' + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Publish package to Azure Artifact feed' + uses: ./.github/actions/nuget/publish-package + with: + package-artifact-name: ${{ env.package-artifact-name }} + nuget-feed-url: ${{ vars.NUGET_PACKAGE_FEED_URL }} + nuget-feed-api-key: ${{ secrets.NUGET_PACKAGE_FEED_API_KEY }} + nuget-feed-server: 'AzureArtifacts' + working-directory: ${{ runner.temp }}/${{ env.nuget-packages-directory }} + dotnet-sdk-version: ${{ env.dotnet-sdk-version }}' + + benchmark: + if: ${{ github.env.is_release || vars.BENCHMARKDOTNET_RUN_OVERRIDE == 'true' }} + name: Benchmark with .NET CLI on ${{ matrix.os }} + needs: [build] + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: Install .NET SDK + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.x + 9.x + - name: Download Build + uses: actions/download-artifact@v5 + with: + name: build + - name: Benchmark + working-directory: ${{ vars.BENCHMARKDOTNET_WORKING_DIRECTORY }} + run: dotnet run --configuration ${{ env.build-configuration }} /p:Platform=${{ env.build-platform }} --framework ${{ vars.DEFAULT_BUILD_FRAMEWORK }} --runtimes ${{ vars.BENCHMARKDOTNET_RUNTIMES }} --filter ${{ vars.BENCHMARKDOTNET_FILTER }} --artifacts ${{ runner.temp }}/benchmarks/ --exporters GitHub --memory --iterationTime 100 --join + - name: Upload Benchmark Results + uses: actions/upload-artifact@v4 + with: + name: benchmark-${{ matrix.os }} + path: | + ${{ runner.temp }}/benchmarks/**/*-report-github.md + - name: Write Benchmark Summary + shell: bash + run: cat **/*-report-github.md > $GITHUB_STEP_SUMMARY + working-directory: ${{ runner.temp }}/benchmarks/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..35af2740 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,249 @@ +name: 'Release' + +on: + push: + branches: + - 'preview/**' + - 'release/**' + paths: + - 'src/**' + +permissions: + actions: read + pages: write + id-token: write + contents: write + +concurrency: + group: release-${{ github.head_ref || github.ref }} + cancel-in-progress: false + +env: + dotnet-sdk-version: '9.x' + build-configuration: 'Release' + build-platform: 'Any CPU' + git-version: '6.0.x' + test-result-directory: 'test-results' + nuget-packages-directory: 'nuget-packages' + +jobs: + workflow-variables: + name: 'Set workflow variables' + runs-on: ubuntu-latest + + outputs: + is-release: ${{ startsWith(github.ref_name, 'release') }} + is-preview: ${{ startsWith(github.ref_name, 'preview') }} + + steps: + - name: 'Set workflow variables' + id: github + run: | + echo "is-release:${{ startsWith(github.ref_name, 'release') }}" + echo "is-preview:${{ startsWith(github.ref_name, 'preview') }}" + + validate-release: + name: 'Validate release' + needs: [workflow-variables] + runs-on: ubuntu-latest + steps: + - name: 'Validate release branch' + if: ${{ needs.workflow-variables.outputs.is-release != 'true' && needs.workflow-variables.outputs.is-preview != 'true' }} + run: | + echo "This workflow can only be run on 'release/**' or 'preview/**' branches." + exit 1 + + versioning: + name: 'Extract version from branch' + runs-on: ubuntu-latest + needs: [workflow-variables, validate-release] + outputs: + friendly-version: ${{ steps.format-version.outputs.friendly-version }} + assembly-version: ${{ steps.format-version.outputs.assembly-version }} + assembly-informational-version: ${{ steps.format-version.outputs.assembly-informational-version }} + file-version: ${{ steps.format-version.outputs.file-version }} + release-version: ${{ steps.format-version.outputs.release-version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + - name: 'Setup .NET ${{ env.dotnet-sdk-version }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + - name: 'Extract version from branch name' + id: extract-version + uses: './.github/actions/versioning/extract-version' + with: + branch-name: ${{ github.ref_name }} + - name: 'Create build number' + shell: bash + id: create-build-number + run: | + git fetch --unshallow --filter=tree:0 + build_number=$(git rev-list --count origin/${{ github.ref_name }} ^origin/main) + echo "build-number=$build_number" >> $GITHUB_OUTPUT + - name: 'Create pre-release tag' + shell: bash + id: create-pre-release-tag + env: + build-number: ${{ steps.create-build-number.outputs.build-number }} + run: | + if [[ '${{ needs.workflow-variables.outputs.is-release }}' == 'true' ]]; then + echo "pre-release-tag=" >> $GITHUB_OUTPUT + elif [[ '${{ needs.workflow-variables.outputs.is-preview }}' == 'true' ]]; then + pre_release_tag='preview' + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + else + pre_release_tag=$(echo ${{ github.ref_name }} | tr '/' '-' | tr '.' '-'| tr '_' '-') + echo "pre-release-tag=$pre_release_tag" >> $GITHUB_OUTPUT + fi + - name: 'Format version' + id: format-version + uses: ./.github/actions/versioning/format-version + with: + version: ${{ steps.extract-version.outputs.version }} + patch: ${{ github.run_number }} + build-number: ${{ steps.create-build-number.outputs.build-number }} + sha: ${{ github.sha }} + pre-release-tag: ${{ steps.create-pre-release-tag.outputs.pre-release-tag }} + + build: + name: 'Compile source code' + needs: [workflow-variables, versioning, validate-release] + runs-on: ubuntu-latest + + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Compile source code' + uses: ./.github/actions/source/compile + with: + project-path: '**/PolylineAlgorithm.csproj' + assembly-version: ${{ env.assembly-version }} + assembly-informational-version: ${{ env.assembly-informational-version }} + file-version: ${{ env.file-version }} + treat-warnins-as-error: ${{ needs.workflow-variables.outputs.is-release }} + + test: + name: 'Run tests' + needs: [build, validate-release] + runs-on: ubuntu-latest + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Setup .NET' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Run tests' + uses: ./.github/actions/testing/test + with: + project-path: '**/PolylineAlgorithm.Tests.csproj' + test-results-directory: '${{ runner.temp }}/${{ env.test-result-directory }}/' + code-coverage-settings-file: '${{ github.workspace}}/code-coverage-settings.xml' + + - name: 'Generate test report' + uses: ./.github/actions/testing/test-report + id: test-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write test report summary + run: cat ${{ steps.test-report.outputs.test-report-file }} >> $GITHUB_STEP_SUMMARY + + - name: 'Generate code coverage' + uses: ./.github/actions/testing/code-coverage + id: code-coverage-report + with: + test-result-folder: '${{ runner.temp }}/${{ env.test-result-directory }}/' + + - name: Write code coverage report summary + run: cat ${{ steps.code-coverage-report.outputs.code-coverage-report-file }} >> $GITHUB_STEP_SUMMARY + + pack: + name: 'Package binaries' + needs: [versioning, build, test, validate-release] + runs-on: ubuntu-latest + env: + assembly-version: ${{ needs.versioning.outputs.assembly-version }} + assembly-informational-version: ${{ needs.versioning.outputs.assembly-informational-version }} + file-version: ${{ needs.versioning.outputs.file-version }} + release-version: ${{ needs.versioning.outputs.release-version }} + package-artifact-name: package + outputs: + package-artifact-name: ${{ env.package-artifact-name }} + steps: + - name: 'Checkout ${{ github.base_ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: Download Build + uses: actions/download-artifact@v5 + with: + name: build + + - name: Pack with .NET + run: | + dotnet pack ${{ vars.SRC_DEFAULT_GLOB_PATTERN }} --configuration ${{ env.build-configuration }} /p:Platform="${{ env.build-platform }}" /p:PackageVersion=${{ env.release-version }} /p:Version=${{ env.assembly-version }} /p:AssemblyInformationalVersion=${{ env.assembly-informational-version }} /p:FileVersion=${{ env.file-version }} --output ${{ runner.temp }}/${{ env.nuget-packages-directory }} + + - name: Upload Package + uses: actions/upload-artifact@v4 + with: + name: ${{ env.package-artifact-name }} + path: | + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.nupkg + ${{ runner.temp }}/${{ env.nuget-packages-directory }}/**/*.snupkg + + publish-package: + name: 'Publish package' + needs: [pack, validate-release] + env: + package-artifact-name: ${{ needs.pack.outputs.package-artifact-name }} + runs-on: ubuntu-latest + environment: 'NuGet' + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.dotnet-sdk-version }} + + - name: 'Publish package to Azure Artifact feed' + uses: ./.github/actions/nuget/publish-package + with: + package-artifact-name: ${{ env.package-artifact-name }} + nuget-feed-url: ${{ vars.NUGET_PACKAGE_FEED_URL }} + nuget-feed-api-key: ${{ secrets.NUGET_PACKAGE_FEED_API_KEY }} + nuget-feed-server: 'NuGet' + working-directory: ${{ runner.temp }}/${{ env.nuget-packages-directory }} + dotnet-sdk-version: ${{ env.dotnet-sdk-version }}' + + + release: + name: 'Create release' + needs: [publish-package, validate-release, versioning] + runs-on: ubuntu-latest + env: + release-version: ${{ needs.versioning.outputs.release-version }} + steps: + - name: 'Checkout ${{ github.head_ref || github.ref }}' + uses: actions/checkout@v5 + + - name: 'Create GitHub Release' + uses: ./.github/actions/github/create-release + with: + release-version: ${{ env.release-version }} diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index 1526b959..00000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Your GitHub workflow file under .github/workflows/ -# Trigger the action on push to main -on: - push: - branches: - - main - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - actions: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - publish-docs: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Dotnet Setup - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.x - - - run: dotnet tool update -g docfx - - run: docfx ./docs/docfx.json - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - # Upload entire repository - path: './docs/_site' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 3c4efe20..88197d63 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + +# BenchmarkDotNet artifacts +**/BenchmarkDotNet.Artifacts/ diff --git a/DropoutCoder.PolylineAlgorithm.sln b/DropoutCoder.PolylineAlgorithm.sln deleted file mode 100644 index a7673087..00000000 --- a/DropoutCoder.PolylineAlgorithm.sln +++ /dev/null @@ -1,61 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.8.34330.188 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm", "src\DropoutCoder.PolylineAlgorithm.csproj", "{882322A6-E758-4662-8D1C-7C555C8FC3F2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{51C886AF-D610-48A4-9D73-2DEB38742801}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{576FEFFC-B624-40C3-A8AF-4E5233802EA0}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{7F9807A1-01FF-40C3-9342-3F3F35D632DA}" - ProjectSection(SolutionItems) = preProject - nuget\DropoutCoder.PolylineAlgorithm.nuspec = nuget\DropoutCoder.PolylineAlgorithm.nuspec - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Tests", "tests\DropoutCoder.PolylineAlgorithm.Tests.csproj", "{30324A08-AA42-425D-87DA-8F9C6AF60454}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C13E31F9-B8EF-4915-A1C8-BC33F6431EB9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{33C03F16-4313-4579-87E6-65892AF21D7D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks.csproj", "{9C7CBAD5-415B-4589-86E1-01C849F9C56C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {882322A6-E758-4662-8D1C-7C555C8FC3F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {882322A6-E758-4662-8D1C-7C555C8FC3F2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {882322A6-E758-4662-8D1C-7C555C8FC3F2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {882322A6-E758-4662-8D1C-7C555C8FC3F2}.Release|Any CPU.Build.0 = Release|Any CPU - {30324A08-AA42-425D-87DA-8F9C6AF60454}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {30324A08-AA42-425D-87DA-8F9C6AF60454}.Debug|Any CPU.Build.0 = Debug|Any CPU - {30324A08-AA42-425D-87DA-8F9C6AF60454}.Release|Any CPU.ActiveCfg = Release|Any CPU - {30324A08-AA42-425D-87DA-8F9C6AF60454}.Release|Any CPU.Build.0 = Release|Any CPU - {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Release|Any CPU.Build.0 = Release|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {882322A6-E758-4662-8D1C-7C555C8FC3F2} = {51C886AF-D610-48A4-9D73-2DEB38742801} - {30324A08-AA42-425D-87DA-8F9C6AF60454} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} - {9C7CBAD5-415B-4589-86E1-01C849F9C56C} = {33C03F16-4313-4579-87E6-65892AF21D7D} - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B} = {33C03F16-4313-4579-87E6-65892AF21D7D} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82} - EndGlobalSection -EndGlobal diff --git a/LICENSE b/LICENSE index ee65c099..f38ec86e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Petr Šrámek +Copyright (c) 2025 Pete Sramek Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/PolylineAlgorithm.slnx b/PolylineAlgorithm.slnx new file mode 100644 index 00000000..5eac2683 --- /dev/null +++ b/PolylineAlgorithm.slnx @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 2695d8c8..156a8f2a 100644 --- a/README.md +++ b/README.md @@ -1,113 +1,29 @@ -# .NET Polyline Algorithm (.NET Standard 2.0) +# PolylineAlgorithm for .NET -Lightweight .NET Standard 2.0 library implementing Google Polyline Algorithm. Designed with respect to flexibility, but still with easy to use. +[![NuGet](https://img.shields.io/nuget/v/PolylineAlgorithm.svg)](https://www.nuget.org/packages/PolylineAlgorithm/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![Build](https://github.com/sramekpete/polyline-algorithm-csharp/actions/workflows/build.yml/badge.svg)](https://github.com/sramekpete/polyline-algorithm-csharp/actions/workflows/build.yml) -## Getting started -### Prerequisites +Lightweight .NET Standard 2.1 library implementing Google Encoded Polyline Algorithm. +Package should be primarily used as baseline for libraries that implement polyline encoding/decoding functionality. -.NET Polyline Algorithm is avalable as nuget package Cloudikka.PolylineAlgorithm targeting .NET Standard 2.0. +More info about the algorithm can be found at [Google Developers](https://developers.google.com/maps/documentation/utilities/polylinealgorithm). -Command line: +## Prerequisites -`Install-Package Cloudikka.PolylineAlgorithm` +PolylineAlgorithm for .NET is available as a NuGet package targeting .NET Standard 2.1. -NuGet Package Manager: +.NET CLI: `dotnet add package PolylineAlgorithm` -`Cloudikka.PolylineAlgorithm` +Package Manager Console: `Install-Package PolylineAlgorithm` -#### Warning +## How to use it -Library is using ValueTuple Structure. ValueTuple struct is avalable in .NET Framework 4.7 and above. Incase your project is targeting lower version of .NET Framework you probably have to install System.ValueTuple NuGet package. (not tested yet) - -Command line: +In the majority of cases you would like to inherit `AbstractPolylineDecoder` and `AbstractPolylineEncoder` classes and implement abstract methods that are mainly responsible for extracting data from your coordinate and polyline types and creating new instances of them. -`Install-Package System.ValueTuple` +In some cases you may want to implement your own decoder and encoder from scratch. +In that case you can use `PolylineEncoding` static class that offers static methods for encoding and decoding polyline segments. -NuGet Package Manager: +## Documentation -`System.ValueTuple` - -### Hot to use it - -There are three ways how to use .NET Polyline Algorithm library based on your needs. For each is available Encode and Decode methods. - -#### Static methods - -Whenever you just need to encode or decode Google polyline you can use static methods defined in static PolylineAlgorithm class. - -##### Decoding - -```csharp - string polyline = "polyline"; - IEnumerable<(double, double)> coordinates = PolylineAlgorithm.Decode(polyline); -``` - -##### Encoding - -```csharp - IEnumerable<(double, double)> coordinates = new (double, double) [] { (35.635, 76.27182), (35.2435, 75.625), ... }; - string polyline = PolylineAlgorithm.Encode(coordinates); -``` - - -#### Default instance - -If you need to use dependency injection, you would like to have instance to deliver the work for you. In that case you can use default instance of PolylineEncoding class, which implements IPolylineEncoding<(double Latitude, double Longitude)> interface. - -##### Decoding - -```csharp - string polyline = "polyline"; - var encoding = new PolylineEncoding(); - IEnumerable<(double, double)> coordinates = encoding.Decode(polyline); -``` - -##### Encoding - -```csharp - IEnumerable<(double, double)> coordinates = new (double, double) [] { (35.635, 76.27182), (35.2435, 75.625), ... }; - var encoding = new PolylineEncoding(); - string polyline = encoding.Encode(coordinates); -``` - -#### Inherited base class - -There may be a scenario you need to pass and return different types to and from without a need to add another extra layer. In this case you can inherit PolylineEncodingBase class and override template methods CreateResult and GetCoordinates. - -##### Inheriting - -```csharp - public class MyPolylineEncoding : PolylineEncodingBase { - - protected override Coordinate CreateResult(double latitude, double longitude) { - return new Coordinate(latitude, longitude); - } - - protected override (double Latitude, double Longitude) GetCoordinate(Coordinate source) { - return (source.Latitude, source.Longitude); - } - - } -``` - -##### Decoding - -```csharp - string polyline = "polyline"; - var encoding = new MyPolylineEncoding(); - IEnumerable coordinates = encoding.Decode(polyline); -``` - -##### Encoding - -```csharp - IEnumerable coordinates = new Coordinate [] { new Coordinate(35.635, 76.27182), new Coordinate(35.2435, 75.625), ... }; - var encoding = new MyPolylineEncoding(); - string polyline = encoding.Encode(coordinates); -``` - -### Documentation - -Documentation is can be found at https://dropoutcoder.github.io/polyline-algorithm-csharp/api/index.html. - -Happy coding! +Documentation is can be found at [https://sramekpete.github.io/polyline-algorithm-csharp/](https://sramekpete.github.io/polyline-algorithm-csharp/). \ No newline at end of file diff --git a/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.yml b/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.yml new file mode 100644 index 00000000..fef191a3 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.yml @@ -0,0 +1,190 @@ +### YamlMime:ApiPage +title: Class AbstractPolylineDecoder +body: +- api1: Class AbstractPolylineDecoder + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2 + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L23 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2 + commentId: T:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2 +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Abstraction + url: PolylineAlgorithm.Abstraction.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. +- code: 'public abstract class AbstractPolylineDecoder : IPolylineDecoder' +- h4: Type Parameters +- parameters: + - name: TPolyline + - name: TCoordinate +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: AbstractPolylineDecoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.html +- h4: Implements +- list: + - text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: This abstract class provides a base implementation for decoding polylines, allowing subclasses to define how to handle specific polyline formats. +- h2: Constructors +- api3: AbstractPolylineDecoder() + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L27 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.#ctor + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.#ctor +- markdown: Initializes a new instance of the class with default encoding options. +- code: protected AbstractPolylineDecoder() +- api3: AbstractPolylineDecoder(PolylineEncodingOptions) + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2__ctor_PolylineAlgorithm_PolylineEncodingOptions_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L39 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.#ctor(PolylineAlgorithm.PolylineEncodingOptions) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.#ctor(PolylineAlgorithm.PolylineEncodingOptions) +- markdown: Initializes a new instance of the class with the specified encoding options. +- code: protected AbstractPolylineDecoder(PolylineEncodingOptions options) +- h4: Parameters +- parameters: + - name: options + type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: The to use for encoding operations. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when options is null +- h2: Properties +- api3: Options + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_Options + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L46 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.Options + commentId: P:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.Options +- markdown: Gets the encoding options used by this polyline encoder. +- code: public PolylineEncodingOptions Options { get; } +- h4: Property Value +- parameters: + - type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html +- h2: Methods +- api3: CreateCoordinate(double, double) + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_CreateCoordinate_System_Double_System_Double_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L153 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.CreateCoordinate(System.Double,System.Double) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.CreateCoordinate(System.Double,System.Double) +- markdown: Creates a coordinate instance from the given latitude and longitude values. +- code: protected abstract TCoordinate CreateCoordinate(double latitude, double longitude) +- h4: Parameters +- parameters: + - name: latitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The latitude value. + - name: longitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The longitude value. +- h4: Returns +- parameters: + - type: + - TCoordinate + description: A coordinate instance of type TCoordinate. +- api3: Decode(TPolyline) + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_Decode__0_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L66 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.Decode(`0) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.Decode(`0) +- markdown: Decodes an encoded TPolyline into a sequence of TCoordinate instances. +- code: public IEnumerable Decode(TPolyline polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - TPolyline + description: The TPolyline instance containing the encoded polyline string to decode. +- h4: Returns +- parameters: + - type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - TCoordinate + - '>' + description: An of TCoordinate representing the decoded latitude and longitude pairs. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when polyline is null. + - type: + - text: ArgumentException + url: https://learn.microsoft.com/dotnet/api/system.argumentexception + description: Thrown when polyline is empty. + - type: + - text: InvalidPolylineException + url: PolylineAlgorithm.InvalidPolylineException.html + description: Thrown when the polyline format is invalid or malformed at a specific position. +- api3: GetReadOnlyMemory(TPolyline) + id: PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_GetReadOnlyMemory__0_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs#L139 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.GetReadOnlyMemory(`0) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineDecoder`2.GetReadOnlyMemory(`0) +- markdown: Converts the provided polyline instance into a for decoding. +- code: protected abstract ReadOnlyMemory GetReadOnlyMemory(TPolyline polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - TPolyline + description: The TPolyline instance containing the encoded polyline data to decode. +- h4: Returns +- parameters: + - type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A representing the encoded polyline data. +languageId: csharp +metadata: + description: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. diff --git a/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.yml b/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.yml new file mode 100644 index 00000000..74595727 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.yml @@ -0,0 +1,204 @@ +### YamlMime:ApiPage +title: Class AbstractPolylineEncoder +body: +- api1: Class AbstractPolylineEncoder + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2 + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L25 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2 + commentId: T:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2 +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Abstraction + url: PolylineAlgorithm.Abstraction.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. +- code: 'public abstract class AbstractPolylineEncoder : IPolylineEncoder' +- h4: Type Parameters +- parameters: + - name: TCoordinate + - name: TPolyline +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: AbstractPolylineEncoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.html +- h4: Implements +- list: + - text: IPolylineEncoder + url: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: This abstract class serves as a base for specific polyline encoders, allowing customization of the encoding process. +- h2: Constructors +- api3: AbstractPolylineEncoder() + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L29 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.#ctor + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.#ctor +- markdown: Initializes a new instance of the class with default encoding options. +- code: protected AbstractPolylineEncoder() +- api3: AbstractPolylineEncoder(PolylineEncodingOptions) + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2__ctor_PolylineAlgorithm_PolylineEncodingOptions_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L39 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.#ctor(PolylineAlgorithm.PolylineEncodingOptions) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.#ctor(PolylineAlgorithm.PolylineEncodingOptions) +- markdown: Initializes a new instance of the class with the specified encoding options. +- code: protected AbstractPolylineEncoder(PolylineEncodingOptions options) +- h4: Parameters +- parameters: + - name: options + type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: The to use for encoding operations. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when options is null +- h2: Properties +- api3: Options + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_Options + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L46 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.Options + commentId: P:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.Options +- markdown: Gets the encoding options used by this polyline encoder. +- code: public PolylineEncodingOptions Options { get; } +- h4: Property Value +- parameters: + - type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html +- h2: Methods +- api3: CreatePolyline(ReadOnlyMemory) + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_CreatePolyline_System_ReadOnlyMemory_System_Char__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L199 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.CreatePolyline(System.ReadOnlyMemory{System.Char}) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.CreatePolyline(System.ReadOnlyMemory{System.Char}) +- markdown: Creates a polyline instance from the provided read-only sequence of characters. +- code: protected abstract TPolyline CreatePolyline(ReadOnlyMemory polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A containing the encoded polyline characters. +- h4: Returns +- parameters: + - type: + - TPolyline + description: An instance of TPolyline representing the encoded polyline. +- api3: Encode(IEnumerable) + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_Encode_System_Collections_Generic_IEnumerable__0__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L64 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.Encode(System.Collections.Generic.IEnumerable{`0}) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.Encode(System.Collections.Generic.IEnumerable{`0}) +- markdown: Encodes a collection of TCoordinate instances into an encoded TPolyline string. +- code: public TPolyline Encode(IEnumerable coordinates) +- h4: Parameters +- parameters: + - name: coordinates + type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - TCoordinate + - '>' + description: The collection of TCoordinate objects to encode. +- h4: Returns +- parameters: + - type: + - TPolyline + description: >- + An instance of TPolyline representing the encoded coordinates. + + Returns default if the input collection is empty or null. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when coordinates is null. + - type: + - text: ArgumentException + url: https://learn.microsoft.com/dotnet/api/system.argumentexception + description: Thrown when coordinates is an empty enumeration. +- api3: GetLatitude(TCoordinate) + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_GetLatitude__0_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L219 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.GetLatitude(`0) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.GetLatitude(`0) +- markdown: Extracts the latitude value from the specified coordinate. +- code: protected abstract double GetLatitude(TCoordinate current) +- h4: Parameters +- parameters: + - name: current + type: + - TCoordinate + description: The coordinate from which to extract the latitude. +- h4: Returns +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The latitude value as a . +- api3: GetLongitude(TCoordinate) + id: PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_GetLongitude__0_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs#L209 + metadata: + uid: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.GetLongitude(`0) + commentId: M:PolylineAlgorithm.Abstraction.AbstractPolylineEncoder`2.GetLongitude(`0) +- markdown: Extracts the longitude value from the specified coordinate. +- code: protected abstract double GetLongitude(TCoordinate current) +- h4: Parameters +- parameters: + - name: current + type: + - TCoordinate + description: The coordinate from which to extract the longitude. +- h4: Returns +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The longitude value as a . +languageId: csharp +metadata: + description: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. diff --git a/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineDecoder-2.yml b/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineDecoder-2.yml new file mode 100644 index 00000000..c548a5cf --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineDecoder-2.yml @@ -0,0 +1,49 @@ +### YamlMime:ApiPage +title: Interface IPolylineDecoder +body: +- api1: Interface IPolylineDecoder + id: PolylineAlgorithm_Abstraction_IPolylineDecoder_2 + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs#L13 + metadata: + uid: PolylineAlgorithm.Abstraction.IPolylineDecoder`2 + commentId: T:PolylineAlgorithm.Abstraction.IPolylineDecoder`2 +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Abstraction + url: PolylineAlgorithm.Abstraction.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Defines a contract for decoding an encoded polyline into a sequence of geographic coordinates. +- code: public interface IPolylineDecoder +- h4: Type Parameters +- parameters: + - name: TPolyline + - name: TCoordinate +- h2: Methods +- api3: Decode(TPolyline) + id: PolylineAlgorithm_Abstraction_IPolylineDecoder_2_Decode__0_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs#L23 + metadata: + uid: PolylineAlgorithm.Abstraction.IPolylineDecoder`2.Decode(`0) + commentId: M:PolylineAlgorithm.Abstraction.IPolylineDecoder`2.Decode(`0) +- markdown: Decodes the specified encoded polyline into a sequence of geographic coordinates. +- code: IEnumerable Decode(TPolyline polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - TPolyline + description: The TPolyline instance containing the encoded polyline string to decode. +- h4: Returns +- parameters: + - type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - TCoordinate + - '>' + description: An of TCoordinate representing the decoded latitude and longitude pairs. +languageId: csharp +metadata: + description: Defines a contract for decoding an encoded polyline into a sequence of geographic coordinates. diff --git a/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineEncoder-2.yml b/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineEncoder-2.yml new file mode 100644 index 00000000..99fbc198 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Abstraction.IPolylineEncoder-2.yml @@ -0,0 +1,49 @@ +### YamlMime:ApiPage +title: Interface IPolylineEncoder +body: +- api1: Interface IPolylineEncoder + id: PolylineAlgorithm_Abstraction_IPolylineEncoder_2 + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs#L13 + metadata: + uid: PolylineAlgorithm.Abstraction.IPolylineEncoder`2 + commentId: T:PolylineAlgorithm.Abstraction.IPolylineEncoder`2 +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Abstraction + url: PolylineAlgorithm.Abstraction.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Defines a contract for encoding a sequence of geographic coordinates into an encoded polyline string. +- code: public interface IPolylineEncoder +- h4: Type Parameters +- parameters: + - name: TCoordinate + - name: TPolyline +- h2: Methods +- api3: Encode(IEnumerable) + id: PolylineAlgorithm_Abstraction_IPolylineEncoder_2_Encode_System_Collections_Generic_IEnumerable__0__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs#L23 + metadata: + uid: PolylineAlgorithm.Abstraction.IPolylineEncoder`2.Encode(System.Collections.Generic.IEnumerable{`0}) + commentId: M:PolylineAlgorithm.Abstraction.IPolylineEncoder`2.Encode(System.Collections.Generic.IEnumerable{`0}) +- markdown: Encodes a sequence of geographic coordinates into an encoded polyline representation. +- code: TPolyline Encode(IEnumerable coordinates) +- h4: Parameters +- parameters: + - name: coordinates + type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - TCoordinate + - '>' + description: The collection of TCoordinate instances to encode into a polyline. +- h4: Returns +- parameters: + - type: + - TPolyline + description: A TPolyline containing the encoded polyline string that represents the input coordinates. +languageId: csharp +metadata: + description: Defines a contract for encoding a sequence of geographic coordinates into an encoded polyline string. diff --git a/api-reference/1.0/PolylineAlgorithm.Abstraction.yml b/api-reference/1.0/PolylineAlgorithm.Abstraction.yml new file mode 100644 index 00000000..ff580e3c --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Abstraction.yml @@ -0,0 +1,35 @@ +### YamlMime:ApiPage +title: Namespace PolylineAlgorithm.Abstraction +body: +- api1: Namespace PolylineAlgorithm.Abstraction + id: PolylineAlgorithm_Abstraction + metadata: + uid: PolylineAlgorithm.Abstraction + commentId: N:PolylineAlgorithm.Abstraction +- h3: Classes +- parameters: + - type: + text: AbstractPolylineDecoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.html + description: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. + - type: + text: AbstractPolylineEncoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.html + description: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. +- h3: Interfaces +- parameters: + - type: + text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html + description: Defines a contract for decoding an encoded polyline into a sequence of geographic coordinates. + - type: + text: IPolylineEncoder + url: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.html + description: Defines a contract for encoding a sequence of geographic coordinates into an encoded polyline string. +languageId: csharp diff --git a/api-reference/1.0/PolylineAlgorithm.Coordinate.yml b/api-reference/1.0/PolylineAlgorithm.Coordinate.yml new file mode 100644 index 00000000..809d45d2 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Coordinate.yml @@ -0,0 +1,250 @@ +### YamlMime:ApiPage +title: Struct Coordinate +body: +- api1: Struct Coordinate + id: PolylineAlgorithm_Coordinate + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L22 + metadata: + uid: PolylineAlgorithm.Coordinate + commentId: T:PolylineAlgorithm.Coordinate +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Represents a geographic coordinate as a pair of latitude and longitude values. +- code: 'public readonly struct Coordinate : IEquatable' +- h4: Implements +- list: + - text: IEquatable + url: https://learn.microsoft.com/dotnet/api/system.iequatable-1 +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: >- + This struct is designed to be immutable and lightweight, providing a simple way to represent + + geographic coordinates in degrees. It includes validation for latitude and longitude ranges + + and provides methods for equality comparison and string representation. +- h2: Constructors +- api3: Coordinate() + id: PolylineAlgorithm_Coordinate__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L28 + metadata: + uid: PolylineAlgorithm.Coordinate.#ctor + commentId: M:PolylineAlgorithm.Coordinate.#ctor +- markdown: Initializes a new instance of the struct with default values (0) for and . +- code: public Coordinate() +- api3: Coordinate(double, double) + id: PolylineAlgorithm_Coordinate__ctor_System_Double_System_Double_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L46 + metadata: + uid: PolylineAlgorithm.Coordinate.#ctor(System.Double,System.Double) + commentId: M:PolylineAlgorithm.Coordinate.#ctor(System.Double,System.Double) +- markdown: Initializes a new instance of the struct with the specified latitude and longitude values. +- code: public Coordinate(double latitude, double longitude) +- h4: Parameters +- parameters: + - name: latitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The latitude component of the coordinate, in degrees. Must be between -90 and 90. + - name: longitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The longitude component of the coordinate, in degrees. Must be between -180 and 180. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentOutOfRangeException + url: https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception + description: >- + Thrown when latitude is less than -90 or greater than 90, + + or when longitude is less than -180 or greater than 180. +- h2: Properties +- api3: Latitude + id: PolylineAlgorithm_Coordinate_Latitude + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L62 + metadata: + uid: PolylineAlgorithm.Coordinate.Latitude + commentId: P:PolylineAlgorithm.Coordinate.Latitude +- markdown: Gets the latitude component of the coordinate, in degrees. +- code: public double Latitude { get; } +- h4: Property Value +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double +- api3: Longitude + id: PolylineAlgorithm_Coordinate_Longitude + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L67 + metadata: + uid: PolylineAlgorithm.Coordinate.Longitude + commentId: P:PolylineAlgorithm.Coordinate.Longitude +- markdown: Gets the longitude component of the coordinate, in degrees. +- code: public double Longitude { get; } +- h4: Property Value +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double +- h2: Methods +- api3: Equals(object?) + id: PolylineAlgorithm_Coordinate_Equals_System_Object_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L82 + metadata: + uid: PolylineAlgorithm.Coordinate.Equals(System.Object) + commentId: M:PolylineAlgorithm.Coordinate.Equals(System.Object) +- markdown: Indicates whether this instance and a specified object are equal. +- code: public override bool Equals(object? obj) +- h4: Parameters +- parameters: + - name: obj + type: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - '?' + description: The object to compare with the current instance. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if obj and this instance are the same type and represent the same value; otherwise, false. +- api3: Equals(Coordinate) + id: PolylineAlgorithm_Coordinate_Equals_PolylineAlgorithm_Coordinate_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L102 + metadata: + uid: PolylineAlgorithm.Coordinate.Equals(PolylineAlgorithm.Coordinate) + commentId: M:PolylineAlgorithm.Coordinate.Equals(PolylineAlgorithm.Coordinate) +- markdown: Indicates whether the current object is equal to another object of the same type. +- code: public bool Equals(Coordinate other) +- h4: Parameters +- parameters: + - name: other + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: An object to compare with this object. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the current object is equal to the other parameter; otherwise, false. +- api3: GetHashCode() + id: PolylineAlgorithm_Coordinate_GetHashCode + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L85 + metadata: + uid: PolylineAlgorithm.Coordinate.GetHashCode + commentId: M:PolylineAlgorithm.Coordinate.GetHashCode +- markdown: Returns the hash code for this instance. +- code: public override int GetHashCode() +- h4: Returns +- parameters: + - type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: A 32-bit signed integer that is the hash code for this instance. +- api3: IsDefault() + id: PolylineAlgorithm_Coordinate_IsDefault + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L75 + metadata: + uid: PolylineAlgorithm.Coordinate.IsDefault + commentId: M:PolylineAlgorithm.Coordinate.IsDefault +- markdown: Determines whether this coordinate is the default value (both and are 0). +- code: public bool IsDefault() +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if both latitude and longitude are 0; otherwise, false. +- api3: ToString() + id: PolylineAlgorithm_Coordinate_ToString + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L93 + metadata: + uid: PolylineAlgorithm.Coordinate.ToString + commentId: M:PolylineAlgorithm.Coordinate.ToString +- markdown: 'Returns a string representation of this coordinate in the format: { Latitude: [double], Longitude: [double] }.' +- code: public override string ToString() +- h4: Returns +- parameters: + - type: + - text: string + url: https://learn.microsoft.com/dotnet/api/system.string + description: A string representation of the coordinate. +- h2: Operators +- api3: operator ==(Coordinate, Coordinate) + id: PolylineAlgorithm_Coordinate_op_Equality_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Coordinate_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L119 + metadata: + uid: PolylineAlgorithm.Coordinate.op_Equality(PolylineAlgorithm.Coordinate,PolylineAlgorithm.Coordinate) + commentId: M:PolylineAlgorithm.Coordinate.op_Equality(PolylineAlgorithm.Coordinate,PolylineAlgorithm.Coordinate) +- markdown: Determines whether two instances are equal. +- code: public static bool operator ==(Coordinate left, Coordinate right) +- h4: Parameters +- parameters: + - name: left + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: The first coordinate to compare. + - name: right + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: The second coordinate to compare. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if both coordinates are equal; otherwise, false. +- api3: operator !=(Coordinate, Coordinate) + id: PolylineAlgorithm_Coordinate_op_Inequality_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Coordinate_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Coordinate.cs#L129 + metadata: + uid: PolylineAlgorithm.Coordinate.op_Inequality(PolylineAlgorithm.Coordinate,PolylineAlgorithm.Coordinate) + commentId: M:PolylineAlgorithm.Coordinate.op_Inequality(PolylineAlgorithm.Coordinate,PolylineAlgorithm.Coordinate) +- markdown: Determines whether two instances are not equal. +- code: public static bool operator !=(Coordinate left, Coordinate right) +- h4: Parameters +- parameters: + - name: left + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: The first coordinate to compare. + - name: right + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: The second coordinate to compare. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the coordinates are not equal; otherwise, false. +languageId: csharp +metadata: + description: Represents a geographic coordinate as a pair of latitude and longitude values. diff --git a/api-reference/1.0/PolylineAlgorithm.CoordinateValueType.yml b/api-reference/1.0/PolylineAlgorithm.CoordinateValueType.yml new file mode 100644 index 00000000..f39b468a --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.CoordinateValueType.yml @@ -0,0 +1,45 @@ +### YamlMime:ApiPage +title: Enum CoordinateValueType +body: +- api1: Enum CoordinateValueType + id: PolylineAlgorithm_CoordinateValueType + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/CoordinateValueType.cs#L11 + metadata: + uid: PolylineAlgorithm.CoordinateValueType + commentId: T:PolylineAlgorithm.CoordinateValueType +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Represents the type of a geographic coordinate value. +- code: public enum CoordinateValueType +- h2: Fields +- parameters: + - name: Latitude + default: "1" + description: >+ + Represents a latitude value. + + - name: Longitude + default: "2" + description: >+ + Represents a longitude value. + + - name: None + default: "0" + description: >+ + Represents no specific type. This value is used when the type is not applicable or not specified. + +- h2: Remarks +- markdown: >- + This enumeration is used to specify whether a coordinate value represents latitude or + + longitude. Latitude values indicate the north-south position, while longitude values indicate the east-west + + position. +languageId: csharp +metadata: + description: Represents the type of a geographic coordinate value. diff --git a/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineDecoderExtensions.yml b/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineDecoderExtensions.yml new file mode 100644 index 00000000..d318f9b8 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineDecoderExtensions.yml @@ -0,0 +1,182 @@ +### YamlMime:ApiPage +title: Class PolylineDecoderExtensions +body: +- api1: Class PolylineDecoderExtensions + id: PolylineAlgorithm_Extensions_PolylineDecoderExtensions + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs#L16 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineDecoderExtensions + commentId: T:PolylineAlgorithm.Extensions.PolylineDecoderExtensions +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Extensions + url: PolylineAlgorithm.Extensions.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Provides extension methods for the interface to facilitate decoding encoded polylines. +- code: public static class PolylineDecoderExtensions +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: PolylineDecoderExtensions + url: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Methods +- api3: Decode(IPolylineDecoder, string) + id: PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_String_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs#L32 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.String) + commentId: M:PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.String) +- markdown: Decodes an encoded polyline string into a sequence of geographic coordinates. +- code: public static IEnumerable Decode(this IPolylineDecoder decoder, string polyline) +- h4: Parameters +- parameters: + - name: decoder + type: + - text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html + - < + - text: Polyline + url: PolylineAlgorithm.Polyline.html + - ',' + - " " + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: The instance used to perform the decoding operation. + - name: polyline + type: + - text: string + url: https://learn.microsoft.com/dotnet/api/system.string + description: The encoded polyline string to decode. +- h4: Returns +- parameters: + - type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: An containing the decoded latitude and longitude pairs. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when decoder is null. +- api3: Decode(IPolylineDecoder, char[]) + id: PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_Char___ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs#L55 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.Char[]) + commentId: M:PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.Char[]) +- markdown: Decodes an encoded polyline represented as a character array into a sequence of geographic coordinates. +- code: public static IEnumerable Decode(this IPolylineDecoder decoder, char[] polyline) +- h4: Parameters +- parameters: + - name: decoder + type: + - text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html + - < + - text: Polyline + url: PolylineAlgorithm.Polyline.html + - ',' + - " " + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: The instance used to perform the decoding operation. + - name: polyline + type: + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '[' + - ']' + description: The encoded polyline as a character array to decode. +- h4: Returns +- parameters: + - type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: An containing the decoded latitude and longitude pairs. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when decoder is null. +- api3: Decode(IPolylineDecoder, ReadOnlyMemory) + id: PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_ReadOnlyMemory_System_Char__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs#L78 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.ReadOnlyMemory{System.Char}) + commentId: M:PolylineAlgorithm.Extensions.PolylineDecoderExtensions.Decode(PolylineAlgorithm.Abstraction.IPolylineDecoder{PolylineAlgorithm.Polyline,PolylineAlgorithm.Coordinate},System.ReadOnlyMemory{System.Char}) +- markdown: Decodes an encoded polyline represented as a read-only memory of characters into a sequence of geographic coordinates. +- code: public static IEnumerable Decode(this IPolylineDecoder decoder, ReadOnlyMemory polyline) +- h4: Parameters +- parameters: + - name: decoder + type: + - text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html + - < + - text: Polyline + url: PolylineAlgorithm.Polyline.html + - ',' + - " " + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: The instance used to perform the decoding operation. + - name: polyline + type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: The encoded polyline as a read-only memory of characters to decode. +- h4: Returns +- parameters: + - type: + - text: IEnumerable + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: An containing the decoded latitude and longitude pairs. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when decoder is null. +languageId: csharp +metadata: + description: Provides extension methods for the interface to facilitate decoding encoded polylines. diff --git a/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineEncoderExtensions.yml b/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineEncoderExtensions.yml new file mode 100644 index 00000000..4d27b37e --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Extensions.PolylineEncoderExtensions.yml @@ -0,0 +1,130 @@ +### YamlMime:ApiPage +title: Class PolylineEncoderExtensions +body: +- api1: Class PolylineEncoderExtensions + id: PolylineAlgorithm_Extensions_PolylineEncoderExtensions + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs#L16 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineEncoderExtensions + commentId: T:PolylineAlgorithm.Extensions.PolylineEncoderExtensions +- facts: + - name: Namespace + value: + text: PolylineAlgorithm.Extensions + url: PolylineAlgorithm.Extensions.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Provides extension methods for the interface to facilitate encoding geographic coordinates into polylines. +- code: public static class PolylineEncoderExtensions +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: PolylineEncoderExtensions + url: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Methods +- api3: Encode(IPolylineEncoder, ICollection) + id: PolylineAlgorithm_Extensions_PolylineEncoderExtensions_Encode_PolylineAlgorithm_Abstraction_IPolylineEncoder_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Polyline__System_Collections_Generic_ICollection_PolylineAlgorithm_Coordinate__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs#L32 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.Encode(PolylineAlgorithm.Abstraction.IPolylineEncoder{PolylineAlgorithm.Coordinate,PolylineAlgorithm.Polyline},System.Collections.Generic.ICollection{PolylineAlgorithm.Coordinate}) + commentId: M:PolylineAlgorithm.Extensions.PolylineEncoderExtensions.Encode(PolylineAlgorithm.Abstraction.IPolylineEncoder{PolylineAlgorithm.Coordinate,PolylineAlgorithm.Polyline},System.Collections.Generic.ICollection{PolylineAlgorithm.Coordinate}) +- markdown: Encodes a collection of instances into an encoded polyline. +- code: public static Polyline Encode(this IPolylineEncoder encoder, ICollection coordinates) +- h4: Parameters +- parameters: + - name: encoder + type: + - text: IPolylineEncoder + url: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.html + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - ',' + - " " + - text: Polyline + url: PolylineAlgorithm.Polyline.html + - '>' + description: The instance used to perform the encoding operation. + - name: coordinates + type: + - text: ICollection + url: https://learn.microsoft.com/dotnet/api/system.collections.generic.icollection-1 + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '>' + description: The sequence of objects to encode. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: A representing the encoded polyline string for the provided coordinates. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when encoder is null. +- api3: Encode(IPolylineEncoder, Coordinate[]) + id: PolylineAlgorithm_Extensions_PolylineEncoderExtensions_Encode_PolylineAlgorithm_Abstraction_IPolylineEncoder_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Polyline__PolylineAlgorithm_Coordinate___ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs#L55 + metadata: + uid: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.Encode(PolylineAlgorithm.Abstraction.IPolylineEncoder{PolylineAlgorithm.Coordinate,PolylineAlgorithm.Polyline},PolylineAlgorithm.Coordinate[]) + commentId: M:PolylineAlgorithm.Extensions.PolylineEncoderExtensions.Encode(PolylineAlgorithm.Abstraction.IPolylineEncoder{PolylineAlgorithm.Coordinate,PolylineAlgorithm.Polyline},PolylineAlgorithm.Coordinate[]) +- markdown: Encodes an array of instances into an encoded polyline. +- code: public static Polyline Encode(this IPolylineEncoder encoder, Coordinate[] coordinates) +- h4: Parameters +- parameters: + - name: encoder + type: + - text: IPolylineEncoder + url: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.html + - < + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - ',' + - " " + - text: Polyline + url: PolylineAlgorithm.Polyline.html + - '>' + description: The instance used to perform the encoding operation. + - name: coordinates + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + - '[' + - ']' + description: The array of objects to encode. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: A representing the encoded polyline string for the provided coordinates. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when encoder is null. +languageId: csharp +metadata: + description: Provides extension methods for the interface to facilitate encoding geographic coordinates into polylines. diff --git a/api-reference/1.0/PolylineAlgorithm.Extensions.yml b/api-reference/1.0/PolylineAlgorithm.Extensions.yml new file mode 100644 index 00000000..c39da0ca --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Extensions.yml @@ -0,0 +1,19 @@ +### YamlMime:ApiPage +title: Namespace PolylineAlgorithm.Extensions +body: +- api1: Namespace PolylineAlgorithm.Extensions + id: PolylineAlgorithm_Extensions + metadata: + uid: PolylineAlgorithm.Extensions + commentId: N:PolylineAlgorithm.Extensions +- h3: Classes +- parameters: + - type: + text: PolylineDecoderExtensions + url: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.html + description: Provides extension methods for the interface to facilitate decoding encoded polylines. + - type: + text: PolylineEncoderExtensions + url: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.html + description: Provides extension methods for the interface to facilitate encoding geographic coordinates into polylines. +languageId: csharp diff --git a/api-reference/1.0/PolylineAlgorithm.InvalidPolylineException.yml b/api-reference/1.0/PolylineAlgorithm.InvalidPolylineException.yml new file mode 100644 index 00000000..3f440ad0 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.InvalidPolylineException.yml @@ -0,0 +1,73 @@ +### YamlMime:ApiPage +title: Class InvalidPolylineException +body: +- api1: Class InvalidPolylineException + id: PolylineAlgorithm_InvalidPolylineException + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/InvalidPolylineException.cs#L19 + metadata: + uid: PolylineAlgorithm.InvalidPolylineException + commentId: T:PolylineAlgorithm.InvalidPolylineException +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Exception thrown when a polyline is determined to be malformed or invalid during processing. +- code: 'public sealed class InvalidPolylineException : Exception, ISerializable' +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: Exception + url: https://learn.microsoft.com/dotnet/api/system.exception + - text: InvalidPolylineException + url: PolylineAlgorithm.InvalidPolylineException.html +- h4: Implements +- list: + - text: ISerializable + url: https://learn.microsoft.com/dotnet/api/system.runtime.serialization.iserializable +- h4: Inherited Members +- list: + - text: Exception.GetBaseException() + url: https://learn.microsoft.com/dotnet/api/system.exception.getbaseexception + - text: Exception.GetObjectData(SerializationInfo, StreamingContext) + url: https://learn.microsoft.com/dotnet/api/system.exception.getobjectdata + - text: Exception.GetType() + url: https://learn.microsoft.com/dotnet/api/system.exception.gettype + - text: Exception.ToString() + url: https://learn.microsoft.com/dotnet/api/system.exception.tostring + - text: Exception.Data + url: https://learn.microsoft.com/dotnet/api/system.exception.data + - text: Exception.HelpLink + url: https://learn.microsoft.com/dotnet/api/system.exception.helplink + - text: Exception.HResult + url: https://learn.microsoft.com/dotnet/api/system.exception.hresult + - text: Exception.InnerException + url: https://learn.microsoft.com/dotnet/api/system.exception.innerexception + - text: Exception.Message + url: https://learn.microsoft.com/dotnet/api/system.exception.message + - text: Exception.Source + url: https://learn.microsoft.com/dotnet/api/system.exception.source + - text: Exception.StackTrace + url: https://learn.microsoft.com/dotnet/api/system.exception.stacktrace + - text: Exception.TargetSite + url: https://learn.microsoft.com/dotnet/api/system.exception.targetsite + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: This exception is used internally to indicate that a polyline string does not conform to the expected format or contains errors. +languageId: csharp +metadata: + description: Exception thrown when a polyline is determined to be malformed or invalid during processing. diff --git a/api-reference/1.0/PolylineAlgorithm.Polyline.yml b/api-reference/1.0/PolylineAlgorithm.Polyline.yml new file mode 100644 index 00000000..97411b9b --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.Polyline.yml @@ -0,0 +1,315 @@ +### YamlMime:ApiPage +title: Struct Polyline +body: +- api1: Struct Polyline + id: PolylineAlgorithm_Polyline + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L20 + metadata: + uid: PolylineAlgorithm.Polyline + commentId: T:PolylineAlgorithm.Polyline +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Represents an immutable, read-only encoded polyline string. + + Provides methods for creation, inspection, and conversion of polyline data from various character sources. +- code: 'public readonly struct Polyline : IEquatable' +- h4: Implements +- list: + - text: IEquatable + url: https://learn.microsoft.com/dotnet/api/system.iequatable-1 +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: This struct is designed to be lightweight and efficient, allowing for quick comparisons and memory-safe operations. +- h2: Constructors +- api3: Polyline() + id: PolylineAlgorithm_Polyline__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L28 + metadata: + uid: PolylineAlgorithm.Polyline.#ctor + commentId: M:PolylineAlgorithm.Polyline.#ctor +- markdown: Initializes a new, empty instance of the struct. +- code: public Polyline() +- h2: Properties +- api3: IsEmpty + id: PolylineAlgorithm_Polyline_IsEmpty + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L50 + metadata: + uid: PolylineAlgorithm.Polyline.IsEmpty + commentId: P:PolylineAlgorithm.Polyline.IsEmpty +- markdown: Gets a value indicating whether this is empty. +- code: public bool IsEmpty { get; } +- h4: Property Value +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean +- api3: Length + id: PolylineAlgorithm_Polyline_Length + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L55 + metadata: + uid: PolylineAlgorithm.Polyline.Length + commentId: P:PolylineAlgorithm.Polyline.Length +- markdown: Gets the length of the polyline in characters. +- code: public long Length { get; } +- h4: Property Value +- parameters: + - type: + - text: long + url: https://learn.microsoft.com/dotnet/api/system.int64 +- h2: Methods +- api3: CopyTo(char[]) + id: PolylineAlgorithm_Polyline_CopyTo_System_Char___ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L69 + metadata: + uid: PolylineAlgorithm.Polyline.CopyTo(System.Char[]) + commentId: M:PolylineAlgorithm.Polyline.CopyTo(System.Char[]) +- markdown: Copies the characters of this polyline to the specified destination array. +- code: public void CopyTo(char[] destination) +- h4: Parameters +- parameters: + - name: destination + type: + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '[' + - ']' + description: The destination array to copy the characters to. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when destination is null. + - type: + - text: ArgumentException + url: https://learn.microsoft.com/dotnet/api/system.argumentexception + description: Thrown when the length of destination does not match the polyline's length. +- api3: Equals(Polyline) + id: PolylineAlgorithm_Polyline_Equals_PolylineAlgorithm_Polyline_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L110 + metadata: + uid: PolylineAlgorithm.Polyline.Equals(PolylineAlgorithm.Polyline) + commentId: M:PolylineAlgorithm.Polyline.Equals(PolylineAlgorithm.Polyline) +- markdown: Indicates whether the current object is equal to another object of the same type. +- code: public bool Equals(Polyline other) +- h4: Parameters +- parameters: + - name: other + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: An object to compare with this object. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the current object is equal to the other parameter; otherwise, false. +- api3: Equals(object) + id: PolylineAlgorithm_Polyline_Equals_System_Object_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L119 + metadata: + uid: PolylineAlgorithm.Polyline.Equals(System.Object) + commentId: M:PolylineAlgorithm.Polyline.Equals(System.Object) +- markdown: Indicates whether this instance and a specified object are equal. +- code: public override bool Equals(object obj) +- h4: Parameters +- parameters: + - name: obj + type: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + description: The object to compare with the current instance. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if obj and this instance are the same type and represent the same value; otherwise, false. +- api3: FromCharArray(char[]) + id: PolylineAlgorithm_Polyline_FromCharArray_System_Char___ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L168 + metadata: + uid: PolylineAlgorithm.Polyline.FromCharArray(System.Char[]) + commentId: M:PolylineAlgorithm.Polyline.FromCharArray(System.Char[]) +- markdown: Creates a from a Unicode character array. +- code: public static Polyline FromCharArray(char[] polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '[' + - ']' + description: A character array representing an encoded polyline. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The instance corresponding to the specified character array. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when polyline is null. +- api3: FromMemory(ReadOnlyMemory) + id: PolylineAlgorithm_Polyline_FromMemory_System_ReadOnlyMemory_System_Char__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L205 + metadata: + uid: PolylineAlgorithm.Polyline.FromMemory(System.ReadOnlyMemory{System.Char}) + commentId: M:PolylineAlgorithm.Polyline.FromMemory(System.ReadOnlyMemory{System.Char}) +- markdown: Creates a from a read-only memory region of characters. +- code: public static Polyline FromMemory(ReadOnlyMemory polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A read-only memory region representing an encoded polyline. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The instance corresponding to the specified memory region. +- api3: FromString(string) + id: PolylineAlgorithm_Polyline_FromString_System_String_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L188 + metadata: + uid: PolylineAlgorithm.Polyline.FromString(System.String) + commentId: M:PolylineAlgorithm.Polyline.FromString(System.String) +- markdown: Creates a from a string. +- code: public static Polyline FromString(string polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: string + url: https://learn.microsoft.com/dotnet/api/system.string + description: A string representing an encoded polyline. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The instance corresponding to the specified string. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when polyline is null. +- api3: GetHashCode() + id: PolylineAlgorithm_Polyline_GetHashCode + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L124 + metadata: + uid: PolylineAlgorithm.Polyline.GetHashCode + commentId: M:PolylineAlgorithm.Polyline.GetHashCode +- markdown: Returns the hash code for this instance. +- code: public override int GetHashCode() +- h4: Returns +- parameters: + - type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: A 32-bit signed integer that is the hash code for this instance. +- api3: ToString() + id: PolylineAlgorithm_Polyline_ToString + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L87 + metadata: + uid: PolylineAlgorithm.Polyline.ToString + commentId: M:PolylineAlgorithm.Polyline.ToString +- markdown: Returns a string representation of the polyline. +- code: public override string ToString() +- h4: Returns +- parameters: + - type: + - text: string + url: https://learn.microsoft.com/dotnet/api/system.string + description: A string containing the characters of the polyline, or an empty string if the polyline is empty. +- h2: Operators +- api3: operator ==(Polyline, Polyline) + id: PolylineAlgorithm_Polyline_op_Equality_PolylineAlgorithm_Polyline_PolylineAlgorithm_Polyline_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L140 + metadata: + uid: PolylineAlgorithm.Polyline.op_Equality(PolylineAlgorithm.Polyline,PolylineAlgorithm.Polyline) + commentId: M:PolylineAlgorithm.Polyline.op_Equality(PolylineAlgorithm.Polyline,PolylineAlgorithm.Polyline) +- markdown: Determines whether two instances are equal. +- code: public static bool operator ==(Polyline left, Polyline right) +- h4: Parameters +- parameters: + - name: left + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The first polyline to compare. + - name: right + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The second polyline to compare. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the polylines are equal; otherwise, false. +- api3: operator !=(Polyline, Polyline) + id: PolylineAlgorithm_Polyline_op_Inequality_PolylineAlgorithm_Polyline_PolylineAlgorithm_Polyline_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/Polyline.cs#L150 + metadata: + uid: PolylineAlgorithm.Polyline.op_Inequality(PolylineAlgorithm.Polyline,PolylineAlgorithm.Polyline) + commentId: M:PolylineAlgorithm.Polyline.op_Inequality(PolylineAlgorithm.Polyline,PolylineAlgorithm.Polyline) +- markdown: Determines whether two instances are not equal. +- code: public static bool operator !=(Polyline left, Polyline right) +- h4: Parameters +- parameters: + - name: left + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The first polyline to compare. + - name: right + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The second polyline to compare. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the polylines are not equal; otherwise, false. +languageId: csharp +metadata: + description: >- + Represents an immutable, read-only encoded polyline string. + + Provides methods for creation, inspection, and conversion of polyline data from various character sources. diff --git a/api-reference/1.0/PolylineAlgorithm.PolylineDecoder.yml b/api-reference/1.0/PolylineAlgorithm.PolylineDecoder.yml new file mode 100644 index 00000000..4c518e1d --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.PolylineDecoder.yml @@ -0,0 +1,149 @@ +### YamlMime:ApiPage +title: Class PolylineDecoder +body: +- api1: Class PolylineDecoder + id: PolylineAlgorithm_PolylineDecoder + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineDecoder.cs#L11 + metadata: + uid: PolylineAlgorithm.PolylineDecoder + commentId: T:PolylineAlgorithm.PolylineDecoder +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. +- code: 'public sealed class PolylineDecoder : AbstractPolylineDecoder, IPolylineDecoder' +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: AbstractPolylineDecoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.html + - text: PolylineDecoder + url: PolylineAlgorithm.PolylineDecoder.html +- h4: Implements +- list: + - text: IPolylineDecoder + url: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.html +- h4: Inherited Members +- list: + - text: AbstractPolylineDecoder.Options + url: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.html#PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_Options + - text: AbstractPolylineDecoder.Decode(Polyline) + url: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.html#PolylineAlgorithm_Abstraction_AbstractPolylineDecoder_2_Decode__0_ + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h4: Extension Methods +- list: + - text: PolylineDecoderExtensions.Decode(IPolylineDecoder, string) + url: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.html#PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_String_ + - text: PolylineDecoderExtensions.Decode(IPolylineDecoder, char[]) + url: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.html#PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_Char___ + - text: PolylineDecoderExtensions.Decode(IPolylineDecoder, ReadOnlyMemory) + url: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.html#PolylineAlgorithm_Extensions_PolylineDecoderExtensions_Decode_PolylineAlgorithm_Abstraction_IPolylineDecoder_PolylineAlgorithm_Polyline_PolylineAlgorithm_Coordinate__System_ReadOnlyMemory_System_Char__ +- h2: Remarks +- markdown: This abstract class provides a base implementation for decoding polylines, allowing subclasses to define how to handle specific polyline formats. +- h2: Constructors +- api3: PolylineDecoder() + id: PolylineAlgorithm_PolylineDecoder__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineDecoder.cs#L13 + metadata: + uid: PolylineAlgorithm.PolylineDecoder.#ctor + commentId: M:PolylineAlgorithm.PolylineDecoder.#ctor +- markdown: Initializes a new instance of the class with default encoding options. +- code: public PolylineDecoder() +- api3: PolylineDecoder(PolylineEncodingOptions) + id: PolylineAlgorithm_PolylineDecoder__ctor_PolylineAlgorithm_PolylineEncodingOptions_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineDecoder.cs#L17 + metadata: + uid: PolylineAlgorithm.PolylineDecoder.#ctor(PolylineAlgorithm.PolylineEncodingOptions) + commentId: M:PolylineAlgorithm.PolylineDecoder.#ctor(PolylineAlgorithm.PolylineEncodingOptions) +- markdown: Initializes a new instance of the class with the specified encoding options. +- code: public PolylineDecoder(PolylineEncodingOptions options) +- h4: Parameters +- parameters: + - name: options + type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: The to use for encoding operations. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when options is null +- h2: Methods +- api3: CreateCoordinate(double, double) + id: PolylineAlgorithm_PolylineDecoder_CreateCoordinate_System_Double_System_Double_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineDecoder.cs#L21 + metadata: + uid: PolylineAlgorithm.PolylineDecoder.CreateCoordinate(System.Double,System.Double) + commentId: M:PolylineAlgorithm.PolylineDecoder.CreateCoordinate(System.Double,System.Double) +- markdown: Creates a coordinate instance from the given latitude and longitude values. +- code: protected override Coordinate CreateCoordinate(double latitude, double longitude) +- h4: Parameters +- parameters: + - name: latitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The latitude value. + - name: longitude + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The longitude value. +- h4: Returns +- parameters: + - type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: A coordinate instance of type . +- api3: GetReadOnlyMemory(Polyline) + id: PolylineAlgorithm_PolylineDecoder_GetReadOnlyMemory_PolylineAlgorithm_Polyline_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineDecoder.cs#L26 + metadata: + uid: PolylineAlgorithm.PolylineDecoder.GetReadOnlyMemory(PolylineAlgorithm.Polyline) + commentId: M:PolylineAlgorithm.PolylineDecoder.GetReadOnlyMemory(PolylineAlgorithm.Polyline) +- markdown: Converts the provided polyline instance into a for decoding. +- code: protected override ReadOnlyMemory GetReadOnlyMemory(Polyline polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: The instance containing the encoded polyline data to decode. +- h4: Returns +- parameters: + - type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A representing the encoded polyline data. +languageId: csharp +metadata: + description: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. diff --git a/api-reference/1.0/PolylineAlgorithm.PolylineEncoder.yml b/api-reference/1.0/PolylineAlgorithm.PolylineEncoder.yml new file mode 100644 index 00000000..05665bb8 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.PolylineEncoder.yml @@ -0,0 +1,161 @@ +### YamlMime:ApiPage +title: Class PolylineEncoder +body: +- api1: Class PolylineEncoder + id: PolylineAlgorithm_PolylineEncoder + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L11 + metadata: + uid: PolylineAlgorithm.PolylineEncoder + commentId: T:PolylineAlgorithm.PolylineEncoder +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. +- code: 'public sealed class PolylineEncoder : AbstractPolylineEncoder, IPolylineEncoder' +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: AbstractPolylineEncoder + url: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.html + - text: PolylineEncoder + url: PolylineAlgorithm.PolylineEncoder.html +- h4: Implements +- list: + - text: IPolylineEncoder + url: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.html +- h4: Inherited Members +- list: + - text: AbstractPolylineEncoder.Options + url: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.html#PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_Options + - text: AbstractPolylineEncoder.Encode(IEnumerable) + url: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.html#PolylineAlgorithm_Abstraction_AbstractPolylineEncoder_2_Encode_System_Collections_Generic_IEnumerable__0__ + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h4: Extension Methods +- list: + - text: PolylineEncoderExtensions.Encode(IPolylineEncoder, ICollection) + url: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.html#PolylineAlgorithm_Extensions_PolylineEncoderExtensions_Encode_PolylineAlgorithm_Abstraction_IPolylineEncoder_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Polyline__System_Collections_Generic_ICollection_PolylineAlgorithm_Coordinate__ + - text: PolylineEncoderExtensions.Encode(IPolylineEncoder, Coordinate[]) + url: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.html#PolylineAlgorithm_Extensions_PolylineEncoderExtensions_Encode_PolylineAlgorithm_Abstraction_IPolylineEncoder_PolylineAlgorithm_Coordinate_PolylineAlgorithm_Polyline__PolylineAlgorithm_Coordinate___ +- h2: Remarks +- markdown: This abstract class serves as a base for specific polyline encoders, allowing customization of the encoding process. +- h2: Constructors +- api3: PolylineEncoder() + id: PolylineAlgorithm_PolylineEncoder__ctor + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L13 + metadata: + uid: PolylineAlgorithm.PolylineEncoder.#ctor + commentId: M:PolylineAlgorithm.PolylineEncoder.#ctor +- markdown: Initializes a new instance of the class with default encoding options. +- code: public PolylineEncoder() +- api3: PolylineEncoder(PolylineEncodingOptions) + id: PolylineAlgorithm_PolylineEncoder__ctor_PolylineAlgorithm_PolylineEncodingOptions_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L17 + metadata: + uid: PolylineAlgorithm.PolylineEncoder.#ctor(PolylineAlgorithm.PolylineEncodingOptions) + commentId: M:PolylineAlgorithm.PolylineEncoder.#ctor(PolylineAlgorithm.PolylineEncodingOptions) +- markdown: Initializes a new instance of the class with the specified encoding options. +- code: public PolylineEncoder(PolylineEncodingOptions options) +- h4: Parameters +- parameters: + - name: options + type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: The to use for encoding operations. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when options is null +- h2: Methods +- api3: CreatePolyline(ReadOnlyMemory) + id: PolylineAlgorithm_PolylineEncoder_CreatePolyline_System_ReadOnlyMemory_System_Char__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L31 + metadata: + uid: PolylineAlgorithm.PolylineEncoder.CreatePolyline(System.ReadOnlyMemory{System.Char}) + commentId: M:PolylineAlgorithm.PolylineEncoder.CreatePolyline(System.ReadOnlyMemory{System.Char}) +- markdown: Creates a polyline instance from the provided read-only sequence of characters. +- code: protected override Polyline CreatePolyline(ReadOnlyMemory polyline) +- h4: Parameters +- parameters: + - name: polyline + type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A containing the encoded polyline characters. +- h4: Returns +- parameters: + - type: + - text: Polyline + url: PolylineAlgorithm.Polyline.html + description: An instance of representing the encoded polyline. +- api3: GetLatitude(Coordinate) + id: PolylineAlgorithm_PolylineEncoder_GetLatitude_PolylineAlgorithm_Coordinate_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L21 + metadata: + uid: PolylineAlgorithm.PolylineEncoder.GetLatitude(PolylineAlgorithm.Coordinate) + commentId: M:PolylineAlgorithm.PolylineEncoder.GetLatitude(PolylineAlgorithm.Coordinate) +- markdown: Extracts the latitude value from the specified coordinate. +- code: protected override double GetLatitude(Coordinate coordinate) +- h4: Parameters +- parameters: + - name: coordinate + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html +- h4: Returns +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The latitude value as a . +- api3: GetLongitude(Coordinate) + id: PolylineAlgorithm_PolylineEncoder_GetLongitude_PolylineAlgorithm_Coordinate_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoder.cs#L26 + metadata: + uid: PolylineAlgorithm.PolylineEncoder.GetLongitude(PolylineAlgorithm.Coordinate) + commentId: M:PolylineAlgorithm.PolylineEncoder.GetLongitude(PolylineAlgorithm.Coordinate) +- markdown: Extracts the longitude value from the specified coordinate. +- code: protected override double GetLongitude(Coordinate coordinate) +- h4: Parameters +- parameters: + - name: coordinate + type: + - text: Coordinate + url: PolylineAlgorithm.Coordinate.html +- h4: Returns +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The longitude value as a . +languageId: csharp +metadata: + description: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. diff --git a/api-reference/1.0/PolylineAlgorithm.PolylineEncoding.yml b/api-reference/1.0/PolylineAlgorithm.PolylineEncoding.yml new file mode 100644 index 00000000..2028ccbe --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.PolylineEncoding.yml @@ -0,0 +1,254 @@ +### YamlMime:ApiPage +title: Class PolylineEncoding +body: +- api1: Class PolylineEncoding + id: PolylineAlgorithm_PolylineEncoding + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L19 + metadata: + uid: PolylineAlgorithm.PolylineEncoding + commentId: T:PolylineAlgorithm.PolylineEncoding +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: >- + Provides methods for encoding and decoding polyline data, as well as utilities for normalizing and de-normalizing + + geographic coordinate values. +- code: public static class PolylineEncoding +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: PolylineEncoding + url: PolylineAlgorithm.PolylineEncoding.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: >- + The class includes functionality for working with encoded polyline + data, such as reading and writing encoded values, as well as methods for normalizing and de-normalizing geographic + coordinates. It also provides validation utilities to ensure values conform to expected ranges for latitude and + longitude. +- h2: Methods +- api3: Denormalize(int, CoordinateValueType) + id: PolylineAlgorithm_PolylineEncoding_Denormalize_System_Int32_PolylineAlgorithm_CoordinateValueType_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L91 + metadata: + uid: PolylineAlgorithm.PolylineEncoding.Denormalize(System.Int32,PolylineAlgorithm.CoordinateValueType) + commentId: M:PolylineAlgorithm.PolylineEncoding.Denormalize(System.Int32,PolylineAlgorithm.CoordinateValueType) +- markdown: Converts a normalized integer value to its denormalized double representation based on the specified type. +- code: public static double Denormalize(int value, CoordinateValueType type) +- h4: Parameters +- parameters: + - name: value + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: The normalized integer value to be denormalized. Must be within the valid range for the specified type. + - name: type + type: + - text: CoordinateValueType + url: PolylineAlgorithm.CoordinateValueType.html + description: The type that defines the valid range for value. +- h4: Returns +- parameters: + - type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The denormalized double representation of the input value. Returns 0.0 if value is 0. +- h4: Remarks +- markdown: >- + The denormalization process divides the input value by a predefined precision factor to + produce the resulting double. Ensure that value is validated against the specified type before calling this method. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentOutOfRangeException + url: https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception + description: Thrown when value is outside the valid range for the specified type. +- api3: GetCharCount(int) + id: PolylineAlgorithm_PolylineEncoding_GetCharCount_System_Int32_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L222 + metadata: + uid: PolylineAlgorithm.PolylineEncoding.GetCharCount(System.Int32) + commentId: M:PolylineAlgorithm.PolylineEncoding.GetCharCount(System.Int32) +- markdown: >- + Determines the number of characters required to represent the specified integer value within predefined + + variance ranges. +- code: public static int GetCharCount(int variance) +- h4: Parameters +- parameters: + - name: variance + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: >- + The integer value for which the character count is calculated. Must be within the range of a 32-bit signed + + integer. +- h4: Returns +- parameters: + - type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: >- + The number of characters required to represent the variance value, based on its magnitude. + + Returns a value between 1 and 6 inclusive. +- h4: Remarks +- markdown: >- + The method uses predefined ranges to efficiently determine the character count. Smaller + + values require fewer characters, while larger values require more. This method is optimized for performance + + using a switch expression. +- api3: Normalize(double, CoordinateValueType) + id: PolylineAlgorithm_PolylineEncoding_Normalize_System_Double_PolylineAlgorithm_CoordinateValueType_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L180 + metadata: + uid: PolylineAlgorithm.PolylineEncoding.Normalize(System.Double,PolylineAlgorithm.CoordinateValueType) + commentId: M:PolylineAlgorithm.PolylineEncoding.Normalize(System.Double,PolylineAlgorithm.CoordinateValueType) +- markdown: Normalizes a given numeric value based on the specified type and precision settings. +- code: public static int Normalize(double value, CoordinateValueType type) +- h4: Parameters +- parameters: + - name: value + type: + - text: double + url: https://learn.microsoft.com/dotnet/api/system.double + description: The numeric value to normalize. Must be a finite number. + - name: type + type: + - text: CoordinateValueType + url: PolylineAlgorithm.CoordinateValueType.html + description: The type against which the value is validated. Determines the acceptable range for the value. +- h4: Returns +- parameters: + - type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: An integer representing the normalized value. Returns 0 if the input value is 0.0. +- h4: Remarks +- markdown: >- + This method validates the input value to ensure it is finite and within the acceptable range + + for the specified type. If the value is valid, it applies a normalization algorithm using a predefined precision + + factor. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentOutOfRangeException + url: https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception + description: >- + Thrown when value is not a finite number or is outside the valid range for the specified + + type. +- api3: TryReadValue(ref int, ref ReadOnlyMemory, ref int) + id: PolylineAlgorithm_PolylineEncoding_TryReadValue_System_Int32__System_ReadOnlyMemory_System_Char___System_Int32__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L40 + metadata: + uid: PolylineAlgorithm.PolylineEncoding.TryReadValue(System.Int32@,System.ReadOnlyMemory{System.Char}@,System.Int32@) + commentId: M:PolylineAlgorithm.PolylineEncoding.TryReadValue(System.Int32@,System.ReadOnlyMemory{System.Char}@,System.Int32@) +- markdown: Attempts to read a value from the specified buffer and updates the variance. +- code: public static bool TryReadValue(ref int variance, ref ReadOnlyMemory buffer, ref int position) +- h4: Parameters +- parameters: + - name: variance + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: A reference to the integer that will be updated based on the value read from the buffer. + - name: buffer + type: + - text: ReadOnlyMemory + url: https://learn.microsoft.com/dotnet/api/system.readonlymemory-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A reference to the read-only memory buffer containing the data to be processed. + - name: position + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: A reference to the current position within the buffer. The position is incremented as the method reads data. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if a value was successfully read and the end of the buffer was not reached; otherwise, false. +- h4: Remarks +- markdown: >- + This method processes the buffer starting at the specified position and attempts to decode a value. + The decoded value is used to update the variance parameter. The method stops reading when a + termination condition is met or the end of the buffer is reached. +- api3: TryWriteValue(int, ref Span, ref int) + id: PolylineAlgorithm_PolylineEncoding_TryWriteValue_System_Int32_System_Span_System_Char___System_Int32__ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncoding.cs#L133 + metadata: + uid: PolylineAlgorithm.PolylineEncoding.TryWriteValue(System.Int32,System.Span{System.Char}@,System.Int32@) + commentId: M:PolylineAlgorithm.PolylineEncoding.TryWriteValue(System.Int32,System.Span{System.Char}@,System.Int32@) +- markdown: Attempts to write a value derived from the specified variance into the provided buffer at the given position. +- code: public static bool TryWriteValue(int variance, ref Span buffer, ref int position) +- h4: Parameters +- parameters: + - name: variance + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: The integer value used to calculate the output to be written into the buffer. + - name: buffer + type: + - text: Span + url: https://learn.microsoft.com/dotnet/api/system.span-1 + - < + - text: char + url: https://learn.microsoft.com/dotnet/api/system.char + - '>' + description: A reference to the span of characters where the value will be written. + - name: position + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: >- + A reference to the current position in the buffer where writing begins. This value is updated to reflect the new + + position after writing. +- h4: Returns +- parameters: + - type: + - text: bool + url: https://learn.microsoft.com/dotnet/api/system.boolean + description: true if the value was successfully written to the buffer; otherwise, false. +- h4: Remarks +- markdown: >- + This method performs bounds checking to ensure that the buffer has sufficient space to + + accommodate the calculated value. If the buffer does not have enough space, the method returns false without modifying the buffer or position. +languageId: csharp +metadata: + description: >- + Provides methods for encoding and decoding polyline data, as well as utilities for normalizing and de-normalizing + + geographic coordinate values. diff --git a/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptions.yml b/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptions.yml new file mode 100644 index 00000000..4869791d --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptions.yml @@ -0,0 +1,74 @@ +### YamlMime:ApiPage +title: Class PolylineEncodingOptions +body: +- api1: Class PolylineEncodingOptions + id: PolylineAlgorithm_PolylineEncodingOptions + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptions.cs#L18 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptions + commentId: T:PolylineAlgorithm.PolylineEncodingOptions +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Options for configuring polyline encoding. +- code: public sealed class PolylineEncodingOptions +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Remarks +- markdown: This class allows you to set options such as buffer size and logger factory for encoding operations. +- h2: Properties +- api3: LoggerFactory + id: PolylineAlgorithm_PolylineEncodingOptions_LoggerFactory + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptions.cs#L34 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptions.LoggerFactory + commentId: P:PolylineAlgorithm.PolylineEncodingOptions.LoggerFactory +- markdown: Gets or sets the precision for encoding coordinates. +- code: public ILoggerFactory LoggerFactory { get; } +- h4: Property Value +- parameters: + - type: + - text: ILoggerFactory + url: https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggerfactory +- h4: Remarks +- markdown: The default logger factory is , which does not log any messages. +- api3: MaxBufferSize + id: PolylineAlgorithm_PolylineEncodingOptions_MaxBufferSize + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptions.cs#L26 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptions.MaxBufferSize + commentId: P:PolylineAlgorithm.PolylineEncodingOptions.MaxBufferSize +- markdown: Gets the maximum buffer size for encoding operations. +- code: public int MaxBufferSize { get; } +- h4: Property Value +- parameters: + - type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 +- h4: Remarks +- markdown: The default maximum buffer size is 64,000 bytes (64 KB). This can be adjusted based on the expected size of the polyline data, but should be enough for common cases. +languageId: csharp +metadata: + description: Options for configuring polyline encoding. diff --git a/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptionsBuilder.yml b/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptionsBuilder.yml new file mode 100644 index 00000000..f54c56a2 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.PolylineEncodingOptionsBuilder.yml @@ -0,0 +1,126 @@ +### YamlMime:ApiPage +title: Class PolylineEncodingOptionsBuilder +body: +- api1: Class PolylineEncodingOptionsBuilder + id: PolylineAlgorithm_PolylineEncodingOptionsBuilder + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs#L15 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptionsBuilder + commentId: T:PolylineAlgorithm.PolylineEncodingOptionsBuilder +- facts: + - name: Namespace + value: + text: PolylineAlgorithm + url: PolylineAlgorithm.html + - name: Assembly + value: PolylineAlgorithm.dll +- markdown: Provides a builder for configuring options for polyline encoding operations. +- code: public class PolylineEncodingOptionsBuilder +- h4: Inheritance +- inheritance: + - text: object + url: https://learn.microsoft.com/dotnet/api/system.object + - text: PolylineEncodingOptionsBuilder + url: PolylineAlgorithm.PolylineEncodingOptionsBuilder.html +- h4: Inherited Members +- list: + - text: object.Equals(object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object) + - text: object.Equals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object) + - text: object.GetHashCode() + url: https://learn.microsoft.com/dotnet/api/system.object.gethashcode + - text: object.GetType() + url: https://learn.microsoft.com/dotnet/api/system.object.gettype + - text: object.MemberwiseClone() + url: https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone + - text: object.ReferenceEquals(object, object) + url: https://learn.microsoft.com/dotnet/api/system.object.referenceequals + - text: object.ToString() + url: https://learn.microsoft.com/dotnet/api/system.object.tostring +- h2: Methods +- api3: Build() + id: PolylineAlgorithm_PolylineEncodingOptionsBuilder_Build + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs#L37 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptionsBuilder.Build + commentId: M:PolylineAlgorithm.PolylineEncodingOptionsBuilder.Build +- markdown: Builds a new instance using the configured options. +- code: public PolylineEncodingOptions Build() +- h4: Returns +- parameters: + - type: + - text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: A configured instance. +- api3: Create() + id: PolylineAlgorithm_PolylineEncodingOptionsBuilder_Create + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs#L27 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptionsBuilder.Create + commentId: M:PolylineAlgorithm.PolylineEncodingOptionsBuilder.Create +- markdown: Creates a new instance for the specified coordinate type. +- code: public static PolylineEncodingOptionsBuilder Create() +- h4: Returns +- parameters: + - type: + - text: PolylineEncodingOptionsBuilder + url: PolylineAlgorithm.PolylineEncodingOptionsBuilder.html + description: An instance for configuring polyline encoding options. +- api3: WithLoggerFactory(ILoggerFactory) + id: PolylineAlgorithm_PolylineEncodingOptionsBuilder_WithLoggerFactory_Microsoft_Extensions_Logging_ILoggerFactory_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs#L72 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptionsBuilder.WithLoggerFactory(Microsoft.Extensions.Logging.ILoggerFactory) + commentId: M:PolylineAlgorithm.PolylineEncodingOptionsBuilder.WithLoggerFactory(Microsoft.Extensions.Logging.ILoggerFactory) +- markdown: Sets the logger factory for logging during encoding operations. +- code: public PolylineEncodingOptionsBuilder WithLoggerFactory(ILoggerFactory loggerFactory) +- h4: Parameters +- parameters: + - name: loggerFactory + type: + - text: ILoggerFactory + url: https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggerfactory + description: The instance of a logger factory. +- h4: Returns +- parameters: + - type: + - text: PolylineEncodingOptionsBuilder + url: PolylineAlgorithm.PolylineEncodingOptionsBuilder.html + description: The current builder instance. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentNullException + url: https://learn.microsoft.com/dotnet/api/system.argumentnullexception + description: Thrown when loggerFactory is null. +- api3: WithMaxBufferSize(int) + id: PolylineAlgorithm_PolylineEncodingOptionsBuilder_WithMaxBufferSize_System_Int32_ + src: https://github.com/sramekpete/polyline-algorithm-csharp/blob/develop/1.0/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs#L54 + metadata: + uid: PolylineAlgorithm.PolylineEncodingOptionsBuilder.WithMaxBufferSize(System.Int32) + commentId: M:PolylineAlgorithm.PolylineEncodingOptionsBuilder.WithMaxBufferSize(System.Int32) +- markdown: Sets the buffer size for encoding operations. +- code: public PolylineEncodingOptionsBuilder WithMaxBufferSize(int bufferSize) +- h4: Parameters +- parameters: + - name: bufferSize + type: + - text: int + url: https://learn.microsoft.com/dotnet/api/system.int32 + description: The maximum buffer size. Must be greater than 11. +- h4: Returns +- parameters: + - type: + - text: PolylineEncodingOptionsBuilder + url: PolylineAlgorithm.PolylineEncodingOptionsBuilder.html + description: The current builder instance. +- h4: Exceptions +- parameters: + - type: + - text: ArgumentOutOfRangeException + url: https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception + description: Thrown when bufferSize is less than or equal to 11. +languageId: csharp +metadata: + description: Provides a builder for configuring options for polyline encoding operations. diff --git a/api-reference/1.0/PolylineAlgorithm.yml b/api-reference/1.0/PolylineAlgorithm.yml new file mode 100644 index 00000000..ace2f946 --- /dev/null +++ b/api-reference/1.0/PolylineAlgorithm.yml @@ -0,0 +1,71 @@ +### YamlMime:ApiPage +title: Namespace PolylineAlgorithm +body: +- api1: Namespace PolylineAlgorithm + id: PolylineAlgorithm + metadata: + uid: PolylineAlgorithm + commentId: N:PolylineAlgorithm +- h3: Namespaces +- parameters: + - type: + text: PolylineAlgorithm.Abstraction + url: PolylineAlgorithm.Abstraction.html + - type: + text: PolylineAlgorithm.Extensions + url: PolylineAlgorithm.Extensions.html +- h3: Classes +- parameters: + - type: + text: InvalidPolylineException + url: PolylineAlgorithm.InvalidPolylineException.html + description: Exception thrown when a polyline is determined to be malformed or invalid during processing. + - type: + text: PolylineDecoder + url: PolylineAlgorithm.PolylineDecoder.html + description: >- + Decodes encoded polyline strings into sequences of geographic coordinates. + + Implements the interface. + - type: + text: PolylineEncoder + url: PolylineAlgorithm.PolylineEncoder.html + description: >- + Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. + + Implements the interface. + - type: + text: PolylineEncoding + url: PolylineAlgorithm.PolylineEncoding.html + description: >- + Provides methods for encoding and decoding polyline data, as well as utilities for normalizing and de-normalizing + + geographic coordinate values. + - type: + text: PolylineEncodingOptions + url: PolylineAlgorithm.PolylineEncodingOptions.html + description: Options for configuring polyline encoding. + - type: + text: PolylineEncodingOptionsBuilder + url: PolylineAlgorithm.PolylineEncodingOptionsBuilder.html + description: Provides a builder for configuring options for polyline encoding operations. +- h3: Structs +- parameters: + - type: + text: Coordinate + url: PolylineAlgorithm.Coordinate.html + description: Represents a geographic coordinate as a pair of latitude and longitude values. + - type: + text: Polyline + url: PolylineAlgorithm.Polyline.html + description: >- + Represents an immutable, read-only encoded polyline string. + + Provides methods for creation, inspection, and conversion of polyline data from various character sources. +- h3: Enums +- parameters: + - type: + text: CoordinateValueType + url: PolylineAlgorithm.CoordinateValueType.html + description: Represents the type of a geographic coordinate value. +languageId: csharp diff --git a/api-reference/1.0/toc.yml b/api-reference/1.0/toc.yml new file mode 100644 index 00000000..b69f5d3f --- /dev/null +++ b/api-reference/1.0/toc.yml @@ -0,0 +1,46 @@ +### YamlMime:TableOfContent +- name: PolylineAlgorithm + href: PolylineAlgorithm.yml + items: + - name: Classes + - name: InvalidPolylineException + href: PolylineAlgorithm.InvalidPolylineException.yml + - name: PolylineDecoder + href: PolylineAlgorithm.PolylineDecoder.yml + - name: PolylineEncoder + href: PolylineAlgorithm.PolylineEncoder.yml + - name: PolylineEncoding + href: PolylineAlgorithm.PolylineEncoding.yml + - name: PolylineEncodingOptions + href: PolylineAlgorithm.PolylineEncodingOptions.yml + - name: PolylineEncodingOptionsBuilder + href: PolylineAlgorithm.PolylineEncodingOptionsBuilder.yml + - name: Structs + - name: Coordinate + href: PolylineAlgorithm.Coordinate.yml + - name: Polyline + href: PolylineAlgorithm.Polyline.yml + - name: Enums + - name: CoordinateValueType + href: PolylineAlgorithm.CoordinateValueType.yml +- name: PolylineAlgorithm.Abstraction + href: PolylineAlgorithm.Abstraction.yml + items: + - name: Classes + - name: AbstractPolylineDecoder + href: PolylineAlgorithm.Abstraction.AbstractPolylineDecoder-2.yml + - name: AbstractPolylineEncoder + href: PolylineAlgorithm.Abstraction.AbstractPolylineEncoder-2.yml + - name: Interfaces + - name: IPolylineDecoder + href: PolylineAlgorithm.Abstraction.IPolylineDecoder-2.yml + - name: IPolylineEncoder + href: PolylineAlgorithm.Abstraction.IPolylineEncoder-2.yml +- name: PolylineAlgorithm.Extensions + href: PolylineAlgorithm.Extensions.yml + items: + - name: Classes + - name: PolylineDecoderExtensions + href: PolylineAlgorithm.Extensions.PolylineDecoderExtensions.yml + - name: PolylineEncoderExtensions + href: PolylineAlgorithm.Extensions.PolylineEncoderExtensions.yml diff --git a/api-reference/api-reference.json b/api-reference/api-reference.json new file mode 100644 index 00000000..78956c32 --- /dev/null +++ b/api-reference/api-reference.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json", + "build": { + "xref": [ + "https://learn.microsoft.com/en-us/dotnet/.xrefmap.json" + ], + "content": [ + { + "files": [ + "index.md", + "toc.yml", + "guide/*.{md,yml}" + ], + "exclude": [ + "_docs/**" + ] + }, + { + "dest": "", + "files": [ "*.yml" ], + "group": "v1.0", + "src": "1.0", + "rootTocPath": "~/toc.html" + }, + { + "dest": "", + "files": [ "*.yml" ], + "group": "v1.1", + "src": "1.1", + "rootTocPath": "~/toc.html" + } + ], + "resource": [ + { + "files": [ + "media/**" + ] + } + ], + "groups": { + "v1.0": { "dest": "1.0" }, + "v1.1": { "dest": "1.1" } + }, + "output": "_docs", + "template": [ + "default", + "modern" + ], + "maxParallelism": 1, + "globalMetadata": { + "_appName": "PolylineAlgorithm for .NET", + "_appTitle": "PolylineAlgorithm for .NET", + "_enableSearch": true, + "_enableNewTab": true, + "_disableContribution": false, + "pdf": false + } + } +} \ No newline at end of file diff --git a/api-reference/assembly-metadata.json b/api-reference/assembly-metadata.json new file mode 100644 index 00000000..0416ceed --- /dev/null +++ b/api-reference/assembly-metadata.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json", + "metadata": [ + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "dest": "temp", + "outputFormat": "apiPage" + } + ] +} \ No newline at end of file diff --git a/api-reference/favicon.ico b/api-reference/favicon.ico new file mode 100644 index 00000000..eb57e8d7 Binary files /dev/null and b/api-reference/favicon.ico differ diff --git a/api-reference/guide/getting-started.md b/api-reference/guide/getting-started.md new file mode 100644 index 00000000..8b3a7945 --- /dev/null +++ b/api-reference/guide/getting-started.md @@ -0,0 +1 @@ +# Getting Started \ No newline at end of file diff --git a/api-reference/guide/introduction.md b/api-reference/guide/introduction.md new file mode 100644 index 00000000..f6ecaa67 --- /dev/null +++ b/api-reference/guide/introduction.md @@ -0,0 +1 @@ +# Introduction \ No newline at end of file diff --git a/api-reference/guide/toc.yml b/api-reference/guide/toc.yml new file mode 100644 index 00000000..d7e9ea8c --- /dev/null +++ b/api-reference/guide/toc.yml @@ -0,0 +1,4 @@ +- name: Introduction + href: introduction.md +- name: Getting Started + href: getting-started.md \ No newline at end of file diff --git a/api-reference/index.md b/api-reference/index.md new file mode 100644 index 00000000..5403debe --- /dev/null +++ b/api-reference/index.md @@ -0,0 +1,26 @@ +# PolylineAlgorithm for .NET + +[![Build](https://github.com/sramekpete/polyline-algorithm-csharp/actions/workflows/build.yml/badge.svg)](https://github.com/sramekpete/polyline-algorithm-csharp/actions/workflows/build.yml) +[![NuGet](https://img.shields.io/nuget/v/PolylineAlgorithm.svg)](https://www.nuget.org/packages/PolylineAlgorithm/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Lightweight .NET Standard 2.1 library implementing Google Encoded Polyline Algorithm. +More info about the algorithm can be found at [Google Developers](https://developers.google.com/maps/documentation/utilities/polylinealgorithm). + +## Prerequisites + +PolylineAlgorithm for .NET is available as a NuGet package targeting .NET Standard 2.1. + +**.NET CLI** + +`dotnet add package PolylineAlgorithm` + +**Package Manager Console** + +`Install-Package PolylineAlgorithm` + +## How to use it + +In the majority of cases you would like to inherit `AbstractPolylineDecoder` and `AbstractPolylineEncoder` classes and implement abstract methods that are mainly responsible for extracting data from your coordinate and polyline types and creating new instances of them. + +In some cases you may want to implement your own decoder and encoder from scratch. In that case you can use `PolylineEncoding` static class that offers static methods for encoding and decoding polyline segments. \ No newline at end of file diff --git a/api-reference/media/polyline-algorithm-50x46.png b/api-reference/media/polyline-algorithm-50x46.png new file mode 100644 index 00000000..6e14d059 Binary files /dev/null and b/api-reference/media/polyline-algorithm-50x46.png differ diff --git a/api-reference/media/polyline-algorithm.png b/api-reference/media/polyline-algorithm.png new file mode 100644 index 00000000..d07cf781 Binary files /dev/null and b/api-reference/media/polyline-algorithm.png differ diff --git a/api-reference/toc.yml b/api-reference/toc.yml new file mode 100644 index 00000000..114c10f6 --- /dev/null +++ b/api-reference/toc.yml @@ -0,0 +1,8 @@ +### YamlMime:TableOfContent +- name: Guide + href: guide/ +- name: Reference + dropdown: true + items: + - name: v1.0 + href: 1.0/PolylineAlgorithm.html \ No newline at end of file diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj deleted file mode 100644 index 2d5b8cc1..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs deleted file mode 100644 index 798fd3ae..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace DropoutCoder.PolylineAlgorithm.Benchmarks -{ - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm.Encoding; - - [MemoryDiagnoser] - [MarkdownExporter] - public class PolylineEncodingBenchmark - { - private Consumer _consumer = new Consumer(); - - [Params(10_000, 100_000, 1_000_000, Priority = 2)] - public int N; - - public IEnumerable<(double, double)> Coordinates; - - public PolylineEncoding Encoding { get; private set; } - - public string Polyline; - - [GlobalSetup] - public void Setup() - { - Encoding = new PolylineEncoding(); - Coordinates = new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; - Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - } - - [Benchmark] - public void Decode() => Encoding - .Decode(Polyline) - .Consume(_consumer); - - [Benchmark] - public void Encode() => Encoding - .Encode(Coordinates) - .Consume(_consumer); - } -} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs deleted file mode 100644 index d6e3655e..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace DropoutCoder.PolylineAlgorithm.Benchmarks -{ - using BenchmarkDotNet.Running; - - internal class Program - { - static void Main(string[] args) - { - BenchmarkRunner - .Run(); - } - } -} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs deleted file mode 100644 index 9854d042..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright (c) Petr Šrámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks -{ - /// - /// Defines global constant values - /// - internal static class Constants - { - #region Constants - - /// - /// Defines the coordinate precision - /// - public const double Precision = 1E5; - - /// - /// Defines the shift length - /// - public const int ShiftLength = 5; - - #endregion - - /// - /// Defines ASCII characters constant values - /// - internal static class ASCII - { - #region Constants - - /// - /// Defines the ASCII Question Mark - /// - public const int QuestionMark = 63; - - /// - /// Defines the ASCII Space - /// - public const int Space = 32; - - /// - /// Defines the ASCII Unit Separator - /// - public const int UnitSeparator = 31; - - #endregion - } - - /// - /// Defines coordinates constant values - /// - internal static class Coordinate - { - #region Constants - - /// - /// Defines the maximum value for latitude - /// - public const int MaxLatitude = 90; - - /// - /// Defines the maximum value for longitude - /// - public const int MaxLongitude = 180; - - /// - /// Defines the minimum value for latitude - /// - public const int MinLatitude = -MaxLatitude; - - /// - /// Defines the minimum value for longitude - /// - public const int MinLongitude = -MaxLongitude; - - #endregion - } - } -} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs deleted file mode 100644 index 43289f5d..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ /dev/null @@ -1,200 +0,0 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks -{ - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using System; - - [MemoryDiagnoser] - public class DecodePerformanceBenchmark - { - private Consumer _consumer = new Consumer(); - public static IEnumerable<(int, char[])> Polylines() - { - yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI".ToCharArray()); - yield return (2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB".ToCharArray()); - yield return (3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH".ToCharArray()); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1((int, char[]) arg) => V1.Decode(arg.Item2).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V1.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2((int, char[]) arg) => V2.Decode(arg.Item2).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V2.Decode(arg.Item2).Consume(_consumer)); - - private class V1 - { - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) - { - if (polyline is null || polyline.Length == 0) - { - throw new ArgumentException(nameof(polyline)); - } - - int index = 0; - int latitude = 0; - int longitude = 0; - - var result = new List<(double Latitude, double Longitude)>(); - - while (index < polyline.Length) - { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) - { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) - { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) - { - throw new InvalidOperationException(); - } - - result.Add(coordinate); - } - - return result; - } - - private static bool TryCalculateNext(ref char[] polyline, ref int index, ref int value) - { - int chunk; - int sum = 0; - int shifter = 0; - - do - { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) - { - return Convert.ToDouble(value) / Constants.Precision; - } - - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 - { - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) - { - if (polyline is null || polyline.Length == 0) - { - throw new ArgumentException(nameof(polyline)); - } - - int offset = 0; - int latitude = 0; - int longitude = 0; - - while (offset < polyline.Length) - { - if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) - { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) - { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) - { - throw new InvalidOperationException(); - } - - yield return (latitude, longitude); - } - } - - private static bool TryCalculateNext(ref char[] polyline, ref int offset, ref int value) - { - int chunk; - int sum = 0; - int shifter = 0; - - do - { - chunk = polyline[offset++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); - - if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) - { - return value / Constants.Precision; - } - - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - } -} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj deleted file mode 100644 index d799ba3b..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs deleted file mode 100644 index d7a75e02..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ /dev/null @@ -1,222 +0,0 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks -{ - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using Microsoft.Extensions.ObjectPool; - using System.Collections.Generic; - using System.Text; - - [MemoryDiagnoser] - public class EncodePerformanceBenchmark - { - private Consumer _consumer = new Consumer(); - - public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() - { - yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); - yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); - yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1((int, IEnumerable<(double, double)>) arg) => V1.Encode(arg.Item2).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V1.Encode(arg.Item2).Consume(_consumer)); - - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2((int, IEnumerable<(double, double)>) arg) => V2.Encode(arg.Item2).Consume(_consumer); - - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V2.Encode(arg.Item2).Consume(_consumer)); - - private class V1 - { - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates is null || !coordinates.Any()) - { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int lastLatitude = 0; - int lastLongitude = 0; - var sb = new StringBuilder(); - - foreach (var coordinate in coordinates) - { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); - - sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); - - lastLatitude = latitude; - lastLongitude = longitude; - } - - return sb.ToString(); - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) - { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) - { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) - { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 - { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates is null || !coordinates.Any()) - { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int previousLatitude = 0; - int previousLongitude = 0; - - var sb = _pool.Get(); - - foreach (var coordinate in coordinates) - { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); - - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - var result = sb.ToString(); - - _pool.Return(sb); - - return result; - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) - { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) - { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) - { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - } -} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs deleted file mode 100644 index 1a591c1c..00000000 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks -{ - using BenchmarkDotNet.Running; - - internal class Program - { - static void Main(string[] args) - { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj new file mode 100644 index 00000000..338efcf0 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -0,0 +1,26 @@ + + + + Exe + net8.0;net9.0 + 13.0 + enable + enable + true + en + + + + false + + + + + + + + + + + + diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs new file mode 100644 index 00000000..9d09883b --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs @@ -0,0 +1,165 @@ +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using PolylineAlgorithm; +using PolylineAlgorithm.Utility; + +/// +/// Benchmarks for the struct. +/// +public class PolylineBenchmark { + private static readonly Consumer consumer = new(); + + [Params(1, 100, 1_000)] + public int Count; + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + /// + /// Gets the character array representing the encoded polyline. + /// + public char[] CharArrayValue { get; private set; } + + /// + /// Gets the read-only memory representing the encoded polyline. + /// + public ReadOnlyMemory MemoryValue { get; private set; } + + /// + /// Gets the read-only memory representing the encoded polyline. + /// + public Polyline PolylineValue { get; private set; } + + /// + /// Gets the string value representing the encoded polyline. + /// + public string StringValue { get; private set; } + + /// + /// Gets the read-only memory representing the encoded polyline. + /// + public Polyline PolylineNotEqualValue { get; private set; } + + public char[] CopyToDestination { get; private set; } + +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + + + /// + /// Sets up the data for the benchmarks. + /// + [GlobalSetup] + public void SetupData() { + PolylineValue = Polyline.FromString(RandomValueProvider.GetPolyline(Count)); + PolylineNotEqualValue = Polyline.FromString(RandomValueProvider.GetPolyline(Count + Random.Shared.Next(1, 101))); + StringValue = PolylineValue.ToString(); + CharArrayValue = [.. StringValue]; + MemoryValue = CharArrayValue.AsMemory(); + + CopyToDestination = new char[PolylineValue.Length]; + } + + /// + /// Benchmarks the encoding of a list of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public Polyline Polyline_FromString() { + var polyline = Polyline + .FromString(StringValue); + + return polyline; + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public Polyline Polyline_FromCharArray() { + var polyline = Polyline + .FromCharArray(CharArrayValue); + + return polyline; + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public Polyline Polyline_FromMemory() { + var polyline = Polyline + .FromMemory(MemoryValue); + + return polyline; + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public string Polyline_ToString() { + var stringValue = PolylineValue + .ToString(); + + return stringValue; + } + + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public void Polyline_CopyTo() { + PolylineValue + .CopyTo(CopyToDestination); + + CopyToDestination + .Consume(consumer); + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public bool Polyline_Equals_SameValue() { + var equals = PolylineValue + .Equals(PolylineValue); + + return equals; + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public bool Polyline_Equals_DifferentValue() { + var equals = PolylineValue + .Equals(PolylineNotEqualValue); + + return equals; + } + + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public bool Polyline_Equals_DifferentType() { + var equals = PolylineValue + .Equals(StringValue); + + return equals; + } +} \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs new file mode 100644 index 00000000..718cdd8b --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -0,0 +1,52 @@ +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using PolylineAlgorithm; +using PolylineAlgorithm.Utility; + +/// +/// Benchmarks for the class. +/// +public class PolylineDecoderBenchmark { + private readonly Consumer _consumer = new(); + + [Params(1, 100, 1_000)] + public int Count; + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + /// + /// Gets the string value representing the encoded polyline. + /// + public Polyline Polyline { get; private set; } + +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + + /// + /// The polyline decoder instance. + /// + public PolylineDecoder Decoder = new(); + + /// + /// Sets up the data for the benchmarks. + /// + [GlobalSetup] + public void SetupData() { + Polyline = Polyline.FromString(RandomValueProvider.GetPolyline(Count)); + } + + /// + /// Benchmarks the decoding of a polyline from a string. + /// + [Benchmark] + public void PolylineDecoder_Decode() { + Decoder + .Decode(Polyline) + .Consume(_consumer); + } +} \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs new file mode 100644 index 00000000..71743ca8 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -0,0 +1,69 @@ +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Attributes; +using PolylineAlgorithm; +using PolylineAlgorithm.Utility; +using System.Collections.Generic; + +/// +/// Benchmarks for the class. +/// +public class PolylineEncoderBenchmark { + [Params(1, 100, 1_000)] + public int Count; + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + /// + /// Gets the enumeration of coordinates to be encoded. + /// + public IEnumerable Enumeration { get; private set; } + + /// + /// Gets the list of coordinates to be encoded. + /// + public List List { get; private set; } +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + + /// + /// The polyline encoder instance. + /// + public PolylineEncoder Encoder = new(); + + /// + /// Sets up the data for the benchmarks. + /// + [GlobalSetup] + public void SetupData() { + Enumeration = RandomValueProvider.GetCoordinates(Count).Select(c => new Coordinate(c.Latitude, c.Longitude)); + List = [.. Enumeration]; + } + + /// + /// Benchmarks the encoding of a list of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public Polyline PolylineEncoder_Encode_List() { + var polyline = Encoder + .Encode(List!); + + return polyline; + } + + /// + /// Benchmarks the encoding of an enumeration of coordinates into a polyline. + /// + /// The encoded polyline. + [Benchmark] + public Polyline PolylineEncoder_Encode_Enumerator() { + var polyline = Encoder + .Encode(Enumeration!); + + return polyline; + } +} \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs new file mode 100644 index 00000000..e1dffccb --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -0,0 +1,23 @@ +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Running; + +/// +/// The main entry point for the benchmark application. +/// +internal class Program { + /// + /// The main method that runs the benchmarks. + /// + /// The command-line arguments. + static void Main(string[] args) { + BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); + } +} \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Properties/GlobalSuppressions.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Properties/GlobalSuppressions.cs new file mode 100644 index 00000000..39178369 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Properties/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Benchmarks need instance methods.")] \ No newline at end of file diff --git a/code-coverage-settings.xml b/code-coverage-settings.xml new file mode 100644 index 00000000..c22f21e5 --- /dev/null +++ b/code-coverage-settings.xml @@ -0,0 +1,26 @@ + + + + + + + src/** + + + + + + + + ^System\.Diagnostics\.DebuggerHiddenAttribute$ + ^System\.Diagnostics\.DebuggerNonUserCodeAttribute$ + ^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$ + ^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$ + + + + True + True + + + \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 4378419e..00000000 --- a/docs/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -############### -# folder # -############### -/**/DROP/ -/**/TEMP/ -/**/packages/ -/**/bin/ -/**/obj/ -_site diff --git a/docs/api/.gitignore b/docs/api/.gitignore deleted file mode 100644 index da7c71b8..00000000 --- a/docs/api/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -############### -# temp file # -############### -*.yml diff --git a/docs/api/.manifest b/docs/api/.manifest deleted file mode 100644 index 794f97a0..00000000 --- a/docs/api/.manifest +++ /dev/null @@ -1,23 +0,0 @@ -{ - "DropoutCoder.PolylineAlgorithm": "DropoutCoder.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.Encoding": "DropoutCoder.PolylineAlgorithm.Encoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1.Decode(System.String)": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1.Encode(System.Collections.Generic.IEnumerable{`0})": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.CreateResult(System.Double,System.Double)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.GetCoordinate(System.ValueTuple{System.Double,System.Double})": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.CreateResult(System.Double,System.Double)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Decode(System.String)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Encode(System.Collections.Generic.IEnumerable{`0})": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.GetCoordinate(`0)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.Decode(System.Char[])": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.Encode(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Double,System.Double}})": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.Validation": "DropoutCoder.PolylineAlgorithm.Validation.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValid(System.ValueTuple{System.Double,System.Double})": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValidLatitude(System.Double)": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValidLongitude(System.Double)": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml" -} \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md deleted file mode 100644 index 306e118e..00000000 --- a/docs/api/index.md +++ /dev/null @@ -1,4 +0,0 @@ -# This is the API docs homepage. -Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. -## Quick Start Notes: -1. Add images to the *images* folder if the file is referencing an image. diff --git a/docs/docfx.json b/docs/docfx.json deleted file mode 100644 index 86263ff4..00000000 --- a/docs/docfx.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "metadata": [ - { - "src": [ - { - "files": [ - "**.csproj" - ], - "src": "../src/" - } - ], - "dest": "api", - "disableGitFeatures": false - } - ], - "build": { - "content": [ - { - "files": [ - "**.yml", - "index.md" - ], - "src": "api", - "dest": "." - } - ], - "resource": [ - { - "files": [ - "images/**" - ] - } - ], - "overwrite": [ - { - "files": [ - "apidoc/**.md" - ], - "exclude": [ - "obj/**", - "_site/**" - ] - } - ], - "dest": "_site", - "globalMetadataFiles": [], - "fileMetadataFiles": [], - "template": [ - "default", - "modern" - ], - "postProcessors": [], - "noLangKeyword": false, - "keepFileLink": false, - "cleanupCacheHistory": false, - "disableGitFeatures": false - } -} \ No newline at end of file diff --git a/docs/favicon.ico b/docs/favicon.ico deleted file mode 100644 index 71570f61..00000000 Binary files a/docs/favicon.ico and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.eot b/docs/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index b93a4953..00000000 Binary files a/docs/fonts/glyphicons-halflings-regular.eot and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.svg b/docs/fonts/glyphicons-halflings-regular.svg deleted file mode 100644 index 94fb5490..00000000 --- a/docs/fonts/glyphicons-halflings-regular.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/fonts/glyphicons-halflings-regular.ttf b/docs/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 1413fc60..00000000 Binary files a/docs/fonts/glyphicons-halflings-regular.ttf and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.woff b/docs/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 9e612858..00000000 Binary files a/docs/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.woff2 b/docs/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b54..00000000 Binary files a/docs/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ diff --git a/docs/logo.svg b/docs/logo.svg deleted file mode 100644 index ccb2d7bc..00000000 --- a/docs/logo.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Created by Docfx - - - - - - - diff --git a/docs/manifest.json b/docs/manifest.json deleted file mode 100644 index 202b1ff4..00000000 --- a/docs/manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"homepages":[],"source_base_path":"C:/Projects/GitHub/Cloudikka/polyline-algorithm-csharp/src/Cloudikka.PolylineAlgorithm","xrefmap":"xrefmap.yml","files":[{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.PolylineAlgorithm.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.PolylineAlgorithm.html","hash":"DuxXQJFG0JnJK4XZfGoqSw=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Validation.CoordinateValidator.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Validation.CoordinateValidator.html","hash":"bHKr12B+LaPPoDIiM/GdEw=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Validation.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Validation.html","hash":"JRNjS8Iv+pO6MsunBCDXvA=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.html","hash":"m5VwU6ucCYySNK9o1V+ObQ=="}},"is_incremental":false},{"type":"Toc","source_relative_path":"../../docs/source/api/toc.yml","output":{".html":{"relative_path":"api/toc.html","hash":"MJBrHUiuNZAV/fYefVG24A=="}},"is_incremental":false},{"type":"Toc","source_relative_path":"../../docs/source/toc.yml","output":{".html":{"relative_path":"toc.html","hash":"ErjYhgldNN21zQh8L4Olrg=="}},"is_incremental":false},{"type":"Toc","source_relative_path":"../../docs/source/articles/toc.yml","output":{".html":{"relative_path":"articles/toc.html","hash":"dsfYf/xjrWq6mnqKHgnW9g=="}},"is_incremental":false},{"type":"Conceptual","source_relative_path":"../../docs/source/api/index.md","output":{".html":{"relative_path":"api/index.html","hash":"dPgHIsVe2ZXJr7/R6lmg7Q=="}},"is_incremental":false},{"type":"Conceptual","source_relative_path":"../../docs/source/index.md","output":{".html":{"relative_path":"index.html","hash":"OqddFoprNY6Yz18TAcxrrA=="}},"is_incremental":false},{"type":"Conceptual","source_relative_path":"../../docs/source/articles/intro.md","output":{".html":{"relative_path":"articles/intro.html","hash":"bhq6zzP77tZUevOHXJu4fw=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Encoding.IPolylineEncoding-1.html","hash":"TcaAT5pBvPQKZDEXksnw6w=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Encoding.PolylineEncoding.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Encoding.PolylineEncoding.html","hash":"AkMKRIs+xaAFilAKiDfIRA=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.html","hash":"xGg93o6lzLNcZTa046c4cQ=="}},"is_incremental":false},{"type":"ManagedReference","source_relative_path":"../../docs/source/api/Cloudikka.PolylineAlgorithm.Encoding.yml","output":{".html":{"relative_path":"api/Cloudikka.PolylineAlgorithm.Encoding.html","hash":"q9cIXLi1Eu31lwAwDxYBmA=="}},"is_incremental":false}]} \ No newline at end of file diff --git a/docs/search-stopwords.json b/docs/search-stopwords.json deleted file mode 100644 index 0bdcc2c0..00000000 --- a/docs/search-stopwords.json +++ /dev/null @@ -1,121 +0,0 @@ -[ - "a", - "able", - "about", - "across", - "after", - "all", - "almost", - "also", - "am", - "among", - "an", - "and", - "any", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "do", - "does", - "either", - "else", - "ever", - "every", - "for", - "from", - "get", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "in", - "into", - "is", - "it", - "its", - "just", - "least", - "let", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "only", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "where", - "which", - "while", - "who", - "whom", - "why", - "will", - "with", - "would", - "yet", - "you", - "your" -] diff --git a/docs/styles/docfx.css b/docs/styles/docfx.css deleted file mode 100644 index 83800086..00000000 --- a/docs/styles/docfx.css +++ /dev/null @@ -1,882 +0,0 @@ -/* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. */ -html, -body { - font-family: 'Segoe UI', Tahoma, Helvetica, sans-serif; - height: 100%; -} -button, -a { - color: #337ab7; - cursor: pointer; -} -button:hover, -button:focus, -a:hover, -a:focus { - color: #23527c; - text-decoration: none; -} -a.disable, -a.disable:hover { - text-decoration: none; - cursor: default; - color: #000000; -} - -/* workaround for leave space for fixed navbar with # anchor url*/ - -h1:before, -h2:before, -h3:before, -h4:before { - content: ''; - display: block; - position: relative; - width: 0; - height: 100px; - margin-top: -100px; -} - -h1, h2, h3, h4, h5, h6, span.xref { - word-wrap: break-word; - word-break: break-all; -} - -h1 mark, -h2 mark, -h3 mark, -h4 mark, -h5 mark, -h6 mark { - padding: 0; -} - -.inheritance .level0:before, -.inheritance .level1:before, -.inheritance .level2:before, -.inheritance .level3:before, -.inheritance .level4:before, -.inheritance .level5:before { - content: '↳'; - margin-right: 5px; -} - -.inheritance .level0 { - margin-left: 0em; -} - -.inheritance .level1 { - margin-left: 1em; -} - -.inheritance .level2 { - margin-left: 2em; -} - -.inheritance .level3 { - margin-left: 3em; -} - -.inheritance .level4 { - margin-left: 4em; -} - -.inheritance .level5 { - margin-left: 5em; -} - -span.parametername, -span.paramref, -span.typeparamref { - font-style: italic; -} -span.languagekeyword{ - font-weight: bold; -} - -svg:hover path { - fill: #ffffff; -} - -.hljs { - display: inline; - background-color: inherit; - padding: 0; -} -/* additional spacing fixes */ -.btn + .btn { - margin-left: 10px; -} -.btn.pull-right { - margin-left: 10px; - margin-top: 5px; -} -.table { - margin-bottom: 10px; -} -table p { - margin-bottom: 0; -} -table a { - display: inline-block; -} -h1, -.h1, -h2, -.h2, -h3, -.h3 { - margin-top: 15px; - margin-bottom: 10px; - font-weight: 400; -} -h4, -.h4, -h5, -.h5, -h6, -.h6 { - margin-top: 10px; - margin-bottom: 5px; -} -.navbar { - margin-bottom: 0; -} -#wrapper { - min-height: 100%; - position: relative; -} -/* blends header footer and content together with gradient effect */ -.grad-top { - /* For Safari 5.1 to 6.0 */ - /* For Opera 11.1 to 12.0 */ - /* For Firefox 3.6 to 15 */ - background: linear-gradient(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0)); - /* Standard syntax */ - height: 5px; -} -.grad-bottom { - /* For Safari 5.1 to 6.0 */ - /* For Opera 11.1 to 12.0 */ - /* For Firefox 3.6 to 15 */ - background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05)); - /* Standard syntax */ - height: 5px; -} -.divider { - margin: 0 5px; - color: #cccccc; -} -hr { - border-color: #cccccc; -} -header { - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 1000; -} -header .navbar { - border-width: 0 0 1px; - border-radius: 0; -} -.navbar-brand { - font-size: inherit; - padding: 0; -} -.navbar-collapse { - margin: 0 -15px; -} -.subnav { - min-height: 40px; -} - -.inheritance h5, .inheritedMembers h5{ - padding-bottom: 5px; - border-bottom: 1px solid #ccc; -} - -article h1, article h2, article h3, article h4{ - margin-top: 25px; -} - -article h4{ - border-bottom: 1px solid #ccc; -} - -article span.small.pull-right{ - margin-top: 20px; -} - -article section { - margin-left: 1em; -} - -/*.expand-all { - padding: 10px 0; -}*/ -.breadcrumb { - margin: 0; - padding: 10px 0; - background-color: inherit; - white-space: nowrap; -} -.breadcrumb > li + li:before { - content: "\00a0/"; -} -#autocollapse.collapsed .navbar-header { - float: none; -} -#autocollapse.collapsed .navbar-toggle { - display: block; -} -#autocollapse.collapsed .navbar-collapse { - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); -} -#autocollapse.collapsed .navbar-collapse.collapse { - display: none !important; -} -#autocollapse.collapsed .navbar-nav { - float: none !important; - margin: 7.5px -15px; -} -#autocollapse.collapsed .navbar-nav > li { - float: none; -} -#autocollapse.collapsed .navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; -} -#autocollapse.collapsed .collapse.in, -#autocollapse.collapsed .collapsing { - display: block !important; -} -#autocollapse.collapsed .collapse.in .navbar-right, -#autocollapse.collapsed .collapsing .navbar-right { - float: none !important; -} -#autocollapse .form-group { - width: 100%; -} -#autocollapse .form-control { - width: 100%; -} -#autocollapse .navbar-header { - margin-left: 0; - margin-right: 0; -} -#autocollapse .navbar-brand { - margin-left: 0; -} -.collapse.in, -.collapsing { - text-align: center; -} -.collapsing .navbar-form { - margin: 0 auto; - max-width: 400px; - padding: 10px 15px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -} -.collapsed .collapse.in .navbar-form { - margin: 0 auto; - max-width: 400px; - padding: 10px 15px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -} -.navbar .navbar-nav { - display: inline-block; -} -.docs-search { - background: white; - vertical-align: middle; -} -.docs-search > .search-query { - font-size: 14px; - border: 0; - width: 120%; - color: #555; -} -.docs-search > .search-query:focus { - outline: 0; -} -.search-results-frame { - clear: both; - display: table; - width: 100%; -} -.search-results.ng-hide { - display: none; -} -.search-results-container { - padding-bottom: 1em; - border-top: 1px solid #111; - background: rgba(25, 25, 25, 0.5); -} -.search-results-container .search-results-group { - padding-top: 50px !important; - padding: 10px; -} -.search-results-group-heading { - font-family: "Open Sans"; - padding-left: 10px; - color: white; -} -.search-close { - position: absolute; - left: 50%; - margin-left: -100px; - color: white; - text-align: center; - padding: 5px; - background: #333; - border-top-right-radius: 5px; - border-top-left-radius: 5px; - width: 200px; - box-shadow: 0 0 10px #111; -} -#search { - display: none; -} - -/* Search results display*/ -#search-results { - max-width: 960px !important; - margin-top: 120px; - margin-bottom: 115px; - margin-left: auto; - margin-right: auto; - line-height: 1.8; - display: none; -} - -#search-results>.search-list { - text-align: center; - font-size: 2.5rem; - margin-bottom: 50px; -} - -#search-results p { - text-align: center; -} - -#search-results .sr-items { - font-size: 24px; -} - -.sr-item { - margin-bottom: 25px; -} - -.sr-item>.item-href { - font-size: 14px; - color: #093; -} - -.sr-item>.item-brief { - font-size: 13px; -} - -.pagination>li>a { - color: #47A7A0 -} - -.pagination>.active>a { - background-color: #47A7A0; - border-color: #47A7A0; -} - -.fixed_header { - position: fixed; - width: 100%; - padding-bottom: 10px; - padding-top: 10px; - margin: 0px; - top: 0; - z-index: 9999; - left: 0; -} - -.fixed_header+.toc{ - margin-top: 50px; - margin-left: 0; -} - -.sidenav, .fixed_header, .toc { - background-color: #f1f1f1; -} - -.sidetoc { - position: fixed; - width: 260px; - top: 150px; - bottom: 0; - overflow-x: hidden; - overflow-y: auto; - background-color: #f1f1f1; - border-left: 1px solid #e7e7e7; - border-right: 1px solid #e7e7e7; - z-index: 1; -} - -body .toc{ - background-color: #f1f1f1; - overflow-x: hidden; -} - -.sidetoggle.ng-hide { - display: block !important; -} -.sidetoc-expand > .caret { - margin-left: 0px; - margin-top: -2px; -} -.sidetoc-expand > .caret-side { - border-left: 4px solid; - border-top: 4px solid transparent; - border-bottom: 4px solid transparent; - margin-left: 4px; - margin-top: -4px; -} -.sidetoc-heading { - font-weight: 500; -} - -.toc { - margin: 0px 0 0 10px; - padding: 0 10px; -} -.expand-stub { - position: absolute; - left: -10px; -} -.toc .nav > li > a.sidetoc-expand { - position: absolute; - top: 0; - left: 0; -} -.toc .nav > li > a { - color: #666666; - display: inline; - padding: 0; -} -.toc .nav > li > .expand-stub + a { - margin-left: 5px; - display: block; -} -.toc .nav > li > a:hover, -.toc .nav > li > a:focus { - color: #000000; - background: none; - text-decoration: inherit; -} -.toc .nav > li.active > a { - color: #337ab7; -} -.toc .nav > li.active > a:hover, -.toc .nav > li.active > a:focus { - color: #23527c; -} - -.toc .nav > li> .expand-stub { - cursor: pointer; -} - -.toc .nav > li.active > .expand-stub::before, -.toc .nav > li.in > .expand-stub::before, -.toc .nav > li.in.active > .expand-stub::before, -.toc .nav > li.filtered > .expand-stub::before { - content: "-"; -} - -.toc .nav > li > .expand-stub::before, -.toc .nav > li.active > .expand-stub::before { - content: "+"; -} - -.toc .nav > li.filtered > ul, -.toc .nav > li.in > ul { - display: block; -} - -.toc .nav > li > ul { - display: none; -} - -.toc .level1 > li { - font-weight: bold; - margin-top: 10px; - position: relative; -} -.toc .level2 { - font-weight: normal; - margin-top: 5px; - margin-left: 15px; - font-size: 14px; -} -.toc .level3 { - font-size: 12px; -} -.toc-toggle { - display: none; - margin: 0 15px 0px 15px; -} -.sidefilter { - position: fixed; - top: 90px; - width: 260px; - background-color: #f1f1f1; - padding: 15px; - border-left: 1px solid #e7e7e7; - border-right: 1px solid #e7e7e7; - z-index: 1; -} -.toc-filter { - border-radius: 5px; - background: #fff; - color: #666666; - padding: 5px; - position: relative; - margin: 0 5px 0 5px; -} -.toc-filter > input { - border: 0; - color: #666666; - padding-left: 20px; - width: 100%; -} -.toc-filter > input:focus { - outline: 0; -} -.toc-filter > .filter-icon { - position: absolute; - top: 10px; - left: 5px; -} -.article { - margin-top: 120px; - margin-bottom: 115px; -} - -#_content>a{ - margin-top: 105px; -} - -.article.grid-right { - margin-left: 280px; -} - -.inheritance hr { - margin-top: 5px; - margin-bottom: 5px; -} -.article img { - max-width: 100%; -} -.sideaffix { - margin-top: 50px; - font-size: 12px; - max-height: 100%; - overflow: hidden; - top: 100px; - bottom: 10px; - position: fixed; -} -.affix { - position: relative; - height: 100%; -} -.sideaffix > div.contribution { - margin-bottom: 20px; -} -.sideaffix > div.contribution > ul > li > a.contribution-link { - padding: 6px 10px; - font-weight: bold; - font-size: 14px; -} -.sideaffix > div.contribution > ul > li > a.contribution-link:hover { - background-color: #ffffff; -} -.sideaffix ul.nav > li > a:focus { - background: none; -} -.affix h5 { - font-weight: bold; - text-transform: uppercase; - padding-left: 10px; - font-size: 12px; -} -.affix > ul.level1 { - overflow: hidden; - padding-bottom: 10px; - height: calc(100% - 100px); - margin-right: -20px; -} -.affix ul > li > a:before { - color: #cccccc; - position: absolute; -} -.affix ul > li > a:hover { - background: none; - color: #666666; -} -.affix ul > li.active > a, -.affix ul > li.active > a:before { - color: #337ab7; -} -.affix ul > li > a { - padding: 5px 12px; - color: #666666; -} -.affix > ul > li.active:last-child { - margin-bottom: 50px; -} -.affix > ul > li > a:before { - content: "|"; - font-size: 16px; - top: 1px; - left: 0; -} -.affix > ul > li.active > a, -.affix > ul > li.active > a:before { - color: #337ab7; - font-weight: bold; -} -.affix ul ul > li > a { - padding: 2px 15px; -} -.affix ul ul > li > a:before { - content: ">"; - font-size: 14px; - top: -1px; - left: 5px; -} -.affix ul > li > a:before, -.affix ul ul { - display: none; -} -.affix ul > li.active > ul, -.affix ul > li.active > a:before, -.affix ul > li > a:hover:before { - display: block; - white-space: nowrap; -} -.codewrapper { - position: relative; -} -.trydiv { - height: 0px; -} -.tryspan { - position: absolute; - top: 0px; - right: 0px; - border-style: solid; - border-radius: 0px 4px; - box-sizing: border-box; - border-width: 1px; - border-color: #cccccc; - text-align: center; - padding: 2px 8px; - background-color: white; - font-size: 12px; - cursor: pointer; - z-index: 100; - display: none; - color: #767676; -} -.tryspan:hover { - background-color: #3b8bd0; - color: white; - border-color: #3b8bd0; -} -.codewrapper:hover .tryspan { - display: block; -} -.sample-response .response-content{ - max-height: 200px; -} -footer { - position: absolute; - left: 0; - right: 0; - bottom: 0; - z-index: 1000; -} -.footer { - border-top: 1px solid #e7e7e7; - background-color: #f8f8f8; - padding: 15px 0; -} -@media (min-width: 768px) { - #sidetoggle.collapse { - display: block; - } - .topnav .navbar-nav { - float: none; - white-space: nowrap; - } - .topnav .navbar-nav > li { - float: none; - display: inline-block; - } -} -@media only screen and (max-width: 768px) { - #mobile-indicator { - display: block; - } - /* TOC display for responsive */ - .article { - margin-top: 30px !important; - } - header { - position: static; - } - .topnav { - text-align: center; - } - .sidenav { - padding: 15px 0; - margin-left: -15px; - margin-right: -15px; - } - .sidefilter { - position: static; - width: auto; - float: none; - border: none; - } - .sidetoc { - position: static; - width: auto; - float: none; - padding-bottom: 0px; - border: none; - } - .toc .level2 > li { - display: inline-block; - } - .toc .level2 > li:after { - margin-left: -3px; - margin-right: 5px; - content: ", "; - color: #666666; - } - .article.grid-right { - margin-left: 0; - } - .grad-top, - .grad-bottom { - display: none; - } - .toc-toggle { - display: block; - } - .sidetoggle.ng-hide { - display: none !important; - } - /*.expand-all { - display: none; - }*/ - .sideaffix { - display: none; - } - .mobile-hide { - display: none; - } - .breadcrumb { - white-space: inherit; - } - - /* workaround for #hashtag url is no longer needed*/ - h1:before, - h2:before, - h3:before, - h4:before { - content: ''; - display: none; - } -} - -/* For toc iframe */ -@media (max-width: 260px) { - .toc .level2 > li { - display: block; - } - - .toc .level2 > li:after { - display: none; - } -} - -/* For code snippet line highlight */ -pre > code .line-highlight { - background-color: #ffffcc; -} - -/* Alerts */ -.alert h5 { - text-transform: uppercase; - font-weight: bold; - margin-top: 0; -} - -.alert h5:before { - position:relative; - top:1px; - display:inline-block; - font-family:'Glyphicons Halflings'; - line-height:1; - -webkit-font-smoothing:antialiased; - -moz-osx-font-smoothing:grayscale; - margin-right: 5px; - font-weight: normal; -} - -.alert-info h5:before { - content:"\e086" -} - -.alert-warning h5:before { - content:"\e127" -} - -.alert-danger h5:before { - content:"\e107" -} - -/* For Embedded Video */ -div.embeddedvideo { - padding-top: 56.25%; - position: relative; - width: 100%; -} - -div.embeddedvideo iframe { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 100%; - height: 100%; -} - -/* For printer */ -@media print{ - .article.grid-right { - margin-top: 0px; - margin-left: 0px; - } - .sideaffix { - display: none; - } - .mobile-hide { - display: none; - } - .footer { - display: none; - } -} \ No newline at end of file diff --git a/docs/styles/docfx.js b/docs/styles/docfx.js deleted file mode 100644 index 0f84531f..00000000 --- a/docs/styles/docfx.js +++ /dev/null @@ -1,700 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. -$(function () { - var active = 'active'; - var expanded = 'in'; - var collapsed = 'collapsed'; - var filtered = 'filtered'; - var show = 'show'; - var hide = 'hide'; - - // Styling for tables in conceptual documents using Bootstrap. - // See http://getbootstrap.com/css/#tables - (function () { - $('table').addClass('table table-bordered table-striped table-condensed'); - })(); - - // Styling for alerts. - (function () { - $('.NOTE, .TIP').addClass('alert alert-info'); - $('.WARNING').addClass('alert alert-warning'); - $('.IMPORTANT, .CAUTION').addClass('alert alert-danger'); - })(); - - // Enable highlight.js - (function () { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); - })(); - - // Line highlight for code snippet - (function () { - $('pre code[highlight-lines]').each(function (i, block) { - if (block.innerHTML === "") return; - var lines = block.innerHTML.split('\n'); - - queryString = block.getAttribute('highlight-lines'); - if (!queryString) return; - - var ranges = queryString.split(','); - for (var j = 0, range; range = ranges[j++];) { - var found = range.match(/^(\d+)\-(\d+)?$/); - if (found) { - // consider region as `{startlinenumber}-{endlinenumber}`, in which {endlinenumber} is optional - var start = +found[1]; - var end = +found[2]; - if (isNaN(end) || end > lines.length) { - end = lines.length; - } - } else { - // consider region as a sigine line number - if (isNaN(range)) continue; - var start = +range; - var end = start; - } - if (start <= 0 || end <= 0 || start > end || start > lines.length) { - // skip current region if invalid - continue; - } - lines[start - 1] = '' + lines[start - 1]; - lines[end - 1] = lines[end - 1] + ''; - } - - block.innerHTML = lines.join('\n'); - }); - })(); - - //Adjust the position of search box in navbar - (function () { - autoCollapse(); - $(window).on('resize', autoCollapse); - $(document).on('click', '.navbar-collapse.in', function (e) { - if ($(e.target).is('a')) { - $(this).collapse('hide'); - } - }); - - function autoCollapse() { - var navbar = $('#autocollapse'); - if (navbar.height() === null) { - setTimeout(autoCollapse, 300); - } - navbar.removeClass(collapsed); - if (navbar.height() > 60) { - navbar.addClass(collapsed); - } - } - })(); - - // Support full-text-search - (function () { - var query; - var relHref = $("meta[property='docfx\\:rel']").attr("content") || ""; - var search = searchFactory(); - search(); - highlightKeywords(); - addSearchEvent(); - - // Search factory - function searchFactory() { - var worker = new Worker(relHref + 'styles/search-worker.js'); - if (!worker) return localSearch; - return window.Worker ? webWorkerSearch : localSearch; - - function localSearch() { - console.log("using local search"); - var lunrIndex = lunr(function () { - this.ref('href'); - this.field('title', { boost: 50 }); - this.field('keywords', { boost: 20 }); - }); - lunr.tokenizer.seperator = /[\s\-\.]+/; - var searchData = {}; - var searchDataRequest = new XMLHttpRequest(); - - var indexPath = relHref + "index.json"; - if (indexPath) { - searchDataRequest.open('GET', indexPath); - searchDataRequest.onload = function () { - searchData = JSON.parse(this.responseText); - for (var prop in searchData) { - lunrIndex.add(searchData[prop]); - } - } - searchDataRequest.send(); - } - - $("body").bind("queryReady", function () { - var hits = lunrIndex.search(query); - var results = []; - hits.forEach(function (hit) { - var item = searchData[hit.ref]; - results.push({ 'href': item.href, 'title': item.title, 'keywords': item.keywords }); - }); - handleSearchResults(results); - }); - } - - function webWorkerSearch() { - console.log("using Web Worker"); - var indexReady = $.Deferred(); - - worker.onmessage = function (oEvent) { - switch (oEvent.data.e) { - case 'index-ready': - indexReady.resolve(); - break; - case 'query-ready': - var hits = oEvent.data.d; - handleSearchResults(hits); - break; - } - } - - indexReady.promise().done(function () { - $("body").bind("queryReady", function () { - worker.postMessage({ q: query }); - }); - }); - } - }; - - // Highlight the searching keywords - function highlightKeywords() { - var q = url('?q'); - if (q !== null) { - var keywords = q.split("%20"); - keywords.forEach(function (keyword) { - if (keyword !== "") { - $('.data-searchable *').mark(keyword); - $('article *').mark(keyword); - } - }); - } - } - - function addSearchEvent() { - $('body').bind("searchEvent", function () { - $('#search-query').keypress(function (e) { - return e.which !== 13; - }); - - $('#search-query').keyup(function () { - query = $(this).val(); - if (query.length < 3) { - flipContents("show"); - } else { - flipContents("hide"); - $("body").trigger("queryReady"); - $('#search-results>.search-list').text('Search Results for "' + query + '"'); - } - }).off("keydown"); - }); - } - - function flipContents(action) { - if (action === "show") { - $('.hide-when-search').show(); - $('#search-results').hide(); - } else { - $('.hide-when-search').hide(); - $('#search-results').show(); - } - } - - function relativeUrlToAbsoluteUrl(currentUrl, relativeUrl) { - var currentItems = currentUrl.split(/\/+/); - var relativeItems = relativeUrl.split(/\/+/); - var depth = currentItems.length - 1; - var items = []; - for (var i = 0; i < relativeItems.length; i++) { - if (relativeItems[i] === '..') { - depth--; - } else if (relativeItems[i] !== '.') { - items.push(relativeItems[i]); - } - } - return currentItems.slice(0, depth).concat(items).join('/'); - } - - function extractContentBrief(content) { - var briefOffset = 512; - var words = query.split(/\s+/g); - var queryIndex = content.indexOf(words[0]); - var briefContent; - if (queryIndex > briefOffset) { - return "..." + content.slice(queryIndex - briefOffset, queryIndex + briefOffset) + "..."; - } else if (queryIndex <= briefOffset) { - return content.slice(0, queryIndex + briefOffset) + "..."; - } - } - - function handleSearchResults(hits) { - var numPerPage = 10; - $('#pagination').empty(); - $('#pagination').removeData("twbs-pagination"); - if (hits.length === 0) { - $('#search-results>.sr-items').html('

No results found

'); - } else { - $('#pagination').twbsPagination({ - totalPages: Math.ceil(hits.length / numPerPage), - visiblePages: 5, - onPageClick: function (event, page) { - var start = (page - 1) * numPerPage; - var curHits = hits.slice(start, start + numPerPage); - $('#search-results>.sr-items').empty().append( - curHits.map(function (hit) { - var currentUrl = window.location.href; - var itemRawHref = relativeUrlToAbsoluteUrl(currentUrl, relHref + hit.href); - var itemHref = relHref + hit.href + "?q=" + query; - var itemTitle = hit.title; - var itemBrief = extractContentBrief(hit.keywords); - - var itemNode = $('
').attr('class', 'sr-item'); - var itemTitleNode = $('
').attr('class', 'item-title').append($('').attr('href', itemHref).attr("target", "_blank").text(itemTitle)); - var itemHrefNode = $('
').attr('class', 'item-href').text(itemRawHref); - var itemBriefNode = $('
').attr('class', 'item-brief').text(itemBrief); - itemNode.append(itemTitleNode).append(itemHrefNode).append(itemBriefNode); - return itemNode; - }) - ); - query.split(/\s+/).forEach(function (word) { - if (word !== '') { - $('#search-results>.sr-items *').mark(word); - } - }); - } - }); - } - } - })(); - - // Update href in navbar - (function () { - var toc = $('#sidetoc'); - var breadcrumb = new Breadcrumb(); - loadNavbar(); - loadToc(); - function loadNavbar() { - var navbarPath = $("meta[property='docfx\\:navrel']").attr("content"); - var tocPath = $("meta[property='docfx\\:tocrel']").attr("content"); - if (tocPath) tocPath = tocPath.replace(/\\/g, '/'); - if (navbarPath) navbarPath = navbarPath.replace(/\\/g, '/'); - $.get(navbarPath, function (data) { - $(data).find("#toc>ul").appendTo("#navbar"); - if ($('#search-results').length !== 0) { - $('#search').show(); - $('body').trigger("searchEvent"); - } - var index = navbarPath.lastIndexOf('/'); - var navrel = ''; - if (index > -1) { - navrel = navbarPath.substr(0, index + 1); - } - $('#navbar>ul').addClass('navbar-nav'); - var currentAbsPath = getAbsolutePath(window.location.pathname); - // set active item - $('#navbar').find('a[href]').each(function (i, e) { - var href = $(e).attr("href"); - if (isRelativePath(href)) { - href = navrel + href; - $(e).attr("href", href); - - // TODO: currently only support one level navbar - var isActive = false; - var originalHref = e.name; - if (originalHref) { - originalHref = navrel + originalHref; - if (getDirectory(getAbsolutePath(originalHref)) === getDirectory(getAbsolutePath(tocPath))) { - isActive = true; - } - } else { - if (getAbsolutePath(href) === currentAbsPath) { - isActive = true; - } - } - if (isActive) { - $(e).parent().addClass(active); - if (!breadcrumb.isNavPartLoaded) { - breadcrumb.insert({ - href: e.href, - name: e.innerHTML - }, 0); - breadcrumb.isNavPartLoaded = true; - } - } else { - $(e).parent().removeClass(active) - } - } - }); - }); - } - - function loadToc() { - var tocPath = $("meta[property='docfx\\:tocrel']").attr("content"); - if (tocPath) tocPath = tocPath.replace(/\\/g, '/'); - $('#sidetoc').load(tocPath + " #sidetoggle > div", function () { - registerTocEvents(); - - var index = tocPath.lastIndexOf('/'); - var tocrel = ''; - if (index > -1) { - tocrel = tocPath.substr(0, index + 1); - } - var currentHref = getAbsolutePath(window.location.pathname); - $('#sidetoc').find('a[href]').each(function (i, e) { - var href = $(e).attr("href"); - if (isRelativePath(href)) { - href = tocrel + href; - $(e).attr("href", href); - } - - if (getAbsolutePath(e.href) === currentHref) { - $(e).parent().addClass(active); - var parent = $(e).parent().parents('li').children('a'); - if (!breadcrumb.isTocPartLoaded) { - for (var i = parent.length - 1; i >= 0; i--) { - breadcrumb.push({ - href: parent[i].href, - name: parent[i].innerHTML - }); - } - breadcrumb.push({ - href: e.href, - name: e.innerHTML - }); - breadcrumb.isTocPartLoaded = true; - } - if (parent.length > 0) { - parent.addClass(active); - } - // for active li, expand it - $(e).parents('ul.nav>li').addClass(expanded); - - // Scroll to active item - var top = 0; - $(e).parents('li').each(function (i, e) { - top += $(e).position().top; - }); - // 50 is the size of the filter box - $('.sidetoc').scrollTop(top - 50); - if ($('footer').is(':visible')) { - $(".sidetoc").css("bottom", "70px"); - } - } else { - $(e).parent().removeClass(active); - $(e).parents('li').children('a').removeClass(active); - } - }); - }); - } - - function registerTocEvents() { - $('.toc .nav > li > .expand-stub').click(function (e) { - $(e.target).parent().toggleClass(expanded); - }); - $('.toc .nav > li > .expand-stub + a:not([href])').click(function (e) { - $(e.target).parent().toggleClass(expanded); - }); - $('#toc_filter_input').on('input', function (e) { - var val = this.value; - if (val === '') { - // Clear 'filtered' class - $('#toc li').removeClass(filtered).removeClass(hide); - return; - } - - // Get leaf nodes - $('#toc li>a').filter(function (i, e) { - return $(e).siblings().length === 0 - }).each(function (i, anchor) { - var text = $(anchor).text(); - var parent = $(anchor).parent(); - var parentNodes = parent.parents('ul>li'); - for (var i = 0; i < parentNodes.length; i++) { - var parentText = $(parentNodes[i]).children('a').text(); - if (parentText) text = parentText + '.' + text; - }; - if (filterNavItem(text, val)) { - parent.addClass(show); - parent.removeClass(hide); - } else { - parent.addClass(hide); - parent.removeClass(show); - } - }); - $('#toc li>a').filter(function (i, e) { - return $(e).siblings().length > 0 - }).each(function (i, anchor) { - var parent = $(anchor).parent(); - if (parent.find('li.show').length > 0) { - parent.addClass(show); - parent.addClass(filtered); - parent.removeClass(hide); - } else { - parent.addClass(hide); - parent.removeClass(show); - parent.removeClass(filtered); - } - }) - - function filterNavItem(name, text) { - if (!text) return true; - if (name.toLowerCase().indexOf(text.toLowerCase()) > -1) return true; - return false; - } - }); - } - - function Breadcrumb() { - var breadcrumb = []; - var isNavPartLoaded = false; - var isTocPartLoaded = false; - this.push = pushBreadcrumb; - this.insert = insertBreadcrumb; - - function pushBreadcrumb(obj) { - breadcrumb.push(obj); - setupBreadCrumb(breadcrumb); - } - - function insertBreadcrumb(obj, index) { - breadcrumb.splice(index, 0, obj); - setupBreadCrumb(breadcrumb); - } - - function setupBreadCrumb() { - var html = formList(breadcrumb, 'breadcrumb'); - $('#breadcrumb').html(html); - } - } - - function getAbsolutePath(href) { - // Use anchor to normalize href - var anchor = $('')[0]; - // Ignore protocal, remove search and query - return anchor.host + anchor.pathname; - } - - function isRelativePath(href) { - return !isAbsolutePath(href); - } - - function isAbsolutePath(href) { - return (/^(?:[a-z]+:)?\/\//i).test(href); - } - - function getDirectory(href) { - if (!href) return ''; - var index = href.lastIndexOf('/'); - if (index == -1) return ''; - if (index > -1) { - return href.substr(0, index); - } - } - })(); - - //Setup Affix - (function () { - var hierarchy = getHierarchy(); - if (hierarchy.length > 0) { - var html = '
In This Article
' - html += formList(hierarchy, ['nav', 'bs-docs-sidenav']); - $("#affix").append(html); - if ($('footer').is(':visible')) { - $(".sideaffix").css("bottom", "70px"); - } - $('#affix').on('activate.bs.scrollspy', function (e) { - if (e.target) { - if ($(e.target).find('li.active').length > 0) { - return; - } - var top = $(e.target).position().top; - $(e.target).parents('li').each(function (i, e) { - top += $(e).position().top; - }); - var container = $('#affix > ul'); - var height = container.height(); - container.scrollTop(container.scrollTop() + top - height/2); - } - }) - } - - function getHierarchy() { - // supported headers are h1, h2, h3, and h4 - // The topest header is ignored - var selector = ".article article"; - var affixSelector = "#affix"; - var headers = ['h4', 'h3', 'h2', 'h1']; - var hierarchy = []; - var toppestIndex = -1; - var startIndex = -1; - // 1. get header hierarchy - for (var i = headers.length - 1; i >= 0; i--) { - var header = $(selector + " " + headers[i]); - var length = header.length; - - // If contains no header in current selector, find the next one - if (length === 0) continue; - - // If the toppest header contains only one item, e.g. title, ignore - if (length === 1 && hierarchy.length === 0 && toppestIndex < 0) { - toppestIndex = i; - continue; - } - - // Get second level children - var nextLevelSelector = i > 0 ? headers[i - 1] : null; - var prevSelector; - for (var j = length - 1; j >= 0; j--) { - var e = header[j]; - var id = e.id; - if (!id) continue; // For affix, id is a must-have - var item = { - name: htmlEncode($(e).text()), - href: "#" + id, - items: [] - }; - if (nextLevelSelector) { - var selector = '#' + id + "~" + nextLevelSelector; - var currentSelector = selector; - if (prevSelector) currentSelector += ":not(" + prevSelector + ")"; - $(header[j]).siblings(currentSelector).each(function (index, e) { - if (e.id) { - item.items.push({ - name: htmlEncode($(e).text()), // innerText decodes text while innerHTML not - href: "#" + e.id - - }) - } - }) - prevSelector = selector; - } - hierarchy.push(item); - } - break; - }; - hierarchy.reverse(); - return hierarchy; - } - - function htmlEncode(str) { - return String(str) - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); - } - - function htmlDecode(value) { - return String(value) - .replace(/"/g, '"') - .replace(/'/g, "'") - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/&/g, '&'); - } - })(); - - function formList(item, classes) { - var level = 1; - var model = { - items: item - }; - var cls = [].concat(classes).join(" "); - return getList(model, cls); - - function getList(model, cls) { - if (!model || !model.items) return null; - var l = model.items.length; - if (l === 0) return null; - var html = '
    '; - level++; - for (var i = 0; i < l; i++) { - var item = model.items[i]; - var href = item.href; - var name = item.name; - if (!name) continue; - html += href ? '
  • ' + name + '' : '
  • ' + name; - html += getList(item, cls) || ''; - html += '
  • '; - } - html += '
'; - return html; - } - } - - // Show footer - (function () { - initFooter(); - $(window).on("scroll", showFooter); - - function initFooter() { - if (needFooter()) { - shiftUpBottomCss(); - $("footer").show(); - } else { - resetBottomCss(); - $("footer").hide(); - } - } - - function showFooter() { - if (needFooter()) { - shiftUpBottomCss(); - $("footer").fadeIn(); - } else { - resetBottomCss(); - $("footer").fadeOut(); - } - } - - function needFooter() { - var scrollHeight = $(document).height(); - var scrollPosition = $(window).height() + $(window).scrollTop(); - return (scrollHeight - scrollPosition) < 1; - } - - function resetBottomCss() { - $(".sidetoc").css("bottom", "0"); - $(".sideaffix").css("bottom", "10px"); - } - - function shiftUpBottomCss() { - $(".sidetoc").css("bottom", "70px"); - $(".sideaffix").css("bottom", "70px"); - } - })(); - - // For LOGO SVG - // Replace SVG with inline SVG - // http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg-image-using-css-jquery-svg-image-replacement - jQuery('img.svg').each(function () { - var $img = jQuery(this); - var imgID = $img.attr('id'); - var imgClass = $img.attr('class'); - var imgURL = $img.attr('src'); - - jQuery.get(imgURL, function (data) { - // Get the SVG tag, ignore the rest - var $svg = jQuery(data).find('svg'); - - // Add replaced image's ID to the new SVG - if (typeof imgID !== 'undefined') { - $svg = $svg.attr('id', imgID); - } - // Add replaced image's classes to the new SVG - if (typeof imgClass !== 'undefined') { - $svg = $svg.attr('class', imgClass + ' replaced-svg'); - } - - // Remove any invalid XML tags as per http://validator.w3.org - $svg = $svg.removeAttr('xmlns:a'); - - // Replace image with new SVG - $img.replaceWith($svg); - - }, 'xml'); - }); -}) diff --git a/docs/styles/docfx.vendor.css b/docs/styles/docfx.vendor.css deleted file mode 100644 index b8c40352..00000000 --- a/docs/styles/docfx.vendor.css +++ /dev/null @@ -1,1466 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ -.label,sub,sup{vertical-align:baseline} -hr,img{border:0} -body,figure{margin:0} -.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.dropdown-menu{float:left} -.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px} -html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%} -article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block} -audio,canvas,progress,video{display:inline-block;vertical-align:baseline} -audio:not([controls]){display:none;height:0} -[hidden],template{display:none} -a{background-color:transparent} -a:active,a:hover{outline:0} -b,optgroup,strong{font-weight:700} -dfn{font-style:italic} -h1{margin:.67em 0} -mark{color:#000;background:#ff0} -sub,sup{position:relative;font-size:75%;line-height:0} -sup{top:-.5em} -sub{bottom:-.25em} -img{vertical-align:middle} -svg:not(:root){overflow:hidden} -hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box} -pre,textarea{overflow:auto} -code,kbd,pre,samp{font-size:1em} -button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit} -.glyphicon,address{font-style:normal} -button{overflow:visible} -button,select{text-transform:none} -button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer} -button[disabled],html input[disabled]{cursor:default} -button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0} -input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0} -input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto} -input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none} -table{border-spacing:0;border-collapse:collapse} -td,th{padding:0} -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ -@media print{blockquote,img,pre,tr{page-break-inside:avoid} -*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important} -a,a:visited{text-decoration:underline} -a[href]:after{content:" (" attr(href) ")"} -abbr[title]:after{content:" (" attr(title) ")"} -a[href^="javascript:"]:after,a[href^="#"]:after{content:""} -blockquote,pre{border:1px solid #999} -thead{display:table-header-group} -img{max-width:100%!important} -h2,h3,p{orphans:3;widows:3} -h2,h3{page-break-after:avoid} -.navbar{display:none} -.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important} -.label{border:1px solid #000} -.table{border-collapse:collapse!important} -.table td,.table th{background-color:#fff!important} -.table-bordered td,.table-bordered th{border:1px solid #ddd!important} -} -.dropdown-menu,.modal-content{-webkit-background-clip:padding-box} -.btn,.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-primary,.open>.dropdown-toggle.btn-warning{background-image:none} -.img-thumbnail,body{background-color:#fff} -@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')} -.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} -.glyphicon-asterisk:before{content:"\002a"} -.glyphicon-plus:before{content:"\002b"} -.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"} -.glyphicon-minus:before{content:"\2212"} -.glyphicon-cloud:before{content:"\2601"} -.glyphicon-envelope:before{content:"\2709"} -.glyphicon-pencil:before{content:"\270f"} -.glyphicon-glass:before{content:"\e001"} -.glyphicon-music:before{content:"\e002"} -.glyphicon-search:before{content:"\e003"} -.glyphicon-heart:before{content:"\e005"} -.glyphicon-star:before{content:"\e006"} -.glyphicon-star-empty:before{content:"\e007"} -.glyphicon-user:before{content:"\e008"} -.glyphicon-film:before{content:"\e009"} -.glyphicon-th-large:before{content:"\e010"} -.glyphicon-th:before{content:"\e011"} -.glyphicon-th-list:before{content:"\e012"} -.glyphicon-ok:before{content:"\e013"} -.glyphicon-remove:before{content:"\e014"} -.glyphicon-zoom-in:before{content:"\e015"} -.glyphicon-zoom-out:before{content:"\e016"} -.glyphicon-off:before{content:"\e017"} -.glyphicon-signal:before{content:"\e018"} -.glyphicon-cog:before{content:"\e019"} -.glyphicon-trash:before{content:"\e020"} -.glyphicon-home:before{content:"\e021"} -.glyphicon-file:before{content:"\e022"} -.glyphicon-time:before{content:"\e023"} -.glyphicon-road:before{content:"\e024"} -.glyphicon-download-alt:before{content:"\e025"} -.glyphicon-download:before{content:"\e026"} -.glyphicon-upload:before{content:"\e027"} -.glyphicon-inbox:before{content:"\e028"} -.glyphicon-play-circle:before{content:"\e029"} -.glyphicon-repeat:before{content:"\e030"} -.glyphicon-refresh:before{content:"\e031"} -.glyphicon-list-alt:before{content:"\e032"} -.glyphicon-lock:before{content:"\e033"} -.glyphicon-flag:before{content:"\e034"} -.glyphicon-headphones:before{content:"\e035"} -.glyphicon-volume-off:before{content:"\e036"} -.glyphicon-volume-down:before{content:"\e037"} -.glyphicon-volume-up:before{content:"\e038"} -.glyphicon-qrcode:before{content:"\e039"} -.glyphicon-barcode:before{content:"\e040"} -.glyphicon-tag:before{content:"\e041"} -.glyphicon-tags:before{content:"\e042"} -.glyphicon-book:before{content:"\e043"} -.glyphicon-bookmark:before{content:"\e044"} -.glyphicon-print:before{content:"\e045"} -.glyphicon-camera:before{content:"\e046"} -.glyphicon-font:before{content:"\e047"} -.glyphicon-bold:before{content:"\e048"} -.glyphicon-italic:before{content:"\e049"} -.glyphicon-text-height:before{content:"\e050"} -.glyphicon-text-width:before{content:"\e051"} -.glyphicon-align-left:before{content:"\e052"} -.glyphicon-align-center:before{content:"\e053"} -.glyphicon-align-right:before{content:"\e054"} -.glyphicon-align-justify:before{content:"\e055"} -.glyphicon-list:before{content:"\e056"} -.glyphicon-indent-left:before{content:"\e057"} -.glyphicon-indent-right:before{content:"\e058"} -.glyphicon-facetime-video:before{content:"\e059"} -.glyphicon-picture:before{content:"\e060"} -.glyphicon-map-marker:before{content:"\e062"} -.glyphicon-adjust:before{content:"\e063"} -.glyphicon-tint:before{content:"\e064"} -.glyphicon-edit:before{content:"\e065"} -.glyphicon-share:before{content:"\e066"} -.glyphicon-check:before{content:"\e067"} -.glyphicon-move:before{content:"\e068"} -.glyphicon-step-backward:before{content:"\e069"} -.glyphicon-fast-backward:before{content:"\e070"} -.glyphicon-backward:before{content:"\e071"} -.glyphicon-play:before{content:"\e072"} -.glyphicon-pause:before{content:"\e073"} -.glyphicon-stop:before{content:"\e074"} -.glyphicon-forward:before{content:"\e075"} -.glyphicon-fast-forward:before{content:"\e076"} -.glyphicon-step-forward:before{content:"\e077"} -.glyphicon-eject:before{content:"\e078"} -.glyphicon-chevron-left:before{content:"\e079"} -.glyphicon-chevron-right:before{content:"\e080"} -.glyphicon-plus-sign:before{content:"\e081"} -.glyphicon-minus-sign:before{content:"\e082"} -.glyphicon-remove-sign:before{content:"\e083"} -.glyphicon-ok-sign:before{content:"\e084"} -.glyphicon-question-sign:before{content:"\e085"} -.glyphicon-info-sign:before{content:"\e086"} -.glyphicon-screenshot:before{content:"\e087"} -.glyphicon-remove-circle:before{content:"\e088"} -.glyphicon-ok-circle:before{content:"\e089"} -.glyphicon-ban-circle:before{content:"\e090"} -.glyphicon-arrow-left:before{content:"\e091"} -.glyphicon-arrow-right:before{content:"\e092"} -.glyphicon-arrow-up:before{content:"\e093"} -.glyphicon-arrow-down:before{content:"\e094"} -.glyphicon-share-alt:before{content:"\e095"} -.glyphicon-resize-full:before{content:"\e096"} -.glyphicon-resize-small:before{content:"\e097"} -.glyphicon-exclamation-sign:before{content:"\e101"} -.glyphicon-gift:before{content:"\e102"} -.glyphicon-leaf:before{content:"\e103"} -.glyphicon-fire:before{content:"\e104"} -.glyphicon-eye-open:before{content:"\e105"} -.glyphicon-eye-close:before{content:"\e106"} -.glyphicon-warning-sign:before{content:"\e107"} -.glyphicon-plane:before{content:"\e108"} -.glyphicon-calendar:before{content:"\e109"} -.glyphicon-random:before{content:"\e110"} -.glyphicon-comment:before{content:"\e111"} -.glyphicon-magnet:before{content:"\e112"} -.glyphicon-chevron-up:before{content:"\e113"} -.glyphicon-chevron-down:before{content:"\e114"} -.glyphicon-retweet:before{content:"\e115"} -.glyphicon-shopping-cart:before{content:"\e116"} -.glyphicon-folder-close:before{content:"\e117"} -.glyphicon-folder-open:before{content:"\e118"} -.glyphicon-resize-vertical:before{content:"\e119"} -.glyphicon-resize-horizontal:before{content:"\e120"} -.glyphicon-hdd:before{content:"\e121"} -.glyphicon-bullhorn:before{content:"\e122"} -.glyphicon-bell:before{content:"\e123"} -.glyphicon-certificate:before{content:"\e124"} -.glyphicon-thumbs-up:before{content:"\e125"} -.glyphicon-thumbs-down:before{content:"\e126"} -.glyphicon-hand-right:before{content:"\e127"} -.glyphicon-hand-left:before{content:"\e128"} -.glyphicon-hand-up:before{content:"\e129"} -.glyphicon-hand-down:before{content:"\e130"} -.glyphicon-circle-arrow-right:before{content:"\e131"} -.glyphicon-circle-arrow-left:before{content:"\e132"} -.glyphicon-circle-arrow-up:before{content:"\e133"} -.glyphicon-circle-arrow-down:before{content:"\e134"} -.glyphicon-globe:before{content:"\e135"} -.glyphicon-wrench:before{content:"\e136"} -.glyphicon-tasks:before{content:"\e137"} -.glyphicon-filter:before{content:"\e138"} -.glyphicon-briefcase:before{content:"\e139"} -.glyphicon-fullscreen:before{content:"\e140"} -.glyphicon-dashboard:before{content:"\e141"} -.glyphicon-paperclip:before{content:"\e142"} -.glyphicon-heart-empty:before{content:"\e143"} -.glyphicon-link:before{content:"\e144"} -.glyphicon-phone:before{content:"\e145"} -.glyphicon-pushpin:before{content:"\e146"} -.glyphicon-usd:before{content:"\e148"} -.glyphicon-gbp:before{content:"\e149"} -.glyphicon-sort:before{content:"\e150"} -.glyphicon-sort-by-alphabet:before{content:"\e151"} -.glyphicon-sort-by-alphabet-alt:before{content:"\e152"} -.glyphicon-sort-by-order:before{content:"\e153"} -.glyphicon-sort-by-order-alt:before{content:"\e154"} -.glyphicon-sort-by-attributes:before{content:"\e155"} -.glyphicon-sort-by-attributes-alt:before{content:"\e156"} -.glyphicon-unchecked:before{content:"\e157"} -.glyphicon-expand:before{content:"\e158"} -.glyphicon-collapse-down:before{content:"\e159"} -.glyphicon-collapse-up:before{content:"\e160"} -.glyphicon-log-in:before{content:"\e161"} -.glyphicon-flash:before{content:"\e162"} -.glyphicon-log-out:before{content:"\e163"} -.glyphicon-new-window:before{content:"\e164"} -.glyphicon-record:before{content:"\e165"} -.glyphicon-save:before{content:"\e166"} -.glyphicon-open:before{content:"\e167"} -.glyphicon-saved:before{content:"\e168"} -.glyphicon-import:before{content:"\e169"} -.glyphicon-export:before{content:"\e170"} -.glyphicon-send:before{content:"\e171"} -.glyphicon-floppy-disk:before{content:"\e172"} -.glyphicon-floppy-saved:before{content:"\e173"} -.glyphicon-floppy-remove:before{content:"\e174"} -.glyphicon-floppy-save:before{content:"\e175"} -.glyphicon-floppy-open:before{content:"\e176"} -.glyphicon-credit-card:before{content:"\e177"} -.glyphicon-transfer:before{content:"\e178"} -.glyphicon-cutlery:before{content:"\e179"} -.glyphicon-header:before{content:"\e180"} -.glyphicon-compressed:before{content:"\e181"} -.glyphicon-earphone:before{content:"\e182"} -.glyphicon-phone-alt:before{content:"\e183"} -.glyphicon-tower:before{content:"\e184"} -.glyphicon-stats:before{content:"\e185"} -.glyphicon-sd-video:before{content:"\e186"} -.glyphicon-hd-video:before{content:"\e187"} -.glyphicon-subtitles:before{content:"\e188"} -.glyphicon-sound-stereo:before{content:"\e189"} -.glyphicon-sound-dolby:before{content:"\e190"} -.glyphicon-sound-5-1:before{content:"\e191"} -.glyphicon-sound-6-1:before{content:"\e192"} -.glyphicon-sound-7-1:before{content:"\e193"} -.glyphicon-copyright-mark:before{content:"\e194"} -.glyphicon-registration-mark:before{content:"\e195"} -.glyphicon-cloud-download:before{content:"\e197"} -.glyphicon-cloud-upload:before{content:"\e198"} -.glyphicon-tree-conifer:before{content:"\e199"} -.glyphicon-tree-deciduous:before{content:"\e200"} -.glyphicon-cd:before{content:"\e201"} -.glyphicon-save-file:before{content:"\e202"} -.glyphicon-open-file:before{content:"\e203"} -.glyphicon-level-up:before{content:"\e204"} -.glyphicon-copy:before{content:"\e205"} -.glyphicon-paste:before{content:"\e206"} -.glyphicon-alert:before{content:"\e209"} -.glyphicon-equalizer:before{content:"\e210"} -.glyphicon-king:before{content:"\e211"} -.glyphicon-queen:before{content:"\e212"} -.glyphicon-pawn:before{content:"\e213"} -.glyphicon-bishop:before{content:"\e214"} -.glyphicon-knight:before{content:"\e215"} -.glyphicon-baby-formula:before{content:"\e216"} -.glyphicon-tent:before{content:"\26fa"} -.glyphicon-blackboard:before{content:"\e218"} -.glyphicon-bed:before{content:"\e219"} -.glyphicon-apple:before{content:"\f8ff"} -.glyphicon-erase:before{content:"\e221"} -.glyphicon-hourglass:before{content:"\231b"} -.glyphicon-lamp:before{content:"\e223"} -.glyphicon-duplicate:before{content:"\e224"} -.glyphicon-piggy-bank:before{content:"\e225"} -.glyphicon-scissors:before{content:"\e226"} -.glyphicon-bitcoin:before,.glyphicon-btc:before,.glyphicon-xbt:before{content:"\e227"} -.glyphicon-jpy:before,.glyphicon-yen:before{content:"\00a5"} -.glyphicon-rub:before,.glyphicon-ruble:before{content:"\20bd"} -.glyphicon-scale:before{content:"\e230"} -.glyphicon-ice-lolly:before{content:"\e231"} -.glyphicon-ice-lolly-tasted:before{content:"\e232"} -.glyphicon-education:before{content:"\e233"} -.glyphicon-option-horizontal:before{content:"\e234"} -.glyphicon-option-vertical:before{content:"\e235"} -.glyphicon-menu-hamburger:before{content:"\e236"} -.glyphicon-modal-window:before{content:"\e237"} -.glyphicon-oil:before{content:"\e238"} -.glyphicon-grain:before{content:"\e239"} -.glyphicon-sunglasses:before{content:"\e240"} -.glyphicon-text-size:before{content:"\e241"} -.glyphicon-text-color:before{content:"\e242"} -.glyphicon-text-background:before{content:"\e243"} -.glyphicon-object-align-top:before{content:"\e244"} -.glyphicon-object-align-bottom:before{content:"\e245"} -.glyphicon-object-align-horizontal:before{content:"\e246"} -.glyphicon-object-align-left:before{content:"\e247"} -.glyphicon-object-align-vertical:before{content:"\e248"} -.glyphicon-object-align-right:before{content:"\e249"} -.glyphicon-triangle-right:before{content:"\e250"} -.glyphicon-triangle-left:before{content:"\e251"} -.glyphicon-triangle-bottom:before{content:"\e252"} -.glyphicon-triangle-top:before{content:"\e253"} -.glyphicon-console:before{content:"\e254"} -.glyphicon-superscript:before{content:"\e255"} -.glyphicon-subscript:before{content:"\e256"} -.glyphicon-menu-left:before{content:"\e257"} -.glyphicon-menu-right:before{content:"\e258"} -.glyphicon-menu-down:before{content:"\e259"} -.glyphicon-menu-up:before{content:"\e260"} -*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} -html{font-size:10px;-webkit-tap-highlight-color:transparent} -body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333} -button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit} -a{color:#337ab7;text-decoration:none} -a:focus,a:hover{color:#23527c;text-decoration:underline} -a:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px} -.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto} -.img-rounded{border-radius:6px} -.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out} -.img-circle{border-radius:50%} -hr{margin-top:20px;margin-bottom:20px;border-top:1px solid #eee} -.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0} -.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} -[role=button]{cursor:pointer} -.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit} -.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777} -.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px} -.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%} -.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px} -.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%} -.h1,h1{font-size:36px} -.h2,h2{font-size:30px} -.h3,h3{font-size:24px} -.h4,h4{font-size:18px} -.h5,h5{font-size:14px} -.h6,h6{font-size:12px} -p{margin:0 0 10px} -.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4} -dt,kbd kbd,label{font-weight:700} -address,blockquote .small,blockquote footer,blockquote small,dd,dt,pre{line-height:1.42857143} -@media (min-width:768px){.lead{font-size:21px} -} -.small,small{font-size:85%} -.mark,mark{padding:.2em;background-color:#fcf8e3} -.list-inline,.list-unstyled{padding-left:0;list-style:none} -.text-left{text-align:left} -.text-right{text-align:right} -.text-center{text-align:center} -.text-justify{text-align:justify} -.text-nowrap{white-space:nowrap} -.text-lowercase{text-transform:lowercase} -.text-uppercase{text-transform:uppercase} -.text-capitalize{text-transform:capitalize} -.text-muted{color:#777} -.text-primary{color:#337ab7} -a.text-primary:focus,a.text-primary:hover{color:#286090} -.text-success{color:#3c763d} -a.text-success:focus,a.text-success:hover{color:#2b542c} -.text-info{color:#31708f} -a.text-info:focus,a.text-info:hover{color:#245269} -.text-warning{color:#8a6d3b} -a.text-warning:focus,a.text-warning:hover{color:#66512c} -.text-danger{color:#a94442} -a.text-danger:focus,a.text-danger:hover{color:#843534} -.bg-primary{color:#fff;background-color:#337ab7} -a.bg-primary:focus,a.bg-primary:hover{background-color:#286090} -.bg-success{background-color:#dff0d8} -a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3} -.bg-info{background-color:#d9edf7} -a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee} -.bg-warning{background-color:#fcf8e3} -a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5} -.bg-danger{background-color:#f2dede} -a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9} -pre code,table{background-color:transparent} -.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee} -dl,ol,ul{margin-top:0} -blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child,ol ol,ol ul,ul ol,ul ul{margin-bottom:0} -address,dl{margin-bottom:20px} -ol,ul{margin-bottom:10px} -.list-inline{margin-left:-5px} -.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px} -dd{margin-left:0} -@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap} -.dl-horizontal dd{margin-left:180px} -.container{width:750px} -} -abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777} -.initialism{font-size:90%;text-transform:uppercase} -blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee} -blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#777} -legend,pre{display:block;color:#333} -blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'} -.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0} -code,kbd{padding:2px 4px;font-size:90%} -caption,th{text-align:left} -.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''} -.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'} -code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace} -code{color:#c7254e;background-color:#f9f2f4;border-radius:4px} -kbd{color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)} -kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none} -pre{padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px} -.container,.container-fluid{margin-right:auto;margin-left:auto} -pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;border-radius:0} -.container,.container-fluid{padding-right:15px;padding-left:15px} -.pre-scrollable{overflow-y:scroll} -@media (min-width:992px){.container{width:970px} -} -@media (min-width:1200px){.container{width:1170px} -} -.row{margin-right:-15px;margin-left:-15px} -.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px} -.col-xs-12{width:100%} -.col-xs-11{width:91.66666667%} -.col-xs-10{width:83.33333333%} -.col-xs-9{width:75%} -.col-xs-8{width:66.66666667%} -.col-xs-7{width:58.33333333%} -.col-xs-6{width:50%} -.col-xs-5{width:41.66666667%} -.col-xs-4{width:33.33333333%} -.col-xs-3{width:25%} -.col-xs-2{width:16.66666667%} -.col-xs-1{width:8.33333333%} -.col-xs-pull-12{right:100%} -.col-xs-pull-11{right:91.66666667%} -.col-xs-pull-10{right:83.33333333%} -.col-xs-pull-9{right:75%} -.col-xs-pull-8{right:66.66666667%} -.col-xs-pull-7{right:58.33333333%} -.col-xs-pull-6{right:50%} -.col-xs-pull-5{right:41.66666667%} -.col-xs-pull-4{right:33.33333333%} -.col-xs-pull-3{right:25%} -.col-xs-pull-2{right:16.66666667%} -.col-xs-pull-1{right:8.33333333%} -.col-xs-pull-0{right:auto} -.col-xs-push-12{left:100%} -.col-xs-push-11{left:91.66666667%} -.col-xs-push-10{left:83.33333333%} -.col-xs-push-9{left:75%} -.col-xs-push-8{left:66.66666667%} -.col-xs-push-7{left:58.33333333%} -.col-xs-push-6{left:50%} -.col-xs-push-5{left:41.66666667%} -.col-xs-push-4{left:33.33333333%} -.col-xs-push-3{left:25%} -.col-xs-push-2{left:16.66666667%} -.col-xs-push-1{left:8.33333333%} -.col-xs-push-0{left:auto} -.col-xs-offset-12{margin-left:100%} -.col-xs-offset-11{margin-left:91.66666667%} -.col-xs-offset-10{margin-left:83.33333333%} -.col-xs-offset-9{margin-left:75%} -.col-xs-offset-8{margin-left:66.66666667%} -.col-xs-offset-7{margin-left:58.33333333%} -.col-xs-offset-6{margin-left:50%} -.col-xs-offset-5{margin-left:41.66666667%} -.col-xs-offset-4{margin-left:33.33333333%} -.col-xs-offset-3{margin-left:25%} -.col-xs-offset-2{margin-left:16.66666667%} -.col-xs-offset-1{margin-left:8.33333333%} -.col-xs-offset-0{margin-left:0} -@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left} -.col-sm-12{width:100%} -.col-sm-11{width:91.66666667%} -.col-sm-10{width:83.33333333%} -.col-sm-9{width:75%} -.col-sm-8{width:66.66666667%} -.col-sm-7{width:58.33333333%} -.col-sm-6{width:50%} -.col-sm-5{width:41.66666667%} -.col-sm-4{width:33.33333333%} -.col-sm-3{width:25%} -.col-sm-2{width:16.66666667%} -.col-sm-1{width:8.33333333%} -.col-sm-pull-12{right:100%} -.col-sm-pull-11{right:91.66666667%} -.col-sm-pull-10{right:83.33333333%} -.col-sm-pull-9{right:75%} -.col-sm-pull-8{right:66.66666667%} -.col-sm-pull-7{right:58.33333333%} -.col-sm-pull-6{right:50%} -.col-sm-pull-5{right:41.66666667%} -.col-sm-pull-4{right:33.33333333%} -.col-sm-pull-3{right:25%} -.col-sm-pull-2{right:16.66666667%} -.col-sm-pull-1{right:8.33333333%} -.col-sm-pull-0{right:auto} -.col-sm-push-12{left:100%} -.col-sm-push-11{left:91.66666667%} -.col-sm-push-10{left:83.33333333%} -.col-sm-push-9{left:75%} -.col-sm-push-8{left:66.66666667%} -.col-sm-push-7{left:58.33333333%} -.col-sm-push-6{left:50%} -.col-sm-push-5{left:41.66666667%} -.col-sm-push-4{left:33.33333333%} -.col-sm-push-3{left:25%} -.col-sm-push-2{left:16.66666667%} -.col-sm-push-1{left:8.33333333%} -.col-sm-push-0{left:auto} -.col-sm-offset-12{margin-left:100%} -.col-sm-offset-11{margin-left:91.66666667%} -.col-sm-offset-10{margin-left:83.33333333%} -.col-sm-offset-9{margin-left:75%} -.col-sm-offset-8{margin-left:66.66666667%} -.col-sm-offset-7{margin-left:58.33333333%} -.col-sm-offset-6{margin-left:50%} -.col-sm-offset-5{margin-left:41.66666667%} -.col-sm-offset-4{margin-left:33.33333333%} -.col-sm-offset-3{margin-left:25%} -.col-sm-offset-2{margin-left:16.66666667%} -.col-sm-offset-1{margin-left:8.33333333%} -.col-sm-offset-0{margin-left:0} -} -@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left} -.col-md-12{width:100%} -.col-md-11{width:91.66666667%} -.col-md-10{width:83.33333333%} -.col-md-9{width:75%} -.col-md-8{width:66.66666667%} -.col-md-7{width:58.33333333%} -.col-md-6{width:50%} -.col-md-5{width:41.66666667%} -.col-md-4{width:33.33333333%} -.col-md-3{width:25%} -.col-md-2{width:16.66666667%} -.col-md-1{width:8.33333333%} -.col-md-pull-12{right:100%} -.col-md-pull-11{right:91.66666667%} -.col-md-pull-10{right:83.33333333%} -.col-md-pull-9{right:75%} -.col-md-pull-8{right:66.66666667%} -.col-md-pull-7{right:58.33333333%} -.col-md-pull-6{right:50%} -.col-md-pull-5{right:41.66666667%} -.col-md-pull-4{right:33.33333333%} -.col-md-pull-3{right:25%} -.col-md-pull-2{right:16.66666667%} -.col-md-pull-1{right:8.33333333%} -.col-md-pull-0{right:auto} -.col-md-push-12{left:100%} -.col-md-push-11{left:91.66666667%} -.col-md-push-10{left:83.33333333%} -.col-md-push-9{left:75%} -.col-md-push-8{left:66.66666667%} -.col-md-push-7{left:58.33333333%} -.col-md-push-6{left:50%} -.col-md-push-5{left:41.66666667%} -.col-md-push-4{left:33.33333333%} -.col-md-push-3{left:25%} -.col-md-push-2{left:16.66666667%} -.col-md-push-1{left:8.33333333%} -.col-md-push-0{left:auto} -.col-md-offset-12{margin-left:100%} -.col-md-offset-11{margin-left:91.66666667%} -.col-md-offset-10{margin-left:83.33333333%} -.col-md-offset-9{margin-left:75%} -.col-md-offset-8{margin-left:66.66666667%} -.col-md-offset-7{margin-left:58.33333333%} -.col-md-offset-6{margin-left:50%} -.col-md-offset-5{margin-left:41.66666667%} -.col-md-offset-4{margin-left:33.33333333%} -.col-md-offset-3{margin-left:25%} -.col-md-offset-2{margin-left:16.66666667%} -.col-md-offset-1{margin-left:8.33333333%} -.col-md-offset-0{margin-left:0} -} -@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left} -.col-lg-12{width:100%} -.col-lg-11{width:91.66666667%} -.col-lg-10{width:83.33333333%} -.col-lg-9{width:75%} -.col-lg-8{width:66.66666667%} -.col-lg-7{width:58.33333333%} -.col-lg-6{width:50%} -.col-lg-5{width:41.66666667%} -.col-lg-4{width:33.33333333%} -.col-lg-3{width:25%} -.col-lg-2{width:16.66666667%} -.col-lg-1{width:8.33333333%} -.col-lg-pull-12{right:100%} -.col-lg-pull-11{right:91.66666667%} -.col-lg-pull-10{right:83.33333333%} -.col-lg-pull-9{right:75%} -.col-lg-pull-8{right:66.66666667%} -.col-lg-pull-7{right:58.33333333%} -.col-lg-pull-6{right:50%} -.col-lg-pull-5{right:41.66666667%} -.col-lg-pull-4{right:33.33333333%} -.col-lg-pull-3{right:25%} -.col-lg-pull-2{right:16.66666667%} -.col-lg-pull-1{right:8.33333333%} -.col-lg-pull-0{right:auto} -.col-lg-push-12{left:100%} -.col-lg-push-11{left:91.66666667%} -.col-lg-push-10{left:83.33333333%} -.col-lg-push-9{left:75%} -.col-lg-push-8{left:66.66666667%} -.col-lg-push-7{left:58.33333333%} -.col-lg-push-6{left:50%} -.col-lg-push-5{left:41.66666667%} -.col-lg-push-4{left:33.33333333%} -.col-lg-push-3{left:25%} -.col-lg-push-2{left:16.66666667%} -.col-lg-push-1{left:8.33333333%} -.col-lg-push-0{left:auto} -.col-lg-offset-12{margin-left:100%} -.col-lg-offset-11{margin-left:91.66666667%} -.col-lg-offset-10{margin-left:83.33333333%} -.col-lg-offset-9{margin-left:75%} -.col-lg-offset-8{margin-left:66.66666667%} -.col-lg-offset-7{margin-left:58.33333333%} -.col-lg-offset-6{margin-left:50%} -.col-lg-offset-5{margin-left:41.66666667%} -.col-lg-offset-4{margin-left:33.33333333%} -.col-lg-offset-3{margin-left:25%} -.col-lg-offset-2{margin-left:16.66666667%} -.col-lg-offset-1{margin-left:8.33333333%} -.col-lg-offset-0{margin-left:0} -} -caption{padding-top:8px;padding-bottom:8px;color:#777} -.table{width:100%;max-width:100%;margin-bottom:20px} -.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd} -.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd} -.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0} -.table>tbody+tbody{border-top:2px solid #ddd} -.table .table{background-color:#fff} -.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px} -.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd} -.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px} -.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9} -.table-hover>tbody>tr:hover,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5} -table col[class*=col-]{position:static;display:table-column;float:none} -table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none} -.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8} -.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8} -.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6} -.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7} -.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3} -.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3} -.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc} -.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede} -.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc} -.table-responsive{min-height:.01%;overflow-x:auto} -@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd} -.table-responsive>.table{margin-bottom:0} -.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap} -.table-responsive>.table-bordered{border:0} -.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0} -.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0} -.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0} -} -fieldset,legend{padding:0;border:0} -fieldset{min-width:0;margin:0} -legend{width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;border-bottom:1px solid #e5e5e5} -label{display:inline-block;max-width:100%;margin-bottom:5px} -input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none} -input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal} -.form-control,output{font-size:14px;line-height:1.42857143;color:#555;display:block} -input[type=file]{display:block} -input[type=range]{display:block;width:100%} -select[multiple],select[size]{height:auto} -input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px} -output{padding-top:7px} -.form-control{width:100%;height:34px;padding:6px 12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s} -.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)} -.form-control::-moz-placeholder{color:#999;opacity:1} -.form-control:-ms-input-placeholder{color:#999} -.form-control::-webkit-input-placeholder{color:#999} -.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .form-control-feedback,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d} -.form-control::-ms-expand{background-color:transparent;border:0} -.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1} -.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed} -textarea.form-control{height:auto} -@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px} -.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px} -.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px} -} -.form-group{margin-bottom:15px} -.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px} -.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer} -.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px} -.checkbox+.checkbox,.radio+.radio{margin-top:-5px} -.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer} -.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px} -.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed} -.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0} -.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0} -.form-group-sm .form-control,.input-sm{padding:5px 10px;border-radius:3px;font-size:12px} -.input-sm{height:30px;line-height:1.5} -select.input-sm{height:30px;line-height:30px} -select[multiple].input-sm,textarea.input-sm{height:auto} -.form-group-sm .form-control{height:30px;line-height:1.5} -.form-group-lg .form-control,.input-lg{border-radius:6px;padding:10px 16px;font-size:18px} -.form-group-sm select.form-control{height:30px;line-height:30px} -.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto} -.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5} -.input-lg{height:46px;line-height:1.3333333} -select.input-lg{height:46px;line-height:46px} -select[multiple].input-lg,textarea.input-lg{height:auto} -.form-group-lg .form-control{height:46px;line-height:1.3333333} -.form-group-lg select.form-control{height:46px;line-height:46px} -.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto} -.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333} -.has-feedback{position:relative} -.has-feedback .form-control{padding-right:42.5px} -.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none} -.collapsing,.dropdown,.dropup{position:relative} -.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px} -.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px} -.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)} -.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168} -.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d} -.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .form-control-feedback,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b} -.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)} -.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b} -.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b} -.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .form-control-feedback,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442} -.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)} -.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483} -.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442} -.has-feedback label~.form-control-feedback{top:25px} -.has-feedback label.sr-only~.form-control-feedback{top:0} -.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373} -@media (min-width:768px){.form-inline .form-control-static,.form-inline .form-group{display:inline-block} -.form-inline .control-label,.form-inline .form-group{margin-bottom:0;vertical-align:middle} -.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle} -.form-inline .input-group{display:inline-table;vertical-align:middle} -.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto} -.form-inline .input-group>.form-control{width:100%} -.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle} -.form-inline .checkbox label,.form-inline .radio label{padding-left:0} -.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0} -.form-inline .has-feedback .form-control-feedback{top:0} -.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right} -} -.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0} -.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px} -.form-horizontal .form-group{margin-right:-15px;margin-left:-15px} -.form-horizontal .has-feedback .form-control-feedback{right:15px} -@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px} -.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px} -} -.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;border-radius:4px} -.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px} -.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none} -.btn.active,.btn:active{outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)} -.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65} -a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none} -.btn-default{color:#333;background-color:#fff;border-color:#ccc} -.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c} -.btn-default.active,.btn-default:active,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad} -.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c} -.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc} -.btn-default .badge{color:#fff;background-color:#333} -.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4} -.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40} -.btn-primary.active,.btn-primary:active,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74} -.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40} -.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4} -.btn-primary .badge{color:#337ab7;background-color:#fff} -.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c} -.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625} -.btn-success.active,.btn-success:active,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439} -.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625} -.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none} -.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c} -.btn-success .badge{color:#5cb85c;background-color:#fff} -.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da} -.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85} -.btn-info.active,.btn-info:active,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc} -.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85} -.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da} -.btn-info .badge{color:#5bc0de;background-color:#fff} -.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236} -.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d} -.btn-warning.active,.btn-warning:active,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512} -.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d} -.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236} -.btn-warning .badge{color:#f0ad4e;background-color:#fff} -.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a} -.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19} -.btn-danger.active,.btn-danger:active,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925} -.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19} -.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a} -.btn-danger .badge{color:#d9534f;background-color:#fff} -.btn-link{font-weight:400;color:#337ab7;border-radius:0} -.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none} -.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent} -.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent} -.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none} -.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} -.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} -.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px} -.btn-block{display:block;width:100%} -.btn-block+.btn-block{margin-top:5px} -input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%} -.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear} -.fade.in{opacity:1} -.collapse{display:none} -.collapse.in{display:block} -tr.collapse.in{display:table-row} -tbody.collapse.in{display:table-row-group} -.collapsing{height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility} -.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent} -.dropdown-toggle:focus{outline:0} -.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)} -.dropdown-menu-right,.dropdown-menu.pull-right{right:0;left:auto} -.dropdown-header,.dropdown-menu>li>a{display:block;padding:3px 20px;line-height:1.42857143;white-space:nowrap} -.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle,.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0} -.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child,.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0} -.btn-group-vertical>.btn:not(:first-child):not(:last-child),.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn,.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0} -.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5} -.dropdown-menu>li>a{clear:both;font-weight:400;color:#333} -.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5} -.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0} -.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777} -.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)} -.open>.dropdown-menu{display:block} -.open>a{outline:0} -.dropdown-menu-left{right:auto;left:0} -.dropdown-header{font-size:12px;color:#777} -.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990} -.nav-justified>.dropdown .dropdown-menu,.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto} -.pull-right>.dropdown-menu{right:0;left:auto} -.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9} -.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px} -@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto} -.navbar-right .dropdown-menu-left{right:auto;left:0} -} -.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle} -.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left} -.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2} -.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px} -.btn-toolbar{margin-left:-5px} -.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px} -.btn .caret,.btn-group>.btn:first-child{margin-left:0} -.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0} -.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px} -.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px} -.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)} -.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none} -.btn-lg .caret{border-width:5px 5px 0} -.dropup .btn-lg .caret{border-width:0 5px 5px} -.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%} -.btn-group-vertical>.btn-group>.btn{float:none} -.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0} -.btn-group-vertical>.btn:first-child:not(:last-child){border-radius:4px 4px 0 0} -.btn-group-vertical>.btn:last-child:not(:first-child){border-radius:0 0 4px 4px} -.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0} -.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0} -.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0} -.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate} -.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%} -.btn-group-justified>.btn-group .btn{width:100%} -.btn-group-justified>.btn-group .dropdown-menu{left:auto} -[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none} -.input-group{position:relative;display:table;border-collapse:separate} -.input-group[class*=col-]{float:none;padding-right:0;padding-left:0} -.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0} -.input-group .form-control:focus{z-index:3} -.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} -select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px} -select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto} -.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} -select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px} -select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto} -.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell} -.nav>li,.nav>li>a{display:block;position:relative} -.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0} -.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle} -.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px} -.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px} -.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px} -.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0} -.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0} -.input-group-addon:first-child{border-right:0} -.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0} -.input-group-addon:last-child{border-left:0} -.input-group-btn{position:relative;font-size:0;white-space:nowrap} -.input-group-btn>.btn{position:relative} -.input-group-btn>.btn+.btn{margin-left:-1px} -.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2} -.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px} -.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px} -.nav{padding-left:0;margin-bottom:0;list-style:none} -.nav>li>a{padding:10px 15px} -.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee} -.nav>li.disabled>a{color:#777} -.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent} -.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7} -.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5} -.nav>li>a>img{max-width:none} -.nav-tabs{border-bottom:1px solid #ddd} -.nav-tabs>li{float:left;margin-bottom:-1px} -.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0} -.nav-tabs>li>a:hover{border-color:#eee #eee #ddd} -.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent} -.nav-tabs.nav-justified{width:100%;border-bottom:0} -.nav-tabs.nav-justified>li{float:none} -.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center;margin-right:0;border-radius:4px} -.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd} -@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%} -.nav-tabs.nav-justified>li>a{margin-bottom:0;border-bottom:1px solid #ddd;border-radius:4px 4px 0 0} -.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff} -} -.nav-pills>li{float:left} -.nav-justified>li,.nav-stacked>li{float:none} -.nav-pills>li>a{border-radius:4px} -.nav-pills>li+li{margin-left:2px} -.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7} -.nav-stacked>li+li{margin-top:2px;margin-left:0} -.nav-justified{width:100%} -.nav-justified>li>a{margin-bottom:5px;text-align:center} -.nav-tabs-justified{border-bottom:0} -.nav-tabs-justified>li>a{margin-right:0;border-radius:4px} -.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd} -@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%} -.nav-justified>li>a{margin-bottom:0} -.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0} -.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff} -} -.tab-content>.tab-pane{display:none} -.tab-content>.active{display:block} -.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0} -.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent} -.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)} -.navbar-collapse.in{overflow-y:auto} -@media (min-width:768px){.navbar{border-radius:4px} -.navbar-header{float:left} -.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none} -.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important} -.navbar-collapse.in{overflow-y:visible} -.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0} -} -.embed-responsive,.modal,.modal-open,.progress{overflow:hidden} -@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px} -} -.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px} -.navbar-static-top{z-index:1000;border-width:0 0 1px} -.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030} -.navbar-fixed-top{top:0;border-width:0 0 1px} -.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0} -.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px} -.navbar-brand:focus,.navbar-brand:hover{text-decoration:none} -.navbar-brand>img{display:block} -@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0} -.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0} -.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px} -} -.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px} -.navbar-toggle:focus{outline:0} -.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px} -.navbar-toggle .icon-bar+.icon-bar{margin-top:4px} -.navbar-nav{margin:7.5px -15px} -.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px} -@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none} -.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px} -.navbar-nav .open .dropdown-menu>li>a{line-height:20px} -.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none} -} -.progress-bar-striped,.progress-striped .progress-bar,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -@media (min-width:768px){.navbar-toggle{display:none} -.navbar-nav{float:left;margin:0} -.navbar-nav>li{float:left} -.navbar-nav>li>a{padding-top:15px;padding-bottom:15px} -} -.navbar-form{padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin:8px -15px} -@media (min-width:768px){.navbar-form .form-control-static,.navbar-form .form-group{display:inline-block} -.navbar-form .control-label,.navbar-form .form-group{margin-bottom:0;vertical-align:middle} -.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle} -.navbar-form .input-group{display:inline-table;vertical-align:middle} -.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto} -.navbar-form .input-group>.form-control{width:100%} -.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle} -.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0} -.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0} -.navbar-form .has-feedback .form-control-feedback{top:0} -.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none} -} -.breadcrumb>li,.pagination{display:inline-block} -.btn .badge,.btn .label{top:-1px;position:relative} -@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px} -.navbar-form .form-group:last-child{margin-bottom:0} -} -.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0} -.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0} -.navbar-btn{margin-top:8px;margin-bottom:8px} -.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px} -.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px} -.navbar-text{margin-top:15px;margin-bottom:15px} -@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px} -.navbar-left{float:left!important} -.navbar-right{float:right!important;margin-right:-15px} -.navbar-right~.navbar-right{margin-right:0} -} -.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7} -.navbar-default .navbar-brand{color:#777} -.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent} -.navbar-default .navbar-nav>li>a,.navbar-default .navbar-text{color:#777} -.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent} -.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7} -.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent} -.navbar-default .navbar-toggle{border-color:#ddd} -.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd} -.navbar-default .navbar-toggle .icon-bar{background-color:#888} -.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7} -.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7} -@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777} -.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent} -.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7} -.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent} -} -.navbar-default .navbar-link{color:#777} -.navbar-default .navbar-link:hover{color:#333} -.navbar-default .btn-link{color:#777} -.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333} -.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc} -.navbar-inverse{background-color:#222;border-color:#080808} -.navbar-inverse .navbar-brand{color:#9d9d9d} -.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent} -.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#9d9d9d} -.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent} -.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808} -.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent} -.navbar-inverse .navbar-toggle{border-color:#333} -.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333} -.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff} -.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010} -.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808} -@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808} -.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808} -.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d} -.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent} -.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808} -.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent} -} -.navbar-inverse .navbar-link{color:#9d9d9d} -.navbar-inverse .navbar-link:hover{color:#fff} -.navbar-inverse .btn-link{color:#9d9d9d} -.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff} -.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444} -.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px} -.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"} -.breadcrumb>.active{color:#777} -.pagination{padding-left:0;margin:20px 0;border-radius:4px} -.pager li,.pagination>li{display:inline} -.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd} -.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px} -.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px} -.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd} -.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7} -.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd} -.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333} -.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px} -.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px} -.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5} -.badge,.label{font-weight:700;line-height:1;white-space:nowrap;text-align:center} -.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px} -.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px} -.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none} -.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px} -.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee} -.pager .next>a,.pager .next>span{float:right} -.pager .previous>a,.pager .previous>span{float:left} -.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff} -a.badge:focus,a.badge:hover,a.label:focus,a.label:hover{color:#fff;cursor:pointer;text-decoration:none} -.label{display:inline;padding:.2em .6em .3em;font-size:75%;color:#fff;border-radius:.25em} -.label:empty{display:none} -.label-default{background-color:#777} -.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e} -.label-primary{background-color:#337ab7} -.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090} -.label-success{background-color:#5cb85c} -.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44} -.label-info{background-color:#5bc0de} -.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5} -.label-warning{background-color:#f0ad4e} -.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f} -.label-danger{background-color:#d9534f} -.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c} -.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;color:#fff;vertical-align:middle;background-color:#777;border-radius:10px} -.badge:empty{display:none} -.media-object,.thumbnail{display:block} -.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px} -.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff} -.jumbotron,.jumbotron .h1,.jumbotron h1{color:inherit} -.list-group-item>.badge{float:right} -.list-group-item>.badge+.badge{margin-right:5px} -.nav-pills>li>a>.badge{margin-left:3px} -.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;background-color:#eee} -.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200} -.alert,.thumbnail{margin-bottom:20px} -.alert .alert-link,.close{font-weight:700} -.jumbotron>hr{border-top-color:#d5d5d5} -.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px} -.jumbotron .container{max-width:100%} -@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px} -.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px} -.jumbotron .h1,.jumbotron h1{font-size:63px} -} -.thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out} -.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto} -a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7} -.thumbnail .caption{padding:9px;color:#333} -.alert{padding:15px;border:1px solid transparent;border-radius:4px} -.alert h4{margin-top:0;color:inherit} -.alert>p,.alert>ul{margin-bottom:0} -.alert>p+p{margin-top:5px} -.alert-dismissable,.alert-dismissible{padding-right:35px} -.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit} -.modal,.modal-backdrop{top:0;right:0;bottom:0;left:0} -.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6} -.alert-success hr{border-top-color:#c9e2b3} -.alert-success .alert-link{color:#2b542c} -.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1} -.alert-info hr{border-top-color:#a6e1ec} -.alert-info .alert-link{color:#245269} -.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc} -.alert-warning hr{border-top-color:#f7e1b5} -.alert-warning .alert-link{color:#66512c} -.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1} -.alert-danger hr{border-top-color:#e4b9c0} -.alert-danger .alert-link{color:#843534} -@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0} -to{background-position:0 0} -} -@-o-keyframes progress-bar-stripes{from{background-position:40px 0} -to{background-position:0 0} -} -@keyframes progress-bar-stripes{from{background-position:40px 0} -to{background-position:0 0} -} -.progress{height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)} -.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease} -.progress-bar-striped,.progress-striped .progress-bar{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px} -.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite} -.progress-bar-success{background-color:#5cb85c} -.progress-striped .progress-bar-success{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -.progress-striped .progress-bar-info,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -.progress-bar-info{background-color:#5bc0de} -.progress-striped .progress-bar-info{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -.progress-bar-warning{background-color:#f0ad4e} -.progress-striped .progress-bar-warning{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -.progress-bar-danger{background-color:#d9534f} -.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)} -.media{margin-top:15px} -.media:first-child{margin-top:0} -.media,.media-body{overflow:hidden;zoom:1} -.media-body{width:10000px} -.media-object.img-thumbnail{max-width:none} -.media-right,.media>.pull-right{padding-left:10px} -.media-left,.media>.pull-left{padding-right:10px} -.media-body,.media-left,.media-right{display:table-cell;vertical-align:top} -.media-middle{vertical-align:middle} -.media-bottom{vertical-align:bottom} -.media-heading{margin-top:0;margin-bottom:5px} -.media-list{padding-left:0;list-style:none} -.list-group{padding-left:0;margin-bottom:20px} -.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd} -.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px} -.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px} -a.list-group-item,button.list-group-item{color:#555} -a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333} -a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5} -button.list-group-item{width:100%;text-align:left} -.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee} -.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit} -.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777} -.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7} -.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit} -.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef} -.list-group-item-success{color:#3c763d;background-color:#dff0d8} -a.list-group-item-success,button.list-group-item-success{color:#3c763d} -a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit} -a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6} -a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d} -.list-group-item-info{color:#31708f;background-color:#d9edf7} -a.list-group-item-info,button.list-group-item-info{color:#31708f} -a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit} -a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3} -a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f} -.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3} -a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b} -a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit} -a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc} -a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b} -.list-group-item-danger{color:#a94442;background-color:#f2dede} -a.list-group-item-danger,button.list-group-item-danger{color:#a94442} -a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit} -a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc} -a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442} -.panel-heading>.dropdown .dropdown-toggle,.panel-title,.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit} -.list-group-item-heading{margin-top:0;margin-bottom:5px} -.list-group-item-text{margin-bottom:0;line-height:1.3} -.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)} -.panel-title,.panel>.list-group,.panel>.panel-collapse>.list-group,.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0} -.panel-body{padding:15px} -.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px} -.panel-title{margin-top:0;font-size:16px} -.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px} -.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0} -.panel-group .panel-heading,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0} -.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px} -.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px} -.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0} -.list-group+.panel-footer,.panel-heading+.list-group .list-group-item:first-child{border-top-width:0} -.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px} -.panel>.table-responsive:first-child>.table:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px} -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px} -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px} -.panel>.table-responsive:last-child>.table:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px} -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px} -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px} -.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd} -.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0} -.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0} -.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0} -.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0} -.panel>.table-responsive{margin-bottom:0;border:0} -.panel-group{margin-bottom:20px} -.panel-group .panel{margin-bottom:0;border-radius:4px} -.panel-group .panel+.panel{margin-top:5px} -.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd} -.panel-group .panel-footer{border-top:0} -.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd} -.panel-default{border-color:#ddd} -.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd} -.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd} -.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333} -.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd} -.panel-primary{border-color:#337ab7} -.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7} -.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7} -.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff} -.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7} -.panel-success{border-color:#d6e9c6} -.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6} -.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6} -.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d} -.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6} -.panel-info{border-color:#bce8f1} -.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1} -.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1} -.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f} -.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1} -.panel-warning{border-color:#faebcc} -.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc} -.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc} -.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b} -.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc} -.panel-danger{border-color:#ebccd1} -.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1} -.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1} -.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442} -.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1} -.embed-responsive{position:relative;display:block;height:0;padding:0} -.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0} -.embed-responsive-16by9{padding-bottom:56.25%} -.embed-responsive-4by3{padding-bottom:75%} -.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)} -.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)} -.well-lg{padding:24px;border-radius:6px} -.well-sm{padding:9px;border-radius:3px} -.close{float:right;font-size:21px;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2} -.popover,.tooltip{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;line-break:auto;text-decoration:none} -.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5} -button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0} -.modal{position:fixed;z-index:1050;display:none;-webkit-overflow-scrolling:touch;outline:0} -.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)} -.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)} -.modal-open .modal{overflow-x:hidden;overflow-y:auto} -.modal-dialog{position:relative;width:auto;margin:10px} -.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)} -.modal-backdrop{position:fixed;z-index:1040;background-color:#000} -.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0} -.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5} -.modal-header{padding:15px;border-bottom:1px solid #e5e5e5} -.modal-header .close{margin-top:-2px} -.modal-title{margin:0;line-height:1.42857143} -.modal-body{position:relative;padding:15px} -.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5} -.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px} -.modal-footer .btn-group .btn+.btn{margin-left:-1px} -.modal-footer .btn-block+.btn-block{margin-left:0} -.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll} -@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto} -.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)} -.modal-sm{width:300px} -} -@media (min-width:992px){.modal-lg{width:900px} -} -.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;text-align:left;text-align:start;filter:alpha(opacity=0);opacity:0} -.tooltip.in{filter:alpha(opacity=90);opacity:.9} -.tooltip.top{padding:5px 0;margin-top:-3px} -.tooltip.right{padding:0 5px;margin-left:3px} -.tooltip.bottom{padding:5px 0;margin-top:3px} -.tooltip.left{padding:0 5px;margin-left:-3px} -.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px} -.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid} -.tooltip.top .tooltip-arrow,.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;border-width:5px 5px 0;border-top-color:#000} -.tooltip.top .tooltip-arrow{left:50%;margin-left:-5px} -.tooltip.top-left .tooltip-arrow{right:5px;margin-bottom:-5px} -.tooltip.top-right .tooltip-arrow{left:5px;margin-bottom:-5px} -.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000} -.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000} -.tooltip.bottom .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow{border-width:0 5px 5px;border-bottom-color:#000;top:0} -.tooltip.bottom .tooltip-arrow{left:50%;margin-left:-5px} -.tooltip.bottom-left .tooltip-arrow{right:5px;margin-top:-5px} -.tooltip.bottom-right .tooltip-arrow{left:5px;margin-top:-5px} -.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-size:14px;text-align:left;text-align:start;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)} -.carousel-caption,.carousel-control{color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)} -.popover.top{margin-top:-10px} -.popover.right{margin-left:10px} -.popover.bottom{margin-top:10px} -.popover.left{margin-left:-10px} -.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0} -.popover-content{padding:9px 14px} -.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid} -.carousel,.carousel-inner{position:relative} -.popover>.arrow{border-width:11px} -.popover>.arrow:after{content:"";border-width:10px} -.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0} -.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0} -.popover.left>.arrow:after,.popover.right>.arrow:after{bottom:-10px;content:" "} -.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0} -.popover.right>.arrow:after{left:1px;border-right-color:#fff;border-left-width:0} -.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)} -.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff} -.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)} -.popover.left>.arrow:after{right:1px;border-right-width:0;border-left-color:#fff} -.carousel-inner{width:100%;overflow:hidden} -.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left} -.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1} -@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px} -.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)} -.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)} -.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)} -} -.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block} -.carousel-inner>.active{left:0} -.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%} -.carousel-inner>.next{left:100%} -.carousel-inner>.prev{left:-100%} -.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0} -.carousel-inner>.active.left{left:-100%} -.carousel-inner>.active.right{left:100%} -.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5} -.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x} -.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x} -.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9} -.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px} -.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px} -.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px} -.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1} -.carousel-control .icon-prev:before{content:'\2039'} -.carousel-control .icon-next:before{content:'\203a'} -.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none} -.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px} -.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff} -.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px} -.carousel-caption .btn,.text-hide{text-shadow:none} -@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px} -.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px} -.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px} -.carousel-caption{right:20%;left:20%;padding-bottom:30px} -.carousel-indicators{bottom:20px} -} -.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "} -.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both} -.center-block{display:block;margin-right:auto;margin-left:auto} -.pull-right{float:right!important} -.pull-left{float:left!important} -.hide{display:none!important} -.show{display:block!important} -.hidden,.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important} -.invisible{visibility:hidden} -.text-hide{font:0/0 a;color:transparent;background-color:transparent;border:0} -.affix{position:fixed} -@-ms-viewport{width:device-width} -@media (max-width:767px){.visible-xs{display:block!important} -table.visible-xs{display:table!important} -tr.visible-xs{display:table-row!important} -td.visible-xs,th.visible-xs{display:table-cell!important} -.visible-xs-block{display:block!important} -.visible-xs-inline{display:inline!important} -.visible-xs-inline-block{display:inline-block!important} -} -@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important} -table.visible-sm{display:table!important} -tr.visible-sm{display:table-row!important} -td.visible-sm,th.visible-sm{display:table-cell!important} -.visible-sm-block{display:block!important} -.visible-sm-inline{display:inline!important} -.visible-sm-inline-block{display:inline-block!important} -} -@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important} -table.visible-md{display:table!important} -tr.visible-md{display:table-row!important} -td.visible-md,th.visible-md{display:table-cell!important} -.visible-md-block{display:block!important} -.visible-md-inline{display:inline!important} -.visible-md-inline-block{display:inline-block!important} -} -@media (min-width:1200px){.visible-lg{display:block!important} -table.visible-lg{display:table!important} -tr.visible-lg{display:table-row!important} -td.visible-lg,th.visible-lg{display:table-cell!important} -.visible-lg-block{display:block!important} -.visible-lg-inline{display:inline!important} -.visible-lg-inline-block{display:inline-block!important} -.hidden-lg{display:none!important} -} -@media (max-width:767px){.hidden-xs{display:none!important} -} -@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important} -} -@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important} -} -.visible-print{display:none!important} -@media print{.visible-print{display:block!important} -table.visible-print{display:table!important} -tr.visible-print{display:table-row!important} -td.visible-print,th.visible-print{display:table-cell!important} -} -.visible-print-block{display:none!important} -@media print{.visible-print-block{display:block!important} -} -.visible-print-inline{display:none!important} -@media print{.visible-print-inline{display:inline!important} -} -.visible-print-inline-block{display:none!important} -@media print{.visible-print-inline-block{display:inline-block!important} -.hidden-print{display:none!important} -} -.hljs{display:block;background:#fff;padding:.5em;color:#333;overflow-x:auto;-webkit-text-size-adjust:none} -.bash .hljs-shebang,.hljs-comment,.java .hljs-javadoc,.javascript .hljs-javadoc,.rust .hljs-preprocessor{color:#969896} -.apache .hljs-sqbracket,.c .hljs-preprocessor,.coffeescript .hljs-regexp,.coffeescript .hljs-subst,.cpp .hljs-preprocessor,.hljs-string,.javascript .hljs-regexp,.json .hljs-attribute,.less .hljs-built_in,.makefile .hljs-variable,.markdown .hljs-blockquote,.markdown .hljs-emphasis,.markdown .hljs-link_label,.markdown .hljs-strong,.markdown .hljs-value,.nginx .hljs-number,.nginx .hljs-regexp,.objectivec .hljs-preprocessor .hljs-title,.perl .hljs-regexp,.php .hljs-regexp,.scss .hljs-built_in,.xml .hljs-value{color:#df5000} -.css .hljs-at_rule,.css .hljs-important,.go .hljs-typename,.haskell .hljs-type,.hljs-keyword,.http .hljs-request,.ini .hljs-setting,.java .hljs-javadoctag,.javascript .hljs-javadoctag,.javascript .hljs-tag,.less .hljs-at_rule,.less .hljs-tag,.nginx .hljs-title,.objectivec .hljs-preprocessor,.php .hljs-phpdoc,.scss .hljs-at_rule,.scss .hljs-important,.scss .hljs-tag,.sql .hljs-built_in,.stylus .hljs-at_rule,.swift .hljs-preprocessor{color:#a71d5d} -.apache .hljs-cbracket,.apache .hljs-common,.apache .hljs-keyword,.bash .hljs-built_in,.bash .hljs-literal,.c .hljs-built_in,.c .hljs-number,.coffeescript .hljs-built_in,.coffeescript .hljs-literal,.coffeescript .hljs-number,.cpp .hljs-built_in,.cpp .hljs-number,.cs .hljs-built_in,.cs .hljs-number,.css .hljs-attribute,.css .hljs-function,.css .hljs-hexcolor,.css .hljs-number,.go .hljs-built_in,.go .hljs-constant,.haskell .hljs-number,.http .hljs-attribute,.http .hljs-literal,.java .hljs-number,.javascript .hljs-built_in,.javascript .hljs-literal,.javascript .hljs-number,.json .hljs-number,.less .hljs-attribute,.less .hljs-function,.less .hljs-hexcolor,.less .hljs-number,.makefile .hljs-keyword,.markdown .hljs-link_reference,.nginx .hljs-built_in,.objectivec .hljs-built_in,.objectivec .hljs-literal,.objectivec .hljs-number,.php .hljs-literal,.php .hljs-number,.puppet .hljs-function,.python .hljs-number,.ruby .hljs-constant,.ruby .hljs-number,.ruby .hljs-prompt,.ruby .hljs-subst .hljs-keyword,.ruby .hljs-symbol,.rust .hljs-number,.scss .hljs-attribute,.scss .hljs-function,.scss .hljs-hexcolor,.scss .hljs-number,.scss .hljs-preprocessor,.sql .hljs-number,.stylus .hljs-attribute,.stylus .hljs-hexcolor,.stylus .hljs-number,.stylus .hljs-params,.swift .hljs-built_in,.swift .hljs-number{color:#0086b3} -.apache .hljs-tag,.cs .hljs-xmlDocTag,.css .hljs-tag,.stylus .hljs-tag,.xml .hljs-title{color:#63a35c} -.bash .hljs-variable,.cs .hljs-preprocessor,.cs .hljs-preprocessor .hljs-keyword,.css .hljs-attr_selector,.css .hljs-value,.ini .hljs-keyword,.ini .hljs-value,.javascript .hljs-tag .hljs-title,.makefile .hljs-constant,.nginx .hljs-variable,.scss .hljs-variable,.xml .hljs-tag{color:#333} -.bash .hljs-title,.c .hljs-title,.coffeescript .hljs-title,.cpp .hljs-title,.cs .hljs-title,.css .hljs-class,.css .hljs-id,.css .hljs-pseudo,.diff .hljs-chunk,.haskell .hljs-pragma,.haskell .hljs-title,.ini .hljs-title,.java .hljs-title,.javascript .hljs-title,.less .hljs-class,.less .hljs-id,.less .hljs-pseudo,.makefile .hljs-title,.objectivec .hljs-title,.perl .hljs-sub,.php .hljs-title,.puppet .hljs-title,.python .hljs-decorator,.python .hljs-title,.ruby .hljs-parent,.ruby .hljs-title,.rust .hljs-title,.scss .hljs-class,.scss .hljs-id,.scss .hljs-pseudo,.stylus .hljs-class,.stylus .hljs-id,.stylus .hljs-pseudo,.stylus .hljs-title,.swift .hljs-title,.xml .hljs-attribute{color:#795da3} -.coffeescript .hljs-attribute,.coffeescript .hljs-reserved{color:#1d3e81} -.diff .hljs-chunk{font-weight:700} -.diff .hljs-addition{color:#55a532;background-color:#eaffea} -.diff .hljs-deletion{color:#bd2c00;background-color:#ffecec} -.markdown .hljs-link_url{text-decoration:underline} \ No newline at end of file diff --git a/docs/styles/docfx.vendor.js b/docs/styles/docfx.vendor.js deleted file mode 100644 index 95c2d628..00000000 --- a/docs/styles/docfx.vendor.js +++ /dev/null @@ -1,45 +0,0 @@ -/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ -return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("