diff --git a/.env.test b/.env.test index 2f053a6e..3398f16e 100644 --- a/.env.test +++ b/.env.test @@ -7,6 +7,9 @@ PRIMO_SCOPE=cdi PRIMO_TAB=all PRIMO_VID=01MIT_INST:MIT SYNDETICS_PRIMO_URL=https://syndetics.com/index.php?client=primo +TACOS_HOST=FAKE_TACOS_HOST +TACOS_URL=http://FAKE_TACOS_HOST/graphql +TACOS_SOURCE=FAKE_TACOS_SOURCE TIMDEX_GRAPHQL=https://FAKE_TIMDEX_HOST/graphql TIMDEX_HOST=FAKE_TIMDEX_HOST TIMDEX_INDEX=FAKE_TIMDEX_INDEX \ No newline at end of file diff --git a/README.md b/README.md index 0ac7c522..3af8e50f 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ mode (e.g., `GDT=false` will still enable GDT features). Note that this is curre may have unexpected consequences if applied to other TIMDEX UI apps. - `GLOBAL_ALERT`: The main functionality for this comes from our theme gem, but when set the value will be rendered as safe html above the main header of the site. +- `ORIGINS`: sets origins for CORS (currently used only for TACOS API calls). - `PLATFORM_NAME`: The value set is added to the header after the MIT Libraries logo. The logic and CSS for this comes from our theme gem. - `PRIMO_TIMEOUT`: The number of seconds before a Primo request times out (default 6). - `REQUESTS_PER_PERIOD` - number of requests that can be made for general throttles per `REQUEST_PERIOD` @@ -136,6 +137,10 @@ may have unexpected consequences if applied to other TIMDEX UI apps. - `REDIRECT_REQUEST_PERIOD`- time in minutes used along with `REDIRECT_REQUEST_PERIOD` - `SENTRY_DSN`: Client key for Sentry exception logging. - `SENTRY_ENV`: Sentry environment for the application. Defaults to 'unknown' if unset. +- `TACOS_SOURCE`: If set, this value is sent to TACOS (as the `sourceSystem` value) to distinguish which application +instance is sending what search traffic. Defaults to "unset" if not defined. +- `TACOS_URL`: The GraphQL endpoint for the [TACOS API](https://github.com/mitlibraries/tacos/). When set, the + application will log search terms to TACOS (and eventually return suggested resources that TACOS detects). - `TIMDEX_INDEX`: Name of the index, or alias, to provide to the GraphQL endpoint. Defaults to `nil` which will let TIMDEX determine the best index to use. Wildcard values can be set, for example `rdi*` would search any indexes that begin with `rdi` in the underlying OpenSearch instance behind TIMDEX. - `TIMDEX_SOURCES`: Comma-separated list of sources to display in the advanced-search source selection element. This overrides the default which is set in ApplicationHelper. @@ -143,6 +148,10 @@ may have unexpected consequences if applied to other TIMDEX UI apps. #### Test Environment-only Variables - `SPEC_REPORTER`: Optional variable. If set, enables spec reporter style output from tests rather than minimal output. +- `TACOS_HOST`: Test Env only. Used to ensure the VCR cassettes can properly scrub specific host data to make sure we +get the same cassettes regardless of which host was used to generate the cassettes. This should be set to the hostname +that matches `TACOS_URL`. Ex: If `TACOS_URL` is `http://localhost:3001/graphql` then `TACOS_HOST` should be +`localhost:3001`. - `TIMDEX_HOST`: Test Env only. Used to ensure the VCR cassettes can properly scrub specific host data to make sure we get the same cassettes regardless of which host was used to generate the cassettes. This should be set to the host name that matches `TIMDEX_GRAPHQL`. Ex: If `TIMDEX_GRAPHQL` is `https://www.example.com/graphql` then `TIMDEX_HOST` should be `www.example.com`. ### Generating VCR Cassettes diff --git a/app/controllers/tacos_controller.rb b/app/controllers/tacos_controller.rb new file mode 100644 index 00000000..715e2247 --- /dev/null +++ b/app/controllers/tacos_controller.rb @@ -0,0 +1,9 @@ +class TacosController < ApplicationController + layout false + + def analyze + return unless ApplicationHelper.tacos_enabled? + + Tacos.analyze(params[:q]) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 710d0aa5..04cb03c6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,9 @@ module ApplicationHelper + def tacos_enabled? + ENV.fetch('TACOS_URL', '').present? + end + module_function :tacos_enabled? + def timdex_sources ENV.fetch('TIMDEX_SOURCES', timdex_source_defaults).split(',') end diff --git a/app/models/tacos.rb b/app/models/tacos.rb new file mode 100644 index 00000000..f9e1bc33 --- /dev/null +++ b/app/models/tacos.rb @@ -0,0 +1,49 @@ +class Tacos + # The tacos_client argument here is unused in production - it is provided for + # our test suite so that we can mock various error conditions to ensure that + # error handling happens as we intend. + def self.analyze(term, tacos_client = nil) + tacos_http = setup(tacos_client) + query = '{ "query": "{ logSearchEvent(searchTerm: \"' + clean_term(term) + '\", sourceSystem: \"' + tacos_source + '\" ) { phrase source detectors { suggestedResources { title url } } } }" }' + begin + raw_response = tacos_http.timeout(http_timeout).post(tacos_url, body: query) + JSON.parse(raw_response.to_s) + rescue HTTP::Error + {"error" => "A connection error has occurred"} + rescue JSON::ParserError + {"error" => "A parsing error has occurred"} + end + end + + private + + def self.clean_term(term) + term.gsub('"', '\'') + end + + def self.http_timeout + ENV.fetch('TIMDEX_TIMEOUT', 6).to_f + end + + def self.origins + ENV.fetch('ORIGINS', nil) + end + + # We define the HTTP connection this way so that it can be overridden during + # testing, to make sure that the .analyze method can handle specific error + # conditions. + def self.setup(tacos_client) + tacos_client || HTTP.persistent(tacos_url) + .headers(accept: 'application/json', + 'Content-Type': 'application/json', + origin: origins) + end + + def self.tacos_source + ENV.fetch('TACOS_SOURCE', 'timdexui_unset') + end + + def self.tacos_url + ENV.fetch('TACOS_URL', nil) + end +end diff --git a/app/views/search/_trigger_tacos.html.erb b/app/views/search/_trigger_tacos.html.erb new file mode 100644 index 00000000..967e34fc --- /dev/null +++ b/app/views/search/_trigger_tacos.html.erb @@ -0,0 +1,8 @@ +<% return unless (tacos_enabled? and @enhanced_query[:q].present?) %> + +<% data_url = "/analyze?q=#{URI.encode_www_form_component(@enhanced_query[:q])}" %> + +
> +
diff --git a/app/views/search/results.html.erb b/app/views/search/results.html.erb index d9b97e02..aa89ac79 100644 --- a/app/views/search/results.html.erb +++ b/app/views/search/results.html.erb @@ -68,4 +68,6 @@ <% end %> +<%= render(partial: 'trigger_tacos') if tacos_enabled? %> + <%= javascript_include_tag "filters" %> diff --git a/app/views/tacos/analyze.html.erb b/app/views/tacos/analyze.html.erb new file mode 100644 index 00000000..ef05b8b3 --- /dev/null +++ b/app/views/tacos/analyze.html.erb @@ -0,0 +1 @@ + diff --git a/config/routes.rb b/config/routes.rb index ec77b2e3..ce24c7ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,8 @@ get 'issn', to: 'fact#issn' get 'pmid', to: 'fact#pmid' + get 'analyze', to: 'tacos#analyze' + get 'record/(:id)', to: 'record#view', as: 'record', diff --git a/test/controllers/search_controller_test.rb b/test/controllers/search_controller_test.rb index b3be172c..c33385ed 100644 --- a/test/controllers/search_controller_test.rb +++ b/test/controllers/search_controller_test.rb @@ -275,7 +275,7 @@ def setup end assert_response :success - assert_select('div[data-content-loader-url-value]', 0) + assert_select('div[data-content-loader-url-value].fact-container', 0) end end @@ -305,7 +305,7 @@ def setup assert_response :success - assert_select('div[data-content-loader-url-value]', 0) + assert_select('div[data-content-loader-url-value].fact-container', 0) end end @@ -333,7 +333,7 @@ def setup end assert_response :success - assert_select('div[data-content-loader-url-value]', 0) + assert_select('div[data-content-loader-url-value].fact-container', 0) end end @@ -361,7 +361,31 @@ def setup end assert_response :success - assert_select('div[data-content-loader-url-value]', 0) + assert_select('div[data-content-loader-url-value].fact-container', 0) + end + end + + test 'TACOS intervention is inserted when TACOS enabled' do + VCR.use_cassette('tacos', + allow_playback_repeats: true) do + get '/results?q=tacos' + + assert_response :success + + tacos_div = assert_select('div[data-content-loader-url-value].tacos-container') + assert_equal '/analyze?q=tacos', tacos_div.attribute('data-content-loader-url-value').value + end + end + + test 'TACOS intervention not inserted when TACOS not enabled' do + VCR.use_cassette('tacos', + allow_playback_repeats: true) do + ClimateControl.modify(TACOS_URL: '') do + get '/results?q=tacos' + end + assert_response :success + + assert_select('div[data-content-loader-url-value].tacos-container', 0) end end diff --git a/test/controllers/tacos_controller_test.rb b/test/controllers/tacos_controller_test.rb new file mode 100644 index 00000000..9432182f --- /dev/null +++ b/test/controllers/tacos_controller_test.rb @@ -0,0 +1,12 @@ +require 'test_helper' + +class TacosControllerTest < ActionDispatch::IntegrationTest + test 'analyze route exists but returns an HTML comment for now' do + VCR.use_cassette('tacos direct') do + get '/analyze?q=direct' + + assert_response :success + assert_equal "\n", response.body + end + end +end diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 01df7651..cf3fdbba 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -3,6 +3,16 @@ class ApplicationHelperTest < ActionView::TestCase include ApplicationHelper + test 'tacos_enabled? requires TACOS_URL env variable to have non-zero length' do + ClimateControl.modify TACOS_URL: 'foo' do + assert_equal true, tacos_enabled? + end + + ClimateControl.modify TACOS_URL: '' do + assert_equal false, tacos_enabled? + end + end + test 'index_page_title renders as expected' do assert_equal 'Search | MIT Libraries', index_page_title end diff --git a/test/models/tacos_test.rb b/test/models/tacos_test.rb new file mode 100644 index 00000000..8d545b5a --- /dev/null +++ b/test/models/tacos_test.rb @@ -0,0 +1,62 @@ +require 'test_helper' + +class TacosConnectionError + def timeout(_) + self + end + + def post(_url, body:) + raise HTTP::ConnectionError, "forced connection failure" + end +end + +class TacosParsingError + def timeout(_) + self + end + + def post(_url, body:) + 'This is not valid json' + end +end + +class TacosTest < ActiveSupport::TestCase + test 'TACOS model has a call method that reflects a search term back' do + VCR.use_cassette('tacos popcorn') do + searchterm = 'popcorn' + + result = Tacos.analyze(searchterm) + + assert_instance_of Hash, result + assert_equal searchterm, result['data']['logSearchEvent']['phrase'] + end + end + + test 'TACOS model will use ENV to populate the sourceSystem value' do + VCR.use_cassette('tacos fake system') do + ClimateControl.modify(TACOS_SOURCE: 'faked') do + result = Tacos.analyze('popcorn') + + assert_equal 'faked', result['data']['logSearchEvent']['source'] + end + end + end + + test 'TACOS model catches connection errors' do + tacos_client = TacosConnectionError.new + + result = Tacos.analyze('popcorn', tacos_client) + + assert_instance_of Hash, result + assert_equal 'A connection error has occurred', result['error'] + end + + test 'TACOS model catches parsing errors' do + tacos_client = TacosParsingError.new + + result = Tacos.analyze('popcorn', tacos_client) + + assert_instance_of Hash, result + assert_equal 'A parsing error has occurred', result['error'] + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 60b82092..3f113331 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -18,7 +18,7 @@ end VCR.configure do |config| - config.ignore_localhost = true + config.ignore_localhost = false config.cassette_library_dir = 'test/vcr_cassettes' config.hook_into :webmock config.allow_http_connections_when_no_cassette = false @@ -26,6 +26,8 @@ config.filter_sensitive_data('http://FAKE_TIMDEX_HOST/graphql/') { ENV.fetch('TIMDEX_GRAPHQL').to_s } config.filter_sensitive_data('FAKE_TIMDEX_INDEX') { ENV.fetch('TIMDEX_INDEX').to_s } config.filter_sensitive_data('FAKE_PRIMO_API_KEY') { ENV.fetch('PRIMO_API_KEY').to_s } + config.filter_sensitive_data('FAKE_TACOS_HOST') { ENV.fetch('TACOS_HOST').to_s } + config.filter_sensitive_data('http://FAKE_TACOS_HOST/graphql/') { ENV.fetch('TACOS_URL').to_s } end module ActiveSupport diff --git a/test/vcr_cassettes/tacos.yml b/test/vcr_cassettes/tacos.yml new file mode 100644 index 00000000..58875a52 --- /dev/null +++ b/test/vcr_cassettes/tacos.yml @@ -0,0 +1,88 @@ +--- +http_interactions: +- request: + method: post + uri: https://FAKE_TIMDEX_HOST/graphql + body: + encoding: UTF-8 + string: '{"query":"query TimdexSearch__BaseQuery($q: String, $citation: String, + $contributors: String, $fundingInformation: String, $identifiers: String, + $locations: String, $subjects: String, $title: String, $index: String, $from: + String, $booleanType: String, $accessToFilesFilter: [String!], $contentTypeFilter: + [String!], $contributorsFilter: [String!], $formatFilter: [String!], $languagesFilter: + [String!], $literaryFormFilter: String, $placesFilter: [String!], $sourceFilter: + [String!], $subjectsFilter: [String!]) {\n search(searchterm: $q, citation: + $citation, contributors: $contributors, fundingInformation: $fundingInformation, + identifiers: $identifiers, locations: $locations, subjects: $subjects, title: + $title, index: $index, from: $from, booleanType: $booleanType, accessToFilesFilter: + $accessToFilesFilter, contentTypeFilter: $contentTypeFilter, contributorsFilter: + $contributorsFilter, formatFilter: $formatFilter, languagesFilter: $languagesFilter, + literaryFormFilter: $literaryFormFilter, placesFilter: $placesFilter, sourceFilter: + $sourceFilter, subjectsFilter: $subjectsFilter) {\n hits\n records {\n timdexRecordId\n title\n contentType\n contributors + {\n kind\n value\n }\n publicationInformation\n dates + {\n kind\n value\n }\n links {\n kind\n restrictions\n text\n url\n }\n notes + {\n kind\n value\n }\n highlight {\n matchedField\n matchedPhrases\n }\n provider\n rights + {\n kind\n description\n uri\n }\n sourceLink\n summary\n }\n aggregations + {\n accessToFiles {\n key\n docCount\n }\n contentType + {\n key\n docCount\n }\n contributors {\n key\n docCount\n }\n format + {\n key\n docCount\n }\n languages {\n key\n docCount\n }\n literaryForm + {\n key\n docCount\n }\n places {\n key\n docCount\n }\n source + {\n key\n docCount\n }\n subjects {\n key\n docCount\n }\n }\n }\n}","variables":{"from":"0","q":"tacos","booleanType":"AND","index":"FAKE_TIMDEX_INDEX"},"operationName":"TimdexSearch__BaseQuery"}' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - application/json + User-Agent: + - MIT Libraries Client + Content-Type: + - application/json + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - max-age=0, private, must-revalidate + Content-Length: + - '39172' + Content-Type: + - application/json; charset=utf-8 + Etag: + - W/"46d0fef2dc0398207ff0f67ac58ceb8f" + Nel: + - '{"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1}' + Referrer-Policy: + - strict-origin-when-cross-origin + Report-To: + - '{"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=9lAxEBscLCBgQX%2Bp%2FLIPNnsiIz971izVEylC%2FOD3ERE%3D\u0026sid=67ff5de4-ad2b-4112-9289-cf96be89efed\u0026ts=1759503031"}],"max_age":3600}' + Reporting-Endpoints: + - heroku-nel="https://nel.heroku.com/reports?s=9lAxEBscLCBgQX%2Bp%2FLIPNnsiIz971izVEylC%2FOD3ERE%3D&sid=67ff5de4-ad2b-4112-9289-cf96be89efed&ts=1759503031" + Server: + - Heroku + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + Vary: + - Accept, Origin + Via: + - 1.1 heroku-router + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - 356d6b91-414b-0ba9-98e4-597599888538 + X-Runtime: + - '0.487842' + X-Xss-Protection: + - '0' + Date: + - Fri, 03 Oct 2025 14:50:31 GMT + body: + encoding: ASCII-8BIT + string: !binary |- + eyJkYXRhIjp7InNlYXJjaCI6eyJoaXRzIjo1NywicmVjb3JkcyI6W3sidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MzU0NjA0ODQxMDY3NjEiLCJ0aXRsZSI6IkJyb2Fkd2F5J3MgaG90dGVzdCBkaXNoLiBFcGlzb2RlIDIsIFRhY29zIFx1MDAyNiB0b3N0YWRhcyIsImNvbnRlbnRUeXBlIjpbIlByb2plY3RlZCBtZWRpdW0iXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiZGlyZWN0b3IiLCJ2YWx1ZSI6IkRldmluZSwgS2VsbHkifSx7ImtpbmQiOiJwcm9kdWNlciIsInZhbHVlIjoiRGV2aW5lLCBLZWxseSJ9LHsia2luZCI6ImRpcmVjdG9yIiwidmFsdWUiOiJHcmlmZml0aCwgUC4gSiJ9LHsia2luZCI6InByb2R1Y2VyIiwidmFsdWUiOiJHcmlmZml0aCwgUC4gSiJ9LHsia2luZCI6InB1Ymxpc2hlciIsInZhbHVlIjoiQnJvYWR3YXkgTGljZW5zaW5nIn1dLCJwdWJsaWNhdGlvbkluZm9ybWF0aW9uIjpbIkJyb2Fkd2F5IExpY2Vuc2luZzsgMjAyMDsgTmV3IFlvcmssIE5ZIl0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAyMCJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJBY2FkZW1pYyBWaWRlbyBPbmxpbmUgKEFWT04pIiwidXJsIjoiaHR0cHM6Ly9uYTA2LmFsbWEuZXhsaWJyaXNncm91cC5jb20vdmlldy91cmVzb2x2ZXIvMDFNSVRfSU5TVC9vcGVudXJsP3UuaWdub3JlX2RhdGVfY292ZXJhZ2U9dHJ1ZVx1MDAyNnBvcnRmb2xpb19waWQ9NTM2NjcxNjU1NjAwMDY3NjFcdTAwMjZGb3JjZV9kaXJlY3Q9dHJ1ZSJ9XSwibm90ZXMiOlt7ImtpbmQiOiJUaXRsZSBTdGF0ZW1lbnQgb2YgUmVzcG9uc2liaWxpdHkiLCJ2YWx1ZSI6WyJwcm9kdWNlZCBcdTAwMjYgZGlyZWN0ZWQgYnkgS2VsbHkgRGV2aW5lIFx1MDAyNiBQLkouIEdyaWZmaXRoIl19LHsia2luZCI6IkdlbmVyYWwgTm90ZSIsInZhbHVlIjpbIlRpdGxlIGZyb20gcmVzb3VyY2UgZGVzY3JpcHRpb24gcGFnZSAodmlld2VkIEFwcmlsIDAzLCAyMDIzKSJdfSx7ImtpbmQiOiJQYXJ0aWNpcGFudCBvciBQZXJmb3JtZXIgTm90ZSIsInZhbHVlIjpbIkZlYXR1cmluZzogU2VyZ2lvIFRydWppbGxvLCBKYWNrIE5vc2V3b3J0aHksIEthdGllIFdlYmJlciJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbIlwiVElOQVwi4oCZcyBLYXRpZSBXZWJiZXIgbWFrZXMgJ3ZlZ2FuJyB2ZWdnaWUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNldGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSB3aGlsZSBkaXNjdXNzaW5nIHRoZSBiZW5lZml0cyBvZiBkYXRpbmcgYSBGcmVuY2ggcm9ja2VyIl19LHsibWF0Y2hlZEZpZWxkIjoiY2l0YXRpb24iLCJtYXRjaGVkUGhyYXNlcyI6WyJFcGlzb2RlIDIsIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UgXHUwMDI2IHRvc3RhZGFzLiAyMDIwLiBOZXcgWW9yaywgTlkgOiBCcm9hZHdheSBMaWNlbnNpbmcuIl19LHsibWF0Y2hlZEZpZWxkIjoidGl0bGUiLCJtYXRjaGVkUGhyYXNlcyI6WyJFcGlzb2RlIDIsIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UgXHUwMDI2IHRvc3RhZGFzIl19LHsibWF0Y2hlZEZpZWxkIjoic3ViamVjdHMudmFsdWUiLCJtYXRjaGVkUGhyYXNlcyI6WyJcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkzNTQ2MDQ4NDEwNjc2MSIsInN1bW1hcnkiOlsiQmVsaWV2ZSBpdCBvciBub3QsIEJyb2Fkd2F54oCZcyBob3R0ZXN0IGRhbmNlcnMgY2FuIEVBVC4gTm93LCBpdCdzIHRpbWUgdG8gZ2V0IHVwIGNsb3NlIGFuZCBwZXJzb25hbCBieSBnb2luZyBpbnNpZGUgdGhlaXIga2l0Y2hlbnMgYXMgdGhleSBzaGFyZSB0aGVpciBmYXZvcml0ZSByZWNpcGVzIGFuZCB2aWV3ZXJzIGxlYXJuIHRoZSBhbnN3ZXJzIHRvIGltcG9ydGFudCBxdWVzdGlvbnMsIGxpa2U6IFdoYXTigJlzIHRoZSBzZWNyZXQgc3BpY2Ugc2hlIGNhbuKAmXQgbGl2ZSB3aXRob3V0PyBEaWQgaGUganVzdCBoZSBsaWNrIHRoZSBzcG9vbj8gSG93IGRvZXMgc2hlIGVhdCBsaWtlIHRoZSB0aGF0IGFuZCBJIHN0aWxsIGhhdmUgYW4gOC1wYWNrPyBUdW5lIGluIHRvIGZpbmQgb3V0ISBUb255IEF3YXJkLXdpbm5pbmcgY2hvcmVvZ3JhcGhlciwgU2VyZ2lvIFRydWppbGxvIChcIkFJTuKAmVQgVE9PIFBST1VEOiBUSEUgTElGRSBBTkQgVElNRVMgT0YgVEhFIFRFTVBUQVRJT05TXCIpLCBtYWtlcyB0cmFkaXRpb25hbCBDb2xvbWJpYW4gJ1Rvc3RhZGFzJyBhbmQgYWRtaXRzIHRvIGJlaW5nIGEgdGF0dGxldGFsZSBncm93aW5nIHVwLiBcIlRJTkFcIuKAmXMgS2F0aWUgV2ViYmVyIG1ha2VzICd2ZWdhbicgdmVnZ2llIHRhY29zIHdoaWxlIGRpc2N1c3NpbmcgdGhlIGJlbmVmaXRzIG9mIGRhdGluZyBhIEZyZW5jaCByb2NrZXIuIl19LHsidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MzU5NjU5MDk2MDY3NjEiLCJ0aXRsZSI6IldvcmtpbmcgcG9zdHVyZSBhc3Nlc3NtZW50IDogdGhlIFRBQ09zICh0aW1lLWJhc2VkIGFzc2Vzc21lbnQgY29tcHV0ZXJpemVkIHN0cmF0ZWd5KSBtZXRob2QiLCJjb250ZW50VHlwZSI6WyJMYW5ndWFnZSBtYXRlcmlhbCJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJlZGl0b3IiLCJ2YWx1ZSI6IkNvbG9tYmluaSwgRGFuaWVsYSJ9LHsia2luZCI6ImVkaXRvciIsInZhbHVlIjoiT2NjaGlwaW50aSwgRS4gKEVucmljbykifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiQ1JDIFByZXNzOyBbMjAxOV07IEJvY2EgUmF0b24sIEZMIl0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAxOSJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOm51bGwsInVybCI6Imh0dHBzOi8vd3d3LnRheWxvcmZyYW5jaXMuY29tL2Jvb2tzLzk3ODEzMTUxNDk1NDcifSx7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJUYXlsb3IgXHUwMDI2IEZyYW5jaXMgRGlzY292ZXJ5IENvbGxlY3Rpb24iLCJ1cmwiOiJodHRwczovL3d3dy50YXlsb3JmcmFuY2lzLmNvbS9ib29rcy85NzgxMzE1MTQ5NTQ3In1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbImVkaXRlZCBieSBEYW5pZWxhIENvbG9tYmluaSBhbmQgRW5yaWNvIE9jY2hpcGludGkiXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiXCJBIENSQyB0aXRsZS5cIiJdfSx7ImtpbmQiOiJCaWJsaW9ncmFwaHkgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGJpYmxpb2dyYXBoaWNhbCByZWZlcmVuY2VzIGFuZCBpbmRleCJdfSx7ImtpbmQiOiJTb3VyY2Ugb2YgRGVzY3JpcHRpb24gTm90ZSIsInZhbHVlIjpbIlByaW50IHZlcnNpb24gcmVjb3JkIl19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJzdW1tYXJ5IiwibWF0Y2hlZFBocmFzZXMiOlsiaW1wbGVtZW50IHRoZSBzdHJhdGVneSBmb3IgY2FsY3VsYXRpbmcgcmlzayBhc3NvY2lhdGVkIHdpdGggZXhwb3N1cmUgdG8gYXdrd2FyZCBwb3N0dXJlcywgaS5lLiB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVEFDT1NcdTAwM2Mvc3Bhblx1MDAzZSJdfSx7Im1hdGNoZWRGaWVsZCI6ImNvbnRlbnRzIiwibWF0Y2hlZFBocmFzZXMiOlsiVGhlIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRBQ09zXHUwMDNjL3NwYW5cdTAwM2UgbWV0aG9kIiwiU2ltcGxlIHRvb2xzIGZvciB1c2luZyB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVEFDT3NcdTAwM2Mvc3Bhblx1MDAzZSBtZXRob2QgdG8gYXNzZXNzIHBvc3R1cmVzIDogYW4gZXhhbXBsZSBvZiBhIG11bHRpdGFzayBqb2Igd2l0aCBpbiBhIiwiU2ltcGxlIHRvb2xzIGZvciB1c2luZyB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVEFDT3NcdTAwM2Mvc3Bhblx1MDAzZSBtZXRob2QgdG8gYXNzZXNzIHBvc3R1cmVzIDogdGhlIGV4YW1wbGUgb2YgYSBtdWx0aXRhc2sgam9iIGJhc2VkIG9uIiwiU2ltcGxlIHRvb2xzIGZvciB1c2luZyB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVEFDT3NcdTAwM2Mvc3Bhblx1MDAzZSBtZXRob2QgdG8gYXNzZXNzIHBvc3R1cmVzIDogdGhlIGV4YW1wbGUgb2YgYSBtdWx0aXRhc2sgam9iIGJhc2VkIGluIl19LHsibWF0Y2hlZEZpZWxkIjoiY2l0YXRpb24iLCJtYXRjaGVkUGhyYXNlcyI6WyJXb3JraW5nIHBvc3R1cmUgYXNzZXNzbWVudCA6IHRoZSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUQUNPc1x1MDAzYy9zcGFuXHUwMDNlICh0aW1lLWJhc2VkIGFzc2Vzc21lbnQgY29tcHV0ZXJpemVkIHN0cmF0ZWd5KSBtZXRob2QuIDIwMTkuIl19LHsibWF0Y2hlZEZpZWxkIjoidGl0bGUiLCJtYXRjaGVkUGhyYXNlcyI6WyJXb3JraW5nIHBvc3R1cmUgYXNzZXNzbWVudCA6IHRoZSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUQUNPc1x1MDAzYy9zcGFuXHUwMDNlICh0aW1lLWJhc2VkIGFzc2Vzc21lbnQgY29tcHV0ZXJpemVkIHN0cmF0ZWd5KSBtZXRob2QiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1OTY1OTA5NjA2NzYxIiwic3VtbWFyeSI6WyJcIlRoaXMgYm9vayBjb3ZlcnMgaG93IHRvIGFuYWx5emUgYXdrd2FyZCB3b3JraW5nIHBvc3R1cmVzIG9mIHRoZSBzcGluZSBhbmQgbG93ZXIgbGltYnMgaW4gc3BlY2lmaWMgZ3JvdXBzIGV4cG9zZWQuIFRoZSBtZXRob2RzIGNvdmVyZWQgc3VnZ2VzdHMgaG93IHRvIGV2YWx1YXRlIHRoZSBwb3N0dXJlcyBjb3JyZWN0bHkgaW4gdmVyeSBjb21wbGV4IHNjZW5hcmlvcyB3aGVyZSB3b3JrZXJzIGFyZSBpbnZvbHZlZCB3aXRoIG11bHRpcGxlIHRhc2tzIGFuZCB3b3JrIGN5Y2xlcyB2YXJ5aW5nIGZyb20gZGF5IHRvIGRheS4gRXhjZWwgc3ByZWFkc2hlZXRzIGxvY2F0ZWQgb24gdGhlIGF1dGhvcnMgd2Vic2l0ZSBoYXZlIGJlZW4gZGV2ZWxvcGVkIHRvIGdhdGhlciwgY29uZGVuc2UsIGFuZCBhdXRvbWF0aWNhbGx5IHByb2Nlc3MgdGhlIGRhdGEuIFRoZSB0b29scyBzZXJ2ZSB0byBpbXBsZW1lbnQgdGhlIHN0cmF0ZWd5IGZvciBjYWxjdWxhdGluZyByaXNrIGFzc29jaWF0ZWQgd2l0aCBleHBvc3VyZSB0byBhd2t3YXJkIHBvc3R1cmVzLCBpLmUuIHRoZSBUQUNPUyBtZXRob2QuIEluY2x1ZGVkIGFyZSA1IGNhc2Ugc3R1ZGllcyB3aGljaCBpbmNsdWRlIHBoeXNpb3RoZXJhcGlzdHMsIHdvcmtlcnMgZnJvbSBjb25zdHJ1Y3Rpb24sIGFyY2hhZW9sb2dpY2FsIGRpZ3MsIHZpbmV5YXJkcywgYW5kIGtpbmRlcmdhcnRlbiB0ZWFjaGVyc1wiLS0iXX0seyJ0aW1kZXhSZWNvcmRJZCI6ImFsbWE6OTkzNTc2NDgzMzIwNjc2MSIsInRpdGxlIjoiV29ya2luZyBQb3N0dXJlIEFzc2Vzc21lbnQgOiBUaGUgVEFDT1MgKFRpbWUtQmFzZWQgQXNzZXNzbWVudCBDb21wdXRlcml6ZWQgU3RyYXRlZ3kpIE1ldGhvZCIsImNvbnRlbnRUeXBlIjpbIkxhbmd1YWdlIG1hdGVyaWFsIl0sImNvbnRyaWJ1dG9ycyI6W3sia2luZCI6ImVkaXRvciIsInZhbHVlIjoiQ29sb21iaW5pLCBEYW5pZWxhIn0seyJraW5kIjoiZWRpdG9yIiwidmFsdWUiOiJPY2NoaXBpbnRpLCBFbnJpY28ifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiQ1JDIFByZXNzOyBbMjAxOF07IEJvY2EgUmF0b24sIEZMIiwiwqkyMDE5Il0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAxOCJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJUYXlsb3IgXHUwMDI2IEZyYW5jaXMgRXZpZGVuY2UgQmFzZWQgRWJvb2sgQ29sbGVjdGlvbiIsInVybCI6Imh0dHBzOi8vbmEwNi5hbG1hLmV4bGlicmlzZ3JvdXAuY29tL3ZpZXcvdXJlc29sdmVyLzAxTUlUX0lOU1Qvb3BlbnVybD91Lmlnbm9yZV9kYXRlX2NvdmVyYWdlPXRydWVcdTAwMjZwb3J0Zm9saW9fcGlkPTUzNzAzNjUyODMwMDA2NzYxXHUwMDI2Rm9yY2VfZGlyZWN0PXRydWUifV0sIm5vdGVzIjpbeyJraW5kIjoiVGl0bGUgU3RhdGVtZW50IG9mIFJlc3BvbnNpYmlsaXR5IiwidmFsdWUiOlsiZWRpdGVkIGJ5IERhbmllbGEgQ29sb21iaW5pIGFuZCBFbnJpY28gT2NjaGlwaW50aSJdfSx7ImtpbmQiOiJCaWJsaW9ncmFwaHkgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGJpYmxpb2dyYXBoaWNhbCByZWZlcmVuY2VzIGFuZCBpbmRleCJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbImltcGxlbWVudCB0aGUgc3RyYXRlZ3kgZm9yIGNhbGN1bGF0aW5nIHJpc2sgYXNzb2NpYXRlZCB3aXRoIGV4cG9zdXJlIHRvIGF3a3dhcmQgcG9zdHVyZXMsIGkuZS4gdGhlIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRBQ09TXHUwMDNjL3NwYW5cdTAwM2UiXX0seyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIlRoZSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUQUNPc1x1MDAzYy9zcGFuXHUwMDNlIE1ldGhvZDogTWV0aG9kcywgQ3JpdGVyaWEsIGFuZCBBcHBsaWNhdGlvbnMgb2YgU2luZ2xlLVRhc2sgSm9icy4iLCJTaW1wbGUgVG9vbHMgZm9yIFVzaW5nIHRoZSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUQUNPc1x1MDAzYy9zcGFuXHUwMDNlIE1ldGhvZCB0byBBc3Nlc3MgUG9zdHVyZXM6IEFuIEV4YW1wbGUgb2YgYSBNdWx0aXRhc2sgSm9iIGluIGEgRGFpbHkiLCJTaW1wbGUgVG9vbHMgZm9yIFVzaW5nIHRoZSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUQUNPc1x1MDAzYy9zcGFuXHUwMDNlIE1ldGhvZCB0byBBc3Nlc3MgUG9zdHVyZXM6IEFuIEV4YW1wbGUgb2YgYSBNdWx0aXRhc2sgSm9iIGluIGEgV2Vla2x5IiwiU2ltcGxlIFRvb2xzIGZvciBVc2luZyB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVEFDT3NcdTAwM2Mvc3Bhblx1MDAzZSBNZXRob2QgdG8gQXNzZXNzIFBvc3R1cmVzOiBBbiBFeGFtcGxlIG9mIGEgTXVsdGl0YXNrIEpvYiBpbiBhbiBBbm51YWwiXX0seyJtYXRjaGVkRmllbGQiOiJjaXRhdGlvbiIsIm1hdGNoZWRQaHJhc2VzIjpbIldvcmtpbmcgUG9zdHVyZSBBc3Nlc3NtZW50IDogVGhlIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRBQ09TXHUwMDNjL3NwYW5cdTAwM2UgKFRpbWUtQmFzZWQgQXNzZXNzbWVudCBDb21wdXRlcml6ZWQgU3RyYXRlZ3kpIE1ldGhvZC4gMjAxOC4iXX0seyJtYXRjaGVkRmllbGQiOiJ0aXRsZSIsIm1hdGNoZWRQaHJhc2VzIjpbIldvcmtpbmcgUG9zdHVyZSBBc3Nlc3NtZW50IDogVGhlIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRBQ09TXHUwMDNjL3NwYW5cdTAwM2UgKFRpbWUtQmFzZWQgQXNzZXNzbWVudCBDb21wdXRlcml6ZWQgU3RyYXRlZ3kpIE1ldGhvZCJdfV0sInByb3ZpZGVyIjpudWxsLCJyaWdodHMiOm51bGwsInNvdXJjZUxpbmsiOiJodHRwczovL21pdC5wcmltby5leGxpYnJpc2dyb3VwLmNvbS9kaXNjb3ZlcnkvZnVsbGRpc3BsYXk/dmlkPTAxTUlUX0lOU1Q6TUlUXHUwMDI2ZG9jaWQ9YWxtYTk5MzU3NjQ4MzMyMDY3NjEiLCJzdW1tYXJ5IjpbIlRoaXMgYm9vayBjb3ZlcnMgaG93IHRvIGFuYWx5emUgYXdrd2FyZCB3b3JraW5nIHBvc3R1cmVzLCBwYXJ0aWN1bGFybHkgb2YgdGhlIHNwaW5lIGFuZCBsb3dlciBsaW1icywgaW4gc3BlY2lmaWMgZ3JvdXBzIGV4cG9zZWQuIFRoZSBtZXRob2RzIGNvdmVyZWQgc3VnZ2VzdHMgaG93IHRvIGV2YWx1YXRlIHRoZSBwb3N0dXJlcyBjb3JyZWN0bHksIHRha2luZyBhY2NvdW50IG9mIHRoZSBkdXJhdGlvbiBhbmQgc2VxdWVuY2Ugb2YgdGhlIHRhc2tzIGludm9sdmVkLCBldmVuIGluIHZlcnkgY29tcGxleCBzY2VuYXJpb3Mgd2hlcmUgd29ya2VycyBhcmUgaW52b2x2ZWQgd2l0aCBtdWx0aXBsZSB0YXNrcyBhbmQgd29yayBjeWNsZXMgdmFyeWluZyBmcm9tIGRheSB0byBkYXkuIEV4Y2VsIHNwcmVhZHNoZWV0cyBsb2NhdGVkIG9uIHRoZSBhdXRob3Jz4oCZIHdlYnNpdGUgKHd3dy5lcG1yZXNlYXJjaC5vcmcpIGhhdmUgYmVlbiBkZXZlbG9wZWQgdG8gZ2F0aGVyLCBjb25kZW5zZSwgYW5kIGF1dG9tYXRpY2FsbHkgcHJvY2VzcyB0aGUgZGF0YS4gVGhlIHRvb2xzIHNlcnZlIHRvIGltcGxlbWVudCB0aGUgc3RyYXRlZ3kgZm9yIGNhbGN1bGF0aW5nIHJpc2sgYXNzb2NpYXRlZCB3aXRoIGV4cG9zdXJlIHRvIGF3a3dhcmQgcG9zdHVyZXMsIGkuZS4gdGhlIFRBQ09TIG1ldGhvZC4gSW5jbHVkZWQgYXJlIDUgY2FzZSBzdHVkaWVzIHdoaWNoIGluY2x1ZGUgcGh5c2lvdGhlcmFwaXN0cywgd29ya2VycyBmcm9tIGNvbnN0cnVjdGlvbiwgYXJjaGFlb2xvZ2ljYWwgZGlncywgdmluZXlhcmRzLCBhbmQga2luZGVyZ2FydGVuIHRlYWNoZXJzLiJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTAwMzI3MDU4MDAxMDY3NjEiLCJ0aXRsZSI6IlBsYW5ldCB0YWNvIDogYSBnbG9iYWwgaGlzdG9yeSBvZiBNZXhpY2FuIGZvb2QiLCJjb250ZW50VHlwZSI6WyJMYW5ndWFnZSBtYXRlcmlhbCJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJOb3Qgc3BlY2lmaWVkIiwidmFsdWUiOiJQaWxjaGVyLCBKZWZmcmV5IE0ifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiT3hmb3JkIFVuaXZlcnNpdHkgUHJlc3M7IFsyMDEyXTsgT3hmb3JkIDsiLCLCqTIwMTIiXSwiZGF0ZXMiOlt7ImtpbmQiOiJQdWJsaWNhdGlvbiBkYXRlIiwidmFsdWUiOiIyMDEyIn1dLCJsaW5rcyI6W3sia2luZCI6IkRpZ2l0YWwgb2JqZWN0IFVSTCIsInJlc3RyaWN0aW9ucyI6bnVsbCwidGV4dCI6IkVCU0NPaG9zdCBFYm9va3MiLCJ1cmwiOiJodHRwOi8vc2VhcmNoLmVic2NvaG9zdC5jb20vbG9naW4uYXNweD9kaXJlY3Q9dHJ1ZVx1MDAyNnNjb3BlPXNpdGVcdTAwMjZkYj1ubGVia1x1MDAyNmRiPW5sYWJrXHUwMDI2QU49NjQyMTUwIn1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkplZmZyZXkgTS4gUGlsY2hlciJdfSx7ImtpbmQiOiJCaWJsaW9ncmFwaHkgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGJpYmxpb2dyYXBoaWNhbCByZWZlcmVuY2VzIChwYWdlcyAyNjgtMjgyKSBhbmQgaW5kZXgiXX0seyJraW5kIjoiU291cmNlIG9mIERlc2NyaXB0aW9uIE5vdGUiLCJ2YWx1ZSI6WyJQcmludCB2ZXJzaW9uIHJlY29yZCJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbIkFzIGxhdGUgYXMgdGhlIDE5NjBzLCBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2V0YWNvc1x1MDAzYy9zcGFuXHUwMDNlIHdlcmUgdmlydHVhbGx5IHVua25vd24gb3V0c2lkZSBNZXhpY28gYW5kIHRoZSBBbWVyaWNhbiBTb3V0aHdlc3QuIl19LHsibWF0Y2hlZEZpZWxkIjoiY29udGVudHMiLCJtYXRjaGVkUGhyYXNlcyI6WyJJbnRyb2R1Y3Rpb246IEEgdGFsZSBvZiB0d28gXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNldGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSIsIlByb3RvLVx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UuIE1haXplIGFuZCB0aGUgbWFraW5nIG9mIE1leGljbyA7IEJ1cnJpdG9zIGluIHRoZSBib3JkZXJsYW5kcyIsIk5hdGlvbmFsIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UuIiwiR2xvYmFsIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UuIFRoZSBmaXJzdCB3YXZlIG9mIGdsb2JhbCBNZXhpY2FuIDsgVGhlIGJsdWUgY29ybiBib25hbnphIl19LHsibWF0Y2hlZEZpZWxkIjoic3ViamVjdHMudmFsdWUiLCJtYXRjaGVkUGhyYXNlcyI6WyJcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIC0gSGlzdG9yeSIsIlx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTAwMzI3MDU4MDAxMDY3NjEiLCJzdW1tYXJ5IjpbIkFzIGxhdGUgYXMgdGhlIDE5NjBzLCB0YWNvcyB3ZXJlIHZpcnR1YWxseSB1bmtub3duIG91dHNpZGUgTWV4aWNvIGFuZCB0aGUgQW1lcmljYW4gU291dGh3ZXN0LiBXaXRoaW4gZmlmdHkgeWVhcnMgdGhlIFVuaXRlZCBTdGF0ZXMgaGFkIHNoaXBwZWQgdGFjbyBzaGVsbHMgZXZlcnl3aGVyZSBmcm9tIEFsYXNrYSB0byBBdXN0cmFsaWEsIE1vcm9jY28gdG8gTW9uZ29saWEuIEJ1dCBob3cgZGlkIHRoaXMgdGFzdHkgaGFuZC1oZWxkIGZvb2QsIGFuZCBNZXhpY2FuIGZvb2QgbW9yZSBicm9hZGx5LCBiZWNvbWUgc28gdWJpcXVpdG91cz8gSW4gdGhpcyBib29rIHRoZSBhdXRob3IgdHJhY2VzIHRoZSBoaXN0b3JpY2FsIG9yaWdpbnMgYW5kIGV2b2x1dGlvbiBvZiBNZXhpY28ncyBuYXRpb25hbCBjdWlzaW5lLCBleHBsb3JlcyBpdHMgaW5jYXJuYXRpb24gYXMgYSBNZXhpY2FuIEFtZXJpY2FuIGZhc3QtZm9vZCwgc2hvd3MgaG93IHN1cmZlcnMgYmVjYW1lIGdsb2JhbCBwaW9uZWVycyBvZiBNZXhpY2FuIGZvb2QsIGFuZCBob3cgQ29yb25hIGJlZXIgY29ucXVlcmVkIHRoZSB3b3JsZC4gVGhlIGF1dGhvciBpcyBwYXJ0aWN1bGFybHkgZW5saWdodGVuaW5nIG9uIHdoYXQgdGhlIGhpc3Rvcnkgb2YgTWV4aWNhbiBmb29kIHJldmVhbHMgYWJvdXQgdGhlIHVuZWFzeSByZWxhdGlvbnNoaXAgYmV0d2VlbiBnbG9iYWxpemF0aW9uIGFuZCBhdXRoZW50aWNpdHkuIFRoZSBidXJyaXRvcyBhbmQgdGFjbyBzaGVsbHMgdGhhdCBtYW55IHBlb3BsZSB0aGluayBvZiBhcyBNZXhpY2FuIHdlcmUgYWN0dWFsbHkgY3JlYXRlZCBpbiB0aGUgVW5pdGVkIFN0YXRlcy4gQnV0IGhlIGFyZ3VlcyB0aGF0IHRoZSBjb250ZW1wb3Jhcnkgc3RydWdnbGUgYmV0d2VlbiBnbG9iYWxpemF0aW9uIGFuZCBuYXRpb25hbCBzb3ZlcmVpZ250eSB0byBkZXRlcm1pbmUgdGhlIGF1dGhlbnRpY2l0eSBvZiBNZXhpY2FuIGZvb2QgZ29lcyBiYWNrIGh1bmRyZWRzIG9mIHllYXJzLiBEdXJpbmcgdGhlIG5pbmV0ZWVudGggY2VudHVyeSwgTWV4aWNhbnMgc2VhcmNoaW5nIGZvciBhIG5hdGlvbmFsIGN1aXNpbmUgd2VyZSB0b3JuIGJldHdlZW4gbm9zdGFsZ2ljIFwiQ3Jlb2xlXCIgSGlzcGFuaWMgZGlzaGVzIG9mIHRoZSBwYXN0IGFuZCBGcmVuY2ggaGF1dGUgY3Vpc2luZSwgdGhlIGdsb2JhbCBmb29kIG9mIHRoZSBkYXkuIEluZGlnZW5vdXMgZm9vZHMgd2VyZSBzY29ybmVkIGFzIHVuZml0IGZvciBjaXZpbGl6ZWQgdGFibGVzLiBPbmx5IHdoZW4gTWV4aWNhbiBBbWVyaWNhbiBkaXNoZXMgd2VyZSBhcHByb3ByaWF0ZWQgYnkgdGhlIGZhc3QgZm9vZCBpbmR1c3RyeSBhbmQgY2FycmllZCBhcm91bmQgdGhlIHdvcmxkIGRpZCBNZXhpY2FuIGVsaXRlcyByZWRpc2NvdmVyIHRoZSBmb29kcyBvZiB0aGUgYW5jaWVudCBNYXlhIGFuZCBBenRlY3MgYW5kIGVtYnJhY2UgdGhlIGluZGlnZW5vdXMgcm9vdHMgb2YgdGhlaXIgbmF0aW9uYWwgY3Vpc2luZS4gRnJvbSBhIHRhY28gY2FydCBpbiBIZXJtb3NpbGxvLCBNZXhpY28gdG8gdGhlIFwiQ2hpbGkgUXVlZW5zXCIgb2YgU2FuIEFudG9uaW8gYW5kIHRhbWFsZSB2ZW5kb3JzIGluIExvcyBBbmdlbGVzLiwgdGhlIGF1dGhvciBmb2xsb3dzIHRoaXMgaGlnaGx5IGFkYXB0YWJsZSBjdWlzaW5lLCBwYXlpbmcgc3BlY2lhbCBhdHRlbnRpb24gdG8gdGhlIHBlb3BsZSB0b28gb2Z0ZW4gb3Zlcmxvb2tlZCBpbiB0aGUgYmF0dGxlIHRvIGRlZmluZSBhdXRoZW50aWMgTWV4aWNhbiBmb29kOiBJbmRpZ2Vub3VzIE1leGljYW5zIGFuZCBNZXhpY2FuIEFtZXJpY2FucyJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTAwMjA5NzkyNzAxMDY3NjEiLCJ0aXRsZSI6IlBsYW5ldCB0YWNvIDogYSBnbG9iYWwgaGlzdG9yeSBvZiBNZXhpY2FuIGZvb2QiLCJjb250ZW50VHlwZSI6WyJMYW5ndWFnZSBtYXRlcmlhbCJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJOb3Qgc3BlY2lmaWVkIiwidmFsdWUiOiJQaWxjaGVyLCBKZWZmcmV5IE0ifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiT3hmb3JkIFVuaXZlcnNpdHkgUHJlc3M7IGMyMDEyOyBOZXcgWW9yayJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMTIifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkplZmZyZXkgTS4gUGlsY2hlciJdfSx7ImtpbmQiOiJCaWJsaW9ncmFwaHkgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGJpYmxpb2dyYXBoaWNhbCByZWZlcmVuY2VzIChwLiAyNjgtMjgyKSBhbmQgaW5kZXgiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6ImNvbnRlbnRzIiwibWF0Y2hlZFBocmFzZXMiOlsiSW50cm9kdWN0aW9uOiBBIFRhbGUgb2YgVHdvIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UiLCJQcm90by1cdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIiwiTmF0aW9uYWwgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSIsIkdsb2JhbCBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIl19LHsibWF0Y2hlZEZpZWxkIjoic3ViamVjdHMudmFsdWUiLCJtYXRjaGVkUGhyYXNlcyI6WyJcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIC0gSGlzdG9yeSIsIlx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTAwMjA5NzkyNzAxMDY3NjEiLCJzdW1tYXJ5IjpudWxsfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1MTI3MDI2NjA2NzYxIiwidGl0bGUiOiJTaW1wbHkgTWluZy4gU2Vhc29uIDE1LCBlcGlzb2RlIDcsIFJpY2sgQmF5bGVzcyIsImNvbnRlbnRUeXBlIjpbIlByb2plY3RlZCBtZWRpdW0iXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiaG9zdCIsInZhbHVlIjoiVHNhaSwgTWluZyJ9LHsia2luZCI6ImRpcmVjdG9yIiwidmFsdWUiOiJEb25uZWxseSwgTGF1cmllIn0seyJraW5kIjoicHJvZHVjZXIiLCJ2YWx1ZSI6IkRvbm5lbGx5LCBMYXVyaWUifSx7ImtpbmQiOiJzcGVha2VyIiwidmFsdWUiOiJCYXlsZXNzLCBSaWNrIn0seyJraW5kIjoicHJvZHVjdGlvbiBjb21wYW55IiwidmFsdWUiOiJXR0JIIEVkdWNhdGlvbmFsIEZvdW5kYXRpb24ifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiUHVibGljIEJyb2FkY2FzdGluZyBTZXJ2aWNlOyAyMDE3OyBBcmxpbmd0b24sIFZBIl0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAxNyJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJBY2FkZW1pYyBWaWRlbyBPbmxpbmUgKEFWT04pIiwidXJsIjoiaHR0cHM6Ly9uYTA2LmFsbWEuZXhsaWJyaXNncm91cC5jb20vdmlldy91cmVzb2x2ZXIvMDFNSVRfSU5TVC9vcGVudXJsP3UuaWdub3JlX2RhdGVfY292ZXJhZ2U9dHJ1ZVx1MDAyNnBvcnRmb2xpb19waWQ9NTM1NTgyNzMwNTAwMDY3NjFcdTAwMjZGb3JjZV9kaXJlY3Q9dHJ1ZSJ9XSwibm90ZXMiOlt7ImtpbmQiOiJUaXRsZSBTdGF0ZW1lbnQgb2YgUmVzcG9uc2liaWxpdHkiLCJ2YWx1ZSI6WyJleGVjdXRpdmUgcHJvZHVjZXIgXHUwMDI2IGRpcmVjdG9yLCBMYXVyaWUgRG9ubmVsbHkgOyBXR0JIIEVkdWNhdGlvbmFsIEZvdW5kYXRpb24iXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiVGl0bGUgZnJvbSByZXNvdXJjZSBkZXNjcmlwdGlvbiBwYWdlICh2aWV3ZWQgU2VwdGVtYmVyIDA1LCAyMDE5KSJdfSx7ImtpbmQiOiJQYXJ0aWNpcGFudCBvciBQZXJmb3JtZXIgTm90ZSIsInZhbHVlIjpbIk1pbmcgVHNhaSwgaG9zdCA7IFJpY2sgQmF5bGVzcywgZ3Vlc3QiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6InN1bW1hcnkiLCJtYXRjaGVkUGhyYXNlcyI6WyJQQlMncyBvd24gY2hlZiBSaWNrIEJheWxlc3Mgc2hhcmVzIGhpcyBNZXhpY2FuIGZsYXZvcnMgd2l0aCBzb21lIE1leGljYW4gU3RyZWV0IENvcm4gXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSB3aXRoIEhvbWVtYWRlIl19LHsibWF0Y2hlZEZpZWxkIjoic3ViamVjdHMudmFsdWUiLCJtYXRjaGVkUGhyYXNlcyI6WyJcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkzNTEyNzAyNjYwNjc2MSIsInN1bW1hcnkiOlsiUEJTJ3Mgb3duIGNoZWYgUmljayBCYXlsZXNzIHNoYXJlcyBoaXMgTWV4aWNhbiBmbGF2b3JzIHdpdGggc29tZSBNZXhpY2FuIFN0cmVldCBDb3JuIFRhY29zIHdpdGggSG9tZW1hZGUgQ29ybiBUb3J0aWxsYXMsIHdoaWxlIE1pbmcgbWFrZXMgaGlzIG5ldyBFZ2cgT21lbGV0IFdyYXAgd2l0aCBhIENvcm4sIFRvbWF0bywgV2F0ZXJjcmVzcywgYW5kIEZlcm1lbnRlZCBCbGFjayBCZWFuIFNhbHNhLiJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1NDI3NTMyNjA2NzYxIiwidGl0bGUiOiJUcnkgVGhhaSB0b25pZ2h0LiBTZWFzb24gMSwgZXBpc29kZSA0LCBCZWVmIExhYWIiLCJjb250ZW50VHlwZSI6WyJQcm9qZWN0ZWQgbWVkaXVtIl0sImNvbnRyaWJ1dG9ycyI6W3sia2luZCI6Im9uLXNjcmVlbiBwcmVzZW50ZXIiLCJ2YWx1ZSI6Ikd1bnRvbmcsIE51Y2hqYW5hIEplYW4ifSx7ImtpbmQiOiJkaXJlY3RvciIsInZhbHVlIjoiUmFpbmV5LCBEZWFuIn0seyJraW5kIjoib24tc2NyZWVuIHByZXNlbnRlciIsInZhbHVlIjoiUmFpbmV5LCBEZWFuIn0seyJraW5kIjoicHJvZHVjdGlvbiBjb21wYW55IiwidmFsdWUiOiJSYWluZXkgTWVkaWEifSx7ImtpbmQiOiJwdWJsaXNoZXIiLCJ2YWx1ZSI6IlJhaW5leSBNZWRpYSJ9XSwicHVibGljYXRpb25JbmZvcm1hdGlvbiI6WyJSYWluZXkgTWVkaWE7IDIwMTg7IFtQbGFjZSBvZiBwdWJsaWNhdGlvbiBub3QgaWRlbnRpZmllZF0iXSwiZGF0ZXMiOlt7ImtpbmQiOiJQdWJsaWNhdGlvbiBkYXRlIiwidmFsdWUiOiIyMDE4In1dLCJsaW5rcyI6W3sia2luZCI6IkRpZ2l0YWwgb2JqZWN0IFVSTCIsInJlc3RyaWN0aW9ucyI6bnVsbCwidGV4dCI6IkFjYWRlbWljIFZpZGVvIE9ubGluZSAoQVZPTikiLCJ1cmwiOiJodHRwczovL25hMDYuYWxtYS5leGxpYnJpc2dyb3VwLmNvbS92aWV3L3VyZXNvbHZlci8wMU1JVF9JTlNUL29wZW51cmw/dS5pZ25vcmVfZGF0ZV9jb3ZlcmFnZT10cnVlXHUwMDI2cG9ydGZvbGlvX3BpZD01MzY1NTY5NDYzMDAwNjc2MVx1MDAyNkZvcmNlX2RpcmVjdD10cnVlIn1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIltob3N0cywgTnVjaGphbmEgXCJKZWFuXCIgR3VudG9uZywgRGVhbiBSYWluZXldIDsgW2RpcmVjdG9yLCBEZWFuIFJhaW5leV0iXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiVGl0bGUgZnJvbSByZXNvdXJjZSBkZXNjcmlwdGlvbiBwYWdlICh2aWV3ZWQgSmFudWFyeSAxNywgMjAyMykiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6InN1bW1hcnkiLCJtYXRjaGVkUGhyYXNlcyI6WyJKZWFuIFx1MDAyNiBEZWFuIHByZXBhcmUgVGhhaSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlIC0gZXIsIHdlIG1lYW4gbWluY2VkIEJlZWYgTGFhYiBzZXJ2ZWQgaW4gbGV0dHVjZSBsZWFmLiJdfV0sInByb3ZpZGVyIjpudWxsLCJyaWdodHMiOm51bGwsInNvdXJjZUxpbmsiOiJodHRwczovL21pdC5wcmltby5leGxpYnJpc2dyb3VwLmNvbS9kaXNjb3ZlcnkvZnVsbGRpc3BsYXk/dmlkPTAxTUlUX0lOU1Q6TUlUXHUwMDI2ZG9jaWQ9YWxtYTk5MzU0Mjc1MzI2MDY3NjEiLCJzdW1tYXJ5IjpbIkplYW4gXHUwMDI2IERlYW4gcHJlcGFyZSBUaGFpIFRhY29zIC0gZXIsIHdlIG1lYW4gbWluY2VkIEJlZWYgTGFhYiBzZXJ2ZWQgaW4gbGV0dHVjZSBsZWFmLiJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1NDIzNzEwMzA2NzYxIiwidGl0bGUiOiJNYW1hY2l0YSA6IHJlY2lwZXMgY2VsZWJyYXRpbmcgbGlmZSBhcyBhIE1leGljYW4gaW1taWdyYW50IGluIEFtZXJpY2EiLCJjb250ZW50VHlwZSI6WyJMYW5ndWFnZSBtYXRlcmlhbCJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJhdXRob3IiLCJ2YWx1ZSI6IlBvbnMsIEFuZHJlYSJ9XSwicHVibGljYXRpb25JbmZvcm1hdGlvbiI6WyJQcmluY2V0b24gQXJjaGl0ZWN0dXJhbCBQcmVzczsgWzIwMjJdOyBOZXcgWW9yayIsIsKpMjAyMiJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMjIifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkFuZHJlYSBQb25zIDsgZm9yZXdvcmQgYnkgSGV0dHkgTHVpIE1jS2lubm9uIl19LHsia2luZCI6IkJpYmxpb2dyYXBoeSBOb3RlIiwidmFsdWUiOlsiSW5jbHVkZXMgYmlibGlvZ3JhcGhpY2FsIHJlZmVyZW5jZXMgYW5kIGluZGV4Il19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIldoZXJlIGFyZSB0aGUgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNldGFjb3NcdTAwM2Mvc3Bhblx1MDAzZT8iXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1NDIzNzEwMzA2NzYxIiwic3VtbWFyeSI6WyJcIkEgbG92ZSBsZXR0ZXIgdG8gYXV0aG9yIEFuZHJlYSBQb25zJ3MgbmF0aXZlIE1leGljbywgd2VhdmluZyBzdG9yaWVzIG9mIGhlciBmYW1pbHkncyBpbW1pZ3JhdGlvbiB0byB0aGUgVW5pdGVkIFN0YXRlcyB3aXRoIDc1IGRlbGljaW91cyByZWNpcGVzIGZyb20gdGhyZWUgZ2VuZXJhdGlvbnMgb2Ygd29tZW4gaW4gaGVyIGZhbWlseVwiLS0iXX0seyJ0aW1kZXhSZWNvcmRJZCI6ImFsbWE6OTkzNTU0MTU0NzMwNjc2MSIsInRpdGxlIjoiSW5kaWdlbm91cyBzdG9yaWVzLiBTZWFzb24gNCwgZXBpc29kZSAyLCBJbmRpZ2Vub3VzIGN1aXNpbmUgaW4gVG9yb250byIsImNvbnRlbnRUeXBlIjpbIlByb2plY3RlZCBtZWRpdW0iXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiZGlyZWN0b3IiLCJ2YWx1ZSI6IllhbmNoeWssIEJyYW5keSJ9LHsia2luZCI6Imhvc3QiLCJ2YWx1ZSI6IllhbmNoeWssIEJyYW5keSJ9LHsia2luZCI6InByb2R1Y2VyIiwidmFsdWUiOiJZYW5jaHlrLCBCcmFuZHkifSx7ImtpbmQiOiJzY3JlZW53cml0ZXIiLCJ2YWx1ZSI6IllhbmNoeWssIEJyYW5keSJ9LHsia2luZCI6InByb2R1Y3Rpb24gY29tcGFueSIsInZhbHVlIjoiQnJhbmR5IFkgUHJvZHVjdGlvbnMifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiQnJhbmR5IFkgUHJvZHVjdGlvbnM7IDIwMjM7IEVkbW9udG9uLCBBQiJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMjMifV0sImxpbmtzIjpbeyJraW5kIjoiRGlnaXRhbCBvYmplY3QgVVJMIiwicmVzdHJpY3Rpb25zIjpudWxsLCJ0ZXh0IjoiQWNhZGVtaWMgVmlkZW8gT25saW5lIChBVk9OKSIsInVybCI6Imh0dHBzOi8vbmEwNi5hbG1hLmV4bGlicmlzZ3JvdXAuY29tL3ZpZXcvdXJlc29sdmVyLzAxTUlUX0lOU1Qvb3BlbnVybD91Lmlnbm9yZV9kYXRlX2NvdmVyYWdlPXRydWVcdTAwMjZwb3J0Zm9saW9fcGlkPTUzNjg2NTM3NzgwMDA2NzYxXHUwMDI2Rm9yY2VfZGlyZWN0PXRydWUifV0sIm5vdGVzIjpbeyJraW5kIjoiVGl0bGUgU3RhdGVtZW50IG9mIFJlc3BvbnNpYmlsaXR5IiwidmFsdWUiOlsiZGlyZWN0b3IvcHJvZHVjZXIvd3JpdGVyLCBCcmFuZHkgWWFuY2h5ayJdfSx7ImtpbmQiOiJHZW5lcmFsIE5vdGUiLCJ2YWx1ZSI6WyJUaXRsZSBmcm9tIHJlc291cmNlIGRlc2NyaXB0aW9uIHBhZ2UgKHZpZXdlZCBPY3RvYmVyIDMwLCAyMDIzKSJdfSx7ImtpbmQiOiJQYXJ0aWNpcGFudCBvciBQZXJmb3JtZXIgTm90ZSIsInZhbHVlIjpbIkhvc3Q6IEJyYW5keSBZYW5jaHlrIl19LHsia2luZCI6IlNvdXJjZSBvZiBEZXNjcmlwdGlvbiBOb3RlIiwidmFsdWUiOlsiVGl0bGUgZnJvbSByZXNvdXJjZSBkZXNjcmlwdGlvbiBwYWdlICh2aWV3ZWQgTm92ZW1iZXIgMDksIDIwMjMpIl19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJzdW1tYXJ5IiwibWF0Y2hlZFBocmFzZXMiOlsiQ2FuYWRpYW4gam91cm5hbGlzdCBCcmFuZHkgWWFuY2h5ayB0YXN0ZXMgSW5kaWdlbm91cyBjdWlzaW5lIHdoaWxlIG1ha2luZyBJbmRpYW4gXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSB3aXRoIENoZWYgU2hhd24iXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1NTQxNTQ3MzA2NzYxIiwic3VtbWFyeSI6WyJDYW5hZGlhbiBqb3VybmFsaXN0IEJyYW5keSBZYW5jaHlrIHRhc3RlcyBJbmRpZ2Vub3VzIGN1aXNpbmUgd2hpbGUgbWFraW5nIEluZGlhbiBUYWNvcyB3aXRoIENoZWYgU2hhd24gQWRsZXIgYXQgdGhlIFBvdyBXb3cgQ2Fmw6kuIl19LHsidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MDAyMzA1Mjc5MDEwNjc2MSIsInRpdGxlIjoiU2VydmUgeW91cnNlbGYgOiBuaWdodGx5IGFkdmVudHVyZXMgaW4gY29va2luZyBmb3Igb25lIiwiY29udGVudFR5cGUiOlsiTGFuZ3VhZ2UgbWF0ZXJpYWwiXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiTm90IHNwZWNpZmllZCIsInZhbHVlIjoiWW9uYW4sIEpvZSJ9XSwicHVibGljYXRpb25JbmZvcm1hdGlvbiI6WyJUZW4gU3BlZWQgUHJlc3M7IGMyMDExOyBCZXJrZWxleSBbQ2FsaWYuXSJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMTEifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkpvZSBZb25hbiA7IHBob3RvZ3JhcGhzIGJ5IEVkIEFuZGVyc29uIl19LHsia2luZCI6IkdlbmVyYWwgTm90ZSIsInZhbHVlIjpbIlwiV2l0aCBvdmVyIDEwMCByZWNpcGVzIGZvciBib3RoIHdlZWtuaWdodCBzdGFwbGVzIGFuZCB3ZWVrZW5kIHByb2plY3RzXCItLUNvdmVyIl19LHsia2luZCI6IkdlbmVyYWwgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGluZGV4Il19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIlx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTAwMjMwNTI3OTAxMDY3NjEiLCJzdW1tYXJ5IjpbIkEgY29sbGVjdGlvbiBvZiBvbmUgaHVuZHJlZCByZWNpcGVzIGZvciBkaXNoZXMgdGhhdCBzZXJ2ZSBvbmUgaW5kaXZpZHVhbCwgd2l0aCBzdGVwLWJ5LXN0ZXAgaW5zdHJ1Y3Rpb25zIGFuZCBwaG90b2dyYXBocy4iXX0seyJ0aW1kZXhSZWNvcmRJZCI6ImFsbWE6OTkwMDI4NTU2ODIwMTA2NzYxIiwidGl0bGUiOiJDb29sIGJlYW5zIDogdGhlIHVsdGltYXRlIGd1aWRlIHRvIGNvb2tpbmcgd2l0aCB0aGUgd29ybGQncyBtb3N0IHZlcnNhdGlsZSBwbGFudC1iYXNlZCBwcm90ZWluLCB3aXRoIDEyNSByZWNpcGVzIiwiY29udGVudFR5cGUiOlsiTGFuZ3VhZ2UgbWF0ZXJpYWwiXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiYXV0aG9yIiwidmFsdWUiOiJZb25hbiwgSm9lIn0seyJraW5kIjoicGhvdG9ncmFwaGVyIiwidmFsdWUiOiJQaWNrLCBBdWJyaWUifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiVGVuIFNwZWVkIFByZXNzOyBbMjAyMF07IENhbGlmb3JuaWEgOyJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMjAifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkpvZSBZb25hbiA7IHBob3RvZ3JhcGhzIGJ5IEF1YnJpZSBQaWNrIl19LHsia2luZCI6IkJpYmxpb2dyYXBoeSBOb3RlIiwidmFsdWUiOlsiSW5jbHVkZXMgYmlibGlvZ3JhcGhpY2FsIHJlZmVyZW5jZXMgYW5kIGluZGV4Il19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIkJ1cmdlcnMsIHNhbmR3aWNoZXMsIHdyYXBzLCBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2V0YWNvc1x1MDAzYy9zcGFuXHUwMDNlIFx1MDAyNiBhIHBpenphIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkwMDI4NTU2ODIwMTA2NzYxIiwic3VtbWFyeSI6WyJcIkEgbW9kZXJuIGFuZCBmcmVzaCBsb29rIGF0IHRoZSBkaXZlcnNlIHdvcmxkIG9mIGJlYW5zIGFuZCBwdWxzZXMsIGluY2x1ZGluZyAxMjUgcmVjaXBlcyBmb3IgZ2xvYmFsbHkgaW5zcGlyZWQgdmVnZXRhcmlhbiBtYWlucywgc25hY2tzLCBzb3VwcywgYW5kIGV2ZW4gZGVzc2VydHNcIi0tIl19LHsidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MzU0NDYwNDE0MDY3NjEiLCJ0aXRsZSI6IlRyZWFzdXJlcyBvZiB0aGUgTWV4aWNhbiB0YWJsZSA6IGNsYXNzaWMgcmVjaXBlcywgbG9jYWwgc2VjcmV0cyIsImNvbnRlbnRUeXBlIjpbIkxhbmd1YWdlIG1hdGVyaWFsIl0sImNvbnRyaWJ1dG9ycyI6W3sia2luZCI6ImF1dGhvciIsInZhbHVlIjoiSmluaWNoLCBQYXRpIn0seyJraW5kIjoicGhvdG9ncmFwaGVyIiwidmFsdWUiOiJNb3NpZXIsIEFuZ2llIn1dLCJwdWJsaWNhdGlvbkluZm9ybWF0aW9uIjpbIkhvdWdodG9uIE1pZmZsaW4gSGFyY291cnQ7IDIwMjE7IEJvc3RvbiIsIsKpMjAyMSJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMjEifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIlBhdGkgSmluaWNoIDsgcGhvdG9ncmFwaHMgYnkgQW5naWUgTW9zaWVyIl19LHsia2luZCI6IkdlbmVyYWwgTm90ZSIsInZhbHVlIjpbIk1hcCBvbiBsaW5lciBwYXBlcnMiXX0seyJraW5kIjoiQmlibGlvZ3JhcGh5IE5vdGUiLCJ2YWx1ZSI6WyJJbmNsdWRlcyBpbmRleCJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbIkZyb20gQmFqYSBsb2JzdGVyIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZXRhY29zXHUwMDNjL3NwYW5cdTAwM2UgdG8gT2F4YWNhbi1zdHlsZSBncmlsbGVkIGZsYW5rIHN0ZWFrLCB0aGVzZSByZWNpcGVzIHJlcHJlc2VudCB0aGUgY3VsaW5hcnkgZGl2ZXJzaXR5Il19LHsibWF0Y2hlZEZpZWxkIjoiY29udGVudHMiLCJtYXRjaGVkUGhyYXNlcyI6WyJcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2VUYWNvc1x1MDAzYy9zcGFuXHUwMDNlLCBxdWVzYWRpbGxhcywgYnVycml0b3MsIGFuZCB0YW1hbGVzIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkzNTQ0NjA0MTQwNjc2MSIsInN1bW1hcnkiOlsiXCJUaGUgJ2J1b3lhbnQgYW5kIGJyYWlueSBNZXhpY2FuIGNvb2tpbmcgYXV0aG9yaXR5JyAoTmV3IFlvcmsgVGltZXMpIGFuZCBzdGFyIG9mIHRoZSB0aHJlZS10aW1lIEphbWVzIEJlYXJkIEF3YXJkLXdpbm5pbmcgUEJTIHNlcmllcyBQYXRpJ3MgTWV4aWNhbiBUYWJsZSBicmluZ3MgdG9nZXRoZXIgbW9yZSB0aGFuIDE1MCBpY29uaWMgZGlzaGVzIHRoYXQgZGVmaW5lIHRoZSBjb3VudHJ5J3MgY3Vpc2luZS4gQWx0aG91Z2ggbWFueSBvZiB1cyBjYW4gcmF0dGxlIG9mZiBvdXIgZmF2b3JpdGUgYXV0aGVudGljIE1leGljYW4gZGlzaGVzLCB3ZSBtaWdodCBiZSBoYXJkIHByZXNzZWQgdG8gbmFtZSBtb3JlIHRoYW4gdGVuLiBXaGljaCBpcyBwcmVwb3N0ZXJvdXMsIGdpdmVuIHRoYXQgTWV4aWNvIGhhcyBhIHJpY2ggY3VsaW5hcnkgaGlzdG9yeSBzdHJldGNoaW5nIGJhY2sgdGhvdXNhbmRzIG9mIHllYXJzLiBGb3IgaGVyIG5ld2VzdCBib29rLCBQYXRpIEppbmljaCBicmluZ3MgaG9tZSB0aGUgc2lnbmF0dXJlIHJlY2lwZXMgdGhhdCBob21lIGNvb2tzLCBtYXJrZXQgdmVuZG9ycywgYW5kIGNoZWZzIGhhdmUgc2hhcmVkIHdpdGggaGVyIGFzIHNoZSBjcmlzc2Nyb3NzZWQgaGVyIG5hdGl2ZSBjb3VudHJ5IGZvciB0aGUgcGFzdCBkZWNhZGUuIEZyb20gQmFqYSBsb2JzdGVyIHRhY29zIHRvIE9heGFjYW4tc3R5bGUgZ3JpbGxlZCBmbGFuayBzdGVhaywgdGhlc2UgcmVjaXBlcyByZXByZXNlbnQgdGhlIGN1bGluYXJ5IGRpdmVyc2l0eSBvZiB0aGUgbmF0aW9uIHRoYXQgaGFzLCBkZXBlbmRpbmcgb24gaG93IHlvdSBjb3VudCB0aGVtLCBhcyBtYW55IGFzIHRoaXJ0eS10d28gZGlmZmVyZW50IGN1aXNpbmVzLiBFYWNoIHJlY2lwZSBpcyBhIGNsYXNzaWMuIEVhY2ggb25lIGNvbWVzIHdpdGggYSBzdG9yeSB0b2xkIGluIFBhdGkncyB3YXJtLCByZWxhdGFibGUgc3R5bGUuIEFuZCBlYWNoIGhhcyBiZWVuIHRlc3RlZCBpbiBQYXRpJ3MgQW1lcmljYW4ga2l0Y2hlbiB0byBlbnN1cmUgaXQgaXMgdGhlIGJlc3Qgb2YgaXRzIGtpbmRcIi0tIl19LHsidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MzUwNTU0NjM3MDY3NjEiLCJ0aXRsZSI6Ik1vcmUgZm9vZCBzdHlsaW5nIGZvciBwaG90b2dyYXBoZXJzIGFuZCBzdHlsaXN0cyA6IGEgZ3VpZGUgdG8gY3JlYXRpbmcgeW91ciBvd24gYXBwZXRpemluZyBhcnQiLCJjb250ZW50VHlwZSI6WyJMYW5ndWFnZSBtYXRlcmlhbCJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJOb3Qgc3BlY2lmaWVkIiwidmFsdWUiOiJCZWxsaW5naGFtLCBMaW5kYSJ9LHsia2luZCI6Ik5vdCBzcGVjaWZpZWQiLCJ2YWx1ZSI6IkJ5YmVlLCBKZWFuIEFubiJ9LHsia2luZCI6Ik5vdCBzcGVjaWZpZWQiLCJ2YWx1ZSI6IlJvZ2VycywgQnJhZCBHIn1dLCJwdWJsaWNhdGlvbkluZm9ybWF0aW9uIjpbIkZvY2FsIFByZXNzOyAyMDEyOyBXYWx0aGFtLCBNYXNzLiJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMTIifV0sImxpbmtzIjpbeyJraW5kIjoiRGlnaXRhbCBvYmplY3QgVVJMIiwicmVzdHJpY3Rpb25zIjpudWxsLCJ0ZXh0IjoiTydSZWlsbHkgT25saW5lIExlYXJuaW5nOiBBY2FkZW1pYy9QdWJsaWMgTGlicmFyeSBFZGl0aW9uIiwidXJsIjoiaHR0cHM6Ly9uYTA2LmFsbWEuZXhsaWJyaXNncm91cC5jb20vdmlldy91cmVzb2x2ZXIvMDFNSVRfSU5TVC9vcGVudXJsP3UuaWdub3JlX2RhdGVfY292ZXJhZ2U9dHJ1ZVx1MDAyNnBvcnRmb2xpb19waWQ9NTM1NDI4ODIyNjAwMDY3NjFcdTAwMjZGb3JjZV9kaXJlY3Q9dHJ1ZSJ9XSwibm90ZXMiOlt7ImtpbmQiOiJUaXRsZSBTdGF0ZW1lbnQgb2YgUmVzcG9uc2liaWxpdHkiLCJ2YWx1ZSI6WyJMaW5kYSBCZWxsaW5naGFtLCBKZWFuIEFubiBCeWJlZSwgQnJhZCBHLiBSb2dlcnMiXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiSW5jbHVkZXMgaW5kZXgiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6ImNvbnRlbnRzIiwibWF0Y2hlZFBocmFzZXMiOlsiXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSJdfV0sInByb3ZpZGVyIjpudWxsLCJyaWdodHMiOm51bGwsInNvdXJjZUxpbmsiOiJodHRwczovL21pdC5wcmltby5leGxpYnJpc2dyb3VwLmNvbS9kaXNjb3ZlcnkvZnVsbGRpc3BsYXk/dmlkPTAxTUlUX0lOU1Q6TUlUXHUwMDI2ZG9jaWQ9YWxtYTk5MzUwNTU0NjM3MDY3NjEiLCJzdW1tYXJ5IjpbIlRoYW5rcyB0byB0aGUgZXhwbG9kaW5nIHBvcHVsYXJpdHkgb2YgZm9vZC1iYXNlZCB0ZWxldmlzaW9uIHNob3dzIChlbnRpcmUgbmV0d29ya3MsIGV2ZW4pLCB3ZWJzaXRlcywgYm9va3MsIGFuZCBtYWdhemluZXMsIGZvb2Qgc3R5bGlzdHMgYW5kIGZvb2QgcGhvdG9ncmFwaGVycyBhcmUgaW4gbW9yZSBkZW1hbmQgdG9kYXkgdGhhbiBldmVyIGJlZm9yZS4gV2hpbGUgdGhlcmUgYXJlIG1hbnkgYW1hemluZyBvcHBvcnR1bml0aWVzIGZvciBjcmVhdGl2ZSBwcm9mZXNzaW9uYWxzIHRvIHNob3djYXNlIHRoZWlyIHdvcmsgaW4gYWRzLCBjb29rYm9va3MsIGJsb2dzLCBhbmQgZm9vZCBwYWNrYWdpbmcsIHRoZXJlIGlzIGFsc28gbW9yZSBjb21wZXRpdGlvbiBmb3IgdGhlc2Ugam9icy4gV2hldGhlciB5b3UgYXJlIGEgZm9vZCBzdHlsaXN0IHdobyB3b3JrcyBhbG9uZ3NpZGUgcGhvdG9ncmFwaGVycyBvciBhIGZvb2QgcGhvdG9ncmFwaGVyIHlvdXJzZWxmLCB5b3UnbGwgZmluZCBldmVyeXRoaW5nIHlvdSBuZWVkIHRvIGtub3cgdG8gZ2l2ZSB5b3VyIHBvcnRmb2xpbyB0aGF0IGxpdHRsZSBleHRyYSBwdXNoIGluIHRoaXMgZXhwZXJ0IGd1aWRlIGJ5ICJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1MTI3MDI4MjA2NzYxIiwidGl0bGUiOiJTaW1wbHkgTWluZy4gU2Vhc29uIDE1LCBlcGlzb2RlIDMsIEFhcsOzbiBTYW5jaGV6IiwiY29udGVudFR5cGUiOlsiUHJvamVjdGVkIG1lZGl1bSJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJob3N0IiwidmFsdWUiOiJUc2FpLCBNaW5nIn0seyJraW5kIjoiZGlyZWN0b3IiLCJ2YWx1ZSI6IkRvbm5lbGx5LCBMYXVyaWUifSx7ImtpbmQiOiJwcm9kdWNlciIsInZhbHVlIjoiRG9ubmVsbHksIExhdXJpZSJ9LHsia2luZCI6InNwZWFrZXIiLCJ2YWx1ZSI6IlPDoW5jaGV6LCBBYXLDs24ifSx7ImtpbmQiOiJwcm9kdWN0aW9uIGNvbXBhbnkiLCJ2YWx1ZSI6IldHQkggRWR1Y2F0aW9uYWwgRm91bmRhdGlvbiJ9XSwicHVibGljYXRpb25JbmZvcm1hdGlvbiI6WyJQdWJsaWMgQnJvYWRjYXN0aW5nIFNlcnZpY2U7IDIwMTc7IEFybGluZ3RvbiwgVkEiXSwiZGF0ZXMiOlt7ImtpbmQiOiJQdWJsaWNhdGlvbiBkYXRlIiwidmFsdWUiOiIyMDE3In1dLCJsaW5rcyI6W3sia2luZCI6IkRpZ2l0YWwgb2JqZWN0IFVSTCIsInJlc3RyaWN0aW9ucyI6bnVsbCwidGV4dCI6IkFjYWRlbWljIFZpZGVvIE9ubGluZSAoQVZPTikiLCJ1cmwiOiJodHRwczovL25hMDYuYWxtYS5leGxpYnJpc2dyb3VwLmNvbS92aWV3L3VyZXNvbHZlci8wMU1JVF9JTlNUL29wZW51cmw/dS5pZ25vcmVfZGF0ZV9jb3ZlcmFnZT10cnVlXHUwMDI2cG9ydGZvbGlvX3BpZD01MzU1ODI3MzAxMDAwNjc2MVx1MDAyNkZvcmNlX2RpcmVjdD10cnVlIn1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbImV4ZWN1dGl2ZSBwcm9kdWNlciBcdTAwMjYgZGlyZWN0b3IsIExhdXJpZSBEb25uZWxseSA7IFdHQkggRWR1Y2F0aW9uYWwgRm91bmRhdGlvbiJdfSx7ImtpbmQiOiJHZW5lcmFsIE5vdGUiLCJ2YWx1ZSI6WyJUaXRsZSBmcm9tIHJlc291cmNlIGRlc2NyaXB0aW9uIHBhZ2UgKHZpZXdlZCBTZXB0ZW1iZXIgMDUsIDIwMTkpIl19LHsia2luZCI6IlBhcnRpY2lwYW50IG9yIFBlcmZvcm1lciBOb3RlIiwidmFsdWUiOlsiTWluZyBUc2FpLCBob3N0IDsgQWFyw7NuIFPDoW5jaGV6LCBndWVzdCJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbIkFhcsOzbiBTw6FuY2hleiAtLSBqdWRnZSBvbiBDaG9wcGVkIGFuZCBNYXN0ZXJjaGVmIC0tIHZpc2l0cyBNaW5nIGluIGhpcyBsb2Z0IHRvIGNvb2sgaGlzIEFsYsOzbmRpZ2FzIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1MTI3MDI4MjA2NzYxIiwic3VtbWFyeSI6WyJPbmUgb2YgdGhlIHdvcmxkJ3MgbW9zdCBkaXN0aW5ndWlzaGVkIExhdGluIGNoZWZzLCBBYXLDs24gU8OhbmNoZXogLS0ganVkZ2Ugb24gQ2hvcHBlZCBhbmQgTWFzdGVyY2hlZiAtLSB2aXNpdHMgTWluZyBpbiBoaXMgbG9mdCB0byBjb29rIGhpcyBBbGLDs25kaWdhcyBUYWNvcywgd2hpbGUgTWluZyBtYWtlcyBCZWVmIGFuZCBTYWx0ZWQgV2F0ZXJjcmVzcyBTY2FsbGlvbiBQYW5jYWtlcy4iXX0seyJ0aW1kZXhSZWNvcmRJZCI6ImFsbWE6OTkzNTc2MjExMzMwNjc2MSIsInRpdGxlIjoiRGVjZW50ZXJpbmcgc3ViamVjdGl2aXR5IGluIGV2ZXJ5ZGF5IGVhdGluZyBhbmQgZHJpbmtpbmcgOiBkaWdlc3RpbmcgcmVhbGl0eSIsImNvbnRlbnRUeXBlIjpbIkxhbmd1YWdlIG1hdGVyaWFsIl0sImNvbnRyaWJ1dG9ycyI6W3sia2luZCI6ImF1dGhvciIsInZhbHVlIjoiTGFyYSwgQWxpIn1dLCJwdWJsaWNhdGlvbkluZm9ybWF0aW9uIjpbIlJvdXRsZWRnZTsgMjAyMTsgT3hmb3JkLCBFbmdsYW5kIDsiXSwiZGF0ZXMiOlt7ImtpbmQiOiJQdWJsaWNhdGlvbiBkYXRlIiwidmFsdWUiOiIyMDIxIn1dLCJsaW5rcyI6W3sia2luZCI6IkRpZ2l0YWwgb2JqZWN0IFVSTCIsInJlc3RyaWN0aW9ucyI6bnVsbCwidGV4dCI6IlRheWxvciBcdTAwMjYgRnJhbmNpcyBFdmlkZW5jZSBCYXNlZCBFYm9vayBDb2xsZWN0aW9uIiwidXJsIjoiaHR0cHM6Ly9uYTA2LmFsbWEuZXhsaWJyaXNncm91cC5jb20vdmlldy91cmVzb2x2ZXIvMDFNSVRfSU5TVC9vcGVudXJsP3UuaWdub3JlX2RhdGVfY292ZXJhZ2U9dHJ1ZVx1MDAyNnBvcnRmb2xpb19waWQ9NTM3MDI4MDc1MDAwMDY3NjFcdTAwMjZGb3JjZV9kaXJlY3Q9dHJ1ZSJ9XSwibm90ZXMiOlt7ImtpbmQiOiJUaXRsZSBTdGF0ZW1lbnQgb2YgUmVzcG9uc2liaWxpdHkiLCJ2YWx1ZSI6WyJBbGkgTGFyYSJdfSx7ImtpbmQiOiJCaWJsaW9ncmFwaHkgTm90ZSIsInZhbHVlIjpbIkluY2x1ZGVzIGJpYmxpb2dyYXBoaWNhbCByZWZlcmVuY2VzIGFuZCBpbmRleCJdfSx7ImtpbmQiOiJTb3VyY2Ugb2YgRGVzY3JpcHRpb24gTm90ZSIsInZhbHVlIjpbIkRlc2NyaXB0aW9uIGJhc2VkIG9uIHByaW50IHZlcnNpb24gcmVjb3JkIl19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJzdW1tYXJ5IiwibWF0Y2hlZFBocmFzZXMiOlsiVGhlIGF1dGhvciB1c2VzIGV4YW1wbGVzIGZyb20gZGFpbHkgbGlmZSByZWxhdGVkIHRvIGVhdGluZyBhbmQgZHJpbmtpbmcgaGFiaXRzIGxpa2UsICdlYXRpbmcgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNldGFjb3NcdTAwM2Mvc3Bhblx1MDAzZScgb3IiXX0seyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIjEgXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSBhbmQgaGVhdCJdfV0sInByb3ZpZGVyIjpudWxsLCJyaWdodHMiOm51bGwsInNvdXJjZUxpbmsiOiJodHRwczovL21pdC5wcmltby5leGxpYnJpc2dyb3VwLmNvbS9kaXNjb3ZlcnkvZnVsbGRpc3BsYXk/dmlkPTAxTUlUX0lOU1Q6TUlUXHUwMDI2ZG9jaWQ9YWxtYTk5MzU3NjIxMTMzMDY3NjEiLCJzdW1tYXJ5IjpbIlRoaXMgYm9vayBhbmFseXplcyB0aGUgY29uZmlndXJhdGlvbnMgb2YgcmVhbGl0eSBhcyBtYW5pZmVzdGVkIGluIGV2ZXJ5ZGF5IHByYWN0aWNlcyBvZiBlYXRpbmcgYW5kIGRyaW5raW5nLiBUaGUgYXV0aG9yIHVzZXMgZXhhbXBsZXMgZnJvbSBkYWlseSBsaWZlIHJlbGF0ZWQgdG8gZWF0aW5nIGFuZCBkcmlua2luZyBoYWJpdHMgbGlrZSwgJ2VhdGluZyB0YWNvcycgb3IgJ3Rha2luZyBhIHNob3Qgb2YgbWV6Y2FsJyB0byBvZmZlciBhbiBpbnRlcmZhY2Ugb2YgaW50ZXJhY3Rpb24gYmV0d2VlbiBib2R5IGFuZCBtaW5kIGNvbm5lY3RpbmcgYWxsIHNjYWxlcyBvZiByZWFsaXR5LiJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1OTYxMjY5MjA2NzYxIiwidGl0bGUiOiJEZWNlbnRlcmluZyBzdWJqZWN0aXZpdHkgaW4gZXZlcnlkYXkgZWF0aW5nIGFuZCBkcmlua2luZyA6IGRpZ2VzdGluZyByZWFsaXR5IiwiY29udGVudFR5cGUiOlsiTGFuZ3VhZ2UgbWF0ZXJpYWwiXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoiYXV0aG9yIiwidmFsdWUiOiJMYXJhLCBBbGkifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiUm91dGxlZGdlOyAyMDIxOyBBYmluZ2RvbiwgT3hvbiA7Il0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAyMSJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOm51bGwsInVybCI6Imh0dHBzOi8vd3d3LnRheWxvcmZyYW5jaXMuY29tL2Jvb2tzLzk3ODEwMDMwODIxOTQifSx7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJUYXlsb3IgXHUwMDI2IEZyYW5jaXMgRGlzY292ZXJ5IENvbGxlY3Rpb24iLCJ1cmwiOiJodHRwczovL3d3dy50YXlsb3JmcmFuY2lzLmNvbS9ib29rcy85NzgxMDAzMDgyMTk0In1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkFsaSBMYXJhIl19LHsia2luZCI6IkJpYmxpb2dyYXBoeSBOb3RlIiwidmFsdWUiOlsiSW5jbHVkZXMgYmlibGlvZ3JhcGhpY2FsIHJlZmVyZW5jZXMgYW5kIGluZGV4Il19LHsia2luZCI6IlNvdXJjZSBvZiBEZXNjcmlwdGlvbiBOb3RlIiwidmFsdWUiOlsiT25saW5lIHJlc291cmNlOyB0aXRsZSBmcm9tIGRpZ2l0YWwgdGl0bGUgcGFnZSAodmlld2VkIG9uIERlY2VtYmVyIDMwLCAyMDIwKSJdfV0sImhpZ2hsaWdodCI6W3sibWF0Y2hlZEZpZWxkIjoic3VtbWFyeSIsIm1hdGNoZWRQaHJhc2VzIjpbIlRoZSBhdXRob3IgdXNlcyBjb25jcmV0ZSBleGFtcGxlcyBmcm9tIGRhaWx5IGxpZmUgcmVsYXRlZCB0byBlYXRpbmcgYW5kIGRyaW5raW5nIGhhYml0c3N1Y2ggYXNcImVhdGluZyBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2V0YWNvc1x1MDAzYy9zcGFuXHUwMDNlIl19LHsibWF0Y2hlZEZpZWxkIjoiY29udGVudHMiLCJtYXRjaGVkUGhyYXNlcyI6WyIxIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZVRhY29zXHUwMDNjL3NwYW5cdTAwM2UgYW5kIGhlYXQiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1OTYxMjY5MjA2NzYxIiwic3VtbWFyeSI6WyJUaGlzIGltcG9ydGFudCBib29rIG9mZmVycyBhIG1vZGVsIHRvIGFuYWx5emUgdGhlIGNvbmZpZ3VyYXRpb25zIG9mIHJlYWxpdHkgYXMgbWFuaWZlc3RlZCBpbiBldmVyeWRheSBwcmFjdGljZXMgb2YgZWF0aW5nIGFuZCBkcmlua2luZyBpbiByZWxhdGlvbiB0byB0aGUgZGV2ZWxvcG1lbnQgb2YgaHVtYW4gc3ViamVjdGl2aXR5LiBUaGUgYXV0aG9yIHVzZXMgY29uY3JldGUgZXhhbXBsZXMgZnJvbSBkYWlseSBsaWZlIHJlbGF0ZWQgdG8gZWF0aW5nIGFuZCBkcmlua2luZyBoYWJpdHNzdWNoIGFzXCJlYXRpbmcgdGFjb3NcIiBvciBcInRha2luZyBhIHNob3Qgb2YgbWV6Y2FsXCIsIHRvIG9mZmVyIGFuIGludGVyZmFjZSBvZiBpbnRlcmFjdGlvbiBiZXR3ZWVuIGJvZHkvbWluZCBhbmQgbWF0ZXJpYWwgZW50aXRpZXMgY29ubmVjdGluZyBhbGwgc2NhbGVzIG9mIHJlYWxpdHkuIEJvcnJvd2luZyBzY2llbnRpZmljIGluc2lnaHRzIGZyb20gbW9sZWN1bGFyIGJpb2xvZ3kgYW5kIG5ldXJvc2NpZW5jZSwgY29tYmluZWQgd2l0aCBhIHRvdWNoIG9mIGRlY29sb25pYWwgc3Bpcml0LCB0aGUgYXV0aG9yIGV4YW1pbmVzIHNwZWNpZmljICdwcm9jZXNzZXMnIGFuZC9vciAnb2JqZWN0cycgdHJpZ2dlcmVkIGJ5IGVhdGluZyBhbmQgZHJpbmtpbmcgZXZlbnRzLCBzdWNoIGFzIHRoZSBwcm9kdWN0aW9uIG9mIGhlYXQgYXMgeW91IGVhdCBhIHRhY28sIG9yIHRoZSBpbnRlcmNoYW5nZSBvZiBrbm93bGVkZ2Ugd2hpbGUgZHJpbmtpbmcgbWV6Y2FsLiBUaGUgYm9vayBkZXZlbG9wcyBhbiBhcHByb2FjaCB0byBodW1hbiBzdWJqZWN0aXZpdHkgaW5mb3JtZWQgYnkgbWF0ZXJpYWwgYW5kIGFlc3RoZXRpYyBlbmNvdW50ZXJzIGJleW9uZCB0aGUgYW5hbHlzaXMgb2YgbGFuZ3VhZ2UsIHJlcHJlc2VudGF0aW9uLCBhbmQgc29jaWFsIHN0cnVjdHVyZXMgYW5kIGFpbXMgdG8gY29udHJpYnV0ZSB0byB0aGUgY29udGVtcG9yYXJ5IGxhbmRzY2FwZSBvZiBlZmZvcnRzIGRlY2VudGVyaW5nIG91ciB1bmRlcnN0YW5kaW5nIG9mIGJvdGggaHVtYW4gYW5kIG5vbi1odW1hbiBhZmZhaXJzLiBXaXRoIGl0cyBtdWx0aWRpbWVuc2lvbmFsIGV4cGxvcmF0aW9uIG9mIG91ciByZWxhdGlvbnNoaXAgd2l0aCBmb29kLCB0aGlzIGlzIHRob3VnaHQtcHJvdm9raW5nIHJlYWRpbmcgZm9yIHNjaG9sYXJzIGFuZCBzdHVkZW50cyBpbiBjcml0aWNhbCBwc3ljaG9sb2d5LCBwaGlsb3NvcGh5LCBhbmQgdGhlIHNvY2lhbCBzY2llbmNlcyJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTAwMTM0ODY5OTAxMDY3NjEiLCJ0aXRsZSI6Ik1hcmlhY2hpIG11c2ljIGluIEFtZXJpY2EgOiBleHBlcmllbmNpbmcgbXVzaWMsIGV4cHJlc3NpbmcgY3VsdHVyZSIsImNvbnRlbnRUeXBlIjpbIkxhbmd1YWdlIG1hdGVyaWFsIl0sImNvbnRyaWJ1dG9ycyI6W3sia2luZCI6Ik5vdCBzcGVjaWZpZWQiLCJ2YWx1ZSI6IlNoZWVoeSwgRGFuaWVsIn1dLCJwdWJsaWNhdGlvbkluZm9ybWF0aW9uIjpbIk94Zm9yZCBVbml2ZXJzaXR5IFByZXNzOyAyMDA2OyBOZXcgWW9yayJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMDYifV0sImxpbmtzIjpudWxsLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkRhbmllbCBTaGVlaHkiXX0seyJraW5kIjoiQmlibGlvZ3JhcGh5IE5vdGUiLCJ2YWx1ZSI6WyJJbmNsdWRlcyBiaWJsaW9ncmFwaGljYWwgcmVmZXJlbmNlcyAocC4gMTAwLTEwNikgYW5kIGluZGV4Il19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJjb250ZW50cyIsIm1hdGNoZWRQaHJhc2VzIjpbIjogXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNldGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSB3aXRoIGtldGNodXAgb3Igc2Fsc2E/IDogdGhlIGNoYWxsZW5nZSBvZiBjaGFuZ2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTAwMTM0ODY5OTAxMDY3NjEiLCJzdW1tYXJ5IjpudWxsfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1MDc0MDc4NTA2NzYxIiwidGl0bGUiOiJUaGF0J3MgdGhlIHRydXRoIiwiY29udGVudFR5cGUiOlsiTXVzaWNhbCBzb3VuZCByZWNvcmRpbmciXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoicGVyZm9ybWVyIiwidmFsdWUiOiJCb2FscywgUmljaGFyZCJ9XSwicHVibGljYXRpb25JbmZvcm1hdGlvbiI6WyJKU1AgUmVjb3JkczsgMjAwNTsgW1BsYWNlIG9mIHB1YmxpY2F0aW9uIG5vdCBpZGVudGlmaWVkXSJdLCJkYXRlcyI6W3sia2luZCI6IlB1YmxpY2F0aW9uIGRhdGUiLCJ2YWx1ZSI6IjIwMDUifV0sImxpbmtzIjpbeyJraW5kIjoiRGlnaXRhbCBvYmplY3QgVVJMIiwicmVzdHJpY3Rpb25zIjpudWxsLCJ0ZXh0IjoiTXVzaWMgT25saW5lOiBBbWVyaWNhbiBNdXNpYyAtIFVuaXRlZCBTdGF0ZXMiLCJ1cmwiOiJodHRwczovL25hMDYuYWxtYS5leGxpYnJpc2dyb3VwLmNvbS92aWV3L3VyZXNvbHZlci8wMU1JVF9JTlNUL29wZW51cmw/dS5pZ25vcmVfZGF0ZV9jb3ZlcmFnZT10cnVlXHUwMDI2cG9ydGZvbGlvX3BpZD01MzU0Njg5NDc4MDAwNjc2MVx1MDAyNkZvcmNlX2RpcmVjdD10cnVlIn1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIlJpY2hhcmQgQm9hbHMiXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiVGl0bGUgZnJvbSBjb3ZlciBpbWFnZSAodmlld2VkIE5vdmVtYmVyIDksIDIwMjEpIl19LHsia2luZCI6IkdlbmVyYWwgTm90ZSIsInZhbHVlIjpbIlN0cmVhbWluZyBhdWRpbyBmaWxlcyJdfSx7ImtpbmQiOiJQYXJ0aWNpcGFudCBvciBQZXJmb3JtZXIgTm90ZSIsInZhbHVlIjpbIlJpY2hhcmQgQm9hbHMsIGxlYWQgZ3VpdGFyLCB2b2NhbHMiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6ImNvbnRlbnRzIiwibWF0Y2hlZFBocmFzZXMiOlsiXHUwMDNjc3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiXHUwMDNlVGFjb3NcdTAwM2Mvc3Bhblx1MDAzZSBmb3IgdHdvIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkzNTA3NDA3ODUwNjc2MSIsInN1bW1hcnkiOm51bGx9LHsidGltZGV4UmVjb3JkSWQiOiJhbG1hOjk5MzUwODE3MzYzMDY3NjEiLCJ0aXRsZSI6IkN1bGluYXJ5IGpvdXJuZXlzLiBTZWFzb24gMiwgZXBpc29kZSA5LCBFbnJpcXVlIE9sdmVyYSA6IE1leGljbyIsImNvbnRlbnRUeXBlIjpbIlByb2plY3RlZCBtZWRpdW0iXSwiY29udHJpYnV0b3JzIjpbeyJraW5kIjoic3BlYWtlciIsInZhbHVlIjoiT2x2ZXJhLCBFbnJpcXVlIn0seyJraW5kIjoicHJvZHVjdGlvbiBjb21wYW55IiwidmFsdWUiOiJDYWJsZSBOZXdzIE5ldHdvcmsifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiQ05OIE5ld3NvdXJjZSBTYWxlczsgMjAxNjsgQXRsYW50YSwgR0EiXSwiZGF0ZXMiOlt7ImtpbmQiOiJQdWJsaWNhdGlvbiBkYXRlIiwidmFsdWUiOiIyMDE2In1dLCJsaW5rcyI6W3sia2luZCI6IkRpZ2l0YWwgb2JqZWN0IFVSTCIsInJlc3RyaWN0aW9ucyI6bnVsbCwidGV4dCI6IkFjYWRlbWljIFZpZGVvIE9ubGluZSAoQVZPTikiLCJ1cmwiOiJodHRwczovL25hMDYuYWxtYS5leGxpYnJpc2dyb3VwLmNvbS92aWV3L3VyZXNvbHZlci8wMU1JVF9JTlNUL29wZW51cmw/dS5pZ25vcmVfZGF0ZV9jb3ZlcmFnZT10cnVlXHUwMDI2cG9ydGZvbGlvX3BpZD01MzU0ODUxNTgxMDAwNjc2MVx1MDAyNkZvcmNlX2RpcmVjdD10cnVlIn1dLCJub3RlcyI6W3sia2luZCI6IlRpdGxlIFN0YXRlbWVudCBvZiBSZXNwb25zaWJpbGl0eSIsInZhbHVlIjpbIkNhYmxlIE5ld3MgTmV0d29yayJdfSx7ImtpbmQiOiJHZW5lcmFsIE5vdGUiLCJ2YWx1ZSI6WyJUaXRsZSBmcm9tIHJlc291cmNlIGRlc2NyaXB0aW9uIHBhZ2UgKHZpZXdlZCBNYXJjaCAwNiwgMjAxOSkiXX1dLCJoaWdobGlnaHQiOlt7Im1hdGNoZWRGaWVsZCI6InN1bW1hcnkiLCJtYXRjaGVkUGhyYXNlcyI6WyJjb25xdWlzdGFkb3JlcyBvZiBTcGFpbiB3aGljaCBoYXZlIGZ1c2VkIHRvZ2V0aGVyIGFuZCBhcmUgZm91bmQgdG9kYXkgaW4gc3RyZWV0cyBmaWxsZWQgd2l0aCB0b3J0YXMsIFx1MDAzY3NwYW4gY2xhc3M9XCJoaWdobGlnaHRcIlx1MDAzZXRhY29zXHUwMDNjL3NwYW5cdTAwM2UiXX1dLCJwcm92aWRlciI6bnVsbCwicmlnaHRzIjpudWxsLCJzb3VyY2VMaW5rIjoiaHR0cHM6Ly9taXQucHJpbW8uZXhsaWJyaXNncm91cC5jb20vZGlzY292ZXJ5L2Z1bGxkaXNwbGF5P3ZpZD0wMU1JVF9JTlNUOk1JVFx1MDAyNmRvY2lkPWFsbWE5OTM1MDgxNzM2MzA2NzYxIiwic3VtbWFyeSI6WyJUaGUgaGlzdG9yeSBvZiBNZXhpY28gaXMgb25lIHRoYXQgaXMgdG9sZCB0aHJvdWdoIGl0cyBjdWlzaW5lIC0gYm9sZCBmbGF2b3VycyBmcm9tIHRoZSBBenRlY3Mgb2YgTWVzb2FtZXJpY2EgYW5kIHRoZSBjb25xdWlzdGFkb3JlcyBvZiBTcGFpbiB3aGljaCBoYXZlIGZ1c2VkIHRvZ2V0aGVyIGFuZCBhcmUgZm91bmQgdG9kYXkgaW4gc3RyZWV0cyBmaWxsZWQgd2l0aCB0b3J0YXMsIHRhY29zIGFuZCB0YW1hbGVzLiJdfSx7InRpbWRleFJlY29yZElkIjoiYWxtYTo5OTM1NTE1MDU3MTA2NzYxIiwidGl0bGUiOiJUaGUgZ3JlYXQgQW1lcmljYW4gcmVjaXBlLiBTZWFzb24gMiwgZXBpc29kZSA3IiwiY29udGVudFR5cGUiOlsiUHJvamVjdGVkIG1lZGl1bSJdLCJjb250cmlidXRvcnMiOlt7ImtpbmQiOiJob3N0IiwidmFsdWUiOiJEZXJyeSwgVGlmZmFueSJ9LHsia2luZCI6Imhvc3QiLCJ2YWx1ZSI6IlJhbW9zLCBBbGVqYW5kcmEgKENoZWYpIn0seyJraW5kIjoiaG9zdCIsInZhbHVlIjoiQ29oZW4sIExlYWggKENoZWYpIn0seyJraW5kIjoiaG9zdCIsInZhbHVlIjoiRWxsaW90LCBHcmFoYW0ifSx7ImtpbmQiOiJwcm9kdWN0aW9uIGNvbXBhbnkiLCJ2YWx1ZSI6IlZQTSBNZWRpYSBDb3Jwb3JhdGlvbiJ9LHsia2luZCI6ImZpbG0gZGlzdHJpYnV0b3IiLCJ2YWx1ZSI6IlB1YmxpYyBCcm9hZGNhc3RpbmcgU2VydmljZSAoVS5TLikifSx7ImtpbmQiOiJwdWJsaXNoZXIiLCJ2YWx1ZSI6IlB1YmxpYyBCcm9hZGNhc3RpbmcgU2VydmljZSAoVS5TLikifV0sInB1YmxpY2F0aW9uSW5mb3JtYXRpb24iOlsiUHVibGljIEJyb2FkY2FzdGluZyBTZXJ2aWNlOyAyMDIzOyBBcmxpbmd0b24sIFZBIl0sImRhdGVzIjpbeyJraW5kIjoiUHVibGljYXRpb24gZGF0ZSIsInZhbHVlIjoiMjAyMyJ9XSwibGlua3MiOlt7ImtpbmQiOiJEaWdpdGFsIG9iamVjdCBVUkwiLCJyZXN0cmljdGlvbnMiOm51bGwsInRleHQiOiJBY2FkZW1pYyBWaWRlbyBPbmxpbmUgKEFWT04pIiwidXJsIjoiaHR0cHM6Ly9uYTA2LmFsbWEuZXhsaWJyaXNncm91cC5jb20vdmlldy91cmVzb2x2ZXIvMDFNSVRfSU5TVC9vcGVudXJsP3UuaWdub3JlX2RhdGVfY292ZXJhZ2U9dHJ1ZVx1MDAyNnBvcnRmb2xpb19waWQ9NTM2ODA0NjU1MzAwMDY3NjFcdTAwMjZGb3JjZV9kaXJlY3Q9dHJ1ZSJ9XSwibm90ZXMiOlt7ImtpbmQiOiJUaXRsZSBTdGF0ZW1lbnQgb2YgUmVzcG9uc2liaWxpdHkiLCJ2YWx1ZSI6WyJwcm9kdWNlZCBieSBWUE0gTWVkaWEgQ29ycG9yYXRpb24gaW4gYXNzb2NpYXRpb24gd2l0aCBQQlMiXX0seyJraW5kIjoiR2VuZXJhbCBOb3RlIiwidmFsdWUiOlsiVGl0bGUgZnJvbSByZXNvdXJjZSBkZXNjcmlwdGlvbiBwYWdlICh2aWV3ZWQgQXVndXN0IDE4LCAyMDIzKSJdfSx7ImtpbmQiOiJQYXJ0aWNpcGFudCBvciBQZXJmb3JtZXIgTm90ZSIsInZhbHVlIjpbIkhvc3RzOiBBbGVqYW5kcmEgUmFtb3MsIFRpZmZhbnkgRGVycnksIExlYWggQ29oZW4sIEdyYWhhbSBFbGxpb3R0Il19XSwiaGlnaGxpZ2h0IjpbeyJtYXRjaGVkRmllbGQiOiJzdW1tYXJ5IiwibWF0Y2hlZFBocmFzZXMiOlsiRnJvbSBjYXJuZSBhc2FkYSBcdTAwM2NzcGFuIGNsYXNzPVwiaGlnaGxpZ2h0XCJcdTAwM2V0YWNvc1x1MDAzYy9zcGFuXHUwMDNlIHRvIGNvcm4gY2hhYXQgdG8gY2hpY2tlbiBjaGFwbGksIHRoZSBjb29rcyBwcmVwYXJlIGRpc2hlcyBpbnNwaXJlZCBieSBhIGNsb3NlIl19XSwicHJvdmlkZXIiOm51bGwsInJpZ2h0cyI6bnVsbCwic291cmNlTGluayI6Imh0dHBzOi8vbWl0LnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL2Rpc2NvdmVyeS9mdWxsZGlzcGxheT92aWQ9MDFNSVRfSU5TVDpNSVRcdTAwMjZkb2NpZD1hbG1hOTkzNTUxNTA1NzEwNjc2MSIsInN1bW1hcnkiOlsiU2VlIGhvdyB0aGUgaG9tZSBjb29rcyBwdXQgaXQgYWxsIG9uIHRoZSBwbGF0ZSBpbiB0aGVpciBsYXN0IGNoYW5jZSB0byBpbXByZXNzIGJlZm9yZSB0aGUgZmluYWxlLiBGcm9tIGNhcm5lIGFzYWRhIHRhY29zIHRvIGNvcm4gY2hhYXQgdG8gY2hpY2tlbiBjaGFwbGksIHRoZSBjb29rcyBwcmVwYXJlIGRpc2hlcyBpbnNwaXJlZCBieSBhIGNsb3NlIGZyaWVuZCBhbmQgcmVjaXBlcyB0aGF0IGNoYW5nZWQgdGhlaXIgbGl2ZXMuIl19XSwiYWdncmVnYXRpb25zIjp7ImFjY2Vzc1RvRmlsZXMiOltdLCJjb250ZW50VHlwZSI6W3sia2V5IjoibGFuZ3VhZ2UgbWF0ZXJpYWwiLCJkb2NDb3VudCI6NDZ9LHsia2V5IjoicHJvamVjdGVkIG1lZGl1bSIsImRvY0NvdW50Ijo5fSx7ImtleSI6Im11c2ljYWwgc291bmQgcmVjb3JkaW5nIiwiZG9jQ291bnQiOjJ9XSwiY29udHJpYnV0b3JzIjpbeyJrZXkiOiJkb25uZWxseSwgbGF1cmllIiwiZG9jQ291bnQiOjR9LHsia2V5IjoieWFuY2h5aywgYnJhbmR5IiwiZG9jQ291bnQiOjR9LHsia2V5IjoicGlsY2hlciwgamVmZnJleSBtIiwiZG9jQ291bnQiOjN9LHsia2V5IjoicHVibGljIGJyb2FkY2FzdGluZyBzZXJ2aWNlICh1LnMuKSIsImRvY0NvdW50IjozfSx7ImtleSI6InJhbW9zLCBhbGVqYW5kcmEgKGNoZWYpIiwiZG9jQ291bnQiOjN9LHsia2V5IjoiY29oZW4sIGxlYWggKGNoZWYpIiwiZG9jQ291bnQiOjJ9LHsia2V5IjoiY29sb21iaW5pLCBkYW5pZWxhIiwiZG9jQ291bnQiOjJ9LHsia2V5IjoiZGVycnksIHRpZmZhbnkiLCJkb2NDb3VudCI6Mn0seyJrZXkiOiJkZXZpbmUsIGtlbGx5IiwiZG9jQ291bnQiOjJ9LHsia2V5IjoiZG9tZcyAbmVjaCwgY29ueGl0YSIsImRvY0NvdW50IjoyfV0sImZvcm1hdCI6W10sImxhbmd1YWdlcyI6W3sia2V5IjoiZW5nbGlzaCIsImRvY0NvdW50Ijo1M30seyJrZXkiOiJpbiBlbmdsaXNoIiwiZG9jQ291bnQiOjl9LHsia2V5Ijoic3BhbmlzaCIsImRvY0NvdW50IjozfSx7ImtleSI6Im5vIGxpbmd1aXN0aWMgY29udGVudCIsImRvY0NvdW50IjoxfSx7ImtleSI6Im9yaWdpbmFsIGxhbmd1YWdlIGluIGVuZ2xpc2giLCJkb2NDb3VudCI6MX0seyJrZXkiOiJwb3J0dWd1ZXNlIiwiZG9jQ291bnQiOjF9XSwibGl0ZXJhcnlGb3JtIjpbeyJrZXkiOiJub25maWN0aW9uIiwiZG9jQ291bnQiOjQ1fSx7ImtleSI6ImZpY3Rpb24iLCJkb2NDb3VudCI6MX1dLCJwbGFjZXMiOltdLCJzb3VyY2UiOlt7ImtleSI6Im1pdCBhbG1hIiwiZG9jQ291bnQiOjU3fV0sInN1YmplY3RzIjpbeyJrZXkiOiJjb29raW5nLCBtZXhpY2FuIiwiZG9jQ291bnQiOjh9LHsia2V5IjoiY29va2luZyIsImRvY0NvdW50Ijo3fSx7ImtleSI6ImZvb2QgaGFiaXRzIiwiZG9jQ291bnQiOjV9LHsia2V5IjoiaGlzdG9yeSIsImRvY0NvdW50Ijo1fSx7ImtleSI6InRhY29zIiwiZG9jQ291bnQiOjV9LHsia2V5IjoiYXJ0aWZpY2lhbCBpbnRlbGxpZ2VuY2UiLCJkb2NDb3VudCI6NH0seyJrZXkiOiJjb29raW5nLCBhbWVyaWNhbiIsImRvY0NvdW50Ijo0fSx7ImtleSI6ImNvb2tpbmcsIG1leGljYW4gLSBoaXN0b3J5IiwiZG9jQ291bnQiOjN9LHsia2V5IjoibWV4aWNhbiBhbWVyaWNhbnMiLCJkb2NDb3VudCI6M30seyJrZXkiOiJtZXhpY28iLCJkb2NDb3VudCI6M31dfX19fQ== + recorded_at: Fri, 03 Oct 2025 14:50:31 GMT +recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/tacos_direct.yml b/test/vcr_cassettes/tacos_direct.yml new file mode 100644 index 00000000..d2a93580 --- /dev/null +++ b/test/vcr_cassettes/tacos_direct.yml @@ -0,0 +1,59 @@ +--- +http_interactions: +- request: + method: post + uri: http://FAKE_TACOS_HOST/graphql + body: + encoding: UTF-8 + string: '{ "query": "{ logSearchEvent(searchTerm: \"direct\", sourceSystem: + \"use\" ) { phrase source detectors { suggestedResources { title url } } } + }" }' + headers: + Accept: + - application/json + Content-Type: + - application/json + Connection: + - Keep-Alive + Host: + - FAKE_TACOS_HOST + User-Agent: + - http.rb/5.3.1 + response: + status: + code: 200 + message: OK + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - '0' + X-Content-Type-Options: + - nosniff + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Type: + - application/json; charset=utf-8 + Vary: + - Accept, Origin + Etag: + - W/"a66b90423fc1658bd873263c1f6ab9f6" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - 4b46e2b5-fde0-4de2-b0bb-5363548b47c6 + X-Runtime: + - '0.079767' + Server-Timing: + - start_processing.action_controller;dur=0.01, sql.active_record;dur=4.70, start_transaction.active_record;dur=0.00, + transaction.active_record;dur=12.18, instantiation.active_record;dur=0.11, + process_action.action_controller;dur=42.34 + Content-Length: + - '100' + body: + encoding: UTF-8 + string: '{"data":{"logSearchEvent":{"phrase":"direct","source":"use","detectors":{"suggestedResources":[]}}}}' + recorded_at: Fri, 03 Oct 2025 15:16:35 GMT +recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/tacos_fake_system.yml b/test/vcr_cassettes/tacos_fake_system.yml new file mode 100644 index 00000000..ba5213bc --- /dev/null +++ b/test/vcr_cassettes/tacos_fake_system.yml @@ -0,0 +1,59 @@ +--- +http_interactions: +- request: + method: post + uri: http://FAKE_TACOS_HOST/graphql + body: + encoding: UTF-8 + string: '{ "query": "{ logSearchEvent(searchTerm: \"popcorn\", sourceSystem: + \"faked\" ) { phrase source detectors { suggestedResources { title url } } + } }" }' + headers: + Accept: + - application/json + Content-Type: + - application/json + Connection: + - Keep-Alive + Host: + - FAKE_TACOS_HOST + User-Agent: + - http.rb/5.3.1 + response: + status: + code: 200 + message: OK + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - '0' + X-Content-Type-Options: + - nosniff + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Type: + - application/json; charset=utf-8 + Vary: + - Accept, Origin + Etag: + - W/"035bbed4446f9d4569481bbb5d2f0b6a" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - 9f427731-b972-4ca5-be53-a80a5c8ee2de + X-Runtime: + - '0.023578' + Server-Timing: + - start_processing.action_controller;dur=0.01, sql.active_record;dur=0.94, start_transaction.active_record;dur=0.00, + instantiation.active_record;dur=0.07, transaction.active_record;dur=0.98, + process_action.action_controller;dur=4.86 + Content-Length: + - '103' + body: + encoding: UTF-8 + string: '{"data":{"logSearchEvent":{"phrase":"popcorn","source":"faked","detectors":{"suggestedResources":[]}}}}' + recorded_at: Fri, 03 Oct 2025 13:55:59 GMT +recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/tacos_popcorn.yml b/test/vcr_cassettes/tacos_popcorn.yml new file mode 100644 index 00000000..0002783a --- /dev/null +++ b/test/vcr_cassettes/tacos_popcorn.yml @@ -0,0 +1,59 @@ +--- +http_interactions: +- request: + method: post + uri: http://FAKE_TACOS_HOST/graphql + body: + encoding: UTF-8 + string: '{ "query": "{ logSearchEvent(searchTerm: \"popcorn\", sourceSystem: + \"use\" ) { phrase source detectors { suggestedResources { title url } } } + }" }' + headers: + Accept: + - application/json + Content-Type: + - application/json + Connection: + - Keep-Alive + Host: + - FAKE_TACOS_HOST + User-Agent: + - http.rb/5.3.1 + response: + status: + code: 200 + message: OK + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - '0' + X-Content-Type-Options: + - nosniff + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Type: + - application/json; charset=utf-8 + Vary: + - Accept, Origin + Etag: + - W/"84adabecd4fb001e4a3306daa2b2321e" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - c72d3c64-ee74-4de3-b095-1416ef3f433b + X-Runtime: + - '0.023035' + Server-Timing: + - start_processing.action_controller;dur=0.01, sql.active_record;dur=0.85, start_transaction.active_record;dur=0.00, + instantiation.active_record;dur=0.07, transaction.active_record;dur=0.85, + process_action.action_controller;dur=4.63 + Content-Length: + - '101' + body: + encoding: UTF-8 + string: '{"data":{"logSearchEvent":{"phrase":"popcorn","source":"use","detectors":{"suggestedResources":[]}}}}' + recorded_at: Fri, 03 Oct 2025 13:55:59 GMT +recorded_with: VCR 6.3.1