From 69bf55b69ac398918c4bb22351db8b07e8f3ca38 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Mon, 5 Oct 2020 20:00:31 -0700 Subject: [PATCH 01/92] dotenv test --- lib/dotenv_test.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/dotenv_test.rb diff --git a/lib/dotenv_test.rb b/lib/dotenv_test.rb new file mode 100644 index 00000000..d26bd1d1 --- /dev/null +++ b/lib/dotenv_test.rb @@ -0,0 +1,8 @@ +# dotenv_practice.rb +require 'dotenv' + +# Tell dotenv to look for the .env file +Dotenv.load + +p ENV["SLACK_API_TOKEN"] + From 2a08ee1d44b6d6ba65d3252fa42aa55542f590d3 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Mon, 5 Oct 2020 20:45:59 -0700 Subject: [PATCH 02/92] updated doteenv_test --- lib/dotenv_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/dotenv_test.rb b/lib/dotenv_test.rb index d26bd1d1..96856295 100644 --- a/lib/dotenv_test.rb +++ b/lib/dotenv_test.rb @@ -1,8 +1,10 @@ # dotenv_practice.rb require 'dotenv' - +require 'httparty' # Tell dotenv to look for the .env file Dotenv.load -p ENV["SLACK_API_TOKEN"] +puts + +channels = HTTParty.get('https://slack.com/api/conversations.list', query: {token: ENV["SLACK_API_TOKEN"]})["channels"].each{|channel| puts channel["name"]} From f5851a94b076b13eaaa48960e784e7859093e94a Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Mon, 5 Oct 2020 21:03:59 -0700 Subject: [PATCH 03/92] add VCR filter to test helper --- test/test_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 1fcf2bab..a07890d2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,6 +9,8 @@ require 'minitest/skip_dsl' require 'vcr' +Dotenv.load + Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| @@ -25,5 +27,7 @@ } # Don't leave our token lying around in a cassette file. - + config.filter_sensitive_data("") do + ENV["LOCATIONIQ_TOKEN"] + end end From e722628bfebd2eebb543dd9b4ca9854ebb71cad9 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Mon, 5 Oct 2020 21:07:13 -0700 Subject: [PATCH 04/92] modified filter sensitive data config --- test/test_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index a07890d2..b900a5bd 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -27,7 +27,7 @@ } # Don't leave our token lying around in a cassette file. - config.filter_sensitive_data("") do - ENV["LOCATIONIQ_TOKEN"] + config.filter_sensitive_data("SLACK_API_TOKEN") do + ENV["SLACK_API_TOKEN"] end end From fdaeddfe8a7c5e337d9f962a9e3176bbf12f5f5d Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Mon, 5 Oct 2020 21:34:15 -0700 Subject: [PATCH 05/92] created workspace class --- lib/slack.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/slack.rb b/lib/slack.rb index 8a0b659b..d9ccb5cb 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +require_relative 'workspace' def main puts "Welcome to the Ada Slack CLI!" From f9e88b0db22bacbf80560229ba534662dd8bba14 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Mon, 5 Oct 2020 21:35:51 -0700 Subject: [PATCH 06/92] added workspace class --- lib/workspace.rb | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib/workspace.rb diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..caec4cd0 --- /dev/null +++ b/lib/workspace.rb @@ -0,0 +1,9 @@ +class Workspace + attr_reader :users, :channels + + def initialize + @users = [] + @channels = [] + end + +end \ No newline at end of file From 59aa0857423a3ea2fc79be270d1ad52d232bfafa Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 20:07:46 -0700 Subject: [PATCH 07/92] created Recipient class and constructor method --- lib/recipient.rb | 10 ++++++++++ test/recipient_test.rb | 0 2 files changed, 10 insertions(+) create mode 100644 lib/recipient.rb create mode 100644 test/recipient_test.rb diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..e757303d --- /dev/null +++ b/lib/recipient.rb @@ -0,0 +1,10 @@ +module SlackCLI + class Recipient + + attr_reader :name, :slack_id + def initialize(slack_id, name) + @slack_id = slack_id + @name = name + end + end +end \ No newline at end of file diff --git a/test/recipient_test.rb b/test/recipient_test.rb new file mode 100644 index 00000000..e69de29b From 46c2351cb971be7b4f6ecdc3335fc32459d9a8e1 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 20:08:37 -0700 Subject: [PATCH 08/92] created recpient test and test for constructor --- test/recipient_test.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index e69de29b..2daf2ed3 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -0,0 +1,19 @@ +require_relative 'test_helper' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + + +describe "initialize" do + before do + @recipient = SlackCLI::Recipient.new("1234ID", "Namey Nameson") + end + it "constructor properly creates a recipient object" do + + expect(@recipient).must_be_instance_of SlackCLI::Recipient + end + + it "slack_id and name are both strings" do + expect(@recipient.slack_id).must_be_instance_of String + expect(@recipient.name).must_be_instance_of String + end +end \ No newline at end of file From b67fcade25e47afc3d9b3de71b7219ff2abda9f4 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 20:09:44 -0700 Subject: [PATCH 09/92] add require for dotenv and require_relative for recpient, deleted redunatnt VCR config code --- test/test_helper.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index b900a5bd..3fc7602d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -3,21 +3,17 @@ add_filter 'test/' end +require 'dotenv' require 'minitest' require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' require 'vcr' - +require_relative '../lib/recipient' Dotenv.load Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -VCR.configure do |config| - config.cassette_library_dir = "test/cassettes" - config.hook_into :webmock -end - VCR.configure do |config| config.cassette_library_dir = "test/cassettes" # folder where casettes will be located config.hook_into :webmock # tie into this other tool called webmock From 5d43a9a22b8f4f768fb15eb27d6827d916d0edff Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 20:34:58 -0700 Subject: [PATCH 10/92] added get, details, and list_all methods --- lib/recipient.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/recipient.rb b/lib/recipient.rb index e757303d..744d2c8c 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -1,3 +1,8 @@ +require 'dotenv' +require 'httparty' + +Dotenv.load + module SlackCLI class Recipient @@ -6,5 +11,20 @@ def initialize(slack_id, name) @slack_id = slack_id @name = name end + + def self.get(url, params) + raise ArgumentError.new("invalid arguments") unless (url.is_a?(String) && params.is_a?(Hash)) + api_info = HTTParty.get(url, query: params) + return api_info + end + + def details + raise NotImplementedError, 'Implement me in a child class!' + end + + def list_all + raise NotImplementedError, 'Implement me in a child class!' + end + end end \ No newline at end of file From ec673650abe70d27929d094fd71b05a570de3eb5 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 20:35:30 -0700 Subject: [PATCH 11/92] added test to verify parameters for get method --- test/recipient_test.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 2daf2ed3..76eb422a 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -16,4 +16,15 @@ expect(@recipient.slack_id).must_be_instance_of String expect(@recipient.name).must_be_instance_of String end -end \ No newline at end of file +end + +describe "self.get method" do + # before do + # @recipient = SlackCLI::Recipient.new("1234ID", "Namey Nameson") + # end + it "raises ArgumentError for incorrect parameters" do + expect{SlackCLI::Recipient.get("url", "not a hash")}.must_raise ArgumentError + end +end + +describe \ No newline at end of file From c77db13075187cca2de895b58589238721b4400e Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 20:41:25 -0700 Subject: [PATCH 12/92] created channel class --- lib/channel.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 lib/channel.rb diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..d5970ae1 --- /dev/null +++ b/lib/channel.rb @@ -0,0 +1,5 @@ +module SlackCLI + class Channel < Recipient + + end +end \ No newline at end of file From 9dc48b0deb3a1605bf029842281e01b04e6d6429 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 20:41:42 -0700 Subject: [PATCH 13/92] created user class and constructor method --- lib/user.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/user.rb diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 00000000..0d63e8bb --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,13 @@ +module SlackCLI + class User < Recipient + + attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji + + def initialize(slack_id, name, real_name, status_text, status_emoji) + super(name, slack_id) + @real_name = real_name + @status_text = status_text + @status_emoji = status_emoji + end + end +end \ No newline at end of file From 02cb3382e03424a1721dff5c03a8ccb6886ea38d Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 21:28:10 -0700 Subject: [PATCH 14/92] added initilize tests --- test/channel_test.rb | 25 +++++++++++++++++++++++++ test/user_test.rb | 0 2 files changed, 25 insertions(+) create mode 100644 test/channel_test.rb create mode 100644 test/user_test.rb diff --git a/test/channel_test.rb b/test/channel_test.rb new file mode 100644 index 00000000..d7444e09 --- /dev/null +++ b/test/channel_test.rb @@ -0,0 +1,25 @@ +require_relative 'test_helper' + +describe 'Channel' do + describe "initialize" do + before do + @channel = SlackCLI::Channel.new() + end + it "constructor properly creates a Channel object" do + expect(@channel).must_be_instance_of SlackCLI::Channel + end + + it "slack_id and name are both strings" do + expect(@channel.slack_id).must_be_instance_of String + expect(@channel.name).must_be_instance_of String + end + + it "topic is a String" do + expect(@channel.topic).must_be_instance_of String + end + + it "member count is an Integer" do + expect(@channel.member_count).must_be_instance_of String + end + end +end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb new file mode 100644 index 00000000..e69de29b From 295be86f5f3888e1c7e16cfacd4d840261d5bd8a Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 21:29:27 -0700 Subject: [PATCH 15/92] addedNotIMplementedError tests --- test/recipient_test.rb | 45 ++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 76eb422a..8fe1a796 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -2,29 +2,40 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +describe "Recipient" do -describe "initialize" do before do - @recipient = SlackCLI::Recipient.new("1234ID", "Namey Nameson") + @recipient = SlackCLI::Recipient.new() end - it "constructor properly creates a recipient object" do - expect(@recipient).must_be_instance_of SlackCLI::Recipient + describe "initialize" do + + it "constructor properly creates a recipient object" do + + expect(@recipient).must_be_instance_of SlackCLI::Recipient + end + + it "slack_id and name are both strings" do + expect(@recipient.slack_id).must_be_instance_of String + expect(@recipient.name).must_be_instance_of String + end end - it "slack_id and name are both strings" do - expect(@recipient.slack_id).must_be_instance_of String - expect(@recipient.name).must_be_instance_of String + describe "self.get method" do + it "raises ArgumentError for incorrect parameters" do + expect{SlackCLI::Recipient.get("url", "not a hash")}.must_raise ArgumentError + end end -end - -describe "self.get method" do - # before do - # @recipient = SlackCLI::Recipient.new("1234ID", "Namey Nameson") - # end - it "raises ArgumentError for incorrect parameters" do - expect{SlackCLI::Recipient.get("url", "not a hash")}.must_raise ArgumentError + + describe 'details' do + it "raises error if not implemented" do + expect(@recipient.details).must_raise NotImplementedError + end end -end -describe \ No newline at end of file + describe 'list_all' do + it "raises error if not implemented" do + expect(@recipient.list_all).must_raise NotImplementedError + end + end +end \ No newline at end of file From 695f40758e6779c3f7fae46395076a1a2ceed462 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 21:31:15 -0700 Subject: [PATCH 16/92] took out arguemnts from constructor --- lib/recipient.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index 744d2c8c..2f0db41f 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -7,7 +7,7 @@ module SlackCLI class Recipient attr_reader :name, :slack_id - def initialize(slack_id, name) + def initialize(slack_id: , name: ) @slack_id = slack_id @name = name end @@ -22,7 +22,7 @@ def details raise NotImplementedError, 'Implement me in a child class!' end - def list_all + def self.list_all raise NotImplementedError, 'Implement me in a child class!' end From 3b78f84a661f1465c89b5b8e7bdd3daedba30d4a Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:22:04 -0700 Subject: [PATCH 17/92] created constructor method for channel --- lib/channel.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/channel.rb b/lib/channel.rb index d5970ae1..97fac42d 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -1,5 +1,15 @@ +require_relative 'recipient' + module SlackCLI class Channel < Recipient + attr_reader :slack_id, :name, :topic, :member_count + + def initialize(slack_id:, name:, topic:, member_count:) + super(name, slack_id) + @topic = topic + @member_count = member_count + end + end end \ No newline at end of file From 7ffa3944a70996167d7ce66b4c461a245aca50c0 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:22:30 -0700 Subject: [PATCH 18/92] added constants to recipient method --- lib/recipient.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index 2f0db41f..267a1f69 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -7,11 +7,18 @@ module SlackCLI class Recipient attr_reader :name, :slack_id - def initialize(slack_id: , name: ) + def initialize(slack_id:, name:) + self.class.validate_id(slack_id) @slack_id = slack_id @name = name end + def self.validate_id(id) + if id.nil? || id <= 0 + raise ArgumentError, 'ID cannot be blank or less than one.' + end + end + def self.get(url, params) raise ArgumentError.new("invalid arguments") unless (url.is_a?(String) && params.is_a?(Hash)) api_info = HTTParty.get(url, query: params) From cfcd60c70fc073fb21d8ed1f4ca66eed21d718f6 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:22:46 -0700 Subject: [PATCH 19/92] added constants to user method --- lib/user.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/user.rb b/lib/user.rb index 0d63e8bb..6469088a 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -1,13 +1,28 @@ +require_relative 'recipient' + module SlackCLI class User < Recipient + USER_URL = "https://slack.com/api/users.list" + PARAM = {token: ENV["SLACK_API_TOKEN"]} + attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji - def initialize(slack_id, name, real_name, status_text, status_emoji) - super(name, slack_id) + def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) + super(slack_id, name) @real_name = real_name @status_text = status_text @status_emoji = status_emoji end + + + + private + + def self.from_api(json_hash) + + end + + end end \ No newline at end of file From 8683608912e5f486700a94926993ccfd8bba06a3 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:23:08 -0700 Subject: [PATCH 20/92] edited before do --- test/channel_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/channel_test.rb b/test/channel_test.rb index d7444e09..f7a73c53 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -3,7 +3,7 @@ describe 'Channel' do describe "initialize" do before do - @channel = SlackCLI::Channel.new() + @channel = SlackCLI::Channel.new(slack_id: "1234id", name: "Channely Channelson", topic: "topic", member_count: 24) end it "constructor properly creates a Channel object" do expect(@channel).must_be_instance_of SlackCLI::Channel From 7431b0614d9d632175399df8bdae4ae0e61a18bf Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:23:42 -0700 Subject: [PATCH 21/92] added parameters in before do --- test/recipient_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 8fe1a796..32471616 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -5,7 +5,7 @@ describe "Recipient" do before do - @recipient = SlackCLI::Recipient.new() + @recipient = SlackCLI::Recipient.new(name: "Namey Nameson", slack_id: "1928id") end describe "initialize" do From 5857759488e82e81fc6efbc081bb8794308195c5 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:24:06 -0700 Subject: [PATCH 22/92] added require_relative to user and channel files --- test/test_helper.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_helper.rb b/test/test_helper.rb index 3fc7602d..b523044b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,6 +10,9 @@ require 'minitest/skip_dsl' require 'vcr' require_relative '../lib/recipient' +require_relative '../lib/user' +require_relative '../lib/channel' + Dotenv.load Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From e48e23fba9659ccd100b097f883ddbba91569cb8 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Tue, 6 Oct 2020 22:24:28 -0700 Subject: [PATCH 23/92] created tests for method and constructor --- test/user_test.rb | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/user_test.rb b/test/user_test.rb index e69de29b..4e0ead02 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -0,0 +1,29 @@ +require_relative 'test_helper' + +describe 'Channel' do + describe "initialize" do + before do + @channel = SlackCLI::User.new(slack_id: "5678id", name: "Namey Nameson", real_name: "Namey Nameson", status_text: "status", status_emoji: ":smiley:") + end + it "constructor properly creates a Channel object" do + expect(@channel).must_be_instance_of SlackCLI::User + end + + it "slack_id and name are both strings" do + expect(@channel.slack_id).must_be_instance_of String + expect(@channel.name).must_be_instance_of String + end + + it "real name is a String" do + expect(@channel.real_name).must_be_instance_of String + end + + it "status text is an String" do + expect(@channel.status_text).must_be_instance_of String + end + + it "status emoji is an String" do + expect(@channel.status_emoji).must_be_instance_of String + end + end +end \ No newline at end of file From 548c1d1d2a51982fdd5f97ed09eeb5c7fdeb50cc Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Tue, 6 Oct 2020 22:38:26 -0700 Subject: [PATCH 24/92] corrected validate_id, fixed super method calls in channel and user, corrected channel test, list_all test (recipient) and user test --- lib/channel.rb | 2 +- lib/recipient.rb | 4 ++-- lib/user.rb | 2 +- test/channel_test.rb | 2 +- test/recipient_test.rb | 4 ++-- test/user_test.rb | 16 ++++++++-------- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/channel.rb b/lib/channel.rb index 97fac42d..50f90dfe 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -6,7 +6,7 @@ class Channel < Recipient attr_reader :slack_id, :name, :topic, :member_count def initialize(slack_id:, name:, topic:, member_count:) - super(name, slack_id) + super(name: name, slack_id: slack_id) @topic = topic @member_count = member_count end diff --git a/lib/recipient.rb b/lib/recipient.rb index 267a1f69..55df1804 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -14,8 +14,8 @@ def initialize(slack_id:, name:) end def self.validate_id(id) - if id.nil? || id <= 0 - raise ArgumentError, 'ID cannot be blank or less than one.' + if id.nil? + raise ArgumentError, 'ID cannot be blank.' end end diff --git a/lib/user.rb b/lib/user.rb index 6469088a..dacb4614 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -9,7 +9,7 @@ class User < Recipient attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) - super(slack_id, name) + super(slack_id: slack_id, name: name) @real_name = real_name @status_text = status_text @status_emoji = status_emoji diff --git a/test/channel_test.rb b/test/channel_test.rb index f7a73c53..45843add 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -19,7 +19,7 @@ end it "member count is an Integer" do - expect(@channel.member_count).must_be_instance_of String + expect(@channel.member_count).must_be_instance_of Integer end end end \ No newline at end of file diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 32471616..ef4a4de0 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -29,13 +29,13 @@ describe 'details' do it "raises error if not implemented" do - expect(@recipient.details).must_raise NotImplementedError + expect{@recipient.details}.must_raise NotImplementedError end end describe 'list_all' do it "raises error if not implemented" do - expect(@recipient.list_all).must_raise NotImplementedError + expect{SlackCLI::Recipient.list_all}.must_raise NotImplementedError end end end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb index 4e0ead02..0bc2c869 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -1,29 +1,29 @@ require_relative 'test_helper' -describe 'Channel' do +describe 'User' do describe "initialize" do before do - @channel = SlackCLI::User.new(slack_id: "5678id", name: "Namey Nameson", real_name: "Namey Nameson", status_text: "status", status_emoji: ":smiley:") + @user = SlackCLI::User.new(slack_id: "5678id", name: "Namey Nameson", real_name: "Namey Nameson", status_text: "status", status_emoji: ":smiley:") end it "constructor properly creates a Channel object" do - expect(@channel).must_be_instance_of SlackCLI::User + expect(@user).must_be_instance_of SlackCLI::User end it "slack_id and name are both strings" do - expect(@channel.slack_id).must_be_instance_of String - expect(@channel.name).must_be_instance_of String + expect(@user.slack_id).must_be_instance_of String + expect(@user.name).must_be_instance_of String end it "real name is a String" do - expect(@channel.real_name).must_be_instance_of String + expect(@user.real_name).must_be_instance_of String end it "status text is an String" do - expect(@channel.status_text).must_be_instance_of String + expect(@user.status_text).must_be_instance_of String end it "status emoji is an String" do - expect(@channel.status_emoji).must_be_instance_of String + expect(@user.status_emoji).must_be_instance_of String end end end \ No newline at end of file From b9c60c42b084bb5779021843875aad62966a2102 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 16:37:28 -0700 Subject: [PATCH 25/92] moved .env path --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3ff4fada..451aa4ea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ .DS_Store # Ignore environemnt variables -.env +lib/.env From 0d6d76c421a5c978b496530371582d22d8406e38 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 16:37:42 -0700 Subject: [PATCH 26/92] created user menu --- lib/slack.rb | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/slack.rb b/lib/slack.rb index d9ccb5cb..d78efe9e 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,13 +1,32 @@ #!/usr/bin/env ruby +require 'dotenv' +require 'httparty' require_relative 'workspace' def main puts "Welcome to the Ada Slack CLI!" workspace = Workspace.new - # TODO project + option = nil + + until option == "quit" || option == "3" + if option == "list users" || option == "1" + puts workspace.users + elsif option == "list channels" || option == "2" + puts workspace.channels + end + menu + option = gets.chomp + end puts "Thank you for using the Ada Slack CLI" end +def menu + puts "Please select one of the three options: " + puts "1. list users" + puts "2. list channels" + puts "3. quit" +end + main if __FILE__ == $PROGRAM_NAME \ No newline at end of file From 70efd758876740cf9e10ed17e033c16b2996af21 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 16:38:03 -0700 Subject: [PATCH 27/92] called to slack API to read conversations.list --- lib/workspace.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index caec4cd0..a680c8d0 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -1,9 +1,19 @@ +require 'dotenv' +require 'httparty' + +Dotenv.load + class Workspace attr_reader :users, :channels + CHANNEL_PATH = "https://slack.com/api/conversations.list" + def initialize + response = HTTParty.get(CHANNEL_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) @users = [] - @channels = [] + @channels = response["channels"] end + + end \ No newline at end of file From 3429b393f2d965c00a1f9fa97add7c103259f861 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 7 Oct 2020 17:23:47 -0700 Subject: [PATCH 28/92] added list_channels call and list_users call for main --- lib/slack.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index d78efe9e..3d7348f9 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -11,9 +11,9 @@ def main until option == "quit" || option == "3" if option == "list users" || option == "1" - puts workspace.users + puts workspace.list_users elsif option == "list channels" || option == "2" - puts workspace.channels + puts workspace.list_channels end menu option = gets.chomp From 3563acaa1c9cb6555e8938628cf2b276e8d25685 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 18:19:21 -0700 Subject: [PATCH 29/92] created Gemfile --- Gemfile | 14 +++++++++++++ Gemfile.lock | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..c816f4e0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,14 @@ +source "https://rubygems.org" + + +gem 'rake' +gem 'minitest' +gem 'minitest-spec' +gem 'minitest-reporters' +gem "pry" +gem 'minitest-skip' +gem 'httparty' +gem 'dotenv' +gem 'table_print' +gem 'vcr' +gem 'simplecov' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..fc54944c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,56 @@ +GEM + remote: https://rubygems.org/ + specs: + ansi (1.5.0) + builder (3.2.4) + coderay (1.1.3) + docile (1.3.2) + dotenv (2.7.6) + httparty (0.18.1) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + method_source (1.0.0) + mime-types (3.3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2020.0512) + minitest (5.14.2) + minitest-reporters (1.4.2) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + minitest-skip (0.0.3) + minitest (~> 5.0) + minitest-spec (0.0.2.1) + minitest (>= 3.0) + multi_xml (0.6.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) + rake (13.0.1) + ruby-progressbar (1.10.1) + simplecov (0.19.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov-html (0.12.3) + table_print (1.5.7) + vcr (6.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + dotenv + httparty + minitest + minitest-reporters + minitest-skip + minitest-spec + pry + rake + simplecov + table_print + vcr + +BUNDLED WITH + 2.1.4 From b13cf8ccac0d138446387f7b62356f12d427bcfd Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 7 Oct 2020 18:20:01 -0700 Subject: [PATCH 30/92] workspace and respective tests --- .gitignore | 1 + lib/slack.rb | 2 +- lib/workspace.rb | 31 ++++++++++++++++++++----------- test/test_helper.rb | 1 + test/workspace_test.rb | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 test/workspace_test.rb diff --git a/.gitignore b/.gitignore index 451aa4ea..de7f7cf3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # Ignore environemnt variables lib/.env +test/.env \ No newline at end of file diff --git a/lib/slack.rb b/lib/slack.rb index 3d7348f9..eadc11fc 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -5,7 +5,7 @@ def main puts "Welcome to the Ada Slack CLI!" - workspace = Workspace.new + workspace = SlackCLI::Workspace.new option = nil diff --git a/lib/workspace.rb b/lib/workspace.rb index a680c8d0..987e5403 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -3,17 +3,26 @@ Dotenv.load -class Workspace - attr_reader :users, :channels +module SlackCLI + class Workspace + attr_reader :users, :channels - CHANNEL_PATH = "https://slack.com/api/conversations.list" - - def initialize - response = HTTParty.get(CHANNEL_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) - @users = [] - @channels = response["channels"] + CHANNEL_PATH = "https://slack.com/api/conversations.list" + USER_PATH = "https://slack.com/api/users.list" + def initialize + env = ENV["SLACK_API_TOKEN"] + users_response = HTTParty.get(USER_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) + channels_response = HTTParty.get(CHANNEL_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) + @users = users_response["members"] + @channels = channels_response["channels"] + end + #user name, real name, slack Id + def list_users + return @users.map{|user| "Slack ID: #{user["id"]}, Username: #{user["name"]}, Real name: #{user["real_name"]}"} + end + #topic, member count, slack ID topic["value"] + def list_channels + return @channels.map{|channel| "Slack ID: #{channel["id"]}, name: #{channel["name"]}, topic: #{channel["topic"]["value"]}, member count: #{channel["num_members"]}"} + end end - - - end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index b523044b..d47946ae 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -12,6 +12,7 @@ require_relative '../lib/recipient' require_relative '../lib/user' require_relative '../lib/channel' +require_relative '../lib/workspace' Dotenv.load diff --git a/test/workspace_test.rb b/test/workspace_test.rb new file mode 100644 index 00000000..58412c41 --- /dev/null +++ b/test/workspace_test.rb @@ -0,0 +1,33 @@ +require_relative 'test_helper' + +describe 'Workspace' do + + before do + sleep(1) + VCR.use_cassette("user_channel_find") do + @workspace = SlackCLI::Workspace.new + end + end + + describe "initialize" do + it "creates an instance of Workspace" do + expect(@workspace).must_be_instance_of SlackCLI::Workspace + end + + it "creates an array of User objects" do + expect(@workspace.users).must_be_nil #must_be_instance_of SlackCLI::User + end + + it "creates an array of Channel objects" do + expect(@workspace.channels.first).must_be_instance_of SlackCLI::Channel + end + end + + describe "list users method" do + + end + + describe "list channels method" do + + end +end \ No newline at end of file From c05bec0bf218f78435acdac8631635f6df7ed8fc Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 18:35:14 -0700 Subject: [PATCH 31/92] changed .env path --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index de7f7cf3..c1500343 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ .DS_Store # Ignore environemnt variables -lib/.env -test/.env \ No newline at end of file +.env \ No newline at end of file From e1e2ece6a578ee06c5bcbc13f7b19a7c9e879bd5 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 18:35:28 -0700 Subject: [PATCH 32/92] added dotenv.load --- lib/slack.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/slack.rb b/lib/slack.rb index eadc11fc..386bd486 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -4,6 +4,8 @@ require_relative 'workspace' def main + Dotenv.load + puts "Welcome to the Ada Slack CLI!" workspace = SlackCLI::Workspace.new From 7ee4d315d97e9527d6f993739a932adb36bdcbef Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 18:35:45 -0700 Subject: [PATCH 33/92] deleted dotenv.load --- lib/workspace.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 987e5403..2970938c 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -1,8 +1,5 @@ -require 'dotenv' require 'httparty' -Dotenv.load - module SlackCLI class Workspace attr_reader :users, :channels From 4e2572f7040c30de51de761984fd7f001d7a1277 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 18:36:04 -0700 Subject: [PATCH 34/92] now has working cassette --- test/cassettes/user_channel_find.yml | 147 +++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 test/cassettes/user_channel_find.yml diff --git a/test/cassettes/user_channel_find.yml b/test/cassettes/user_channel_find.yml new file mode 100644 index 00000000..8f27bb4d --- /dev/null +++ b/test/cassettes/user_channel_find.yml @@ -0,0 +1,147 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 01:31:29 GMT + Server: + - Apache + X-Slack-Req-Id: + - 9a01f13d98fb2e6ce35a4829afe62683 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1278' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-cn1z,haproxy-edge-pdx-r6b3 + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01CDB91DEV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BL0TC86B","team_id":"T01CDB91DEV","name":"water_jessica_api_pro","deleted":false,"color":"3c989f","real_name":"Water + - Jessica - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Jessica - API Project","real_name_normalized":"Water - Jessica - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g16790b5cf92","api_app_id":"A01CDBH820Z","always_active":false,"bot_id":"B01BU12FUEA","image_24":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951747},{"id":"U01C0N8RAUS","team_id":"T01CDB91DEV","name":"jwinchan","deleted":false,"color":"4bbe2e","real_name":"Jessica + Chan","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jessica + Chan","real_name_normalized":"Jessica Chan","display_name":"Jessica (she.her)","display_name_normalized":"Jessica + (she.her)","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g39037b8a717","first_name":"Jessica","last_name":"Chan","image_24":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601951226,"has_2fa":false},{"id":"U01C6TTNL6Q","team_id":"T01CDB91DEV","name":"iris.lux0","deleted":false,"color":"9f69e7","real_name":"iris.lux0","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"iris.lux0","real_name_normalized":"iris.lux0","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g8d593922863","image_24":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601950931},{"id":"U01CDBMR333","team_id":"T01CDB91DEV","name":"water_iris_api_projec","deleted":false,"color":"e7392d","real_name":"Water + - Iris - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602120689,"response_metadata":{"next_cursor":""}}' + recorded_at: Thu, 08 Oct 2020 01:31:29 GMT +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 01:31:30 GMT + Server: + - Apache + X-Slack-Req-Id: + - bd356d64c0e20fa141607761b8b3f9f1 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '684' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-crth,haproxy-edge-pdx-3vri + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":2},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":2},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + recorded_at: Thu, 08 Oct 2020 01:31:30 GMT +recorded_with: VCR 6.0.0 From 4c74bde261b0dc24a569d4de9735d020202db2ba Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 20:36:11 -0700 Subject: [PATCH 35/92] created self.list_all method --- lib/channel.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/channel.rb b/lib/channel.rb index 50f90dfe..fad7aea3 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -3,6 +3,8 @@ module SlackCLI class Channel < Recipient + CHANNEL_PATH = "https://slack.com/api/conversations.list" + attr_reader :slack_id, :name, :topic, :member_count def initialize(slack_id:, name:, topic:, member_count:) @@ -11,5 +13,11 @@ def initialize(slack_id:, name:, topic:, member_count:) @member_count = member_count end + def self.list_all + return self.get(CHANNEL_PATH, {token: ENV["SLACK_API_TOKEN"]})["channels"].map do |channel| + self.new(slack_id: channel["id"], name: channel["name"], topic: channel["topic"]["value"], member_count: channel["num_members"]) + end + end + end end \ No newline at end of file From 43a286f0e3258183968e151de3d3f2cced3b45ac Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 20:36:37 -0700 Subject: [PATCH 36/92] changed nothing --- lib/slack.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/slack.rb b/lib/slack.rb index 386bd486..b6d428e2 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require 'dotenv' require 'httparty' +require 'table_print' require_relative 'workspace' def main From e5cea3e051250314c437083f9d51abf3466e555c Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 20:36:55 -0700 Subject: [PATCH 37/92] created list_all method --- lib/user.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/user.rb b/lib/user.rb index dacb4614..90af4427 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -2,9 +2,7 @@ module SlackCLI class User < Recipient - - USER_URL = "https://slack.com/api/users.list" - PARAM = {token: ENV["SLACK_API_TOKEN"]} + USER_PATH = "https://slack.com/api/users.list" attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji @@ -15,6 +13,16 @@ def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) @status_emoji = status_emoji end + def self.list_all + return self.get(USER_PATH, {token: ENV["SLACK_API_TOKEN"]})["members"].map do |user| + self.new(slack_id: user["id"], name: user["name"], real_name: user["real_name"], status_text: user["profile"]["status_text"], status_emoji: user["profile"]["status_emoji"]) + end + end + + def details + + end + private From 9b88f1eace33a4fff94fda27237b3d2e4fabf518 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 20:37:20 -0700 Subject: [PATCH 38/92] changed output statements and now calls from user and channel class --- lib/workspace.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 2970938c..bee01249 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -1,25 +1,24 @@ require 'httparty' +require_relative 'user' +require_relative 'channel' module SlackCLI class Workspace attr_reader :users, :channels - CHANNEL_PATH = "https://slack.com/api/conversations.list" - USER_PATH = "https://slack.com/api/users.list" def initialize - env = ENV["SLACK_API_TOKEN"] - users_response = HTTParty.get(USER_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) - channels_response = HTTParty.get(CHANNEL_PATH, query: {token: ENV["SLACK_API_TOKEN"]}) - @users = users_response["members"] - @channels = channels_response["channels"] + @users = User.list_all + @channels = Channel.list_all end + #user name, real name, slack Id def list_users - return @users.map{|user| "Slack ID: #{user["id"]}, Username: #{user["name"]}, Real name: #{user["real_name"]}"} + return @users.map{|user| "Slack ID: #{user.slack_id}, Username: #{user.name}, Real name: #{user.real_name}"} end - #topic, member count, slack ID topic["value"] + + #topic, member count, slack ID, topic["value"] def list_channels - return @channels.map{|channel| "Slack ID: #{channel["id"]}, name: #{channel["name"]}, topic: #{channel["topic"]["value"]}, member count: #{channel["num_members"]}"} + return @channels.map{|channel| "Slack ID: #{channel.slack_id}, name: #{channel.name}, topic: #{channel.topic}, member count: #{channel.member_count}"} end end end \ No newline at end of file From 986dafa2179e1de4b6aed0bbdd679c654e5087f6 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 20:37:41 -0700 Subject: [PATCH 39/92] changed user test --- test/workspace_test.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 58412c41..15317a4d 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -3,7 +3,6 @@ describe 'Workspace' do before do - sleep(1) VCR.use_cassette("user_channel_find") do @workspace = SlackCLI::Workspace.new end @@ -15,7 +14,7 @@ end it "creates an array of User objects" do - expect(@workspace.users).must_be_nil #must_be_instance_of SlackCLI::User + expect(@workspace.users.first).must_be_instance_of SlackCLI::User end it "creates an array of Channel objects" do @@ -24,10 +23,14 @@ end describe "list users method" do - + it "returns an accurate string" do + expect(@workspace.list_users.first).must_equal "Slack ID: USLACKBOT, Username: slackbot, Real name: Slackbot" + end end describe "list channels method" do - + it "returns an accurate string" do + expect(@workspace.list_channels.first).must_equal "Slack ID: C01BL0GSPP1, name: good-place-simulation, topic: torture Chidi, member count: 2" + end end end \ No newline at end of file From 8674ed70cecd1363cd6abc9c0607e951dd37da0a Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 7 Oct 2020 21:24:09 -0700 Subject: [PATCH 40/92] added menu options for select --- lib/slack.rb | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index b6d428e2..eddae8e2 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby require 'dotenv' require 'httparty' -require 'table_print' +#require 'table_print' require_relative 'workspace' def main @@ -11,15 +11,37 @@ def main workspace = SlackCLI::Workspace.new option = nil - - until option == "quit" || option == "3" + current_selection = nil + until option == "quit" || option == "6" if option == "list users" || option == "1" puts workspace.list_users elsif option == "list channels" || option == "2" puts workspace.list_channels + elsif option == "select user" || option == "3" + puts "Are you entering the name or id?" + name_or_id = gets.chomp + if(name_or_id == "id") + puts "Please enter id" + current_selection = workspace.select(recipient_class: "user", id: gets.chomp) + else + puts "Please enter name" + current_selection = workspace.select(recipient_class: "user", name: gets.chomp) + end + elsif option == "select channel" || option == "4" + puts "Are you entering the name or id?" + name_or_id = gets.chomp + if(name_or_id == "id") + puts "Please enter id" + current_selection = workspace.select(recipient_class: "channel", id: gets.chomp) + else + puts "Please enter name" + current_selection = workspace.select(recipient_class: "channel", name: gets.chomp) + end + elsif option == "details" || option == "5" + puts current_selection.details end menu - option = gets.chomp + option = gets.chomp.downcase end puts "Thank you for using the Ada Slack CLI" @@ -29,7 +51,10 @@ def menu puts "Please select one of the three options: " puts "1. list users" puts "2. list channels" - puts "3. quit" + puts "3. select user" + puts "4. select channel" + puts "5. details" + puts "6. quit" end main if __FILE__ == $PROGRAM_NAME \ No newline at end of file From 38ba7538a81943788e1c2c3ed071637ec38b7f72 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 7 Oct 2020 21:24:54 -0700 Subject: [PATCH 41/92] added select method --- lib/workspace.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/workspace.rb b/lib/workspace.rb index bee01249..b459656c 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -20,5 +20,27 @@ def list_users def list_channels return @channels.map{|channel| "Slack ID: #{channel.slack_id}, name: #{channel.name}, topic: #{channel.topic}, member count: #{channel.member_count}"} end + + def select(recipient_class:, name: nil, id: nil) + return ArgumentError.new("Both arguments cannot be empty at once") if(name == nil && id == nil) + + if(recipient_class == "user") + if name + return @users.find{|user| user.name == name} + else + return @users.find{|user| user.slack_id == id} + end + end + + if(recipient_class == "channel") + if name + return @channels.find{|channel| channel.name == name} + else + return @channels.find{|channel| channel.slack_id == id} + end + end + + end + end end \ No newline at end of file From d9df74c0bcef11b0921129277939bbad0978dd4e Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 7 Oct 2020 21:25:26 -0700 Subject: [PATCH 42/92] cassette changed --- test/cassettes/user_channel_find.yml | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/cassettes/user_channel_find.yml b/test/cassettes/user_channel_find.yml index 8f27bb4d..948ec558 100644 --- a/test/cassettes/user_channel_find.yml +++ b/test/cassettes/user_channel_find.yml @@ -144,4 +144,59 @@ http_interactions: channel is for... well, everything else. It\u2019s a place for team jokes, spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' recorded_at: Thu, 08 Oct 2020 01:31:30 GMT +- request: + method: get + uri: https://slack.com/api/users.list?token= + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 04:12:38 GMT + Server: + - Apache + X-Xss-Protection: + - '0' + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - users:read + X-Slack-Req-Id: + - 4725fb10fe2a14b6ed32c47c30ec5e48 + X-Slack-Backend: + - r + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Content-Type-Options: + - nosniff + Content-Length: + - '53' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-miae,haproxy-edge-pdx-0i42 + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"not_authed"}' + recorded_at: Thu, 08 Oct 2020 04:12:38 GMT recorded_with: VCR 6.0.0 From 88d201f03d4e4b5dc76ad116a6c7837b73a34073 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:11:11 -0700 Subject: [PATCH 43/92] created details method --- lib/channel.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/channel.rb b/lib/channel.rb index fad7aea3..95eb3523 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -19,5 +19,9 @@ def self.list_all end end + def details + return "ID: #{@slack_id} \nName: #{@name} \nTopic: #{@topic} \nMember Count: #{@member_count}" + end + end end \ No newline at end of file From bf71c2911f8dd744ddcc05788a88ef891a139109 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:11:37 -0700 Subject: [PATCH 44/92] updated details option --- lib/slack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack.rb b/lib/slack.rb index eddae8e2..33463b9b 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -38,7 +38,7 @@ def main current_selection = workspace.select(recipient_class: "channel", name: gets.chomp) end elsif option == "details" || option == "5" - puts current_selection.details + puts workspace.show_details(current_selection) end menu option = gets.chomp.downcase From 1f0bfb2640adabf57b85723c5dedfe23e65a1114 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:11:51 -0700 Subject: [PATCH 45/92] created details method --- lib/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/user.rb b/lib/user.rb index 90af4427..8e386294 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -20,7 +20,7 @@ def self.list_all end def details - + return "ID: #{@slack_id} \nName: #{@name} \nReal Name: #{@real_name} \nStatus: #{@status_text} \nEmoji: #{@status_emoji}" end From 561f269412435e18c1b5b90fce0eea2cc5a728d7 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:12:07 -0700 Subject: [PATCH 46/92] created show details method --- lib/workspace.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index b459656c..f990a193 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -22,7 +22,7 @@ def list_channels end def select(recipient_class:, name: nil, id: nil) - return ArgumentError.new("Both arguments cannot be empty at once") if(name == nil && id == nil) + raise ArgumentError.new("Both arguments cannot be empty at once") if(name == nil && id == nil) if(recipient_class == "user") if name @@ -42,5 +42,9 @@ def select(recipient_class:, name: nil, id: nil) end + def show_details(recipient) + return recipient.details + end + end end \ No newline at end of file From 046011cd27379cb7643dfc150b6e1fbd13ba42f5 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:12:24 -0700 Subject: [PATCH 47/92] tested list all and details methods --- test/channel_test.rb | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/test/channel_test.rb b/test/channel_test.rb index 45843add..3cb225ea 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -1,10 +1,12 @@ require_relative 'test_helper' describe 'Channel' do + + before do + @channel = SlackCLI::Channel.new(slack_id: "1234id", name: "Channely Channelson", topic: "topic", member_count: 24) + end + describe "initialize" do - before do - @channel = SlackCLI::Channel.new(slack_id: "1234id", name: "Channely Channelson", topic: "topic", member_count: 24) - end it "constructor properly creates a Channel object" do expect(@channel).must_be_instance_of SlackCLI::Channel end @@ -22,4 +24,29 @@ expect(@channel.member_count).must_be_instance_of Integer end end + + describe "list all" do + it "returns an array" do + VCR.use_cassette("channel_list_all") do + expect(SlackCLI::Channel.list_all).must_be_instance_of Array + end + end + + it "returns an array of Channels" do + VCR.use_cassette("channel_list_all") do + expect(SlackCLI::Channel.list_all.first).must_be_instance_of SlackCLI::Channel + end + end + end + + describe "details method" do + + it "returns a string" do + expect(@channel.details).must_be_instance_of String + end + + it "returns accurate information" do + expect(@channel.details).must_equal "ID: #{@channel.slack_id} \nName: #{@channel.name} \nTopic: #{@channel.topic} \nMember Count: #{@channel.member_count}" + end + end end \ No newline at end of file From ff92f77ec4ad676a8af2854667a98085a9289afd Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:12:35 -0700 Subject: [PATCH 48/92] tested list all and details methods --- test/user_test.rb | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/test/user_test.rb b/test/user_test.rb index 0bc2c869..b7a5a676 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -1,10 +1,12 @@ require_relative 'test_helper' describe 'User' do + before do + @user = SlackCLI::User.new(slack_id: "5678id", name: "Namey Nameson", real_name: "Namey Nameson", status_text: "status", status_emoji: ":smiley:") + end + describe "initialize" do - before do - @user = SlackCLI::User.new(slack_id: "5678id", name: "Namey Nameson", real_name: "Namey Nameson", status_text: "status", status_emoji: ":smiley:") - end + it "constructor properly creates a Channel object" do expect(@user).must_be_instance_of SlackCLI::User end @@ -26,4 +28,29 @@ expect(@user.status_emoji).must_be_instance_of String end end + + describe "list all" do + it "returns an array" do + VCR.use_cassette("user_list_all") do + expect(SlackCLI::User.list_all).must_be_instance_of Array + end + end + + it "returns an array of Users" do + VCR.use_cassette("user_list_all") do + expect(SlackCLI::User.list_all.first).must_be_instance_of SlackCLI::User + end + end + end + + describe "details method" do + + it "returns a string" do + expect(@user.details).must_be_instance_of String + end + + it "returns accurate information" do + expect(@user.details).must_equal "ID: #{@user.slack_id} \nName: #{@user.name} \nReal Name: #{@user.real_name} \nStatus: #{@user.status_text} \nEmoji: #{@user.status_emoji}" + end + end end \ No newline at end of file From b15629882ac2405845cc74c8b0bc8be57b980c2f Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:12:49 -0700 Subject: [PATCH 49/92] tested show details method --- test/workspace_test.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 15317a4d..ace07139 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -33,4 +33,34 @@ expect(@workspace.list_channels.first).must_equal "Slack ID: C01BL0GSPP1, name: good-place-simulation, topic: torture Chidi, member count: 2" end end + + describe "select method" do + + it "raises ArgumentError if name or id isn't provided" do + expect{@workspace.select(recipient_class: "user")}.must_raise ArgumentError + end + + it "returns correct User" do + expect(@workspace.select(recipient_class: "user", id: "USLACKBOT").name).must_equal "slackbot" + end + + it "returns correct Channel" do + expect(@workspace.select(recipient_class: "channel", name: "general").slack_id).must_equal "C01BU0NRFHC" + end + + end + + describe "show details method" do + before do + @user = SlackCLI::User.new(slack_id: "1234asdf", name: "testname", real_name: "bob", status_text: "i am a status", status_emoji: ":grr:") + end + + it "returns a string" do + expect(@workspace.show_details(@user)).must_be_instance_of String + end + + it "returns accurate information" do + expect(@workspace.show_details(@user)).must_equal @user.details + end + end end \ No newline at end of file From cbe5d6613f1431dad5b2af240e3c6d6bf6b9d6cf Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:13:04 -0700 Subject: [PATCH 50/92] updated cassettes --- test/cassettes/channel_list_all.yml | 73 +++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/cassettes/channel_list_all.yml diff --git a/test/cassettes/channel_list_all.yml b/test/cassettes/channel_list_all.yml new file mode 100644 index 00000000..20025e3e --- /dev/null +++ b/test/cassettes/channel_list_all.yml @@ -0,0 +1,73 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 05:09:46 GMT + Server: + - Apache + X-Slack-Req-Id: + - c8fc035fa016569f00ddc5364179d198 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '684' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-x7jt,haproxy-edge-pdx-jxbh + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":2},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":2},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + recorded_at: Thu, 08 Oct 2020 05:09:47 GMT +recorded_with: VCR 6.0.0 From ef8e895896886284d8d9675b287c5f0f4d927950 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Wed, 7 Oct 2020 22:13:21 -0700 Subject: [PATCH 51/92] new cassettes --- test/cassettes/user_list_all.yml | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 test/cassettes/user_list_all.yml diff --git a/test/cassettes/user_list_all.yml b/test/cassettes/user_list_all.yml new file mode 100644 index 00000000..6c2393d9 --- /dev/null +++ b/test/cassettes/user_list_all.yml @@ -0,0 +1,77 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 05:05:26 GMT + Server: + - Apache + X-Slack-Req-Id: + - 5ccf2bf5af8f301670df24728fbdcf3d + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1279' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-hwvv,haproxy-edge-pdx-f5k6 + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01CDB91DEV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BL0TC86B","team_id":"T01CDB91DEV","name":"water_jessica_api_pro","deleted":false,"color":"3c989f","real_name":"Water + - Jessica - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Jessica - API Project","real_name_normalized":"Water - Jessica - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g16790b5cf92","api_app_id":"A01CDBH820Z","always_active":false,"bot_id":"B01BU12FUEA","image_24":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951747},{"id":"U01C0N8RAUS","team_id":"T01CDB91DEV","name":"jwinchan","deleted":false,"color":"4bbe2e","real_name":"Jessica + Chan","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jessica + Chan","real_name_normalized":"Jessica Chan","display_name":"Jessica (she.her)","display_name_normalized":"Jessica + (she.her)","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g39037b8a717","first_name":"Jessica","last_name":"Chan","image_24":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601951226,"has_2fa":false},{"id":"U01C6TTNL6Q","team_id":"T01CDB91DEV","name":"iris.lux0","deleted":false,"color":"9f69e7","real_name":"iris.lux0","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"iris.lux0","real_name_normalized":"iris.lux0","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g8d593922863","image_24":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601950931},{"id":"U01CDBMR333","team_id":"T01CDB91DEV","name":"water_iris_api_projec","deleted":false,"color":"e7392d","real_name":"Water + - Iris - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602133526,"response_metadata":{"next_cursor":""}}' + recorded_at: Thu, 08 Oct 2020 05:05:26 GMT +recorded_with: VCR 6.0.0 From 96ff74a81d279f6cb26674ea92c1713d5bd7feb1 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 16:40:36 -0700 Subject: [PATCH 52/92] added send message to interface --- lib/slack.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 33463b9b..01f08fae 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -12,7 +12,7 @@ def main option = nil current_selection = nil - until option == "quit" || option == "6" + until option == "quit" || option == "7" if option == "list users" || option == "1" puts workspace.list_users elsif option == "list channels" || option == "2" @@ -39,6 +39,10 @@ def main end elsif option == "details" || option == "5" puts workspace.show_details(current_selection) + elsif option == "send message" || option == "6" + puts "please enter message" + message = gets.chomp + workspace.send_message(message, current_selection) end menu option = gets.chomp.downcase @@ -54,7 +58,8 @@ def menu puts "3. select user" puts "4. select channel" puts "5. details" - puts "6. quit" + puts "6. send message" + puts "7. quit" end main if __FILE__ == $PROGRAM_NAME \ No newline at end of file From d92b0e4608a75445ee7e854502bf929ba33b97cf Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 16:41:05 -0700 Subject: [PATCH 53/92] added send_message --- lib/workspace.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/workspace.rb b/lib/workspace.rb index f990a193..930108b0 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -46,5 +46,21 @@ def show_details(recipient) return recipient.details end + def send_message(message, recipient) + response = HTTParty.post( + "https://slack.com/api/chat.postMessage", + body: { + token: ENV["SLACK_API_TOKEN"], + text: message, + channel: recipient.slack_id, + as_user: "true" + }, + headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } + ) + + return response.code == 200 && response.parsed_response["ok"] + end + + end end \ No newline at end of file From d4696367cb4fd9d0ad2a8913e05a693b8bd96d5c Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 16:41:56 -0700 Subject: [PATCH 54/92] added tests for send_message --- test/workspace_test.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index ace07139..8585d05b 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -63,4 +63,22 @@ expect(@workspace.show_details(@user)).must_equal @user.details end end + + describe "send_message method" do + it "can send a valid message to user" do + VCR.use_cassette("slack-posts-user") do + recipient = @workspace.select(recipient_class: "user", id: "U01C6TTNL6Q") + response = @workspace.send_message("Test Test Test", recipient) + expect(response).must_equal true + end + end + + it "can send a valid message to channel" do + VCR.use_cassette("slack-posts-channel") do + recipient = @workspace.select(recipient_class: "channel", id: "C01BU0NRFHC") + response = @workspace.send_message("Test Test Test", recipient) + expect(response).must_equal true + end + end + end end \ No newline at end of file From 2f3a1ec683cc8a43053f76a77c0f3532f9a9e09a Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 16:42:24 -0700 Subject: [PATCH 55/92] new cassetts for send_message --- test/cassettes/slack-posts-channel.yml | 70 ++++++++++++++++++++++++++ test/cassettes/slack-posts-user.yml | 70 ++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 test/cassettes/slack-posts-channel.yml create mode 100644 test/cassettes/slack-posts-user.yml diff --git a/test/cassettes/slack-posts-channel.yml b/test/cassettes/slack-posts-channel.yml new file mode 100644 index 00000000..0849491a --- /dev/null +++ b/test/cassettes/slack-posts-channel.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=C01BU0NRFHC&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 23:35:01 GMT + Server: + - Apache + X-Slack-Req-Id: + - 5b437ab515233ed456f357a83ebd7c89 + X-Oauth-Scopes: + - chat:write,users:read,channels:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '334' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-l4g1,haproxy-edge-pdx-8rbg + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"C01BU0NRFHC","ts":"1602200101.000600","message":{"bot_id":"B01C0UMPS1Z","type":"message","text":"Test + Test Test","user":"U01CDBMR333","ts":"1602200101.000600","team":"T01CDB91DEV","bot_profile":{"id":"B01C0UMPS1Z","deleted":false,"name":"Water + - Iris - API Project","updated":1601951694,"app_id":"A01CDBH7333","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}}}' + recorded_at: Thu, 08 Oct 2020 23:35:01 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/slack-posts-user.yml b/test/cassettes/slack-posts-user.yml new file mode 100644 index 00000000..44ef90ba --- /dev/null +++ b/test/cassettes/slack-posts-user.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=U01C6TTNL6Q&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 23:28:53 GMT + Server: + - Apache + X-Slack-Req-Id: + - 51a669113834b1e6f83285aef8a68a77 + X-Oauth-Scopes: + - chat:write,users:read,channels:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '332' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-9c0q,haproxy-edge-pdx-uehx + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"D01C6U6GXRS","ts":"1602199733.000100","message":{"bot_id":"B01C0UMPS1Z","type":"message","text":"Test + Test Test","user":"U01CDBMR333","ts":"1602199733.000100","team":"T01CDB91DEV","bot_profile":{"id":"B01C0UMPS1Z","deleted":false,"name":"Water + - Iris - API Project","updated":1601951694,"app_id":"A01CDBH7333","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}}}' + recorded_at: Thu, 08 Oct 2020 23:28:53 GMT +recorded_with: VCR 6.0.0 From 2cea42939338fa7651d779bb0d5b3ebfd88850fa Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:20:24 -0700 Subject: [PATCH 56/92] updated send message syntax --- lib/dotenv_test.rb | 10 ---------- lib/slack.rb | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 lib/dotenv_test.rb diff --git a/lib/dotenv_test.rb b/lib/dotenv_test.rb deleted file mode 100644 index 96856295..00000000 --- a/lib/dotenv_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -# dotenv_practice.rb -require 'dotenv' -require 'httparty' -# Tell dotenv to look for the .env file -Dotenv.load - -puts - -channels = HTTParty.get('https://slack.com/api/conversations.list', query: {token: ENV["SLACK_API_TOKEN"]})["channels"].each{|channel| puts channel["name"]} - diff --git a/lib/slack.rb b/lib/slack.rb index 01f08fae..cf603a8a 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -42,7 +42,7 @@ def main elsif option == "send message" || option == "6" puts "please enter message" message = gets.chomp - workspace.send_message(message, current_selection) + workspace.send_message(message, current_selection.slack_id) end menu option = gets.chomp.downcase From f2df8108110edbf0efc08ad046e81f4b3a69ceb2 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:20:50 -0700 Subject: [PATCH 57/92] raise error for incorrect input --- lib/workspace.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 930108b0..8f233a5a 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -46,19 +46,24 @@ def show_details(recipient) return recipient.details end - def send_message(message, recipient) + def send_message(message, recipient_id) + response = HTTParty.post( "https://slack.com/api/chat.postMessage", body: { token: ENV["SLACK_API_TOKEN"], text: message, - channel: recipient.slack_id, + channel: recipient_id, as_user: "true" }, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } ) - return response.code == 200 && response.parsed_response["ok"] + unless response.code == 200 && response.parsed_response["ok"] + raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") + end + + return true end From deb623b21d9cb8ee6d4e68c7b57a0ea74b152805 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:21:37 -0700 Subject: [PATCH 58/92] recorded new cassettes for testing --- test/cassettes/slack-posts-channel.yml | 65 ++++++++++++++++++++++++++ test/cassettes/slack-posts-user.yml | 65 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/test/cassettes/slack-posts-channel.yml b/test/cassettes/slack-posts-channel.yml index 0849491a..cf297f8e 100644 --- a/test/cassettes/slack-posts-channel.yml +++ b/test/cassettes/slack-posts-channel.yml @@ -67,4 +67,69 @@ http_interactions: Test Test","user":"U01CDBMR333","ts":"1602200101.000600","team":"T01CDB91DEV","bot_profile":{"id":"B01C0UMPS1Z","deleted":false,"name":"Water - Iris - API Project","updated":1601951694,"app_id":"A01CDBH7333","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}}}' recorded_at: Thu, 08 Oct 2020 23:35:01 GMT +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=%23%3CSlackCLI%3A%3AChannel%3A0x00007fa73fb01768%3E&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 00:10:11 GMT + Server: + - Apache + X-Slack-Req-Id: + - 3f9daeae6ac8e56f16456501b2305326 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '60' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-tazm,haproxy-edge-pdx-vs95 + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"channel_not_found"}' + recorded_at: Fri, 09 Oct 2020 00:10:10 GMT recorded_with: VCR 6.0.0 diff --git a/test/cassettes/slack-posts-user.yml b/test/cassettes/slack-posts-user.yml index 44ef90ba..7f7a209e 100644 --- a/test/cassettes/slack-posts-user.yml +++ b/test/cassettes/slack-posts-user.yml @@ -67,4 +67,69 @@ http_interactions: Test Test","user":"U01CDBMR333","ts":"1602199733.000100","team":"T01CDB91DEV","bot_profile":{"id":"B01C0UMPS1Z","deleted":false,"name":"Water - Iris - API Project","updated":1601951694,"app_id":"A01CDBH7333","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}}}' recorded_at: Thu, 08 Oct 2020 23:28:53 GMT +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=%23%3CSlackCLI%3A%3AUser%3A0x00007fa742ae3030%3E&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 00:10:11 GMT + Server: + - Apache + X-Slack-Req-Id: + - ca392929b69a66ba73a92a5d2b3e88df + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '60' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-eips,haproxy-edge-pdx-9tv4 + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"channel_not_found"}' + recorded_at: Fri, 09 Oct 2020 00:10:10 GMT recorded_with: VCR 6.0.0 From 13723656005c9436a58887bdd2345899d40022ea Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:22:03 -0700 Subject: [PATCH 59/92] required relative to new error file --- test/test_helper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index d47946ae..7b667860 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -13,13 +13,14 @@ require_relative '../lib/user' require_relative '../lib/channel' require_relative '../lib/workspace' +require_relative '../lib/slackapierror' Dotenv.load Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| - config.cassette_library_dir = "test/cassettes" # folder where casettes will be located + config.cassette_library_dir = "test/cassettes" # folder where cassettes will be located config.hook_into :webmock # tie into this other tool called webmock config.default_cassette_options = { :record => :new_episodes, # record new data when we don't have it yet From 9d1e3b572a3ca87af459d3381a6246796c9dc943 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:22:53 -0700 Subject: [PATCH 60/92] created tests for edge cases --- test/workspace_test.rb | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 8585d05b..941f8d84 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -67,18 +67,28 @@ describe "send_message method" do it "can send a valid message to user" do VCR.use_cassette("slack-posts-user") do - recipient = @workspace.select(recipient_class: "user", id: "U01C6TTNL6Q") - response = @workspace.send_message("Test Test Test", recipient) + response = @workspace.send_message("Test Test Test", "U01C6TTNL6Q") expect(response).must_equal true end end it "can send a valid message to channel" do VCR.use_cassette("slack-posts-channel") do - recipient = @workspace.select(recipient_class: "channel", id: "C01BU0NRFHC") - response = @workspace.send_message("Test Test Test", recipient) + response = @workspace.send_message("Test Test Test", "C01BU0NRFHC") expect(response).must_equal true end end + + it "returns an error if no recipient selected" do + VCR.use_cassette("slack-posts-no-recipient") do + expect{@workspace.send_message("Test Test Test", nil)}.must_raise SlackCLI::SlackAPIError + end + end + + it "returns an error if wrong channel selected" do + VCR.use_cassette("slack-posts-wrong-channel") do + expect{@workspace.send_message("Test Test Test", "2i3nfidl")}.must_raise SlackCLI::SlackAPIError + end + end end end \ No newline at end of file From 93f7ee00596dd6057b2f7e1d0c9292b5f778e503 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:23:20 -0700 Subject: [PATCH 61/92] created custom error --- lib/slackapierror.rb | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lib/slackapierror.rb diff --git a/lib/slackapierror.rb b/lib/slackapierror.rb new file mode 100644 index 00000000..9c5adb09 --- /dev/null +++ b/lib/slackapierror.rb @@ -0,0 +1,4 @@ +module SlackCLI + class SlackAPIError < StandardError + end +end \ No newline at end of file From bef3c33902e06bc6d71316acd534ad848fb720c9 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 17:23:32 -0700 Subject: [PATCH 62/92] created new cassettes --- test/cassettes/slack-posts-no-recipient.yml | 68 ++++++++++++++++++++ test/cassettes/slack-posts-wrong-channel.yml | 68 ++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 test/cassettes/slack-posts-no-recipient.yml create mode 100644 test/cassettes/slack-posts-wrong-channel.yml diff --git a/test/cassettes/slack-posts-no-recipient.yml b/test/cassettes/slack-posts-no-recipient.yml new file mode 100644 index 00000000..55c6fbec --- /dev/null +++ b/test/cassettes/slack-posts-no-recipient.yml @@ -0,0 +1,68 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 00:16:40 GMT + Server: + - Apache + X-Slack-Req-Id: + - cc21239b7ba51235090c87c5a8ec1df0 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '60' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-jd2d,haproxy-edge-pdx-j73n + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"channel_not_found"}' + recorded_at: Fri, 09 Oct 2020 00:16:39 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/slack-posts-wrong-channel.yml b/test/cassettes/slack-posts-wrong-channel.yml new file mode 100644 index 00000000..15386689 --- /dev/null +++ b/test/cassettes/slack-posts-wrong-channel.yml @@ -0,0 +1,68 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=2i3nfidl&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 00:16:40 GMT + Server: + - Apache + X-Slack-Req-Id: + - 0e52c09c422a7f81069b6f58a60389a3 + X-Oauth-Scopes: + - identify,channels:history,channels:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '60' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-6rku,haproxy-edge-pdx-bh39 + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"channel_not_found"}' + recorded_at: Fri, 09 Oct 2020 00:16:39 GMT +recorded_with: VCR 6.0.0 From 4fd4fc9ddc2c9067863e4949958f31495ebfb285 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 18:16:25 -0700 Subject: [PATCH 63/92] added select method --- lib/recipient.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/recipient.rb b/lib/recipient.rb index 55df1804..cf4585fc 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -33,5 +33,8 @@ def self.list_all raise NotImplementedError, 'Implement me in a child class!' end + def self.select(identifier) + return self.list_all.find{|recipient| recipient.slack_id == identifier || recipient.name == identifier} + end end end \ No newline at end of file From c1365619db753d5461ba017b58ac3db44104f4fa Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 18:17:31 -0700 Subject: [PATCH 64/92] added details and send_message msg --- lib/slack.rb | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 01f08fae..87be3410 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -18,39 +18,41 @@ def main elsif option == "list channels" || option == "2" puts workspace.list_channels elsif option == "select user" || option == "3" - puts "Are you entering the name or id?" - name_or_id = gets.chomp - if(name_or_id == "id") - puts "Please enter id" - current_selection = workspace.select(recipient_class: "user", id: gets.chomp) - else - puts "Please enter name" - current_selection = workspace.select(recipient_class: "user", name: gets.chomp) - end + puts "Enter the name or id" + current_selection = workspace.select("user",gets.chomp) + puts "Selection not found" if(current_selection.nil?) elsif option == "select channel" || option == "4" - puts "Are you entering the name or id?" - name_or_id = gets.chomp - if(name_or_id == "id") - puts "Please enter id" - current_selection = workspace.select(recipient_class: "channel", id: gets.chomp) - else - puts "Please enter name" - current_selection = workspace.select(recipient_class: "channel", name: gets.chomp) - end + puts "Enter the name or id" + current_selection = workspace.select("channel",gets.chomp) + puts "Selection not found" if(current_selection.nil?) elsif option == "details" || option == "5" - puts workspace.show_details(current_selection) + details(current_selection, workspace) elsif option == "send message" || option == "6" - puts "please enter message" - message = gets.chomp - workspace.send_message(message, current_selection) + send_message(current_selection, workspace) end menu option = gets.chomp.downcase end - puts "Thank you for using the Ada Slack CLI" end +def details(recipient, workspace) + if recipient.nil? + puts "No recipient selected" + else + puts workspace.show_details(recipient) + end +end + +def send_message(recipient, workspace) + if recipient.nil? + puts "No recipient selected" + else + puts "please enter message" + workspace.send_message(gets.chomp, recipient) + end +end + def menu puts "Please select one of the three options: " puts "1. list users" From ad290fb3ef485ab1ccffc42977d7f5da645a4cc1 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 18:18:42 -0700 Subject: [PATCH 65/92] removed unnecesary code --- lib/user.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/user.rb b/lib/user.rb index 8e386294..7e12e8ec 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -24,13 +24,5 @@ def details end - - private - - def self.from_api(json_hash) - - end - - end end \ No newline at end of file From abe81c7144208eb3e0fb7cbacd8cd6079e098c2a Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 18:19:23 -0700 Subject: [PATCH 66/92] refactored select method --- lib/workspace.rb | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 930108b0..e5cec8f9 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -21,25 +21,15 @@ def list_channels return @channels.map{|channel| "Slack ID: #{channel.slack_id}, name: #{channel.name}, topic: #{channel.topic}, member count: #{channel.member_count}"} end - def select(recipient_class:, name: nil, id: nil) - raise ArgumentError.new("Both arguments cannot be empty at once") if(name == nil && id == nil) + def select(recipient_class,identifier) + raise ArgumentError.new("Argument cannot be empty") if(identifier == nil) + raise ArgumentError.new("Recipient class must be user or channel") unless recipient_class == "user" || recipient_class == "channel" if(recipient_class == "user") - if name - return @users.find{|user| user.name == name} - else - return @users.find{|user| user.slack_id == id} - end + return User.select(identifier) + elsif(recipient_class == "channel") + return Channel.select(identifier) end - - if(recipient_class == "channel") - if name - return @channels.find{|channel| channel.name == name} - else - return @channels.find{|channel| channel.slack_id == id} - end - end - end def show_details(recipient) From f88c771f0b97dc30a9501b125e7fc851da798bbf Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 19:28:14 -0700 Subject: [PATCH 67/92] added channel history option --- lib/slack.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index b4ecbfd6..8261ccf0 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -12,7 +12,7 @@ def main option = nil current_selection = nil - until option == "quit" || option == "7" + until option == "quit" || option == "8" if option == "list users" || option == "1" puts workspace.list_users elsif option == "list channels" || option == "2" @@ -29,6 +29,10 @@ def main details(current_selection, workspace) elsif option == "send message" || option == "6" send_message(current_selection, workspace) + elsif option == "channel history" || option == "7" + message_history(current_selection, workspace) + else + puts "Please input a valid option" end menu option = gets.chomp.downcase @@ -54,7 +58,16 @@ def send_message(recipient, workspace) end end +def message_history(recipient, workspace) + if recipient.nil? || recipient.is_a? User + puts "Please select a channel" + else + puts workspace.conversation_history(recipient.slack_id) + end +end + def menu + puts "**" * 20 puts "Please select one of the three options: " puts "1. list users" puts "2. list channels" @@ -62,7 +75,9 @@ def menu puts "4. select channel" puts "5. details" puts "6. send message" - puts "7. quit" + puts "7. channel history" + puts "8. quit" + puts "**" * 20 end main if __FILE__ == $PROGRAM_NAME \ No newline at end of file From a99623a7205fe5dc0c8fa512d9314fda6ffc3d0c Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 19:28:26 -0700 Subject: [PATCH 68/92] created channel history method --- lib/workspace.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 07a5e127..7379132e 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -21,7 +21,7 @@ def list_channels return @channels.map{|channel| "Slack ID: #{channel.slack_id}, name: #{channel.name}, topic: #{channel.topic}, member count: #{channel.member_count}"} end - def select(recipient_class,identifier) + def select(recipient_class, identifier) raise ArgumentError.new("Argument cannot be empty") if(identifier == nil) raise ArgumentError.new("Recipient class must be user or channel") unless recipient_class == "user" || recipient_class == "channel" @@ -56,6 +56,13 @@ def send_message(message, recipient_id) return true end + def conversation_history(channel_id) + response = HTTParty.get("https://slack.com/api/conversations.history", query: {token: ENV["SLACK_API_TOKEN"], channel: channel_id}) + return response["messages"].map{ |message| message["text"] } + end + + + end end \ No newline at end of file From 1a75b2c4eb37e0905fd7f4b4cfa1e082b02ec54d Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 19:28:50 -0700 Subject: [PATCH 69/92] tested channel history method --- test/workspace_test.rb | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 941f8d84..0bd751ee 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -37,15 +37,21 @@ describe "select method" do it "raises ArgumentError if name or id isn't provided" do - expect{@workspace.select(recipient_class: "user")}.must_raise ArgumentError + VCR.use_cassette("invalid_select") do + expect{@workspace.select("user", nil)}.must_raise ArgumentError + end end it "returns correct User" do - expect(@workspace.select(recipient_class: "user", id: "USLACKBOT").name).must_equal "slackbot" + VCR.use_cassette("select_user") do + expect(@workspace.select("user", "USLACKBOT").name).must_equal "slackbot" + end end it "returns correct Channel" do - expect(@workspace.select(recipient_class: "channel", name: "general").slack_id).must_equal "C01BU0NRFHC" + VCR.use_cassette("select_channel") do + expect(@workspace.select("channel", "general").slack_id).must_equal "C01BU0NRFHC" + end end end @@ -91,4 +97,24 @@ end end end + + describe "coversation history method" do + it "returns an Array" do + VCR.use_cassette("channel_history") do + expect(@workspace.conversation_history("C01BL0GSPP1")).must_be_instance_of Array + end + end + + it "returns an Array of Strings" do + VCR.use_cassette("channel_history") do + expect(@workspace.conversation_history("C01BL0GSPP1").first).must_be_instance_of String + end + end + + it "returns accurate information" do + VCR.use_cassette("channel_history") do + expect(@workspace.conversation_history("C01BL0GSPP1").first).must_equal "make Chidi choose a puppy" + end + end + end end \ No newline at end of file From b1f8312f0cdd7ce91f8ebfa0f14850e4a0845395 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 19:29:05 -0700 Subject: [PATCH 70/92] recorded new cassettes --- test/cassettes/channel_history.yml | 75 ++++++++++++++++++++++++++++ test/cassettes/select_channel.yml | 73 ++++++++++++++++++++++++++++ test/cassettes/select_user.yml | 78 ++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 test/cassettes/channel_history.yml create mode 100644 test/cassettes/select_channel.yml create mode 100644 test/cassettes/select_user.yml diff --git a/test/cassettes/channel_history.yml b/test/cassettes/channel_history.yml new file mode 100644 index 00000000..898f139a --- /dev/null +++ b/test/cassettes/channel_history.yml @@ -0,0 +1,75 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.history?channel=C01BL0GSPP1&token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 02:23:18 GMT + Server: + - Apache + X-Slack-Req-Id: + - ad77de7e299e39a8f1b90e4bcc8c8b82 + X-Oauth-Scopes: + - chat:write,channels:manage,groups:write,channels:read,users:read,channels:history,groups:history,im:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:history,groups:history,mpim:history,im:history,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '577' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-1obv,haproxy-edge-pdx-rgh8 + body: + encoding: ASCII-8BIT + string: '{"ok":true,"messages":[{"bot_id":"B01BU12FUEA","type":"message","text":"make + Chidi choose a puppy","user":"U01BL0TC86B","ts":"1602195554.001100","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water + - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"bot_id":"B01BU12FUEA","type":"message","text":"flatten + penises","user":"U01BL0TC86B","ts":"1602192941.000900","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water + - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"type":"message","subtype":"channel_join","ts":"1602189817.000700","user":"U01CDBMR333","text":"<@U01CDBMR333> + has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_join","ts":"1602189744.000400","user":"U01BL0TC86B","text":"<@U01BL0TC86B> + has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_topic","ts":"1602116354.000200","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> + set the channel topic: torture Chidi","topic":"torture Chidi"},{"type":"message","subtype":"channel_join","ts":"1601951182.000500","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> + has joined the channel"},{"type":"message","subtype":"channel_join","ts":"1601951127.000200","user":"U01C6TTNL6Q","text":"<@U01C6TTNL6Q> + has joined the channel"}],"has_more":false,"pin_count":0,"channel_actions_ts":null,"channel_actions_count":0}' + recorded_at: Fri, 09 Oct 2020 02:23:17 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/select_channel.yml b/test/cassettes/select_channel.yml new file mode 100644 index 00000000..0ab3f83e --- /dev/null +++ b/test/cassettes/select_channel.yml @@ -0,0 +1,73 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 01:34:48 GMT + Server: + - Apache + X-Slack-Req-Id: + - 6a74dbcb93d4d758cdd2a9681eef20f2 + X-Oauth-Scopes: + - chat:write,channels:manage,groups:write,channels:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '773' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-h7cu,haproxy-edge-pdx-1cbr + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":4},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":3},{"id":"C01C2B4BJ30","name":"jasons-bud-hole","is_channel":true,"is_group":false,"is_im":false,"created":1602195856,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"jasons-bud-hole","is_shared":false,"parent_conversation":null,"creator":"U01BL0TC86B","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"boooortles","creator":"U01C0N8RAUS","last_set":1602195936},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":4},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4}],"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 01:34:47 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/select_user.yml b/test/cassettes/select_user.yml new file mode 100644 index 00000000..b102e651 --- /dev/null +++ b/test/cassettes/select_user.yml @@ -0,0 +1,78 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 01:34:48 GMT + Server: + - Apache + X-Slack-Req-Id: + - feadf76e80da61f1276dab7786d6c73f + X-Oauth-Scopes: + - chat:write,channels:manage,groups:write,channels:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1319' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-immm,haproxy-edge-pdx-vs95 + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01CDB91DEV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BL0TC86B","team_id":"T01CDB91DEV","name":"water_jessica_api_pro","deleted":false,"color":"3c989f","real_name":"Water + - Jessica - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Jessica - API Project","real_name_normalized":"Water - Jessica - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g16790b5cf92","api_app_id":"A01CDBH820Z","always_active":false,"bot_id":"B01BU12FUEA","image_24":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951747},{"id":"U01C0N8RAUS","team_id":"T01CDB91DEV","name":"jwinchan","deleted":false,"color":"4bbe2e","real_name":"Jessica + Chan","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jessica + Chan","real_name_normalized":"Jessica Chan","display_name":"Jessica (she.her)","display_name_normalized":"Jessica + (she.her)","fields":null,"status_text":"Working remotely","status_emoji":":house_with_garden:","status_expiration":1602226799,"avatar_hash":"g39037b8a717","first_name":"Jessica","last_name":"Chan","image_24":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-512.png","status_text_canonical":"Working + remotely","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1602143803},{"id":"U01C6TTNL6Q","team_id":"T01CDB91DEV","name":"iris.lux0","deleted":false,"color":"9f69e7","real_name":"iris.lux0","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"iris.lux0","real_name_normalized":"iris.lux0","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g8d593922863","image_24":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601950931},{"id":"U01CDBMR333","team_id":"T01CDB91DEV","name":"water_iris_api_projec","deleted":false,"color":"e7392d","real_name":"Water + - Iris - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602207288,"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 01:34:47 GMT +recorded_with: VCR 6.0.0 From 7dad6d94f11083f930cdea489f35a41726b6249b Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:24:09 -0700 Subject: [PATCH 71/92] fixed spacing --- lib/channel.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/channel.rb b/lib/channel.rb index 95eb3523..2bb8efed 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -22,6 +22,5 @@ def self.list_all def details return "ID: #{@slack_id} \nName: #{@name} \nTopic: #{@topic} \nMember Count: #{@member_count}" end - end end \ No newline at end of file From 6030580b42a66ff88cb829ff7b98a20679a54c0b Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:24:51 -0700 Subject: [PATCH 72/92] added error for bad api calls --- lib/recipient.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index cf4585fc..9c85d94a 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -21,8 +21,12 @@ def self.validate_id(id) def self.get(url, params) raise ArgumentError.new("invalid arguments") unless (url.is_a?(String) && params.is_a?(Hash)) - api_info = HTTParty.get(url, query: params) - return api_info + response = HTTParty.get(url, query: params) + unless response.code == 200 && response.parsed_response["ok"] + raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") + end + + return response end def details From c0ce8d02b9b5f9f5c9a1f6be444833db31527aac Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:25:31 -0700 Subject: [PATCH 73/92] refactored select --- lib/slack.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 8261ccf0..ce709a17 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -19,11 +19,11 @@ def main puts workspace.list_channels elsif option == "select user" || option == "3" puts "Enter the name or id" - current_selection = workspace.select("user",gets.chomp) + current_selection = workspace.select(SlackCLI::User,gets.chomp) puts "Selection not found" if(current_selection.nil?) elsif option == "select channel" || option == "4" puts "Enter the name or id" - current_selection = workspace.select("channel",gets.chomp) + current_selection = workspace.select(SlackCLI::Channel,gets.chomp) puts "Selection not found" if(current_selection.nil?) elsif option == "details" || option == "5" details(current_selection, workspace) @@ -59,7 +59,7 @@ def send_message(recipient, workspace) end def message_history(recipient, workspace) - if recipient.nil? || recipient.is_a? User + if recipient.nil? || recipient.is_a?(SlackCLI::User) puts "Please select a channel" else puts workspace.conversation_history(recipient.slack_id) From a2604eb7eff8ff7e5f0a102ebadb392881e29a69 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:26:23 -0700 Subject: [PATCH 74/92] refactored select - duck typing instead of if --- lib/workspace.rb | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 7379132e..c47ec50e 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -13,23 +13,18 @@ def initialize #user name, real name, slack Id def list_users - return @users.map{|user| "Slack ID: #{user.slack_id}, Username: #{user.name}, Real name: #{user.real_name}"} + return @users.map{|user| "Slack ID: #{user.slack_id}\nUsername: #{user.name}\nReal name: #{user.real_name}\n"} end #topic, member count, slack ID, topic["value"] def list_channels - return @channels.map{|channel| "Slack ID: #{channel.slack_id}, name: #{channel.name}, topic: #{channel.topic}, member count: #{channel.member_count}"} + return @channels.map{|channel| "Slack ID: #{channel.slack_id}\nName: #{channel.name}\nTopic: #{channel.topic}\nMember count: #{channel.member_count}\n"} end def select(recipient_class, identifier) raise ArgumentError.new("Argument cannot be empty") if(identifier == nil) - raise ArgumentError.new("Recipient class must be user or channel") unless recipient_class == "user" || recipient_class == "channel" - - if(recipient_class == "user") - return User.select(identifier) - elsif(recipient_class == "channel") - return Channel.select(identifier) - end + raise ArgumentError.new("Recipient class must be user or channel") unless recipient_class == SlackCLI::User || recipient_class == SlackCLI::Channel + recipient_class.select(identifier) end def show_details(recipient) @@ -60,9 +55,5 @@ def conversation_history(channel_id) response = HTTParty.get("https://slack.com/api/conversations.history", query: {token: ENV["SLACK_API_TOKEN"], channel: channel_id}) return response["messages"].map{ |message| message["text"] } end - - - - end end \ No newline at end of file From 6efee41cfa8a0d46c72ea0ddfc076c734632c52d Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:27:19 -0700 Subject: [PATCH 75/92] revised test for refactored select method --- test/recipient_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index ef4a4de0..148386d1 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -25,6 +25,19 @@ it "raises ArgumentError for incorrect parameters" do expect{SlackCLI::Recipient.get("url", "not a hash")}.must_raise ArgumentError end + + it "raises SlackAPIError for bad API call" do + VCR.use_cassette("self.get API error") do + expect{SlackCLI::Recipient.get("https://slack.com/api/users.list", {token: "sggreg"})}.must_raise SlackCLI::SlackAPIError + end + end + + it "returns HTTParty::Response for succesful calls" do + VCR.use_cassette("self.get nominal") do + expect(SlackCLI::Recipient.get("https://slack.com/api/users.list", {token: ENV["SLACK_API_TOKEN"]})).must_be_instance_of HTTParty::Response + end + end + end describe 'details' do From a8b0ecbbc9be3669e4351b9a8dfc7d361a3de351 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:28:21 -0700 Subject: [PATCH 76/92] refactored select method --- test/workspace_test.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 0bd751ee..4b967343 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -38,22 +38,27 @@ it "raises ArgumentError if name or id isn't provided" do VCR.use_cassette("invalid_select") do - expect{@workspace.select("user", nil)}.must_raise ArgumentError + expect{@workspace.select(SlackCLI::User, nil)}.must_raise ArgumentError + end + end + + it "raises ArgumentError if class isn't User or Channel" do + VCR.use_cassette("invalid_select") do + expect{@workspace.select(Array, "USLACKBOT")}.must_raise ArgumentError end end it "returns correct User" do VCR.use_cassette("select_user") do - expect(@workspace.select("user", "USLACKBOT").name).must_equal "slackbot" + expect(@workspace.select(SlackCLI::User, "USLACKBOT").name).must_equal "slackbot" end end it "returns correct Channel" do VCR.use_cassette("select_channel") do - expect(@workspace.select("channel", "general").slack_id).must_equal "C01BU0NRFHC" + expect(@workspace.select(SlackCLI::Channel, "general").slack_id).must_equal "C01BU0NRFHC" end end - end describe "show details method" do @@ -98,7 +103,7 @@ end end - describe "coversation history method" do + describe "conversation history method" do it "returns an Array" do VCR.use_cassette("channel_history") do expect(@workspace.conversation_history("C01BL0GSPP1")).must_be_instance_of Array From d56a922df9d4c5a25289dd56f9025dd2021c48c0 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 20:29:12 -0700 Subject: [PATCH 77/92] revised gemfiles and added nu cassettes --- Gemfile | 2 +- Gemfile.lock | 2 - test/cassettes/self_get_API_error.yml | 111 ++++++++++++++++++++++++++ test/cassettes/self_get_nominal.yml | 78 ++++++++++++++++++ 4 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 test/cassettes/self_get_API_error.yml create mode 100644 test/cassettes/self_get_nominal.yml diff --git a/Gemfile b/Gemfile index c816f4e0..0ea8cfba 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,6 @@ gem "pry" gem 'minitest-skip' gem 'httparty' gem 'dotenv' -gem 'table_print' +#gem 'table_print' gem 'vcr' gem 'simplecov' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index fc54944c..f9bf62f5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,7 +33,6 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov-html (0.12.3) - table_print (1.5.7) vcr (6.0.0) PLATFORMS @@ -49,7 +48,6 @@ DEPENDENCIES pry rake simplecov - table_print vcr BUNDLED WITH diff --git a/test/cassettes/self_get_API_error.yml b/test/cassettes/self_get_API_error.yml new file mode 100644 index 00000000..3008de28 --- /dev/null +++ b/test/cassettes/self_get_API_error.yml @@ -0,0 +1,111 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?query=sggreg + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 02:46:16 GMT + Server: + - Apache + X-Xss-Protection: + - '0' + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + X-Accepted-Oauth-Scopes: + - users:read + X-Slack-Req-Id: + - a1add59efff4025ad0e68f83482e816c + X-Slack-Backend: + - r + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Content-Type-Options: + - nosniff + Content-Length: + - '53' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-3ps2,haproxy-edge-pdx-n5m8 + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"not_authed"}' + recorded_at: Fri, 09 Oct 2020 02:46:16 GMT +- request: + method: get + uri: https://slack.com/api/users.list?token=sggreg + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 03:07:22 GMT + Server: + - Apache + X-Slack-Req-Id: + - 4cbdea81582df31116e5ccda2fee4d66 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + X-Slack-Backend: + - r + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Content-Type-Options: + - nosniff + X-Xss-Protection: + - '0' + Content-Length: + - '55' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-swz0,haproxy-edge-iad-rzaq + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"invalid_auth"}' + recorded_at: Fri, 09 Oct 2020 03:07:22 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/self_get_nominal.yml b/test/cassettes/self_get_nominal.yml new file mode 100644 index 00000000..180e19a1 --- /dev/null +++ b/test/cassettes/self_get_nominal.yml @@ -0,0 +1,78 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 03:07:22 GMT + Server: + - Apache + X-Slack-Req-Id: + - f3428a8337c055b22097036a6bcb8af6 + X-Oauth-Scopes: + - chat:write,users:read,channels:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1318' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-b10g,haproxy-edge-iad-azwo + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01CDB91DEV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BL0TC86B","team_id":"T01CDB91DEV","name":"water_jessica_api_pro","deleted":false,"color":"3c989f","real_name":"Water + - Jessica - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Jessica - API Project","real_name_normalized":"Water - Jessica - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g16790b5cf92","api_app_id":"A01CDBH820Z","always_active":false,"bot_id":"B01BU12FUEA","image_24":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951747},{"id":"U01C0N8RAUS","team_id":"T01CDB91DEV","name":"jwinchan","deleted":false,"color":"4bbe2e","real_name":"Jessica + Chan","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jessica + Chan","real_name_normalized":"Jessica Chan","display_name":"Jessica (she.her)","display_name_normalized":"Jessica + (she.her)","fields":null,"status_text":"Working remotely","status_emoji":":house_with_garden:","status_expiration":1602226799,"avatar_hash":"g39037b8a717","first_name":"Jessica","last_name":"Chan","image_24":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-512.png","status_text_canonical":"Working + remotely","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1602143803},{"id":"U01C6TTNL6Q","team_id":"T01CDB91DEV","name":"iris.lux0","deleted":false,"color":"9f69e7","real_name":"iris.lux0","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"iris.lux0","real_name_normalized":"iris.lux0","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g8d593922863","image_24":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601950931},{"id":"U01CDBMR333","team_id":"T01CDB91DEV","name":"water_iris_api_projec","deleted":false,"color":"e7392d","real_name":"Water + - Iris - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602212842,"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 03:07:22 GMT +recorded_with: VCR 6.0.0 From e334b4a8d8757904b1af3216e9e53454205cee91 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:30:42 -0700 Subject: [PATCH 78/92] modified send message and channel history method --- lib/channel.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/channel.rb b/lib/channel.rb index 2bb8efed..de165ff2 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -3,8 +3,6 @@ module SlackCLI class Channel < Recipient - CHANNEL_PATH = "https://slack.com/api/conversations.list" - attr_reader :slack_id, :name, :topic, :member_count def initialize(slack_id:, name:, topic:, member_count:) @@ -14,7 +12,7 @@ def initialize(slack_id:, name:, topic:, member_count:) end def self.list_all - return self.get(CHANNEL_PATH, {token: ENV["SLACK_API_TOKEN"]})["channels"].map do |channel| + return self.get("conversations.list", {token: ENV["SLACK_API_TOKEN"]})["channels"].map do |channel| self.new(slack_id: channel["id"], name: channel["name"], topic: channel["topic"]["value"], member_count: channel["num_members"]) end end @@ -22,5 +20,10 @@ def self.list_all def details return "ID: #{@slack_id} \nName: #{@name} \nTopic: #{@topic} \nMember Count: #{@member_count}" end + + def channel_history + response = Channel.get("conversations.history", {token: ENV["SLACK_API_TOKEN"], channel: @slack_id}) + return response["messages"].map{ |message| message["text"] } + end end end \ No newline at end of file From c590b61190ea5d78d5e3de1119919519d0d2443c Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:32:07 -0700 Subject: [PATCH 79/92] added send message method --- lib/recipient.rb | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index 9c85d94a..96e02738 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -1,5 +1,6 @@ require 'dotenv' require 'httparty' +require_relative 'slackapierror' Dotenv.load @@ -19,13 +20,12 @@ def self.validate_id(id) end end - def self.get(url, params) - raise ArgumentError.new("invalid arguments") unless (url.is_a?(String) && params.is_a?(Hash)) - response = HTTParty.get(url, query: params) + def self.get(end_point, params) + raise ArgumentError.new("invalid arguments") unless (end_point.is_a?(String) && params.is_a?(Hash)) + response = HTTParty.get("https://slack.com/api/#{end_point}", query: params) unless response.code == 200 && response.parsed_response["ok"] raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") end - return response end @@ -40,5 +40,25 @@ def self.list_all def self.select(identifier) return self.list_all.find{|recipient| recipient.slack_id == identifier || recipient.name == identifier} end + + def send_message(message) + + response = HTTParty.post( + "https://slack.com/api/chat.postMessage", + body: { + token: ENV["SLACK_API_TOKEN"], + text: message, + channel: @slack_id, + as_user: "true" + }, + headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } + ) + + unless response.code == 200 && response.parsed_response["ok"] + raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") + end + + return true + end end end \ No newline at end of file From 52468a6d41aaf79847d79d3736774b5a87bb17c6 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:32:20 -0700 Subject: [PATCH 80/92] modified send message and history --- lib/slack.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index ce709a17..b3c09f96 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby require 'dotenv' require 'httparty' -#require 'table_print' +require 'table_print' require_relative 'workspace' def main @@ -14,9 +14,9 @@ def main current_selection = nil until option == "quit" || option == "8" if option == "list users" || option == "1" - puts workspace.list_users + tp workspace.list_users elsif option == "list channels" || option == "2" - puts workspace.list_channels + tp workspace.list_channels elsif option == "select user" || option == "3" puts "Enter the name or id" current_selection = workspace.select(SlackCLI::User,gets.chomp) @@ -31,6 +31,8 @@ def main send_message(current_selection, workspace) elsif option == "channel history" || option == "7" message_history(current_selection, workspace) + elsif option.nil? + puts "" else puts "Please input a valid option" end @@ -52,9 +54,8 @@ def send_message(recipient, workspace) if recipient.nil? puts "No recipient selected" else - puts "please enter message" - message = gets.chomp - workspace.send_message(message, recipient.slack_id) + puts "Please enter message" + workspace.send_message(gets.chomp, recipient) end end @@ -62,7 +63,7 @@ def message_history(recipient, workspace) if recipient.nil? || recipient.is_a?(SlackCLI::User) puts "Please select a channel" else - puts workspace.conversation_history(recipient.slack_id) + puts workspace.conversation_history(recipient) end end From 280fc43008b5e1424e386efdf62ccbe780fea569 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:32:36 -0700 Subject: [PATCH 81/92] did not make changes --- lib/user.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/user.rb b/lib/user.rb index 7e12e8ec..52434606 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -2,7 +2,6 @@ module SlackCLI class User < Recipient - USER_PATH = "https://slack.com/api/users.list" attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji @@ -14,7 +13,7 @@ def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) end def self.list_all - return self.get(USER_PATH, {token: ENV["SLACK_API_TOKEN"]})["members"].map do |user| + return self.get("users.list", {token: ENV["SLACK_API_TOKEN"]})["members"].map do |user| self.new(slack_id: user["id"], name: user["name"], real_name: user["real_name"], status_text: user["profile"]["status_text"], status_emoji: user["profile"]["status_emoji"]) end end @@ -23,6 +22,5 @@ def details return "ID: #{@slack_id} \nName: #{@name} \nReal Name: #{@real_name} \nStatus: #{@status_text} \nEmoji: #{@status_emoji}" end - end end \ No newline at end of file From cbaa629d7b37e60c5a32e44429cd4102392d4e52 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:32:58 -0700 Subject: [PATCH 82/92] modified send message and history methods --- lib/workspace.rb | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index c47ec50e..c0f50b3d 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -13,12 +13,12 @@ def initialize #user name, real name, slack Id def list_users - return @users.map{|user| "Slack ID: #{user.slack_id}\nUsername: #{user.name}\nReal name: #{user.real_name}\n"} + return @users.map{|user| {id: user.slack_id, name: user.name, real_name: user.real_name} } end #topic, member count, slack ID, topic["value"] def list_channels - return @channels.map{|channel| "Slack ID: #{channel.slack_id}\nName: #{channel.name}\nTopic: #{channel.topic}\nMember count: #{channel.member_count}\n"} + return @channels.map{|channel| {id: channel.slack_id, name: channel.name, topic: channel.topic, member_count: channel.member_count}} end def select(recipient_class, identifier) @@ -31,29 +31,13 @@ def show_details(recipient) return recipient.details end - def send_message(message, recipient_id) - - response = HTTParty.post( - "https://slack.com/api/chat.postMessage", - body: { - token: ENV["SLACK_API_TOKEN"], - text: message, - channel: recipient_id, - as_user: "true" - }, - headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } - ) - - unless response.code == 200 && response.parsed_response["ok"] - raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") - end - - return true + def send_message(message, recipient) + recipient.send_message(message) end - def conversation_history(channel_id) - response = HTTParty.get("https://slack.com/api/conversations.history", query: {token: ENV["SLACK_API_TOKEN"], channel: channel_id}) - return response["messages"].map{ |message| message["text"] } + def conversation_history(channel) + return channel.channel_history end + end end \ No newline at end of file From 807898367a2ad05e9e38be5e30a20a7dd4e486d5 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:33:34 -0700 Subject: [PATCH 83/92] modified test to accomodate the table print changes --- test/workspace_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 4b967343..60745ebe 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -23,14 +23,14 @@ end describe "list users method" do - it "returns an accurate string" do - expect(@workspace.list_users.first).must_equal "Slack ID: USLACKBOT, Username: slackbot, Real name: Slackbot" + it "returns an accurate hash" do + expect(@workspace.list_users.first).must_equal ({:id=>"USLACKBOT", :name=>"slackbot", :real_name=>"Slackbot"}) end end describe "list channels method" do - it "returns an accurate string" do - expect(@workspace.list_channels.first).must_equal "Slack ID: C01BL0GSPP1, name: good-place-simulation, topic: torture Chidi, member count: 2" + it "returns accurate hash" do + expect(@workspace.list_channels.first).must_equal ({:id=>"C01BL0GSPP1", :name=>"good-place-simulation", :topic=>"torture Chidi", :member_count=>2}) end end From a29cdb7b5800139d4e95c6c886089de1660fe814 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Thu, 8 Oct 2020 21:33:58 -0700 Subject: [PATCH 84/92] new cassettes and modified gemfile --- Gemfile | 2 +- Gemfile.lock | 2 + test/cassettes/self_get_API_error.yml | 56 +++++++++++++++++++++++++++ test/cassettes/self_get_nominal.yml | 56 +++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 0ea8cfba..c816f4e0 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,6 @@ gem "pry" gem 'minitest-skip' gem 'httparty' gem 'dotenv' -#gem 'table_print' +gem 'table_print' gem 'vcr' gem 'simplecov' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index f9bf62f5..fc54944c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,6 +33,7 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov-html (0.12.3) + table_print (1.5.7) vcr (6.0.0) PLATFORMS @@ -48,6 +49,7 @@ DEPENDENCIES pry rake simplecov + table_print vcr BUNDLED WITH diff --git a/test/cassettes/self_get_API_error.yml b/test/cassettes/self_get_API_error.yml index 3008de28..cbcb6fba 100644 --- a/test/cassettes/self_get_API_error.yml +++ b/test/cassettes/self_get_API_error.yml @@ -108,4 +108,60 @@ http_interactions: encoding: ASCII-8BIT string: '{"ok":false,"error":"invalid_auth"}' recorded_at: Fri, 09 Oct 2020 03:07:22 GMT +- request: + method: get + uri: https://slack.com/api/https://slack.com/api/users.list?token=sggreg + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 404 + message: Not Found + headers: + Date: + - Fri, 09 Oct 2020 04:31:30 GMT + Server: + - Apache + X-Xss-Protection: + - '0' + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Slack-Backend: + - r + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Vary: + - Accept-Encoding + Pragma: + - no-cache + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Robots-Tag: + - noindex,nofollow + Set-Cookie: + - b=osj9nm5xnvsm273vf60kswio; expires=Wed, 09-Oct-2030 04:31:30 GMT; Max-Age=315532800; + path=/; domain=.slack.com; secure; SameSite=None + - x=osj9nm5xnvsm273vf60kswio.1602217890; expires=Fri, 09-Oct-2020 04:46:30 GMT; + Max-Age=900; path=/; domain=.slack.com; secure; SameSite=None + Transfer-Encoding: + - chunked + Content-Type: + - text/html; charset=utf-8 + X-Via: + - haproxy-www-b10g,haproxy-edge-pdx-5d11 + body: + encoding: ASCII-8BIT + string: !binary |- + PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4tVVMiIGNsYXNzPSIiPjxoZWFkPjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC93ZWJwYWNrLm1hbmlmZXN0LmZmOGE2MzFkMzMzYzM5MmQ2Yzc5Lm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQ+d2luZG93LnRzX2VuZHBvaW50X3VybCA9ICJodHRwczpcL1wvc2xhY2suY29tXC9iZWFjb25cL3RpbWluZyI7KGZ1bmN0aW9uKGUpIHsKCXZhciBuPURhdGUubm93P0RhdGUubm93KCk6K25ldyBEYXRlLHI9ZS5wZXJmb3JtYW5jZXx8e30sdD1bXSxhPXt9LGk9ZnVuY3Rpb24oZSxuKXtmb3IodmFyIHI9MCxhPXQubGVuZ3RoLGk9W107YT5yO3IrKyl0W3JdW2VdPT1uJiZpLnB1c2godFtyXSk7cmV0dXJuIGl9LG89ZnVuY3Rpb24oZSxuKXtmb3IodmFyIHIsYT10Lmxlbmd0aDthLS07KXI9dFthXSxyLmVudHJ5VHlwZSE9ZXx8dm9pZCAwIT09biYmci5uYW1lIT1ufHx0LnNwbGljZShhLDEpfTtyLm5vd3x8KHIubm93PXIud2Via2l0Tm93fHxyLm1vek5vd3x8ci5tc05vd3x8ZnVuY3Rpb24oKXtyZXR1cm4oRGF0ZS5ub3c/RGF0ZS5ub3coKTorbmV3IERhdGUpLW59KSxyLm1hcmt8fChyLm1hcms9ci53ZWJraXRNYXJrfHxmdW5jdGlvbihlKXt2YXIgbj17bmFtZTplLGVudHJ5VHlwZToibWFyayIsc3RhcnRUaW1lOnIubm93KCksZHVyYXRpb246MH07dC5wdXNoKG4pLGFbZV09bn0pLHIubWVhc3VyZXx8KHIubWVhc3VyZT1yLndlYmtpdE1lYXN1cmV8fGZ1bmN0aW9uKGUsbixyKXtuPWFbbl0uc3RhcnRUaW1lLHI9YVtyXS5zdGFydFRpbWUsdC5wdXNoKHtuYW1lOmUsZW50cnlUeXBlOiJtZWFzdXJlIixzdGFydFRpbWU6bixkdXJhdGlvbjpyLW59KX0pLHIuZ2V0RW50cmllc0J5VHlwZXx8KHIuZ2V0RW50cmllc0J5VHlwZT1yLndlYmtpdEdldEVudHJpZXNCeVR5cGV8fGZ1bmN0aW9uKGUpe3JldHVybiBpKCJlbnRyeVR5cGUiLGUpfSksci5nZXRFbnRyaWVzQnlOYW1lfHwoci5nZXRFbnRyaWVzQnlOYW1lPXIud2Via2l0R2V0RW50cmllc0J5TmFtZXx8ZnVuY3Rpb24oZSl7cmV0dXJuIGkoIm5hbWUiLGUpfSksci5jbGVhck1hcmtzfHwoci5jbGVhck1hcmtzPXIud2Via2l0Q2xlYXJNYXJrc3x8ZnVuY3Rpb24oZSl7bygibWFyayIsZSl9KSxyLmNsZWFyTWVhc3VyZXN8fChyLmNsZWFyTWVhc3VyZXM9ci53ZWJraXRDbGVhck1lYXN1cmVzfHxmdW5jdGlvbihlKXtvKCJtZWFzdXJlIixlKX0pLGUucGVyZm9ybWFuY2U9ciwiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiYoZGVmaW5lLmFtZHx8ZGVmaW5lLmFqcykmJmRlZmluZSgicGVyZm9ybWFuY2UiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIHJ9KSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lCn0pKHdpbmRvdyk7PC9zY3JpcHQ+PHNjcmlwdD4KCihmdW5jdGlvbiAoKSB7CgkKCXdpbmRvdy5UU01hcmsgPSBmdW5jdGlvbiAobWFya19sYWJlbCkgewoJCWlmICghd2luZG93LnBlcmZvcm1hbmNlIHx8ICF3aW5kb3cucGVyZm9ybWFuY2UubWFyaykgcmV0dXJuOwoJCXBlcmZvcm1hbmNlLm1hcmsobWFya19sYWJlbCk7Cgl9OwoJd2luZG93LlRTTWFyaygnc3RhcnRfbG9hZCcpOwoKCQoJd2luZG93LlRTTWVhc3VyZUFuZEJlYWNvbiA9IGZ1bmN0aW9uIChtZWFzdXJlX2xhYmVsLCBzdGFydF9tYXJrX2xhYmVsKSB7CgkJaWYgKCF3aW5kb3cucGVyZm9ybWFuY2UgfHwgIXdpbmRvdy5wZXJmb3JtYW5jZS5tYXJrIHx8ICF3aW5kb3cucGVyZm9ybWFuY2UubWVhc3VyZSkgewoJCQlyZXR1cm47CgkJfQoKCQlwZXJmb3JtYW5jZS5tYXJrKHN0YXJ0X21hcmtfbGFiZWwgKyAnX2VuZCcpOwoKCQl0cnkgewoJCQlwZXJmb3JtYW5jZS5tZWFzdXJlKG1lYXN1cmVfbGFiZWwsIHN0YXJ0X21hcmtfbGFiZWwsIHN0YXJ0X21hcmtfbGFiZWwgKyAnX2VuZCcpOwoJCQl3aW5kb3cuVFNCZWFjb24obWVhc3VyZV9sYWJlbCwgcGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5TmFtZShtZWFzdXJlX2xhYmVsKVswXS5kdXJhdGlvbik7CgkJfSBjYXRjaCAoZSkgewoJCQkKCQl9Cgl9OwoKCQoJaWYgKCdzZW5kQmVhY29uJyBpbiBuYXZpZ2F0b3IpIHsKCQl3aW5kb3cuVFNCZWFjb24gPSBmdW5jdGlvbiAobGFiZWwsIHZhbHVlKSB7CgkJCXZhciBlbmRwb2ludF91cmwgPSB3aW5kb3cudHNfZW5kcG9pbnRfdXJsIHx8ICdodHRwczovL3NsYWNrLmNvbS9iZWFjb24vdGltaW5nJzsKCQkJbmF2aWdhdG9yLnNlbmRCZWFjb24oCgkJCQllbmRwb2ludF91cmwgKyAnP2RhdGE9JyArIGVuY29kZVVSSUNvbXBvbmVudChsYWJlbCArICc6JyArIHZhbHVlKSwKCQkJCScnCgkJCSk7CgkJfTsKCX0gZWxzZSB7CgkJd2luZG93LlRTQmVhY29uID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkgewoJCQl2YXIgZW5kcG9pbnRfdXJsID0gd2luZG93LnRzX2VuZHBvaW50X3VybCB8fCAnaHR0cHM6Ly9zbGFjay5jb20vYmVhY29uL3RpbWluZyc7CgkJCW5ldyBJbWFnZSgpLnNyYyA9IGVuZHBvaW50X3VybCArICc/ZGF0YT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGxhYmVsICsgJzonICsgdmFsdWUpOwoJCX07Cgl9Cn0pKCk7Cjwvc2NyaXB0PjxzY3JpcHQ+d2luZG93LlRTTWFyaygnc3RlcF9sb2FkJyk7PC9zY3JpcHQ+PG5vc2NyaXB0PjxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjA7IFVSTD0vYXBpL2h0dHBzOi8vc2xhY2suY29tL2FwaS91c2Vycy5saXN0P3Rva2VuPXNnZ3JlZyZhbXA7bm9qc21vZGU9MSI+PC9ub3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+dmFyIHNhZmVfaG9zdHMgPSBbJ2FwcC5vcHRpbWl6ZWx5LmNvbScsICd0aW55c3BlY2suZGV2LnNsYWNrLmNvbSddOwoKaWYgKHNlbGYgIT09IHRvcCAmJiBzYWZlX2hvc3RzLmluZGV4T2YodG9wLmxvY2F0aW9uLmhvc3QpID09PSAtMSkgewoJd2luZG93LmRvY3VtZW50LndyaXRlKAoJCSdcdTAwM0NzdHlsZT5ib2R5ICoge2Rpc3BsYXk6bm9uZSAhaW1wb3J0YW50O31cdTAwM0Mvc3R5bGU+XHUwMDNDYSBocmVmPSIjIiBvbmNsaWNrPScgKwoJCQknInRvcC5sb2NhdGlvbi5ocmVmPXdpbmRvdy5sb2NhdGlvbi5ocmVmIiBzdHlsZT0iZGlzcGxheTpibG9jayAhaW1wb3J0YW50O3BhZGRpbmc6MTBweCI+R28gdG8gU2xhY2suY29tXHUwMDNDL2E+JwoJKTsKfQoKKGZ1bmN0aW9uKCkgewoJdmFyIHRpbWVyOwoJaWYgKHNlbGYgIT09IHRvcCAmJiBzYWZlX2hvc3RzLmluZGV4T2YodG9wLmxvY2F0aW9uLmhvc3QpID09PSAtMSkgewoJCXRpbWVyID0gd2luZG93LnNldEludGVydmFsKGZ1bmN0aW9uKCkgewoJCQlpZiAod2luZG93KSB7CgkJCQl0cnkgewoJCQkJCXZhciBwYWdlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFnZScpOwoJCQkJCXZhciBjbGllbnRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbGllbnQtdWknKTsKCQkJCQl2YXIgc2VjdGlvbkVscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ25hdiwgaGVhZGVyLCBzZWN0aW9uJyk7CgoJCQkJCXBhZ2VFbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHBhZ2VFbCk7CgkJCQkJY2xpZW50RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjbGllbnRFbCk7CgkJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBzZWN0aW9uRWxzLmxlbmd0aDsgaSsrKSB7CgkJCQkJCXNlY3Rpb25FbHNbaV0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzZWN0aW9uRWxzW2ldKTsKCQkJCQl9CgkJCQkJd2luZG93LlRTID0gbnVsbDsKCQkJCQl3aW5kb3cuVEQgPSBudWxsOwoJCQkJCXdpbmRvdy5jbGVhckludGVydmFsKHRpbWVyKTsKCQkJCX0gY2F0Y2ggKGUpIHt9CQoJCQl9CgkJfSwgMjAwKTsKCX0KfSkoKTs8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CndpbmRvdy5kYXRhTGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyIHx8IFtdOwp3aW5kb3cuZGF0YUxheWVyLnB1c2goewoJJ2d0bS5zdGFydCc6IERhdGUubm93KCksCgknZXZlbnQnIDogJ2d0bS5qcycsCgknc2VjdXJlX3BhZ2UnIDogZmFsc2UsCn0pOwp2YXIgZmlyc3RTY3JpcHQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF07CnZhciB0aGlzU2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CnRoaXNTY3JpcHQuYXN5bmMgPSB0cnVlOwp0aGlzU2NyaXB0LnNyYyA9ICcvL3d3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbS9ndG0uanM/aWQ9R1RNLUtIMkxQSyc7CmZpcnN0U2NyaXB0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXNTY3JpcHQsIGZpcnN0U2NyaXB0KTsKPC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZnVuY3Rpb24oZSkgewoJdmFyIGd0bURhdGFMYXllciA9IHdpbmRvdy5kYXRhTGF5ZXIgfHwgW107Cgl2YXIgZ3RtVGFncyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJypbZGF0YS1ndG0tY2xpY2tdJyk7Cgl2YXIgZ3RtQ2xpY2tIYW5kbGVyID0gZnVuY3Rpb24oYykgewoJCXZhciBndG1fZXZlbnRzID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2RhdGEtZ3RtLWNsaWNrJyk7CgkJaWYgKCFndG1fZXZlbnRzKSByZXR1cm47CgkJdmFyIGd0bV9ldmVudHNfYXJyID0gZ3RtX2V2ZW50cy5zcGxpdCgiLCIpOwoJCWZvcih2YXIgZT0wOyBlIDwgZ3RtX2V2ZW50c19hcnIubGVuZ3RoOyBlKyspIHsKCQkJdmFyIGV2ID0gZ3RtX2V2ZW50c19hcnJbZV0udHJpbSgpOwoJCQlndG1EYXRhTGF5ZXIucHVzaCh7ICdldmVudCc6IGV2IH0pOwoJCX0KCX07Cglmb3IodmFyIGc9MDsgZyA8IGd0bVRhZ3MubGVuZ3RoOyBnKyspewoJCXZhciBlbGVtID0gZ3RtVGFnc1tnXTsKCQllbGVtLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZ3RtQ2xpY2tIYW5kbGVyKTsKCX0KfSk7Cjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KKGZ1bmN0aW9uKGUsYyxiLGYsZCxnLGEpe2UuU2xhY2tCZWFjb25PYmplY3Q9ZDsKZVtkXT1lW2RdfHxmdW5jdGlvbigpeyhlW2RdLnE9ZVtkXS5xfHxbXSkucHVzaChbMSpuZXcgRGF0ZSgpLGFyZ3VtZW50c10pfTsKZVtkXS5sPTEqbmV3IERhdGUoKTtnPWMuY3JlYXRlRWxlbWVudChiKTthPWMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoYilbMF07CmcuYXN5bmM9MTtnLnNyYz1mO2EucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZyxhKQp9KSh3aW5kb3csZG9jdW1lbnQsInNjcmlwdCIsImh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9zbGFja19iZWFjb24uYmVkYzEyYzE2ZjI3OTUxOTkyNmQubWluLmpzIiwic2IiKTsKd2luZG93LnNiKCdzZXQnLCAndG9rZW4nLCAnMzMwN2Y0MzY5NjNlMDJkNGY5ZWI4NWNlNTE1OTc0NGMnKTsKd2luZG93LnNiKCd0cmFjaycsICdwYWdldmlldycpOwo8L3NjcmlwdD48bWV0YSBuYW1lPSJyZWZlcnJlciIgY29udGVudD0ibm8tcmVmZXJyZXIiPjxtZXRhIG5hbWU9InN1cGVyZmlzaCIgY29udGVudD0ibm9maXNoIj48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+dmFyIFRTX2xhc3RfbG9nX2RhdGUgPSBudWxsOwp2YXIgVFNNYWtlTG9nRGF0ZSA9IGZ1bmN0aW9uKCkgewoJdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKCXZhciB5ID0gZGF0ZS5nZXRGdWxsWWVhcigpOwoJdmFyIG1vID0gZGF0ZS5nZXRNb250aCgpKzE7Cgl2YXIgZCA9IGRhdGUuZ2V0RGF0ZSgpOwoKCXZhciB0aW1lID0gewoJICBoOiBkYXRlLmdldEhvdXJzKCksCgkgIG1pOiBkYXRlLmdldE1pbnV0ZXMoKSwKCSAgczogZGF0ZS5nZXRTZWNvbmRzKCksCgkgIG1zOiBkYXRlLmdldE1pbGxpc2Vjb25kcygpCgl9OwoKCU9iamVjdC5rZXlzKHRpbWUpLm1hcChmdW5jdGlvbihtb21lbnQsIGluZGV4KSB7CgkJaWYgKG1vbWVudCA9PSAnbXMnKSB7CgkJCWlmICh0aW1lW21vbWVudF0gPCAxMCkgewoJCQkJdGltZVttb21lbnRdID0gdGltZVttb21lbnRdKycwMCc7CgkJCX0gZWxzZSBpZiAodGltZVttb21lbnRdIDwgMTAwKSB7CgkJCQl0aW1lW21vbWVudF0gPSB0aW1lW21vbWVudF0rJzAnOwoJCQl9CgkJfSBlbHNlIGlmICh0aW1lW21vbWVudF0gPCAxMCkgewoJCQl0aW1lW21vbWVudF0gPSAnMCcgKyB0aW1lW21vbWVudF07CgkJfQoJfSk7CgoJdmFyIHN0ciA9IHkgKyAnLycgKyBtbyArICcvJyArIGQgKyAnICcgKyB0aW1lLmggKyAnOicgKyB0aW1lLm1pICsgJzonICsgdGltZS5zICsgJy4nICsgdGltZS5tczsKCWlmIChUU19sYXN0X2xvZ19kYXRlKSB7CgkJdmFyIGRpZmYgPSBkYXRlLVRTX2xhc3RfbG9nX2RhdGU7CgkJLy9zdHIrPSAnICgnK2RpZmYrJ21zKSc7Cgl9CglUU19sYXN0X2xvZ19kYXRlID0gZGF0ZTsKCXJldHVybiBzdHIrJyAnOwp9Cgp2YXIgcGFyc2VEZWVwTGlua1JlcXVlc3QgPSBmdW5jdGlvbihjb2RlKSB7Cgl2YXIgbSA9IGNvZGUubWF0Y2goLyJpZCI6IihbQ0RHXVtBLVowLTldezgsfSkiLyk7Cgl2YXIgaWQgPSBtID8gbVsxXSA6IG51bGw7CgoJbSA9IGNvZGUubWF0Y2goLyJ0ZWFtIjoiKFRbQS1aMC05XXs4LH0pIi8pOwoJdmFyIHRlYW0gPSBtID8gbVsxXSA6IG51bGw7CgoJbSA9IGNvZGUubWF0Y2goLyJtZXNzYWdlIjoiKFswLTldK1wuWzAtOV0rKSIvKTsKCXZhciBtZXNzYWdlID0gbSA/IG1bMV0gOiBudWxsOwoKCXJldHVybiB7IGlkOiBpZCwgdGVhbTogdGVhbSwgbWVzc2FnZTogbWVzc2FnZSB9Owp9CgppZiAoJ3JlbmRlcmVyRXZhbEFzeW5jJyBpbiB3aW5kb3cpIHsKCXZhciBvcmlnUmVuZGVyZXJFdmFsQXN5bmMgPSB3aW5kb3cucmVuZGVyZXJFdmFsQXN5bmM7Cgl3aW5kb3cucmVuZGVyZXJFdmFsQXN5bmMgPSBmdW5jdGlvbihibG9iKSB7CgkJdHJ5IHsKCQkJdmFyIGRhdGEgPSBKU09OLnBhcnNlKGRlY29kZVVSSUNvbXBvbmVudChhdG9iKGJsb2IpKSk7CgkJCWlmIChkYXRhLmNvZGUubWF0Y2goL2hhbmRsZURlZXBMaW5rLykpIHsKCQkJCXZhciByZXF1ZXN0ID0gcGFyc2VEZWVwTGlua1JlcXVlc3QoZGF0YS5jb2RlKTsKCQkJCWlmICghcmVxdWVzdC5pZCB8fCAhcmVxdWVzdC50ZWFtIHx8ICFyZXF1ZXN0Lm1lc3NhZ2UpIHJldHVybjsKCgkJCQlyZXF1ZXN0LmNtZCA9ICdjaGFubmVsJzsKCQkJCVRTU1NCLmhhbmRsZURlZXBMaW5rV2l0aEFyZ3MoSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpOwoJCQkJcmV0dXJuOwoJCQl9IGVsc2UgewoJCQkJb3JpZ1JlbmRlcmVyRXZhbEFzeW5jKGJsb2IpOwoJCQl9CgkJfSBjYXRjaCAoZSkgewoJCX0KCX0KfTwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij52YXIgVFNTU0IgPSB7CgljYWxsOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9Cn07PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24oKSB7Cgl2YXIgd2FzX1RTID0gd2luZG93LlRTOwoJZGVsZXRlIHdpbmRvdy5UUzsKCWlmICh3YXNfVFMpIHdpbmRvdy5UUyA9IHdhc19UUzsKfSk7PC9zY3JpcHQ+PHRpdGxlPlRoZXJlJ3MgYmVlbiBhIGdsaXRjaOKApiB8IFNsYWNrPC90aXRsZT48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vMzJlNjAvc3R5bGUvcm9sbHVwLXNsYWNrX2tpdF9sZWdhY3lfYWRhcHRlcnMuY3NzIiByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PGxpbmsgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2MxMTJiL3N0eWxlL3JvbGx1cC1wbGFzdGljLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9tb2Rlcm4udmVuZG9yLmRhNjc3YjkubWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9hcHBsaWNhdGlvbi4wM2QzZjk2Lm1pbi5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vNGVkMjlhL3N0eWxlL3JvbGx1cC1zbGFja19raXRfaGVscGVycy5jc3MiIHJlbD0ic3R5bGVzaGVldCIgaWQ9InNsYWNrX2tpdF9oZWxwZXJzX3N0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PGxpbmsgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzBjOTc0L3N0eWxlLzQwNC5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vNTcwMGEvc3R5bGUvc3RpY2t5X25hdi5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vMmQ1Nzcvc3R5bGUvZm9vdGVyLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS83YTlhNzgvc3R5bGUvbGlicy9sYXRvLTItY29tcHJlc3NlZC5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bWV0YSBwcm9wZXJ0eT0ib2c6dHlwZSIgY29udGVudD0id2Vic2l0ZSI+PG1ldGEgcHJvcGVydHk9Im9nOnNpdGVfbmFtZSIgY29udGVudD0iU2xhY2siPjxtZXRhIHByb3BlcnR5PSJvZzp0aXRsZSIgY29udGVudD0iVGhlcmUncyBiZWVuIGEgZ2xpdGNo4oCmIj48bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2UiIGNvbnRlbnQ9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS84MDU4OC9pbWcvNDA0LzQwNC1tZXRhLXRodW1iLmpwZyI+PG1ldGEgcHJvcGVydHk9Im9nOmRlc2NyaXB0aW9uIiBjb250ZW50PSJXZSdyZSBub3QgcXVpdGUgc3VyZSB3aGF0IHdlbnQgd3JvbmcuIFlvdSBjYW4gZ28gYmFjaywgb3IgdHJ5IGxvb2tpbmcgb24gb3VyICZsdDthIGhyZWY9JnF1b3Q7aHR0cDovL2dldC5zbGFjay5oZWxwJnF1b3Q7IHRhcmdldD0mcXVvdDtfYmxhbmsmcXVvdDsmZ3Q7SGVscCBDZW50ZXImbHQ7L2EmZ3Q7IGlmIHlvdSBuZWVkIGEgaGFuZC4iPjxtZXRhIHByb3BlcnR5PSJvZzp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vc2xhY2suY29tL2FwaS9odHRwczovL3NsYWNrLmNvbS9hcGkvdXNlcnMubGlzdCI+PGxpbmsgaWQ9ImZhdmljb24iIHJlbD0ic2hvcnRjdXQgaWNvbiIgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L21hcmtldGluZy9pbWcvbWV0YS9mYXZpY29uLTMyLnBuZyIgc2l6ZXM9IjE2eDE2IDMyeDMyIDQ4eDQ4IiB0eXBlPSJpbWFnZS9wbmciPjwvaGVhZD48Ym9keSBjbGFzcz0iIGRlcHJlY2F0ZWQiPjxzY3JpcHQ+dmFyIHcgPSBNYXRoLm1heChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIHx8IDApOwppZiAodyA+IDE0NDApIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCd3aWRlc2NyZWVuJyk7PC9zY3JpcHQ+PG5hdiBjbGFzcz0idG9wIHBlcnNpc3RlbnQiPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tLyIgY2xhc3M9ImxvZ28iIGRhdGEtcWE9ImxvZ28iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWxvZ28iIGFyaWEtbGFiZWw9IlNsYWNrIGhvbWVwYWdlIj48L2E+PHVsPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9pcyIgZGF0YS1xYT0icHJvZHVjdCIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X3Byb2R1Y3QiPlByb2R1Y3Q8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vcHJpY2luZz91aV9zdGVwPTU1JmFtcDt1aV9lbGVtZW50PTUiIGRhdGEtcWE9InByaWNpbmciIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9wcmljaW5nIj5QcmljaW5nPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2V0LnNsYWNrLmhlbHAvaGMvZW4tdXMiIGRhdGEtcWE9InN1cHBvcnQiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9zdXBwb3J0Ij5TdXBwb3J0PC9hPjwvbGk+PGxpIGNsYXNzPSJtb2JpbGVfYnRuIGRvd25sb2FkX3NsYWNrIj48YSBocmVmPSIvZ2V0IiBkYXRhLXFhPSJkb3dubG9hZF9zbGFjayIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X2Rvd25sb2FkIj5Eb3dubG9hZCBTbGFjazwvYT48L2xpPjxsaT48YSBkYXRhLWd0bS1jbGljaz0iU2lnblVwLG9wdG91dF9uYXZfY3JlYXRlX3RlYW0iIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2NyZWF0ZSIgY2xhc3M9IiIgZGF0YS1xYT0iY3JlYXRlX3RlYW0iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9jcmVhdGVfdGVhbSI+Q3JlYXRlIGEgbmV3IHdvcmtzcGFjZTwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9nZXQtc3RhcnRlZCMvZmluZCIgZGF0YS1ndG0tY2xpY2s9Im9wdG91dF9uYXZfZmluZF90ZWFtIiBkYXRhLXFhPSJmaW5kX3RlYW0iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9maW5kX3RlYW0iPkZpbmQgeW91ciB3b3Jrc3BhY2U8L2E+PC9saT48bGkgY2xhc3M9InNpZ25faW4gaGlkZV9vbl9tb2JpbGUiPjxhIGRhdGEtZ3RtLWNsaWNrPSJvcHRvdXRfbmF2X3NpZ25pbiIgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vc2lnbmluIiBjbGFzcz0iYnRuX3N0aWNreSBidG5fZmlsbGVkIiBkYXRhLXFhPSJzaWduX2luIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfc2lnbl9pbiI+U2lnbiBpbjwvYT48L2xpPjxsaSBjbGFzcz0ibW9iaWxlX2J0biBtb2JpbGVfbWVudV9idG4iPjxhIGhyZWY9IiMiIGNsYXNzPSJidG5fc3RpY2t5IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfbW9iaWxlX21lbnVfYnRuIj5NZW51PC9hPjwvbGk+PC91bD48L25hdj48bmF2IGNsYXNzPSJtb2JpbGVfbWVudSBsb2FkaW5nIG1lbnVfc2Nyb2xsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PGRpdiBjbGFzcz0ibW9iaWxlX21lbnVfd3JhcHBlciI+PGRpdiBjbGFzcz0ibW9iaWxlX21lbnVfaGVhZGVyIj48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS8iIGNsYXNzPSJsb2dvIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfbG9nbyI+PC9hPjxhIGhyZWY9IiMiIGNsYXNzPSJjbG9zZSIgYXJpYS1sYWJlbD0iY2xvc2UiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9tZW51X2Nsb3NlIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiB0c19pY29uX3RpbWVzIj48L3RzLWljb24+PC9hPjwvZGl2Pjx1bD48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vaXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9wcm9kdWN0Ij5Qcm9kdWN0PC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaWNpbmc/dWlfc3RlcD01NSZhbXA7dWlfZWxlbWVudD01IiBjbGFzcz0ibW9iaWxlX25hdl9wcmljaW5nIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfcHJpY2luZyI+UHJpY2luZzwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL2dldC5zbGFjay5oZWxwL2hjL2VuLXVzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfc3VwcG9ydCI+U3VwcG9ydDwvYT48L2xpPjxsaT48YSBocmVmPSIvZ2V0IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfZG93bmxvYWQiPkRvd25sb2FkIDxzcGFuIGNsYXNzPSJvcHRpb25hbF9kZXNrdG9wX25hdl9tZXNzYWdlIj50aGUgU2xhY2sgYXBwPC9zcGFuPjwvYT48L2xpPjwvdWw+PHVsIGNsYXNzPSJtb2JpbGVfbWVudV9mb290ZXIiPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9zaWduaW4iIGRhdGEtZ3RtLWNsaWNrPSJvcHRvdXRfbmF2X3NpZ25pbiIgdGFyZ2V0PSJfYmxhbmsiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9zaWduX2luIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiBzbWFsbCBmbG9hdF9ub25lIHRlYW1faWNvbiB0c19pY29uX3BsdXMgZGVmYXVsdCBzaWdudXBfaWNvbiI+PC90cy1pY29uPjxzcGFuIGNsYXNzPSJzd2l0Y2hlcl9sYWJlbCI+U2lnbiBpbjwvc3Bhbj48L2E+PC9saT48bGk+PGEgZGF0YS1ndG0tY2xpY2s9IlNpZ25VcCxvcHRvdXRfbmF2X2NyZWF0ZV90ZWFtIiBocmVmPSJodHRwczovL3NsYWNrLmNvbS9nZXQtc3RhcnRlZCMvY3JlYXRlIiBjbGFzcz0iIiB0YXJnZXQ9Il9ibGFuayIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X2NyZWF0ZV90ZWFtIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiBzbWFsbCBmbG9hdF9ub25lIHRlYW1faWNvbiBjLWljb24tLXNsYWNrIGRlZmF1bHQgc2lnbnVwX2ljb24iPjwvdHMtaWNvbj48c3BhbiBjbGFzcz0ic3dpdGNoZXJfbGFiZWwiPkNyZWF0ZSBhIG5ldyB3b3Jrc3BhY2U8L3NwYW4+PC9hPjwvbGk+PC91bD48L2Rpdj48L25hdj48ZGl2IGlkPSJwYWdlIiBjbGFzcz0iIj48ZGl2IGlkPSJwYWdlX2NvbnRlbnRzIiBkYXRhLXFhPSJwYWdlX2NvbnRlbnRzIiBjbGFzcz0iIj48ZGl2IGlkPSJwcmVsb2FkIj48L2Rpdj48ZGl2IGlkPSJjb250ZW50IiBkYXRhLWJhY2tncm91bmQ9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS84MDU4OC9pbWcvNDA0L21hcnJha2VzaC1tZWFkb3ctODAuanBnIj48aW1nIGlkPSJiYWNrZ3JvdW5kIiBzcmM9ImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEFRQUJBSUFBQUFBQUFQLy8veUg1QkFFQUFBQUFMQUFBQUFBQkFBRUFBQUlCUkFBNyI+PGRpdiBpZD0ic3ByaXRlLXdyYXBwZXIiPjxkaXYgY2xhc3M9InNwcml0ZSBwaWdneSBwaWdneV9jaGV3aW5nIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgY2hpY2tlbiBjaGlja2VuX3dhbGtfbHIiPjxkaXYgY2xhc3M9InN1Yl9zcHJpdGUiPjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBjaGlja2VuIGNoaWNrZW5fcGVja18yeCBmbGlwcGVkIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgcGlnZ3kgcGlnZ3lfd2FsayBwaWdneV93YWxrX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgY2hpY2tlbiBjaGlja2VuX3dhbGtfcmwgZmxpcHBlZCI+PGRpdiBjbGFzcz0ic3ViX3Nwcml0ZSI+PC9kaXY+PC9kaXY+PGRpdiBjbGFzcz0ic3ByaXRlIHBpZ2d5IHBpZ2d5X3dhbGsgZmxpcHBlZCBwaWdneV93YWxrX3JsIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9hbmdsZSBidXR0ZXJmbHlfYW5nbGVfbHIiPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X2FuZ2xlXzEgYnV0dGVyZmx5X2FuZ2xlXzFfbHIiPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X3Jvb2tlZCBidXR0ZXJmbHlfcm9va2VkX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9zaWRlIGJ1dHRlcmZseV9zaWRlX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9hbmdsZSBmbGlwcGVkIGJ1dHRlcmZseV9hbmdsZV9ybCBib3R0b20iPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X2FuZ2xlXzEgZmxpcHBlZCBidXR0ZXJmbHlfYW5nbGVfMV9ybCBib3R0b20iPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X3Jvb2tlZCBmbGlwcGVkIGJ1dHRlcmZseV9yb29rZWRfcmwgYm90dG9tIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9zaWRlIGZsaXBwZWQgYnV0dGVyZmx5X3NpZGVfcmwgYm90dG9tIj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGlkPSJsb2FkZXIiPjw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+PHN2ZyB3aWR0aD0iMzJweCIgaGVpZ2h0PSIzMnB4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgY2xhc3M9InVpbC1oZWFydCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9MTAwIGhlaWdodD0xMDAgZmlsbD0ibm9uZSIgY2xhc3M9ImJrIj48L3JlY3Q+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTAgNTApIj48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTAgLTUwKSI+PHBhdGggZD0iTTkwLDMwLjJjMC0xMS05LTIwLjEtMjAtMjAuMXMtMjAsOS4xLTIwLDIwLjJjMCwwLjIsMC0wLjMsMCwwLjdINTBjMC0xLDAtMC42LDAtMC44YzAtMTEtOS0yMC4xLTIwLTIwLjFzLTIwLDkuMS0yMCwyMC4yIGMwLDAuMiwwLTAuMywwLDAuN2gwYzAuMywyMCwzMCwzOS41LDQwLDU1YzEwLTE1LjUsMzkuNy0zNSw0MC01NWgwQzkwLDMwLDkwLDMwLjQsOTAsMzAuMnoiIGZpbGw9IiNmMDIiPjwvcGF0aD48L2c+PGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJzY2FsZSIgZnJvbT0iMS4zIiB0bz0iMC45IiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgY2FsY01vZGU9InNwbGluZSIgdmFsdWVzPSIxLjM7MC45OzEuMTswLjkiIGtleVRpbWVzPSIwOzAuMzswLjMwMTsxIiBrZXlTcGxpbmVzPSIwIDAuNzUgMC4yNSAxOzAgMSAwIDE7MCAuNzUgLjI1IDEiPjwvYW5pbWF0ZVRyYW5zZm9ybT48L2c+PC9nPjwvc3ZnPjwvZGl2PjxkaXYgY2xhc3M9ImNhcmQiPjxoMT48aSBjbGFzcz0idHNfaWNvbiB0c19pY29uX3dhcm5pbmcgbXVzdGFyZF95ZWxsb3ciPjwvaT5UaGVyZeKAmXMgYmVlbiBhIGdsaXRjaOKApjwvaDE+PHA+V2XigJlyZSBub3QgcXVpdGUgc3VyZSB3aGF0IHdlbnQgd3JvbmcuIFlvdSBjYW4gZ28gYmFjaywgb3IgdHJ5IGxvb2tpbmcgb24gb3VyIDxhIGhyZWY9Imh0dHA6Ly9nZXQuc2xhY2suaGVscC9oYy9lbi11cyIgdGFyZ2V0PSJfYmxhbmsiPkhlbHAgQ2VudGVyPC9hPiBpZiB5b3UgbmVlZCBhIGhhbmQuPC9wPjwvZGl2Pjxub3NjcmlwdD48c3R5bGU+I2xvYWRlciB7CgkJCQkJCWRpc3BsYXk6IG5vbmU7CgkJCQkJfTwvc3R5bGU+PC9ub3NjcmlwdD48c2NyaXB0PgovLyBmaXJlIDQwNAp3aW5kb3cuZGF0YUxheWVyID0gd2luZG93LmRhdGFMYXllciB8fCBbXTsKd2luZG93LmRhdGFMYXllci5wdXNoKHsKCSdldmVudCcgOiAnRXJyb3I0MDQnLAp9KTsKCihmdW5jdGlvbigpIHsKCS8vIHF1aWNrIGhhY2s6IDgtYml0IGFscGhhLWZyaWVuZGx5IGxvZ28KCXZhciBsb2dvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWRlcl9sb2dvJyk7Cgl2YXIgYWx0X3NyYyA9ICdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQVBBQUFBQklDQU1BQUFEL0VvaTRBQUFDK2xCTVZFVUFBQUFvRlNjcUlqRW9KVE1yTERRck1qZzFNRGs3TXpncU9EMDlOVG8vT0QxQ09qOUVQRUZGUFVOSVBVaE5QRW05SHlsSlFVYlBGMXhNUkVsaVBWRmRQMUN3SjFxOEtTcFBSMHpNSVZmTElWdVJNMVNySzFrd1VrNkxObGlHT0Zjc1ZWSEJMU2RUU2svUEpsNVZUVkl6V0UvTkswNi9OQ2pSSzJaWlVWYkNOeXJOTTBVeVlGVmNWRm5QTmt4ZlZsd3VabHJRTldoaFdGN0pQalprVzJIVU9uSEpSVGZGU0NwblgyUnFZbWRzWkduVlJIWElVU2h1Wld0eGFHN01WVExKV0N4MWJIRkxlVzRhakhSNGNIWGFVb04wY25aZ2dEVmVnRHM3aDJ0OGMza3ppMjRoa0hob2dqZUFkbnpiV29aN2VYMTBoallqbUhoN2hqalNjQ3lIZm9RMG1IbC9pVFF1bW9DRmlEVjRpMEdEZ1lXR2lUYlFkQzFIbFh6Z1pvNThqMFdIaFlsQW5YaUpoNHZnYlpMVWVUOHRwWDdVZkNwK2trNDZvMzNnYjVtTWlvNCtwbzJqa1RYZmRadVFqcExXaEN1U2tKU25sREE0cm9hdWxESTVyNGVWazVjOHNZbERyWitIb0dmamY2T1pscHFEb201QnRZMmNtWjdqaHFlQ3FYK2ZuYUdBcW9iY21TN09uaXRTdVpHaW9LVFZuaTVRdlp2bWo2MmxvNmZnb1N1cHBxcGZ3SjludmFyZXBqYm9sN05zdmJHdHFxOTJ2Yk55dnJtd3JiTGlxa0p0dzZScHdjaHZ3Y0t5cjdSd3hxYnJvYnB0eGN6aHNVNjJ0TGh2eDg1Nng4OSt5cXpsdFZtNnVMenNxY0IreTlUbnVHSyt1OERrdW1LSXo3anVzY2Jsdld2QnY4T1B6dExFd2NiSnc4S1YxTDdxdzNmdnVzekl4c3JNeDhXWDFkbk15Yzd0eDRIdXlZbWoyc1hSek1yeHd0UFB6ZEdqMmQvVXpzM1QwTlhqMFovczBKU28zdVRZMHRHeDM4enp5OXJYMU5udjFKNnkzK2JjMTlYbzJLeTQ0ZUs4NHREYjJOengyS2ZmMmRqejA5Kzg1dHJsM2J6ZjNPSHozTEhqM3R6RjV1bm00Ti9JNnVESTZlemw0dWYzNHIzcTVPUDU0T3JwNXV2NTVzZlU3ZkxWNytiNTZNL3Q2dS93NnVuYjhPLzY2UEQ3N2RyaDgrenc3dkwzOE52bTgvVDI4Ty93OHUvNTcvWDI4L2owOXZQdStQUDY5dWYrOXU3eitQdjg5dlg2K2UvNCt2ZjgrZjcyKy83Lyt2bjYvUG44L3Z2ZWd2MXVBQUFBQVhSU1RsTUFRT2JZWmdBQUNnZEpSRUZVZUFIbDJnVjRFMmtleC9ILzZudHBzYWJydnFVclNBNkh0bHg3Rzl6ZFlkMFh5WGFsMlNPNDB4VDNMbWx3RDFxNVd5UzR1eC9kWG5IYlNvcVVhVW1lNTZhWnladi9aTjdKTkpBVDZPZnhmYkR2emk5dk01TkFLYm1nTExtMGZKSjUwdnJyVUVhNDFwdmRKcDJDc21HNzJlTjNLQXYrTUZNcFRpZ0Q5cHE5L2hPanR2ZHRwNCtKaVcyWENjR1ExU29tT2lvNkptNElQTENsS0hnVkJGOFVFU1JETUF3bm9xS2dCRSs2QjBGWGx3aW1RakNZaUNnWEh0VGZ6Zi9aVGRjZ2dpUUlodmhBZ2wzSDF5MVlkOXdGVXIrYjVadStlMjdmam9NNUVCUTZJaGdEd1dBZ29pdWc2dUlFWTRrSkYwSENPY2xuMDNmUHBGdmMwdTlDRUZRaGd1RVFESDFMSDN4anNGRXcyS2Q0dlJrNXdOZFNTNEpSSEVrRVE0SWJuQTBxbk9PTUhoT1VOajMycCs2ZldMQWQ4UEFpZ2hyOE9SRmxnb3AvR3IyT3N6Yk4xelp2MGFMdGRBdDJOM2pCcHVBR253VVY2MUR3QXQ5Tjg3VTkrZG9TZ3l6WUJYaG9MLzFuZ2srRGlnVW9lREFIMkltZitvaTF2RjRXN0Z6d2doT0NHM3dTVkt3d3NqZGRmQzU5VHRzV1hzMm40ZUFjZUdqaFJCQWYzT0Nqb09JNERsN2dyWjNIWjMyQ2dpV2JYZzNCQ3piOGw0TTVJOFo1YTNuRFVDL2U5UHdjZUhoaFFRM3VTMFQ3UWYxRmpCd1Nhd1VLbTU1L0ZZSVkzRGU0d1hzZ2dFMy8vRzAvdmhiNXBnWHlONHZidkIxM0lRQk8rNWhXZFNQS2gxV0pialo4WTZGNjhPV04xaGxKeWJhZHVhRHM4aDdiMU1RWmkvWTdHTUU3QWN1MkhYWEtOajFZclAycVUrUEdqZWZnWHZtbTU2V2ZLNFlBT01aRUVFU2p0eFg1Q1hiWkRkNWZydnZVenY0ZmFJZ2tIclhqOS9nTnRvWVFFaG8zM001Sk4wMXJlYitnWE5tbVpiVnFVbDhpdnNLbk9zR3RQQkY4RGlJdTBmZFhSNldCTDFzVklsVmprVk1TdkJXOFpoQlIrZUdTVGROYVhnK0wwcWE3LzdRTkFwUklXR3BjbGdSL0NvSmxrVVRPNUFUc1pEU1JxM3NVM3kyaFdVd2xWRmVnaWkra3QybU16TFpnSThUYXpqK01NcHVYUW1Dc2hDMkJFY3gxSlV3ZEFFa3JSMWhDMHdEaTVjRkphQ29GOU9mdGx2a1dTdzhjek5oMDUvNThiWWw3RUlqTG9ZVE5LZzkyMUNZS3hnQ1ZyQ0Zzc1FBSlJMU1pNYSs2NHVtV3c5ZVcrQVgxeWpiZGthLzFPQUtCNkUzWXdqbDVjQ3BSZEJoRXlyOW1oandZOTliSWd4S3VIZlF5b2w3cE9iM2s0QWt6RXRDbXVWQmFPUHhvUVZIZXpxbHhranQrenp4N0E0L1RFUlk4Nml0aFJJR09ROCswTm9MYkdOUjdFOXhvcjJ6VHREWUh3RGtURjk4R2RiSUxVdVVLSGJrcGpKQ3dBa1l3YlBXOEhwc2xwcTVkbGlBZVR2aUdELytuaUUrVEZpVVBhVkxlYzFGUmNJWlM3d1dheTl6MGtoMDU2Rmxld0p2R20wb0ZyNEl4c2N0QUd0d1ZQWlFLSDVNTGd2MHh4R080NzZDcjJFRGd0TVdKcndrY3pPNkZMU2g0dG5UVGZPMVZGNGpPNCtDRkQvSllyUUNZeXFOZ1lkU2hReHhBY2JGRUZPZHpnZlg0RDl5b3ErSUEzaEFpU2xQb2hTVW9XTHJwaWQ1YWVJaE45NVdPVEMwWXpwcXVBSlpGUktHY01IbFJWQkZnbkpBL0hBVXplMkdlaGJucFRsLzkvS3VmNTlON0grQ3pnUEpXOVdBNWRFMVBBenFGTlpuKy83WlUzRnM3RjRCNWhXZlRXaVB2Rm1DWG1KdSsvNjk4OEc4Um9TSVROaGNFSHR3YlQ2UXV3V2VjSEsxY2kzcnI1b0hYUVF2V2c5YnlkZ0hta20vNjJ0eW1sYlhhV3VQOU5qdENDRmFsUTZLOVNEMll5OTV2MzMrV2s3d21yQUM1eEdPenloRVpRYWdvQnlERjgxSHZ2Q25mL21pa2ZEYjlEK21tOCtlMjE0b2FYZ3ZzalVlb2ZoSG5MM2huM3hvYWNSTWRySGw5MFp1dG5VUVV3Z0ZURXBFSmRZREVWVnJNM3dRNUJ4c1I1VTJQL0xMOUsxcXZodmRCV1c0NGtRdEw0cFNDMDJvVE5oUEFHdnFxQkpWZ1pCRkk1V3h4MytDZXVZdWU1Zm5kOU1ndURWNnM5SzRXV3d4KzdBa2pERFd5bWNFY0hvVHNaaU1adlcxbW1rcmtRbytDaitLY25HTDBQTjd2cGtkK3lOZnk2bWl4OXVCUFpqUmhlQ2xMZkFDQWc3a1lvaHlNTG1BVDFXQWtJaGNVK2QwMHJlVlYxV0wxMUk1cTFreGpYU2hZUEhhN0VtWHhBRmExS3p5RHNNUTVnY24vcGd0WC9wV3ZwU1NiYmdocTlwaWlOY1NIVFJhY0labEFWTFBldldNMCtBcW5FWkVPMkpJVnh5SGpmOU9GRzc2b3JLMlBlcVdiL2c1S29URERGQk1xdXdFS3c3ZUhVY1NqOXBpVDRwblhBZjJyOXhPUkpsZjlZY05VdEc5YlFKc3VLcW5sVlVPOTBrMXZnbExpN0orVzl4N1Z2c0hadEdlcUN6eVdvVk82a0Y3dk5hcHZjNUlBOU1TamZHYXBOODNYdmk5bXZZd25qVGY5QlFRZ3R4M3g0TkFuRDUvaVYrQlVWb01KdjgvVXF3VVBCNERMWWNTakxsZXFUYy9hTklDdnBlb3dOMTE1OG4wSVNETWl5a2JCbjZOdmFMemtaQjI4US9EdEg3RURKcHRETTkrRng0TUMxMmo2UEw3bDYwKytRR05sbTM1UFBLL0dYd1AvMXZTMm9nQjhENWVIUGozc2k4NW9QU0FHZk0zMmVJKzBLNERzVHl5QUVqYWZZNm9Kb1RiNjMvVFByZDk2OG9rbm5uaE9LL0cyejZickRUMEdhdlpyK0VGdEJDU09DRUxBSjloelBsVUJMMGNFZW11Sjc0Y2pUNE9ITTBsRFlqamdyY1g3bDQ0NndxRzRhYjcySGI2MnhMTzBWYjdwK3FoV21VdTR3WWxaVXlTN2hZdkczd0F3NEp1L2JQQW9pQ01laWU2NUVDckVJUHd5YnBIT1BXSW5maUJpa2gvYlhZSE45ZEU3VHoxQnZhYkYva3hyMy83Zyt4UlFoVWNXMWpVcDlmUlIyL0FxK0J6RndlaW5hQTBIQ0RJaWlmU1h1NklJb210bitGUmZEcDBDR2VnRkx4dDFLakFjRzFxdkFxMlZiL285ZCsyTEgzeHY1djBSeUZjTDVjcmZ4TUVKQUhCVFEwUmhKdnZwekxWRHFoQUJPcnF6eWhNbFZvRE4rQVV2RzNVdW81YVBlaE1IeXpmOTRsKytOZ3UyZ3pxT0tFcVVmNm1sSGZFakdmM2tZV29Ic0ZVV2pILzlweUN4cWFFUTlZcjQrbVZ1bXErbFNyVnBQVkdnNStUZjA4b3VSNVJaV1RjSVNFUW1Pc1hIQU5XQnNCOGJES0JWa2swL3I2VXFmN3l5TU1XTWxHYlRuSUV3UlRsWTM4U3phZVFkc3Z0YVd3aXpOeHNBanVMNWlISmZJaDVWT0tBbWE2azNXSnQrcGYzS2ZQejllSlZOSXh1amlKeUJBNEZPK2krMCtWNWpVNmIwL1RCK1dvMzF2Z204MCtpRW8xTHhwekVlK2VnSmhtelRmTzNpZkhDN2pvTlRvSFRzVFRRK2M3YURSdzJmZDVOWFdrbDJrQXFYaVdndGZqT2pJeExSVzhFdEV3ZkxIaFdIeDZXQngyS2FLOTkwMDduNVFLVTgwUFBwd2xSRDNYRHhBTllQendTdjVObzFkRHBkamFqVDRIRTJvYTVHdUdNeWJBWmUzeWJOOVBwbVRicGVBZXgwWW15b2VOcEhKMldEeU5rN0xpYWFGM2NZRUs1SjNRNG02OVk4MWl0WXR1ay9OYm9HbUdUVGx5QVF6c3Y3ajJZN1hLQ095OXAvOURJSGFoeFpPemVlZFVEZ3BNRm8wOC9VL014b3ZBSFlkV253STJ1eUZxdjRCTy9wbXQyTUpYNERERzk2a2hNZVdkY3E0K0JYbjNpNmVqZUZyeE9mTWxQcjRSRTJIaitURy9xUkVaRnUycm5RTEpwNUJ4NWxBOFhhV2dOM3UvQzNpV1didnJkUTdMMEVqN1pqM3pXczFYVGdwdnZBdTRpREo0Q1U4OGpDU2VhVTdVNTRuSXhtYlJweHdtTkdzdW5qOFBpVGJQb1FsQUY0MHhlaERQak5TSTJHc29BYmpSL0hsd1VYQjR1OUs2Q011UEdyZTgrN1hGQm0zTHB4NDVZVEhpdi9Cb3VZU0s5WVRUVG5BQUFBQUVsRlRrU3VRbUNDJzsKCWlmIChsb2dvKSB7CgkJbG9nbyA9IGxvZ28uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2ltZycpWzBdOwoJCWlmICghbG9nbykgcmV0dXJuOwoJCWxvZ28uc3JjID0gYWx0X3NyYzsKCX0KfSgpKTsKPC9zY3JpcHQ+PC9kaXY+PGRpdiBpZD0ib3ZlcmxheSI+PC9kaXY+PC9kaXY+PGZvb3RlciBkYXRhLXFhPSJmb290ZXIiPjxzZWN0aW9uIGNsYXNzPSJsaW5rcyI+PGRpdiBjbGFzcz0iZ3JpZCI+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF8xIj5Vc2luZyBTbGFjazwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2lzIiBkYXRhLXFhPSJwcm9kdWN0X2Zvb3RlciIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3Byb2R1Y3QiPlByb2R1Y3Q8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vZW50ZXJwcmlzZSIgZGF0YS1xYT0iZW50ZXJwcmlzZV9mb290ZXIiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9lbnRlcnByaXNlIj5FbnRlcnByaXNlPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaWNpbmc/dWlfc3RlcD0yOCZhbXA7dWlfZWxlbWVudD01IiBkYXRhLXFhPSJwcmljaW5nX2Zvb3RlciIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3ByaWNpbmciPlByaWNpbmc8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9nZXQuc2xhY2suaGVscC9oYy9lbi11cyIgZGF0YS1xYT0ic3VwcG9ydF9mb290ZXIiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zdXBwb3J0Ij5TdXBwb3J0PC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2d1aWRlcyIgZGF0YS1xYT0iZ2V0dGluZ19zdGFydGVkIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZ2V0dGluZ19zdGFydGVkIj5TbGFjayBHdWlkZXM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vYXBwcyIgZGF0YS1xYT0iYXBwX2RpcmVjdG9yeSIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2FwcF9kaXJlY3RvcnkiPkFwcCBEaXJlY3Rvcnk8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9hcGkuc2xhY2suY29tLyIgZGF0YS1xYT0iYXBpIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfYXBpIj5BUEk8L2E+PC9saT48L3VsPjwvZGl2PjxkaXYgY2xhc3M9ImNvbCBzcGFuXzFfb2ZfNCBuYXZfY29sIj48dWw+PGxpIGNsYXNzPSJjYXRfMiI+U2xhY2sgPHRzLWljb24gY2xhc3M9InRzX2ljb25faGVhcnQiPjwvdHMtaWNvbj48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9qb2JzIiBkYXRhLXFhPSJqb2JzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfam9icyI+Sm9iczwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9jdXN0b21lcnMiIGRhdGEtcWE9ImN1c3RvbWVycyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2N1c3RvbWVycyI+Q3VzdG9tZXJzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2RldmVsb3BlcnMiIGRhdGEtcWE9ImRldmVsb3BlcnMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9kZXZlbG9wZXJzIj5EZXZlbG9wZXJzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2V2ZW50cyIgZGF0YS1xYT0iZXZlbnRzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZXZlbnRzIj5FdmVudHM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFja2hxLmNvbS8iIGRhdGEtcWE9ImJsb2dfZm9vdGVyIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfYmxvZyI+QmxvZzwvYT48L2xpPjwvdWw+PC9kaXY+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF8zIj5MZWdhbDwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaXZhY3ktcG9saWN5IiBkYXRhLXFhPSJwcml2YWN5IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfcHJpdmFjeSI+UHJpdmFjeTwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9zZWN1cml0eSIgZGF0YS1xYT0ic2VjdXJpdHkiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zZWN1cml0eSI+U2VjdXJpdHk8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vdGVybXMtb2Ytc2VydmljZSIgZGF0YS1xYT0idG9zIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfdG9zIj5UZXJtcyBvZiBTZXJ2aWNlPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3BvbGljaWVzIiBkYXRhLXFhPSJwb2xpY2llcyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3BvbGljaWVzIj5Qb2xpY2llczwvYT48L2xpPjwvdWw+PC9kaXY+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF80Ij5IYW5keSBMaW5rczwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2Rvd25sb2FkcyIgZGF0YS1xYT0iZG93bmxvYWRzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZG93bmxvYWRzIj5Eb3dubG9hZCBkZXNrdG9wIGFwcDwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9kb3dubG9hZHMiIGRhdGEtcWE9ImRvd25sb2Fkc19tb2JpbGUiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9kb3dubG9hZHNfbW9iaWxlIj5Eb3dubG9hZCBtb2JpbGUgYXBwPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2JyYW5kLWd1aWRlbGluZXMiIGRhdGEtcWE9ImJyYW5kX2d1aWRlbGluZXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9icmFuZF9ndWlkZWxpbmVzIj5CcmFuZCBHdWlkZWxpbmVzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2thdHdvcmsuY29tIiBkYXRhLXFhPSJzbGFja19hdF93b3JrIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfYXRfd29yayI+U2xhY2sgYXQgV29yazwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3N0YXR1cy5zbGFjay5jb20vIiBkYXRhLXFhPSJzdGF0dXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zdGF0dXMiPlN0YXR1czwvYT48L2xpPjwvdWw+PC9kaXY+PC9kaXY+PC9zZWN0aW9uPjxkaXYgY2xhc3M9ImZvb3Rub3RlIj48c2VjdGlvbj48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbSIgYXJpYS1sYWJlbD0iU2xhY2sgaG9tZXBhZ2UiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zbGFja19pY29uIj48dHMtaWNvbiBjbGFzcz0iYy1pY29uLS1zbGFjayIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48dWw+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2hlbHAvY29udGFjdCIgZGF0YS1xYT0iY29udGFjdF91cyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2NvbnRhY3RfdXMiPkNvbnRhY3QgVXM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9TbGFja0hRIiBkYXRhLXFhPSJzbGFja190d2l0dGVyIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfdHdpdHRlciIgYXJpYS1sYWJlbD0iU2xhY2sgb24gVHdpdHRlciI+PHRzLWljb24gY2xhc3M9InRzX2ljb25fdHdpdHRlciIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48L2xpPjxsaSBjbGFzcz0ieXQiPjxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNZM1lFQ2dlQmNMQ3pJckZMUDRnYmx3IiBkYXRhLXFhPSJzbGFja195b3V0dWJlIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfeW91dHViZSIgYXJpYS1sYWJlbD0iU2xhY2sgb24gWW91VHViZSI+PHRzLWljb24gY2xhc3M9InRzX2ljb25feW91dHViZSIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48L2xpPjwvdWw+PC9zZWN0aW9uPjwvZGl2PjwvZm9vdGVyPjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KLyoqCiAqIEEgcGxhY2Vob2xkZXIgZnVuY3Rpb24gdGhhdCB0aGUgYnVpbGQgc2NyaXB0IHVzZXMgdG8KICogcmVwbGFjZSBmaWxlIHBhdGhzIHdpdGggdGhlaXIgQ0ROIHZlcnNpb25zLgogKgogKiBAcGFyYW0ge1N0cmluZ30gZmlsZV9wYXRoIC0gRmlsZSBwYXRoCiAqIEByZXR1cm5zIHtTdHJpbmd9CiAqLwpmdW5jdGlvbiB2dnYoZmlsZV9wYXRoKSB7CgkJIHZhciB2dnZfd2FybmluZyA9ICdZb3UgY2Fubm90IHVzZSB2dnYgb24gZHluYW1pYyB2YWx1ZXMuIFBsZWFzZSBtYWtlIHN1cmUgeW91IG9ubHkgcGFzcyBpbiBzdGF0aWMgZmlsZSBwYXRocy4nOyBpZiAod2luZG93LlRTICYmIHdpbmRvdy5UUy53YXJuKSB7IHdpbmRvdy5UUy53YXJuKHZ2dl93YXJuaW5nKTsgfSBlbHNlIHsgY29uc29sZS53YXJuKHZ2dl93YXJuaW5nKTsgfSAKCXJldHVybiBmaWxlX3BhdGg7Cn0KCnZhciBjZG5fdXJsID0gImh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tIjsKdmFyIHZ2dl9hYnNfdXJsID0gImh0dHBzOlwvXC9zbGFjay5jb21cLyI7CnZhciBpbmNfanNfc2V0dXBfZGF0YSA9IHsKCWVtb2ppX3NoZWV0czogewoJCWFwcGxlOiAnaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L2ltZy9lbW9qaV8yMDE3XzEyXzA2L3NoZWV0X2FwcGxlXzY0X2luZGV4ZWRfMjU2LnBuZycsCgkJZ29vZ2xlOiAnaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L2ltZy9lbW9qaV8yMDE3XzEyXzA2L3NoZWV0X2dvb2dsZV82NF9pbmRleGVkXzI1Ni5wbmcnLAoJfSwKfTsKPC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgkvLyBjb21tb24gYm9vdF9kYXRhCgl2YXIgYm9vdF9kYXRhID0geyJhcGlfdXJsIjoiXC9hcGlcLyIsImFwcCI6IndlYiIsInVzZXJfaWQiOm51bGwsInRlYW1faWQiOiJUMDAwMDAwMDAiLCJ2aXNpdG9yX3VpZCI6Im9zajlubTV4bnZzbTI3M3ZmNjBrc3dpbyIsIm5vX2xvZ2luIjp0cnVlLCJ2ZXJzaW9uX3RzIjoiMTYwMjE5OTc4MyIsInZlcnNpb25fdWlkIjoiNTcwM2FhYjYyM2M0ZjdlOTY1NTk1NDQ4ZmMwMDNhNzg2YTkyYjgxMyIsImNhY2hlX3ZlcnNpb24iOiJ2MjEtbm9tYWQiLCJjYWNoZV90c192ZXJzaW9uIjoidjItYnVubnkiLCJyZWRpcl9kb21haW4iOiJzbGFjay1yZWRpci5uZXQiLCJzaWduaW5fdXJsIjoiaHR0cHM6XC9cL3NsYWNrLmNvbVwvc2lnbmluIiwiYWJzX3Jvb3RfdXJsIjoiaHR0cHM6XC9cL3NsYWNrLmNvbVwvIiwidGVhbV91cmwiOiIiLCJpbWFnZV9wcm94eV91cmwiOiJodHRwczpcL1wvc2xhY2staW1ncy5jb21cLyIsImJlYWNvbl90aW1pbmdfdXJsIjoiaHR0cHM6XC9cL3NsYWNrLmNvbVwvYmVhY29uXC90aW1pbmciLCJiZWFjb25fZXJyb3JfdXJsIjoiaHR0cHM6XC9cL3NsYWNrLmNvbVwvYmVhY29uXC9lcnJvciIsImNsb2dfdXJsIjoiY2xvZ1wvdHJhY2tcLyIsImFwaV90b2tlbiI6IiIsInZ2dl9wYXRocyI6eyJsel9zdHJpbmciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvYnYxLThcL2x6LXN0cmluZy0xLjQuNC53b3JrZXIuOGRlMWIwMGQ2NzBmZjNkYzcwNmEwLmpzIiwiY29kZW1pcnJvciI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC9idjEtOFwvY29kZW1pcnJvci5taW4uNTI2ZjkzNjkyNGVlZjE4ZjAwYmIubWluLmpzIiwiY29kZW1pcnJvcl9hZGRvbl9zaW1wbGUiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvYnYxLThcL2NvZGVtaXJyb3Jfc2ltcGxlLjliYzc2YmIzMjYwYTVlZDBlNWRjLm1pbi5qcyIsImNvZGVtaXJyb3JfbG9hZCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC9idjEtOFwvY29kZW1pcnJvcl9sb2FkLmYxYTM3ZjRlNDg2YjJjMjIxMDViLm1pbi5qcyIsImNvZGVtaXJyb3JfZmlsZXMiOnsiamF2YXNjcmlwdCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC9idjEtOFwvY29kZW1pcnJvcl9sYW5nX2phdmFzY3JpcHQuYjI5NWVmODc2ZWVkYWZlODNiMzkubWluLmpzIn19LCJub3RpZmljYXRpb25fc291bmRzIjpbeyJ2YWx1ZSI6ImIyLm1wMyIsImxhYmVsIjoiRGluZyIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2IyLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvYjIub2dnIn0seyJ2YWx1ZSI6ImFuaW1hbF9zdGljay5tcDMiLCJsYWJlbCI6IkJvaW5nIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvYW5pbWFsX3N0aWNrLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvYW5pbWFsX3N0aWNrLm9nZyJ9LHsidmFsdWUiOiJiZWVuX3RyZWUubXAzIiwibGFiZWwiOiJEcm9wIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvYmVlbl90cmVlLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvYmVlbl90cmVlLm9nZyJ9LHsidmFsdWUiOiJjb21wbGV0ZV9xdWVzdF9yZXF1aXJlbWVudC5tcDMiLCJsYWJlbCI6IlRhLWRhIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvY29tcGxldGVfcXVlc3RfcmVxdWlyZW1lbnQubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9jb21wbGV0ZV9xdWVzdF9yZXF1aXJlbWVudC5vZ2cifSx7InZhbHVlIjoiY29uZmlybV9kZWxpdmVyeS5tcDMiLCJsYWJlbCI6IlBsaW5rIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvY29uZmlybV9kZWxpdmVyeS5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2NvbmZpcm1fZGVsaXZlcnkub2dnIn0seyJ2YWx1ZSI6ImZsaXR0ZXJidWcubXAzIiwibGFiZWwiOiJXb3ciLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2U5MVwvc291bmRzXC9wdXNoXC9mbGl0dGVyYnVnLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvZmxpdHRlcmJ1Zy5vZ2cifSx7InZhbHVlIjoiaGVyZV95b3VfZ29fbGlnaHRlci5tcDMiLCJsYWJlbCI6IkhlcmUgeW91IGdvIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvaGVyZV95b3VfZ29fbGlnaHRlci5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2hlcmVfeW91X2dvX2xpZ2h0ZXIub2dnIn0seyJ2YWx1ZSI6ImhpX2Zsb3dlcnNfaGl0Lm1wMyIsImxhYmVsIjoiSGkiLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2U5MVwvc291bmRzXC9wdXNoXC9oaV9mbG93ZXJzX2hpdC5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2hpX2Zsb3dlcnNfaGl0Lm9nZyJ9LHsidmFsdWUiOiJrbm9ja19icnVzaC5tcDMiLCJsYWJlbCI6Iktub2NrIEJydXNoIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwva25vY2tfYnJ1c2gubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9rbm9ja19icnVzaC5vZ2cifSx7InZhbHVlIjoic2F2ZV9hbmRfY2hlY2tvdXQubXAzIiwibGFiZWwiOiJXaG9hISIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL3NhdmVfYW5kX2NoZWNrb3V0Lm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvc2F2ZV9hbmRfY2hlY2tvdXQub2dnIn0seyJ2YWx1ZSI6Iml0ZW1fcGlja3VwLm1wMyIsImxhYmVsIjoiWW9pbmsiLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2U5MVwvc291bmRzXC9wdXNoXC9pdGVtX3BpY2t1cC5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2l0ZW1fcGlja3VwLm9nZyJ9LHsidmFsdWUiOiJodW1tdXMubXAzIiwibGFiZWwiOiJIdW1tdXMiLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2ZhOVwvc291bmRzXC9wdXNoXC9odW1tdXMubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9odW1tdXMub2dnIn0seyJ2YWx1ZSI6Im5vbmUiLCJsYWJlbCI6Ik5vbmUifV0sImFsZXJ0X3NvdW5kcyI6W3sidmFsdWUiOiJmcm9nLm1wMyIsImxhYmVsIjoiRnJvZyIsInVybCI6Imh0dHBzOlwvXC9zbGFjay5nbG9iYWwuc3NsLmZhc3RseS5uZXRcL2EzNGFcL3NvdW5kc1wvZnJvZy5tcDMifV0sImNhbGxfc291bmRzIjpbeyJ2YWx1ZSI6ImNhbGxcL2FsZXJ0X3YyLm1wMyIsImxhYmVsIjoiQWxlcnQiLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL2FsZXJ0X3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC9pbmNvbWluZ19yaW5nX3YyLm1wMyIsImxhYmVsIjoiSW5jb21pbmcgcmluZyIsInVybCI6Imh0dHBzOlwvXC9zbGFjay5nbG9iYWwuc3NsLmZhc3RseS5uZXRcLzA4ZjdcL3NvdW5kc1wvY2FsbFwvaW5jb21pbmdfcmluZ192Mi5tcDMifSx7InZhbHVlIjoiY2FsbFwvb3V0Z29pbmdfcmluZ192Mi5tcDMiLCJsYWJlbCI6Ik91dGdvaW5nIHJpbmciLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL291dGdvaW5nX3JpbmdfdjIubXAzIn0seyJ2YWx1ZSI6ImNhbGxcL3BvcF92Mi5tcDMiLCJsYWJlbCI6IkluY29taW5nIHJlYWN0aW9uIiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC9wb3BfdjIubXAzIn0seyJ2YWx1ZSI6ImNhbGxcL3RoZXlfbGVmdF9jYWxsX3YyLm1wMyIsImxhYmVsIjoiVGhleSBsZWZ0IGNhbGwiLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL3RoZXlfbGVmdF9jYWxsX3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC95b3VfbGVmdF9jYWxsX3YyLm1wMyIsImxhYmVsIjoiWW91IGxlZnQgY2FsbCIsInVybCI6Imh0dHBzOlwvXC9zbGFjay5nbG9iYWwuc3NsLmZhc3RseS5uZXRcLzA4ZjdcL3NvdW5kc1wvY2FsbFwveW91X2xlZnRfY2FsbF92Mi5tcDMifSx7InZhbHVlIjoiY2FsbFwvdGhleV9qb2luZWRfY2FsbF92Mi5tcDMiLCJsYWJlbCI6IlRoZXkgam9pbmVkIGNhbGwiLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL3RoZXlfam9pbmVkX2NhbGxfdjIubXAzIn0seyJ2YWx1ZSI6ImNhbGxcL3lvdV9qb2luZWRfY2FsbF92Mi5tcDMiLCJsYWJlbCI6IllvdSBqb2luZWQgY2FsbCIsInVybCI6Imh0dHBzOlwvXC9zbGFjay5nbG9iYWwuc3NsLmZhc3RseS5uZXRcLzA4ZjdcL3NvdW5kc1wvY2FsbFwveW91X2pvaW5lZF9jYWxsX3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC9jb25maXJtYXRpb25fdjIubXAzIiwibGFiZWwiOiJDb25maXJtYXRpb24iLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL2NvbmZpcm1hdGlvbl92Mi5tcDMifV0sImNhbGxfc291bmRzX3ZlcnNpb24iOiJ2MiIsImltZyI6eyJhcHBfaWNvbiI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC84MDU4OFwvaW1nXC9zbGFja19ncm93bF9pY29uX3ZvZ3VlLnBuZyJ9LCJwYWdlX25lZWRzX2VudGVycHJpc2UiOmZhbHNlLCJwYWdlX25lZWRzX2N1c3RvbV9lbW9qaSI6ZmFsc2UsImlzX2RlcHJlY2F0ZWRfd2ViY2xpZW50X2Jyb3dzZXIiOmZhbHNlLCJpc191bnN1cHBvcnRlZF93ZWJjbGllbnRfYnJvd3NlciI6dHJ1ZSwiZGVmYXVsdF90eiI6IkFtZXJpY2FcL0xvc19BbmdlbGVzIiwiZmVhdHVyZV9kaXNwbGF5X2VtYWlsX2FkZHJlc3Nlc190b19yYWRpbyI6ZmFsc2UsImZlYXR1cmVfaWNvbl9idXR0b25fYXJpYV9sYWJlbF9pMThuIjpmYWxzZSwiZmVhdHVyZV9hbHRfY2hhbm5lbHNfcmVkdWNlciI6ZmFsc2UsImZlYXR1cmVfanNmXzE2MTkiOnRydWUsImZlYXR1cmVfZGVza3RvcF9sYXp5X2xvYWRfZW1vamkiOmZhbHNlLCJmZWF0dXJlX2VkdV84OF9nYSI6ZmFsc2UsImZlYXR1cmVfZXhwb3J0X3ByZWZfdG9fZGlzYWJsZSI6ZmFsc2UsImZlYXR1cmVfYWRkX21lbWJlcl9zdGF0c19hcGkiOmZhbHNlLCJmZWF0dXJlX21lbWJlcl9hbmFseXRpY3NfcGVybWlzc2lvbnMiOmZhbHNlLCJmZWF0dXJlX2J1bGtfdXNlcl9yZWFjdGl2YXRpb25fZ3JpZCI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX211bHRpc3RlcF9jb2xsYWJvcmF0b3JzX21vZGFsIjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX2FsbG93X2N1c3RvbV90aW1lX3NjaGVkdWxlZF90cmlnZ2VyIjp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfc2NoZWR1bGVkX3RyaWdnZXIiOnRydWUsImZlYXR1cmVfYnVpbGRlcl9tZXNzYWdlX2J1dHRvbl9oZWxwZXJfdGV4dCI6ZmFsc2UsImZlYXR1cmVfYnVpbGRlcl9jcmVhdGlvbl9vcmdfcG9saWN5Ijp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfZXh0ZW5zaW9ucyI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX2V4dGVuc2lvbl9zdGVwc19wcmVmIjp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfYWNjZXNzX2Vycm9yX2NvbnRlbnQiOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfcGFnaW5hdGVfd29ya2Zsb3dzX2xpc3QiOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfc3RlcF9saWJyYXJ5Ijp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfdGVhbV9hcHBzX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfYnVpbGRlcl9hcHBzX2NvbGxlY3Rpb25fbGluayI6ZmFsc2UsImZlYXR1cmVfYXBwc19jYW5fc3VibWl0X3dpdGhfd29ya2Zsb3dfc3RlcHMiOnRydWUsImZlYXR1cmVfYnVpbGRlcl9mZWVkYmFja19idXR0b24iOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfbWVzc2FnZV9zdGVwX3JpY2hfdGV4dCI6dHJ1ZSwiZmVhdHVyZV9jaGltZV9hY2Nlc3NfY2hlY2siOnRydWUsImZlYXR1cmVfYXBwX3ZpZXdzX3YxIjp0cnVlLCJmZWF0dXJlX2F1ZGl0X2xvZ3NfdmlldyI6ZmFsc2UsImZlYXR1cmVfYXVkaXRfbG9nc192aWV3X3dvcmtzcGFjZSI6ZmFsc2UsImZlYXR1cmVfb3JnX3RlYW1zX2luX2xvY2FsX2NvbmZpZyI6dHJ1ZSwiZmVhdHVyZV9kYXRhX2xvY2F0aW9uX25ld190cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2RlZmF1bHRfYnJvd3Nlcl9jb250cm9sX3YyIjp0cnVlLCJmZWF0dXJlX2FjY2Vzc2libGVfc2VsZWN0cyI6dHJ1ZSwiZmVhdHVyZV9zZWxlY3Rfb25fdGFiIjp0cnVlLCJmZWF0dXJlX3Byb25vdW5zX2luX3Byb2ZpbGUiOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfZGlzYWJsZV9nbG9iYWxfdHJpZ2dlcnMiOnRydWUsImZlYXR1cmVfd29ya2Zsb3dfYnVpbGRlcl9lbmFibGVkX29yZ19zZXR0aW5nIjp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfY2FuX2FjY2VzcyI6ZmFsc2UsImZlYXR1cmVfYWx3YXlzX3Nob3dfYXJjaGl2ZV9jaGFubmVsX29wdGlvbiI6dHJ1ZSwiZmVhdHVyZV9vcmdfZGFzaGJvYXJkX2dhbnRyeV9hY2Nlc3MiOmZhbHNlLCJmZWF0dXJlX29yZ19kYXNoX2dhbnRyeV9yZWRpcmVjdCI6ZmFsc2UsImZlYXR1cmVfb3JnX2Rhc2hib2FyZF9nYW50cnlfYXBwc19taWdyYXRpb24iOmZhbHNlLCJmZWF0dXJlX2luZm9fYmFycmllcnMiOmZhbHNlLCJmZWF0dXJlX2RheTJfc2hhcmVfbW9kYWwiOmZhbHNlLCJmZWF0dXJlX2dyYW51bGFyX2RuZCI6ZmFsc2UsImZlYXR1cmVfY3VzdG9tX2RuZF90cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2luZm9ybWF0aXZlX2Fubm91bmNlX29ubHlfZm9vdGVyX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfY29udGV4dF9iYXJfdHpfaXNzdWVzIjpmYWxzZSwiZmVhdHVyZV9uZXd4cF80NDAxIjp0cnVlLCJmZWF0dXJlX25ld3hwXzQyODEiOnRydWUsImZlYXR1cmVfbmV3eHBfMzg0OCI6dHJ1ZSwiZmVhdHVyZV9kYXkxX2NvbnZvIjp0cnVlLCJmZWF0dXJlX2RheTFfY29tZnlfc2lkZWJhcl9jb3B5IjpmYWxzZSwiZmVhdHVyZV9kYXkxX2NyZWF0b3JfbGFuZGluZ19jb3B5IjpmYWxzZSwiZmVhdHVyZV9jaGFubmVsX2Jyb3dzZXJfZGF5MSI6dHJ1ZSwiZmVhdHVyZV9iYW5uZXJfYXBwX3JlY3MiOnRydWUsImZlYXR1cmVfY29weV9qb2luZXJfZmxvdyI6dHJ1ZSwiZmVhdHVyZV9hcHByb3ZlZF9vcmdzIjpmYWxzZSwiZmVhdHVyZV9uZXd4cF8zMjc5Ijp0cnVlLCJmZWF0dXJlX25ld3hwXzQxNjAiOnRydWUsImZlYXR1cmVfbmV3eHBfNDE1MyI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80MjAyIjp0cnVlLCJmZWF0dXJlX25ld3hwXzQzMTMiOmZhbHNlLCJmZWF0dXJlX3RpbnlzcGVjayI6ZmFsc2UsImZlYXR1cmVfcXJfY29kZV9pbnZpdGUiOmZhbHNlLCJmZWF0dXJlX2dlbmVyYXRlX2xpZ2h0d2VpZ2h0X2RtX2xpbmsiOmZhbHNlLCJmZWF0dXJlX2Nvbm5lY3RfZG1fZWFybHlfYWNjZXNzIjp0cnVlLCJmZWF0dXJlX29sdWdfZXNjX2NoYW5uZWxzX3dvcmsiOnRydWUsImZlYXR1cmVfb2x1Z19yZW1vdmVfcmVxdWlyZWRfd29ya3NwYWNlX3NldHRpbmciOmZhbHNlLCJmZWF0dXJlX2RhdGFfdGFibGVfaW5fb3JnX2xldmVsX3VzZXJfZ3JvdXBzIjpmYWxzZSwiZmVhdHVyZV9vcmdfc2V0dGluZ3NfbTExbiI6ZmFsc2UsImZlYXR1cmVfZGVwcmVjYXRlX2dldF9tZW1iZXJfYnlfbmFtZSI6ZmFsc2UsImZlYXR1cmVfdW5rbm93bl9maWxlcyI6dHJ1ZSwiZmVhdHVyZV91bmtub3duX21lc3NhZ2VzIjp0cnVlLCJmZWF0dXJlX2FkZF9tZXNzYWdlX3BlcmYiOmZhbHNlLCJmZWF0dXJlX2ZpeF9jdXN0b21fZW1vamlfZXJyb3JzIjp0cnVlLCJmZWF0dXJlX21vZGVybl9kZWxldGVfZmlsZSI6dHJ1ZSwiZmVhdHVyZV9jb3B5X2NoYW5uZWxfbGluayI6dHJ1ZSwiZmVhdHVyZV9jb2xsYXBzZV9yZWFjdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2lhX3N0YXR1c19idXR0b24iOnRydWUsImZlYXR1cmVfZnVsbF9wcm9maWxlX2xpbmsiOnRydWUsImZlYXR1cmVfcHJpbnRfcGRmIjpmYWxzZSwiZmVhdHVyZV9zYWZhcmkxMF9kZXByZWNhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9zYWZhcmkxMF9kZXByZWNhdGlvbl9tb2RhbCI6dHJ1ZSwiZmVhdHVyZV9zYWZhcmkxMF9kZXByZWNhdGlvbl9ibG9jayI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcDQ2MF9kZXByZWNhdGlvbiI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcDQ2MF9kZXByZWNhdGlvbl9ibG9jayI6ZmFsc2UsImZlYXR1cmVfZW1haWxfd29ya2Zsb3ciOmZhbHNlLCJmZWF0dXJlX3dpZGVyX3JlYWN0aW9uX3RpcCI6ZmFsc2UsImZlYXR1cmVfZmlsZV9waWNrZXJfc2VhcmNoIjpmYWxzZSwiZmVhdHVyZV9zb3J0X2J5X3JlY2VuY3lfcG9zdF92MSI6ZmFsc2UsImZlYXR1cmVfc2VuZF9mYWlsZWRfdG9hc3QiOmZhbHNlLCJmZWF0dXJlX2F1ZGlvX3BsYXllciI6ZmFsc2UsImZlYXR1cmVfZWFnZXJseV9tYXJrX2Jyb2FkY2FzdHMiOmZhbHNlLCJmZWF0dXJlX3Nob3dfcmVwbGllc19pbW1lZGlhdGVseSI6ZmFsc2UsImZlYXR1cmVfY29tcG9zZXJfZXNjYXBlX2hhdGNoIjpmYWxzZSwiZmVhdHVyZV9jb21wb3Nlcl9lbWFpbF9jbGFzc2lmaWNhdGlvbiI6ZmFsc2UsImZlYXR1cmVfYW1hem9uX2ExMXlfY3VzdG9tX3N0YXR1c19lbW9qaSI6dHJ1ZSwiZmVhdHVyZV9ieWVfc2xhY2tib3RfaGVscCI6dHJ1ZSwiZmVhdHVyZV9hbGxfZG1fbXV0ZV9ib3RzIjp0cnVlLCJmZWF0dXJlX2ZpbGVfdGhyZWFkcyI6dHJ1ZSwiZmVhdHVyZV9icm9hZGNhc3RfaW5kaWNhdG9yIjp0cnVlLCJmZWF0dXJlX25ld19yZXBsaWVzX2FmdGVyX2JjYXN0Ijp0cnVlLCJmZWF0dXJlX3NvbmljX2Vtb2ppIjp0cnVlLCJmZWF0dXJlX2Vtb2ppXzEyIjpmYWxzZSwiZmVhdHVyZV9lbWFpbF9pbmdlc3Rpb24iOmZhbHNlLCJmZWF0dXJlX2F0dGFjaG1lbnRzX2lubGluZSI6ZmFsc2UsImZlYXR1cmVfZml4X2ZpbGVzIjp0cnVlLCJmZWF0dXJlX2FhYV9hZG1pbl9hcGlzIjp0cnVlLCJmZWF0dXJlX3JlbW92ZV9hY3Rpb25zX2Zyb21fc2lkZWJhciI6ZmFsc2UsImZlYXR1cmVfc2hvcnRjdXRzX3YyX2VkdWNhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9wYWRfMTUzNCI6ZmFsc2UsImZlYXR1cmVfc2hvcnRjdXRzX21lbnVfY2xlYW51cF9pMThuIjpmYWxzZSwiZmVhdHVyZV9hcHBfbGF1bmNoZXJfYWRkX2ljb24iOmZhbHNlLCJmZWF0dXJlX2FwcF9sYXVuY2hlcl9iYW5uZXJzIjpmYWxzZSwiZmVhdHVyZV9hcHBfbGF1bmNoZXJfc2VhcmNoX3BhZ2luYXRpb24iOmZhbHNlLCJmZWF0dXJlX2NoYW5uZWxfc2lkZWJhcl9kcmFmdHNfc2VjdGlvbiI6dHJ1ZSwiZmVhdHVyZV9uYXZpZ2F0ZV9oaXN0b3J5Ijp0cnVlLCJmZWF0dXJlX2kxOG5fZHJhZnRzIjpmYWxzZSwiZmVhdHVyZV9jb21wb3Nlcl91cmFfbXBkbSI6ZmFsc2UsImZlYXR1cmVfcmVjZW50X3N0YXR1c19kZWxldGUiOmZhbHNlLCJmZWF0dXJlX2NvbXBvc2VfZmxvdyI6ZmFsc2UsImZlYXR1cmVfY29tcG9zZV9mbG93X3h3cyI6dHJ1ZSwiZmVhdHVyZV9mYXN0ZXJfY291bnRfYWxsX3VucmVhZHMiOnRydWUsImZlYXR1cmVfc29uaWNfdXNlcl9ncm91cHMiOmZhbHNlLCJmZWF0dXJlX2NoYW5uZWxfc2VsZWN0b3JfZm9yX3RlYW1fZ3Vlc3RzX3VwZGF0ZSI6ZmFsc2UsImZlYXR1cmVfc2tfZGF0YV90YWJsZV9hMTF5IjpmYWxzZSwiZmVhdHVyZV9za19kYXRhX3RhYmxlX3Bpbm5lZF9yb3dzX2FuZF9jb2x1bW5zIjpmYWxzZSwiZmVhdHVyZV9kZXNrdG9wX3N5bXB0b21fZXZlbnRzIjpmYWxzZSwiZmVhdHVyZV9kYXRhX3Jlc2lkZW5jeV9kZWJ1Z2dpbmciOmZhbHNlLCJmZWF0dXJlX25ld19zdWJ0ZWFtX2xpbmtlZF9jaGFubmVsX2xpbWl0Ijp0cnVlLCJmZWF0dXJlX3N1YnRlYW1fdXNlcl9saW1pdCI6dHJ1ZSwiZmVhdHVyZV9lbnRfYWRtaW5fYXBwcm92ZWRfYXBwc192MiI6dHJ1ZSwiZmVhdHVyZV9kYXNoYm9hcmRfc29ydGFibGVfbGlzdHMiOmZhbHNlLCJmZWF0dXJlX3NrX2xvYWRpbmdfYnV0dG9uX21vdGlvbnMiOnRydWUsImZlYXR1cmVfc2tfYmFzZV9pY29uIjpmYWxzZSwiZmVhdHVyZV9za19iYXNpY19zZWxlY3RfYXJpYWxhYmVsIjpmYWxzZSwiZmVhdHVyZV9za19yZXF1aXJlZF9hcmlhbGFiZWwiOmZhbHNlLCJmZWF0dXJlX2NlX2VuZ19jb25uZWN0X2RtcyI6dHJ1ZSwiZmVhdHVyZV9jZV9lbmdfc2VhcmNoX2RlbW8iOmZhbHNlLCJmZWF0dXJlX2NlX2VuZ19oZWxwX3ZpdGVzcyI6ZmFsc2UsImZlYXR1cmVfY2VfZW5nX3ZlcmlmaWVkX3RpY2tldHMiOmZhbHNlLCJmZWF0dXJlX2FwcF9kaXJfcGhvZW5peCI6ZmFsc2UsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX211bHRpX29yZyI6ZmFsc2UsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX211bHRpX29yZ19tcGltIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9vcmdfbXBpbV9mZSI6dHJ1ZSwiZmVhdHVyZV9jaGF0X21waW1fb3Blbl9yZWZhY3Rvcl9mZV9jb3B5Ijp0cnVlLCJmZWF0dXJlX2ZpbmRfYW5fYWRtaW5fZGlzY29ubmVjdF9leHBsYWluZXIiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9vcmdfaW52aXRlc19iZSI6ZmFsc2UsImZlYXR1cmVfc2xhY2tfY29ubmVjdF9pbnZpdGVfdW5mdXJsX2NvcHkiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19sZWdhY3lfcmVjb25uZWN0Ijp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9vcmdfcWFfbGltaXRfb3ZlcnJpZGUiOmZhbHNlLCJmZWF0dXJlX211bHRpX3dvcmtzcGFjZV9zaGFyZWRfY2hhbm5lbHNfYmUiOmZhbHNlLCJmZWF0dXJlX2VzY190b19td3NjX3Byb3RvdHlwZV9iZSI6ZmFsc2UsImZlYXR1cmVfbXdzY194d3NfdG9fZXNjIjpmYWxzZSwiZmVhdHVyZV9yZXZva2VfZXNjX2ludml0ZXNfZmUiOmZhbHNlLCJmZWF0dXJlX213c2NfZXNjX3RvX3h3cyI6ZmFsc2UsImZlYXR1cmVfcmVtb3ZlX2RvdWJsZV9yaW5ncyI6ZmFsc2UsImZlYXR1cmVfcmVtb3ZlX2RvdWJsZV9kaWFtb25kcyI6ZmFsc2UsImZlYXR1cmVfY2hhbm5lbHNfdmlld19pbl9tc2MiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19lbW9qaV9kZWxpZ2h0Ijp0cnVlLCJmZWF0dXJlX2NyZWF0ZV9wcml2YXRlX2NfY2hhbm5lbHMiOmZhbHNlLCJmZWF0dXJlX2dkcHJfdXNlcl9qb2luX3RvcyI6dHJ1ZSwiZmVhdHVyZV91c2VyX2ludml0ZV90b3NfYXByaWxfMjAxOCI6dHJ1ZSwiZmVhdHVyZV9ub19tb3JlX2dldF9vcmlnaW5hdGluZ190ZWFtX2ZlIjp0cnVlLCJmZWF0dXJlX3JvbGVzX2FyZV9mcmVzaF9waGFzZV8xIjpmYWxzZSwiZmVhdHVyZV9jaGFubmVsX21nbXRfbWVzc2FnZV9jb3VudCI6ZmFsc2UsImZlYXR1cmVfYW9wc18zMzIwX3JldHVybl91c2VyX2lkc19hbmRfZXJyb3Jfc3RyaW5ncyI6dHJ1ZSwiZmVhdHVyZV9mdW5uZWxfY2FrZSI6ZmFsc2UsImZlYXR1cmVfbmV1ZV90eXBlIjpmYWxzZSwiZmVhdHVyZV9jdXN0X2FjcV9pMThuX3R3ZWFrcyI6ZmFsc2UsImZlYXR1cmVfZXhwb3J0c19jb3B5X3VwZGF0ZXMiOnRydWUsImZlYXR1cmVfd2hpdGVsaXN0X3plbmRlc2tfY2hhdF93aWRnZXQiOmZhbHNlLCJmZWF0dXJlX2NvbW1lbmRhdGlvbnNfc3B5Ijp0cnVlLCJmZWF0dXJlX3h3c19pMThuIjpmYWxzZSwiZmVhdHVyZV91c2VfaW1ncHJveHlfcmVzaXppbmciOnRydWUsImZlYXR1cmVfc2hhcmVfbWVudGlvbl9jb21tZW50X2NsZWFudXAiOmZhbHNlLCJmZWF0dXJlX2JvYXJkc19pMThuIjpmYWxzZSwiZmVhdHVyZV9kaXNhYmxlX2JrX2luX3RocmVhZCI6ZmFsc2UsImZlYXR1cmVfbmV3X2xvY2FsZV90b2FzdCI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX2V4cG9ydHMiOmZhbHNlLCJmZWF0dXJlX2RvY3NfbWVudGlvbnNfYW5kX2NoYW5uZWxzIjpmYWxzZSwiZmVhdHVyZV9jYWxsc19zdXJ2ZXlfcmVxdWVzdF9yZXNwb25zZSI6dHJ1ZSwiZmVhdHVyZV90b2tlbl9pcF93aGl0ZWxpc3QiOnRydWUsImZlYXR1cmVfc2lkZWJhcl90aGVtZV91bmRvIjp0cnVlLCJmZWF0dXJlX2FsbG93X2ludHJhX3dvcmRfZm9ybWF0dGluZyI6dHJ1ZSwiZmVhdHVyZV9pMThuX2NoYW5uZWxzX3ZhbGlkYXRlX2Vtb2ppIjp0cnVlLCJmZWF0dXJlX2Z3X2VuZ19ub3JtYWxpemF0aW9uIjp0cnVlLCJmZWF0dXJlX3NsaW1fc2Nyb2xsYmFyIjpmYWxzZSwiZmVhdHVyZV9wcmltYXJ5X3NlYXJjaCI6ZmFsc2UsImZlYXR1cmVfbW9kZXJuX3NvdW5kcyI6ZmFsc2UsImZlYXR1cmVfcXVpY2tfY29weV9jb2RlX2Jsb2NrcyI6dHJ1ZSwiZmVhdHVyZV9zdGVlcGxlX2NodXJjaCI6dHJ1ZSwiZmVhdHVyZV9zdGVlcGxlX2NodXJjaF9saW5rIjp0cnVlLCJmZWF0dXJlX3N0ZWVwbGVfY2h1cmNoX2V4dCI6dHJ1ZSwiZmVhdHVyZV9zdHJvbGxlcnNfdG9fcGVyY2giOnRydWUsImZlYXR1cmVfZmlsZV9icm93c2VyX3YyIjpmYWxzZSwiZmVhdHVyZV9wZW9wbGVfc2VhcmNoIjpmYWxzZSwiZmVhdHVyZV9yZWFjdF9tZXNzYWdlcyI6dHJ1ZSwiZmVhdHVyZV9lZGdlX3VwbG9hZF9wcm94eV9jaGVjayI6ZmFsc2UsImZlYXR1cmVfdW5yZWFkX2NvdW50c19kZWxheSI6dHJ1ZSwiZmVhdHVyZV9sZWdhY3lfZmlsZV91cGxvYWRfYW5hbHl0aWNzIjp0cnVlLCJmZWF0dXJlX21wZG1fbGltaXRfY2hhbm5lbF9jcmVhdGlvbiI6ZmFsc2UsImZlYXR1cmVfc25pcHBldF9tb2Rlc19pMThuIjpmYWxzZSwiZmVhdHVyZV9la21fbWVzc2FnZV9yZXZvY2F0aW9uX3BvbGxpbmdfdGVzdCI6ZmFsc2UsImZlYXR1cmVfdGVhbV9hZG1pbnNfbGlzdF9hcGkiOnRydWUsImZlYXR1cmVfbW92ZWRfZGV0YWlscyI6ZmFsc2UsImZlYXR1cmVfYWx0X21lbWJlcnNfcmVkdWNlciI6ZmFsc2UsImZlYXR1cmVfbXNfbGF0ZXN0Ijp0cnVlLCJmZWF0dXJlX2d1ZXN0c191c2VfZW50aXRsZW1lbnRzIjp0cnVlLCJmZWF0dXJlX3Jvb21zX2pvaW5fYXBpIjp0cnVlLCJmZWF0dXJlX3Jvb21zX2pvaW5fdXJsIjpmYWxzZSwiZmVhdHVyZV9jYWxsc19zaXBfaW50ZWdyYXRpb25fbGFiZWxzIjpmYWxzZSwiZmVhdHVyZV90YXNrc192MV9jb3B5IjpmYWxzZSwiZmVhdHVyZV9jYWxsc19jb252ZXJzYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9jdXN0b21fc3RhdHVzX2NhbGVuZGFyX3N5bmNfY29weSI6dHJ1ZSwiZmVhdHVyZV9jdXN0b21fc3RhdHVzX2NhbGVuZGFyX3N5bmMiOmZhbHNlLCJmZWF0dXJlX21hc2tfdW5kb2N1bWVudGVkX2Vycm9ycyI6ZmFsc2UsImZlYXR1cmVfYXBwX2FjdGlvbnNfYWRtaW5fcGFnZXMiOnRydWUsImZlYXR1cmVfYXBwX3ZpZXdzX3JlbWluZGVycyI6dHJ1ZSwiZmVhdHVyZV9yZW1pbmRlcnNfb3JnX3NoYXJkIjpmYWxzZSwiZmVhdHVyZV9yZW1pbmRlcnNfZ3JpZF9taWdyYXRpb25zX29yZ19zaGFyZCI6dHJ1ZSwiZmVhdHVyZV9ibG9ja3NfcmVtaW5kZXJzX2xpc3QiOmZhbHNlLCJmZWF0dXJlX21lc3NhZ2VfYmxvY2tzIjpmYWxzZSwiZmVhdHVyZV9zaWxlbmNlX2FwcF9kbXMiOmZhbHNlLCJmZWF0dXJlX3NldF90el9hdXRvbWF0aWNhbGx5Ijp0cnVlLCJmZWF0dXJlX2NvbmZpcm1fY2xlYXJfYWxsX3VucmVhZHNfcHJlZiI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19tb3VudHMiOnRydWUsImZlYXR1cmVfYXR0YWNobWVudHNfdjIiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X2V4cGFuZGFibGVfYmxvY2siOmZhbHNlLCJmZWF0dXJlX2dyb3VwX2Jsb2NrIjpmYWxzZSwiZmVhdHVyZV9ibG9ja19raXRfZGVlcF9saW5rcyI6dHJ1ZSwiZmVhdHVyZV9zaG93X2Jsb2NrX2tpdF9pbl9zaGFyZV9kaWFsb2dzIjpmYWxzZSwiZmVhdHVyZV9ibG9ja19raXRfdXNlcl9ibG9jayI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X3JhZGlvX2J1dHRvbnMiOnRydWUsImZlYXR1cmVfbXJrZHduX29uX3JhZGlvX2J1dHRvbiI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19raXRfdGFibGUiOmZhbHNlLCJmZWF0dXJlX2NoZWNrYm94ZXNfcmFkaW9zX2luX21lc3NhZ2VzIjp0cnVlLCJmZWF0dXJlX2lucHV0X2Jsb2NrX3B0aV93ZmJfZGlzcGF0Y2hfYWN0aW9uIjpmYWxzZSwiZmVhdHVyZV9pbnB1dF9ibG9ja3NfZW1pdF9hY3Rpb25zIjp0cnVlLCJmZWF0dXJlX2Jsb2NrX2tpdF9mdWxsX2FjdGlvbnNfc3RhdGUiOnRydWUsImZlYXR1cmVfaW5wdXRfYmxvY2tzX2luX2FwcF9ob21lIjp0cnVlLCJmZWF0dXJlX2lucHV0X2Jsb2Nrc19pbl9tZXNzYWdlcyI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X2Z1bGxfdmlld19zdGF0ZSI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19raXRfYWN0aW9uX3NlY3Rpb25faW5fdmlld19zdGF0ZSI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19raXRfc3RhdGVfaW5fYmxvY2tzX2FjdGlvbnMiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X2VtcHR5X3N0YXRlX3RyYW5zbGF0aW9uX2Zvcl92aWV3X3N0YXRlIjp0cnVlLCJmZWF0dXJlX211bHRpc2VsZWN0c19pbl9hY3Rpb25zX2Jsb2NrIjpmYWxzZSwiZmVhdHVyZV9ibG9ja19raXRfcmFuZ2VfZGF0ZXBpY2tlciI6ZmFsc2UsImZlYXR1cmVfZGVsZXRlX2FwcF9ob21lc19hc3NvY2lhdGVkX3dpdGhfZGVsZXRlZF9zZXJ2aWNlIjpmYWxzZSwiZmVhdHVyZV9ibG9ja19raXRfdGltZXBpY2tlciI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19raXRfdGltZXBpY2tlcl9yZW1pbmQiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X2RhdGVwaWNrZXJfaW5wdXQiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X2FwcF9iZXRhIjp0cnVlLCJmZWF0dXJlX2FkZF9hcHBfaG9tZV90ZWFtX25hbWUiOmZhbHNlLCJmZWF0dXJlX2JlYWNvbl9qc19lcnJvcnMiOmZhbHNlLCJmZWF0dXJlX2JlYWNvbl9qc19hZG1pbl9lcnJvcnMiOmZhbHNlLCJmZWF0dXJlX3VzZXJfYXBwX2Rpc2FibGVfc3BlZWRfYnVtcCI6dHJ1ZSwiZmVhdHVyZV90cmFjdG9yX3NoYXJlZF9pbnZpdGVfbGluayI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF8yMTE5Ijp0cnVlLCJmZWF0dXJlX3RyYWN0b3JfYmFja3VwX2NoYW5uZWxuYW1lX2NvcHkiOnRydWUsImZlYXR1cmVfZGVncmFkZWRfcnRtX2Fsd2F5c19mYWlscyI6ZmFsc2UsImZlYXR1cmVfYXBwc19tYW5hZ2VfcGVybWlzc2lvbnNfc2NvcGVfY2hhbmdlcyI6dHJ1ZSwiZmVhdHVyZV9yZW1pbmRlcl9jcm9zc193b3Jrc3BhY2UiOnRydWUsImZlYXR1cmVfcDJwIjpmYWxzZSwiZmVhdHVyZV9jbGFzc2ljX25hdiI6ZmFsc2UsImZlYXR1cmVfbmV3X3JlYWN0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9wYWdlc19leGFtcGxlIjpmYWxzZSwiZmVhdHVyZV9zb25pY19waW5zIjpmYWxzZSwiZmVhdHVyZV9zb25pY192aWRlb19wbGFjZWhvbGRlciI6dHJ1ZSwiZmVhdHVyZV9pYXAxIjpmYWxzZSwiZmVhdHVyZV9pYV9nYSI6dHJ1ZSwiZmVhdHVyZV9pYV9kZWJ1Z19vZmYiOmZhbHNlLCJmZWF0dXJlX2lhX2kxOG4iOnRydWUsImZlYXR1cmVfaWFfdGhlbWVzIjp0cnVlLCJmZWF0dXJlX2lhX21lbWJlcl9wcm9maWxlIjp0cnVlLCJmZWF0dXJlX3dvcmtzcGFjZV9zY2ltX21hbmFnZW1lbnQiOmZhbHNlLCJmZWF0dXJlX3VuaWZpZWRfbWVtYmVyIjpmYWxzZSwiZmVhdHVyZV90dXJuX21wZG1fbm90aWZzX29uIjp0cnVlLCJmZWF0dXJlX2Rlc2t0b3BfcmVsb2FkX29uX2dlbmVyaWNfZXJyb3IiOnRydWUsImZlYXR1cmVfZGVza3RvcF9leHRlbmRfYXBwX21lbnUiOmZhbHNlLCJmZWF0dXJlX2Rlc2t0b3BfcmVzdGFydF9zZXJ2aWNlX3dvcmtlciI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcF9zeXN0ZW1fbm90aWZpY2F0aW9uX3BsYXliYWNrIjpmYWxzZSwiZmVhdHVyZV9hMTF5X2R5c2xleGljIjpmYWxzZSwiZmVhdHVyZV9kb2xvcmVzIjpmYWxzZSwiZmVhdHVyZV9kZXNrdG9wX2ZvcmNlX3Byb2R1Y3Rpb25fY2hhbm5lbCI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcF9sb2dzX3VwbG9hZCI6ZmFsc2UsImZlYXR1cmVfbWFjb3NfZGlzYWJsZV9odyI6dHJ1ZSwiZmVhdHVyZV9hdF9oZXJlX3dhcm5pbmciOmZhbHNlLCJmZWF0dXJlX2JvdHNfbm90X21lbWJlcnMiOnRydWUsImZlYXR1cmVfd3RhX3N0b3BfY3JlYXRpb24iOnRydWUsImZlYXR1cmVfbTExbl9jaGFubmVsX2RldGFpbHMiOmZhbHNlLCJmZWF0dXJlX3BsYXRmb3JtX2RlcHJlY2F0aW9uc19mZSI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX2FjdGlvbnMiOnRydWUsImZlYXR1cmVfc2hvcnRjdXRzX3Byb21wdCI6dHJ1ZSwiZmVhdHVyZV9uZXdfY29sb3JfcGlja2VyX3N0cmluZ3MiOmZhbHNlLCJmZWF0dXJlX2FjY2Vzc2libGVfZGlhbG9ncyI6dHJ1ZSwiZmVhdHVyZV9hY2Nlc3NpYmxlX2Vtb2ppX3NraW5fdG9uZV9waWNrZXIiOnRydWUsImZlYXR1cmVfY2FsbHNfY2xpcGJvYXJkX2Jyb2FkY2FzdGluZ19vcHRpbiI6dHJ1ZSwiZmVhdHVyZV9zY3JlZW5fc2hhcmVfbmVlZHNfYWVybyI6ZmFsc2UsImZlYXR1cmVfYWNjZXNzaWJsZV9mc19kaWFsb2dzIjp0cnVlLCJmZWF0dXJlX2NoYW5uZWxfaGVhZGVyX2xhYmVscyI6ZmFsc2UsImZlYXR1cmVfdHJhcF9rYl93aXRoaW5fZnNfbW9kYWxzIjp0cnVlLCJmZWF0dXJlX21vZGVybl9pbWFnZV92aWV3ZXIiOnRydWUsImZlYXR1cmVfZW1vamlfYnlfaWQiOnRydWUsImZlYXR1cmVfbWNfbWlncmF0aW9uX2Jhbm5lciI6dHJ1ZSwiZmVhdHVyZV9hcmlhX2FwcGxpY2F0aW9uX21vZGUiOmZhbHNlLCJmZWF0dXJlX3VwZGF0ZV9tdWx0aXdvcmtzcGFjZV9jaGFubmVsX21vZGFsIjp0cnVlLCJmZWF0dXJlX21vZGVybl9yZXF1ZXN0X3dvcmtzcGFjZV9kaWFsb2ciOmZhbHNlLCJmZWF0dXJlX3dvcmtzcGFjZV9hcHBzX21hbmFnZV9nYW50cnkiOmZhbHNlLCJmZWF0dXJlX3dvcmtzcGFjZV9hcHBzX21hbmFnZV9nYW50cnlfdjJfcjEiOnRydWUsImZlYXR1cmVfYXBwX2FkbWluX2J1dHRvbnNfc3BlZWRidW1wIjp0cnVlLCJmZWF0dXJlX2FwcF9hZG1pbl9idXR0b25zX3NwZWVkYnVtcF92MiI6ZmFsc2UsImZlYXR1cmVfbW9kZXJuX3Byb2ZpbGVfZmxleHBhbmUiOmZhbHNlLCJmZWF0dXJlX3NjZ19jb252ZXJzaW9uX2NoYW5uZWxzIjp0cnVlLCJmZWF0dXJlX2VudGVycHJpc2VfcmV0ZW50aW9uX2FsbG93X292ZXJyaWRlX29uX29yZ19sZXZlbF9jaGFubmVscyI6ZmFsc2UsImZlYXR1cmVfZW50ZXJwcmlzZV9yZXRlbnRpb25fYWRtaW5fcmV0ZW50aW9uX2J5X2NjbSI6ZmFsc2UsImZlYXR1cmVfZXhwb3J0c19maWx0ZXIiOnRydWUsImZlYXR1cmVfdHJhY2tfdGltZV9zcGVudCI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX2ludml0ZV90b2tlbml6YXRpb24iOnRydWUsImZlYXR1cmVfaW1wb3J0c19jYW5jZWwiOnRydWUsImZlYXR1cmVfZW1haWxfd29ya29iamVjdF91aSI6ZmFsc2UsImZlYXR1cmVfZW1haWxfbm90aWZ5IjpmYWxzZSwiZmVhdHVyZV9lbWFpbF9mb3JjZV9kb3dubG9hZCI6dHJ1ZSwiZmVhdHVyZV9vZmZpY2VfZGlyZWN0b3J5IjpmYWxzZSwiZmVhdHVyZV9jYWxlbmRhcl9zaW1wbGVfYWdlbmRhX3ZpZXciOmZhbHNlLCJmZWF0dXJlX3RlYW1fdGhlbWVzIjpmYWxzZSwiZmVhdHVyZV91bmZ1cmxfbWV0YWRhdGEiOmZhbHNlLCJmZWF0dXJlX3BhcGVyY2xpcF9jb2FjaG1hcmtfZXhwZXJpbWVudHMiOnRydWUsImZlYXR1cmVfcGx1c19tZW51X2FkZF9hcHBzX2xpbmsiOmZhbHNlLCJmZWF0dXJlX3JlbmFtZV9jaGFubmVsX2Rpc2FibGVfZmVlZGJhY2tfaTE4biI6ZmFsc2UsImZlYXR1cmVfcmVjZW50X2ZpbGVzX29tbmlwaWNrZXIiOmZhbHNlLCJmZWF0dXJlX3JlY2VudF9kZXNrdG9wX2ZpbGVzIjpmYWxzZSwiZmVhdHVyZV9lbWFpbF9maWxlX3VuZnVybF9mb3JtYXQiOnRydWUsImZlYXR1cmVfbGlua19wcm90b2NvbF9iZXRhIjpmYWxzZSwiZmVhdHVyZV9zdHJpcGVfbGlnaHRfbGVnYWN5X3B1cmNoYXNlX21vZGUiOmZhbHNlLCJmZWF0dXJlX2NoZWNrb3V0X2ZvcmNlX2ludG9fbGVnYWN5IjpmYWxzZSwiZmVhdHVyZV9zb25pY19wbGFjZWhvbGRlcl9sYWJlbHMiOmZhbHNlLCJmZWF0dXJlX3NvbmljX2VzY19jcmVhdGlvbiI6ZmFsc2UsImZlYXR1cmVfZGFuZ2Vyb3VzbHlfZ3VhcmRfaWFfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9pYV9jb250ZXh0X21lbnVzIjpmYWxzZSwiZmVhdHVyZV9pYV9sYXlvdXQiOmZhbHNlLCJmZWF0dXJlX21pc2NfaWFfYTExeV90cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX3RocmVhZGVkX2NhbGxfYmxvY2siOmZhbHNlLCJmZWF0dXJlX2VuYWJsZV9yZWFkX3RpbWVfdmFsaWRhdGlvbnNfZm9yX3Nob3J0Y3V0cyI6ZmFsc2UsImZlYXR1cmVfbWVzc2FnZV9hY3Rpb25zX2luX2FwcF9hY3Rpb25zX2ZyYW1ld29ya19jbGllbnQiOnRydWUsImZlYXR1cmVfbWVzc2FnZV9hY3Rpb25zX2luX2FwcF9hY3Rpb25zX2ZyYW1ld29ya19kZXZlbG9wZXIiOnRydWUsImZlYXR1cmVfc2xhY2tfbWVzc2FnZV9hdHRhY2htZW50X3Rvb2x0aXAiOmZhbHNlLCJmZWF0dXJlX2VudGVycHJpc2VfbW9iaWxlX2RldmljZV9jaGVjayI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80NDAyIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19jdXN0b21fZW1vamlzX3VybCI6ZmFsc2UsImZlYXR1cmVfbmV3X2NvcHlfZm9yX2lkZW50aXR5X2Jhc2ljIjpmYWxzZSwiZmVhdHVyZV9zb25pY19sZWF2ZV93b3Jrc3BhY2VfZGlhbG9nIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbmV3X3VzZXJfdHJpYWwiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX2ludml0ZXJfdHJpYWwiOmZhbHNlLCJmZWF0dXJlX3NjX2ludml0ZV9qb2luX3BlbmRpbmdfY2hhbm5lbF9hY3Rpb24iOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9lbWFpbF9pbnZpdGUiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzXzkwX2RheV90cmlhbCI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfOTBfZGF5X3RyaWFsX2ludml0ZXIiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19kYXkxX2NyZWF0b3IiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19oYXBwaWVyX3BhdGhzIjpmYWxzZSwiZmVhdHVyZV9sYXRlX3BheW1lbnRfc3VjY2Vzc19ub3RpZmljYXRpb24iOmZhbHNlLCJmZWF0dXJlX2F1c3RyYWxpYV90YXhfY2hhbmdlX25vdGlmaWNhdGlvbiI6ZmFsc2UsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxfaW52aXRlc192MiI6dHJ1ZSwiZmVhdHVyZV9iZXR0ZXJfaW52aXRlc19jYWxsX3YyX2FwaSI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfaW52aXRlX2NyZWF0ZV9lZHVjYXRpb24iOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX2ludml0ZV9lbWFpbF9ib3VuY2Vfbm90aWZpY2F0aW9uIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19pbnZpdGVfZW1haWxfcmVtaW5kZXIiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX2NvbnRlbnQiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX3RyaWFsX2VkdSI6dHJ1ZSwiZmVhdHVyZV91c2VyX2ludml0ZV9lbWFpbF9ib3VuY2Vfbm90aWZpY2F0aW9uX3RyYW5zbGF0aW9uIjp0cnVlLCJmZWF0dXJlX3BhaWRfb25ib2FyZGluZ19wYWdldXBkYXRlIjp0cnVlLCJmZWF0dXJlX3RyYWNlX3dlYmFwcF9pbml0Ijp0cnVlLCJmZWF0dXJlX3RyYWNlX2pxX2luaXQiOnRydWUsImZlYXR1cmVfdHJpYWxfZW5kX2wxMG4iOnRydWUsImZlYXR1cmVfdHJpYWxfZW5kaW5nX2VtYWlsX3VwZGF0ZXMiOnRydWUsImZlYXR1cmVfd29ya3NwYWNlX21lbnVfcGxhbl9pbmZvIjp0cnVlLCJmZWF0dXJlX3BhcnRuZXJfdGVybXNfaTE4biI6ZmFsc2UsImZlYXR1cmVfcGFydG5lcl9mYXFfaTE4biI6dHJ1ZSwiZmVhdHVyZV9oaWdobGlnaHRfcGFpZF9mZWF0dXJlcyI6ZmFsc2UsImZlYXR1cmVfdHJpYWxfZXhwaXJhdGlvbl9kYXRlX2kxOG4iOnRydWUsImZlYXR1cmVfc3RyaXBlX2NvbXBsZXRlbHlfZG93bl9iYW5uZXIiOmZhbHNlLCJmZWF0dXJlX2ZhaXJfYmlsbGluZ19kZXRhaWxfaW52b2ljZV9zdGF0ZW1lbnRzIjpmYWxzZSwiZmVhdHVyZV9jaGVja291dF96aXBfYXV0b2NvbXBsZXRlX3RyYW5zbGF0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9iaWxsaW5nX21lbWJlcl9lbWFpbF91cGRhdGVzIjpmYWxzZSwiZmVhdHVyZV9mYWlyX2JpbGxpbmdfYmFja2VuZF9yZWZhY3RvciI6dHJ1ZSwiZmVhdHVyZV91YWVfdGF4X2lkX2NvbGxlY3Rpb24iOnRydWUsImZlYXR1cmVfY2hpbGVfdGF4X2lkX2NvbGxlY3Rpb24iOnRydWUsImZlYXR1cmVfa3NhX3RheF9pZF9jb2xsZWN0aW9uIjp0cnVlLCJmZWF0dXJlX2luZG9uZXNpYV90YXhfY2hhbmdlX25vdGlmaWNhdGlvbiI6ZmFsc2UsImZlYXR1cmVfaW5kb25lc2lhX3RheF9hc3Nlc3NtZW50IjpmYWxzZSwiZmVhdHVyZV9jYXBpdGFsaXplX3NpbmdsZV9jaGFubmVsX3N0YXR1cyI6dHJ1ZSwiZmVhdHVyZV9lbnRlcnByaXNlX2FuYWx5dGljc18yMDE5X3EzX2VuaGFuY2VtZW50cyI6ZmFsc2UsImZlYXR1cmVfbW9kZXJuaXplX29yZ19kYXNoX2NoYXJ0cyI6dHJ1ZSwiZmVhdHVyZV9tb2Rlcm5pemVfb3JnX3RlYW1fYW5hbHl0aWNzIjpmYWxzZSwiZmVhdHVyZV9tZXNzYWdlc19mcm9tX2FwcHNfYW5hbHl0aWNzIjpmYWxzZSwiZmVhdHVyZV9vcmdfbGV2ZWxfYXBwcyI6ZmFsc2UsImZlYXR1cmVfb3JnX2xldmVsX2FwcHNfY3VzdG9tIjpmYWxzZSwiZmVhdHVyZV9vcmdfbGV2ZWxfYXBwc19hZG1pbl9iZXRhIjpmYWxzZSwiZmVhdHVyZV9zc29fdmFsaWRhdGVfYXVkaWVuY2UiOnRydWUsImZlYXR1cmVfY2hhbm5lbF9zZWN0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX3NlY3Rpb25zX3NpZGViYXJfYmVoYXZpb3JfdWkiOmZhbHNlLCJmZWF0dXJlX2FuYWx5dGljc19zY2ltX2ZpZWxkc19wYWlkIjpmYWxzZSwiZmVhdHVyZV9nb29nbGVfZGlyZWN0b3J5X2ludml0ZXMiOmZhbHNlLCJmZWF0dXJlX21pZ3JhdGVfZ29vZ2xlX2RpcmVjdG9yeV9hcGlzIjp0cnVlLCJmZWF0dXJlX3NlYXJjaF9yZXN1bHRzX3ZpcnR1YWxpemVkIjpmYWxzZSwiZmVhdHVyZV9zaG93X2VtYWlsX2ZvcndhcmRlZF9ieSI6ZmFsc2UsImZlYXR1cmVfbmV3X2Vub3VnaF9wZXJpb2RpY19yZWxvYWRzIjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX3dvcmtmbG93X2FjdGl2aXR5Ijp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfZXhwb3J0X2Zvcm1fY3N2X2FkbWluIjp0cnVlLCJmZWF0dXJlX2hlYWRlcl9ibG9jayI6dHJ1ZSwiZmVhdHVyZV9oZWFkZXJfYmxvY2tfYmtiIjp0cnVlLCJmZWF0dXJlX3JhdGVfbGltaXRfYXBwX2NyZWF0aW9uIjp0cnVlLCJmZWF0dXJlX2dpcGh5X3Nob3J0Y3V0IjpmYWxzZSwiZmVhdHVyZV9kb3dubG9hZF9maW5kZXJfdXBkYXRlIjp0cnVlLCJmZWF0dXJlX3NoYXJlX21vZGFsX2RpYWxvZyI6ZmFsc2UsImZlYXR1cmVfb25lZHJpdmVfZXJyb3JfdHJhbnNsYXRpb25zIjp0cnVlLCJmZWF0dXJlX2NoYW5uZWxfc2lkZWJhcl9zdW1tYXJ5IjpmYWxzZSwiZmVhdHVyZV9icm93c2VyX3BpY2tlciI6ZmFsc2UsImZlYXR1cmVfZWR1XzEwMSI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80Njg4Ijp0cnVlLCJmZWF0dXJlX2FwcF9kaXJfZ3Jhbl9ib3Rfc3VibWl0Ijp0cnVlLCJmZWF0dXJlX2FwcF9kaXJfd29ya2Zsb3dfc3RlcHMiOnRydWUsImZlYXR1cmVfYXBwX2Rpcl93b3JrZmxvd19zdGVwc19wcm9tbyI6dHJ1ZSwiZmVhdHVyZV9hcHBfbGlzdGluZ19yZWZyZXNoIjp0cnVlLCJmZWF0dXJlX2FwcF9saXN0aW5nX3JlZnJlc2hfc2NvcGVzIjp0cnVlLCJmZWF0dXJlX2FwcF9saXN0aW5nX3JlZnJlc2hfb3JnX2RlcGxveXMiOmZhbHNlLCJmZWF0dXJlX2FwcF9saXN0aW5nX3JlZnJlc2hfcHRfMiI6dHJ1ZSwiZmVhdHVyZV9oY191cGRhdGVkX3RpdGxlIjpmYWxzZSwiZmVhdHVyZV9wYXJzZWNfbWV0aG9kcyI6ZmFsc2UsImZlYXR1cmVfc291bF9zZWFyY2hlcnMiOmZhbHNlLCJmZWF0dXJlX3NuZF9xdWVyeV9yZWZpbmVtZW50cyI6dHJ1ZSwiZmVhdHVyZV9lbWFpbF9jbGFzc2lmaWNhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9wcmltYXJ5X293bmVyX2NvbnNpc3RlbnRfcm9sZXMiOnRydWUsImZlYXR1cmVfaW52aXRlX3RvX2NoYW5uZWxfYnlfZW1haWxfdWkiOnRydWUsImZlYXR1cmVfZWR1XzExMCI6dHJ1ZSwiZmVhdHVyZV9zaXdzX2xpbmtzIjpmYWxzZSwiZmVhdHVyZV9sb2NhbGVfaXRfSVQiOmZhbHNlLCJmZWF0dXJlX2xvY2FsZV9rb19LUiI6dHJ1ZSwiZmVhdHVyZV9sb2NhbGVfcnVfUlUiOmZhbHNlLCJmZWF0dXJlX2xvY2FsZV96aF9DTiI6ZmFsc2UsImZlYXR1cmVfbG9jYWxlX3poX1RXIjpmYWxzZSwiZmVhdHVyZV9zZWFyY2hfZmlsdGVyX2ZpbGVfYXR0YWNobWVudHMiOmZhbHNlLCJmZWF0dXJlX21wZG1fYXVkaWVuY2VfZXhwYW5zaW9uIjp0cnVlLCJmZWF0dXJlX25ld3hwXzQzMTIiOmZhbHNlLCJmZWF0dXJlX2NlX2VuZ19zZWFyY2hfemVuZGVza19hcGkiOmZhbHNlLCJmZWF0dXJlX2JrX2Vycm9yX21lc3NhZ2luZyI6dHJ1ZSwiZmVhdHVyZV9sYXJnZV9lbW9qaV9pbl90b29sdGlwIjp0cnVlLCJmZWF0dXJlX25ld3hwXzM3OTUiOmZhbHNlLCJmZWF0dXJlX25ld19ub3RpZmljYXRpb25zX3N0cmluZyI6ZmFsc2UsImZlYXR1cmVfYXBwc19ldmVudF9hdXRob3JpemF0aW9uc19saXN0X2VuZHBvaW50X2E3ZTUxZiI6dHJ1ZSwiZmVhdHVyZV9ndWFyZF9jaGFubmVsX2RldGFpbHNfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV92ZXJpZmllZF9vcmdzX2ZlIjpmYWxzZSwiZmVhdHVyZV9yZWZpbmVfeW91cl9zZWFyY2hfaTE4biI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80NTk3Ijp0cnVlLCJmZWF0dXJlX2ZpbGVfYWN0aW9uc19maXgiOmZhbHNlLCJmZWF0dXJlX2lubGluZV9mZWVkYmFjayI6ZmFsc2UsImZlYXR1cmVfZWR1XzE4MiI6dHJ1ZSwiZmVhdHVyZV9jcmVkaXRfYmFubmVyX2Jhc2ljX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfaWRyX2JhY2tmaWxscyI6ZmFsc2UsImZlYXR1cmVfZWR1XzE4NyI6dHJ1ZSwiZmVhdHVyZV9hZGRfdG9fY2hhbm5lbF9wcm90b3R5cGUiOmZhbHNlLCJmZWF0dXJlX3N0cmlwZV9oYWNrX21pZ3JhdGlvbiI6ZmFsc2UsImZlYXR1cmVfcGFpZF9iZW5lZml0c19hbGVydF90cmFuc2xhdGlvbnMiOnRydWUsImZlYXR1cmVfcGxhbl9iZW5lZml0c19kYXlfb25lX3RyaWFsX2hlYWRlcl91cGRhdGVfaTE4biI6dHJ1ZSwiZmVhdHVyZV90cmlhbF9hd2FyZW5lc3NfdHJhbnNsYXRpb25zIjp0cnVlLCJmZWF0dXJlX2NhbGxzX2xvY2F0aW9uX3dhcm5pbmdfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9lc2Nfd2hvX2Nhbl9yZXF1ZXN0X3ByZWYiOmZhbHNlLCJmZWF0dXJlX3NpZGViYXJfdHJpYWxfYmFkZ2VfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9mZWF0dXJlX2NvbnRleHRfbWVudV9rZXlib2FyZF9zaG9ydGN1dCI6ZmFsc2UsImZlYXR1cmVfZWR1XzE5NiI6ZmFsc2UsImZlYXR1cmVfaW50ZXJhY3RpdmVfc2VwYXJhdG9ycyI6ZmFsc2UsImZlYXR1cmVfc2VhcmNoX2FyaWFfaW5pdGlhbF9zdGF0ZSI6ZmFsc2UsImZlYXR1cmVfZnJlZV90cmlhbF9jaGF0IjpmYWxzZSwiZmVhdHVyZV91a192YXRfaG1yY192YWxpZGF0aW9uIjpmYWxzZSwiY2xpZW50X2xvZ3MiOnsiMCI6eyJudW1iZXJzIjpbIjAiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiMiI6eyJudW1iZXJzIjpbIjIiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNCI6eyJudW1iZXJzIjpbIjQiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNSI6eyJudW1iZXJzIjpbIjUiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiMjMiOnsibnVtYmVycyI6WyIyMyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJzb3VuZHMiOnsibmFtZSI6InNvdW5kcyIsIm51bWJlcnMiOlsiMzciXX0sIjM3Ijp7Im5hbWUiOiJzb3VuZHMiLCJudW1iZXJzIjpbIjM3Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwiNDciOnsibnVtYmVycyI6WyI0NyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI0OCI6eyJudW1iZXJzIjpbIjQ4Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIk1lc3NhZ2UgSGlzdG9yeSI6eyJuYW1lIjoiTWVzc2FnZSBIaXN0b3J5IiwibnVtYmVycyI6WyI1OCJdfSwiNTgiOnsibmFtZSI6Ik1lc3NhZ2UgSGlzdG9yeSIsIm51bWJlcnMiOlsiNTgiXSwidXNlcl9mYWNpbmciOnRydWV9LCI2NyI6eyJudW1iZXJzIjpbIjY3Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjcyIjp7Im51bWJlcnMiOlsiNzIiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNzMiOnsibnVtYmVycyI6WyI3MyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI4MiI6eyJudW1iZXJzIjpbIjgyIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjg4Ijp7Im51bWJlcnMiOlsiODgiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiOTEiOnsibnVtYmVycyI6WyI5MSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI5MyI6eyJudW1iZXJzIjpbIjkzIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjk2Ijp7Im51bWJlcnMiOlsiOTYiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiOTkiOnsibnVtYmVycyI6WyI5OSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJDaGFubmVsIE1hcmtpbmcgKE1TKSI6eyJuYW1lIjoiQ2hhbm5lbCBNYXJraW5nIChNUykiLCJudW1iZXJzIjpbIjE0MSJdfSwiMTQxIjp7Im5hbWUiOiJDaGFubmVsIE1hcmtpbmcgKE1TKSIsIm51bWJlcnMiOlsiMTQxIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwiQ2hhbm5lbCBNYXJraW5nIChDbGllbnQpIjp7Im5hbWUiOiJDaGFubmVsIE1hcmtpbmcgKENsaWVudCkiLCJudW1iZXJzIjpbIjE0MiJdfSwiMTQyIjp7Im5hbWUiOiJDaGFubmVsIE1hcmtpbmcgKENsaWVudCkiLCJudW1iZXJzIjpbIjE0MiJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIkNsb3NlIE9sZCBJTXMgKENsaWVudCkiOnsibmFtZSI6IkNsb3NlIE9sZCBJTXMgKENsaWVudCkiLCJudW1iZXJzIjpbIjIyMSJdfSwiMjIxIjp7Im5hbWUiOiJDbG9zZSBPbGQgSU1zIChDbGllbnQpIiwibnVtYmVycyI6WyIyMjEiXSwidXNlcl9mYWNpbmciOnRydWV9LCIzNjUiOnsibnVtYmVycyI6WyIzNjUiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiMzg5Ijp7Im51bWJlcnMiOlsiMzg5Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjQzOCI6eyJudW1iZXJzIjpbIjQzOCJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI0NDQiOnsibnVtYmVycyI6WyI0NDQiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNDgxIjp7Im51bWJlcnMiOlsiNDgxIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjQ4OCI6eyJudW1iZXJzIjpbIjQ4OCJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI1MjkiOnsibnVtYmVycyI6WyI1MjkiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNTUyIjp7Im51bWJlcnMiOlsiNTUyIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sImRhc2hib2FyZCI6eyJuYW1lIjoiZGFzaGJvYXJkIiwibnVtYmVycyI6WyI2NjYiXX0sIjY2NiI6eyJuYW1lIjoiZGFzaGJvYXJkIiwibnVtYmVycyI6WyI2NjYiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNjY3Ijp7Im51bWJlcnMiOlsiNjY3Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjc3MyI6eyJudW1iZXJzIjpbIjc3MyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI3NzciOnsibnVtYmVycyI6WyI3NzciXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNzk0Ijp7Im51bWJlcnMiOlsiNzk0Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIkNsaWVudCBSZXNwb25zaXZlbmVzcyI6eyJuYW1lIjoiQ2xpZW50IFJlc3BvbnNpdmVuZXNzIiwidXNlcl9mYWNpbmciOmZhbHNlLCJudW1iZXJzIjpbIjgwOCJdfSwiODA4Ijp7Im5hbWUiOiJDbGllbnQgUmVzcG9uc2l2ZW5lc3MiLCJ1c2VyX2ZhY2luZyI6ZmFsc2UsIm51bWJlcnMiOlsiODA4Il19LCJNZXNzYWdlIFBhbmUgU2Nyb2xsaW5nIjp7Im5hbWUiOiJNZXNzYWdlIFBhbmUgU2Nyb2xsaW5nIiwibnVtYmVycyI6WyI4ODgiXX0sIjg4OCI6eyJuYW1lIjoiTWVzc2FnZSBQYW5lIFNjcm9sbGluZyIsIm51bWJlcnMiOlsiODg4Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwiVW5yZWFkIGJhbm5lciBhbmQgZGl2aWRlciI6eyJuYW1lIjoiVW5yZWFkIGJhbm5lciBhbmQgZGl2aWRlciIsIm51bWJlcnMiOlsiOTk5Il19LCI5OTkiOnsibmFtZSI6IlVucmVhZCBiYW5uZXIgYW5kIGRpdmlkZXIiLCJudW1iZXJzIjpbIjk5OSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIjEwMDAiOnsibnVtYmVycyI6WyIxMDAwIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIkR1cGxpY2F0ZSBiYWRnZXMgKGRlc2t0b3AgYXBwIGljb25zKSI6eyJuYW1lIjoiRHVwbGljYXRlIGJhZGdlcyAoZGVza3RvcCBhcHAgaWNvbnMpIiwibnVtYmVycyI6WyIxNzAxIl19LCIxNzAxIjp7Im5hbWUiOiJEdXBsaWNhdGUgYmFkZ2VzIChkZXNrdG9wIGFwcCBpY29ucykiLCJudW1iZXJzIjpbIjE3MDEiXSwidXNlcl9mYWNpbmciOnRydWV9LCJNZW1iZXJzIjp7Im5hbWUiOiJNZW1iZXJzIiwibnVtYmVycyI6WyIxOTc1Il19LCIxOTc1Ijp7Im5hbWUiOiJNZW1iZXJzIiwibnVtYmVycyI6WyIxOTc1Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwibGF6eSBsb2FkaW5nIjp7Im5hbWUiOiJsYXp5IGxvYWRpbmciLCJudW1iZXJzIjpbIjE5ODkiXX0sIjE5ODkiOnsibmFtZSI6ImxhenkgbG9hZGluZyIsIm51bWJlcnMiOlsiMTk4OSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sInRoaW5fY2hhbm5lbF9tZW1iZXJzaGlwIjp7Im5hbWUiOiJ0aGluX2NoYW5uZWxfbWVtYmVyc2hpcCIsIm51bWJlcnMiOlsiMTk5MCJdfSwiMTk5MCI6eyJuYW1lIjoidGhpbl9jaGFubmVsX21lbWJlcnNoaXAiLCJudW1iZXJzIjpbIjE5OTAiXSwidXNlcl9mYWNpbmciOnRydWV9LCJzdGF0cyI6eyJuYW1lIjoic3RhdHMiLCJudW1iZXJzIjpbIjE5OTEiXX0sIjE5OTEiOnsibmFtZSI6InN0YXRzIiwibnVtYmVycyI6WyIxOTkxIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwibXMiOnsibmFtZSI6Im1zIiwibnVtYmVycyI6WyIxOTk2Il19LCIxOTk2Ijp7Im5hbWUiOiJtcyIsIm51bWJlcnMiOlsiMTk5NiJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sInNoYXJlZF9jaGFubmVsc19jb25uZWN0aW9uIjp7Im5hbWUiOiJzaGFyZWRfY2hhbm5lbHNfY29ubmVjdGlvbiIsIm51bWJlcnMiOlsiMTk5OSJdfSwiMTk5OSI6eyJuYW1lIjoic2hhcmVkX2NoYW5uZWxzX2Nvbm5lY3Rpb24iLCJudW1iZXJzIjpbIjE5OTkiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiZG5kIjp7Im5hbWUiOiJkbmQiLCJudW1iZXJzIjpbIjIwMDIiXX0sIjIwMDIiOnsibmFtZSI6ImRuZCIsIm51bWJlcnMiOlsiMjAwMiJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIjIwMDMiOnsibnVtYmVycyI6WyIyMDAzIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIlRocmVhZHMiOnsibmFtZSI6IlRocmVhZHMiLCJudW1iZXJzIjpbIjIwMDQiXX0sIjIwMDQiOnsibmFtZSI6IlRocmVhZHMiLCJudW1iZXJzIjpbIjIwMDQiXSwidXNlcl9mYWNpbmciOnRydWV9LCIyMDA1Ijp7Im51bWJlcnMiOlsiMjAwNSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJSZWFjdGlvbnMiOnsibmFtZSI6IlJlYWN0aW9ucyIsIm51bWJlcnMiOlsiMjAwNiJdfSwiMjAwNiI6eyJuYW1lIjoiUmVhY3Rpb25zIiwibnVtYmVycyI6WyIyMDA2Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwiVFNTU0IuZm9jdXNUYWJBbmRTd2l0Y2hUb0NoYW5uZWwiOnsibmFtZSI6IlRTU1NCLmZvY3VzVGFiQW5kU3dpdGNoVG9DaGFubmVsIiwibnVtYmVycyI6WyIyMDA3Il19LCIyMDA3Ijp7Im5hbWUiOiJUU1NTQi5mb2N1c1RhYkFuZFN3aXRjaFRvQ2hhbm5lbCIsIm51bWJlcnMiOlsiMjAwNyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJQcmVzZW5jZSBEZXRlY3Rpb24iOnsibmFtZSI6IlByZXNlbmNlIERldGVjdGlvbiIsIm51bWJlcnMiOlsiMjAxNyJdfSwiMjAxNyI6eyJuYW1lIjoiUHJlc2VuY2UgRGV0ZWN0aW9uIiwibnVtYmVycyI6WyIyMDE3Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwibWNfc2licyI6eyJuYW1lIjoibWNfc2licyIsIm51bWJlcnMiOlsiOTk5OSJdfSwiOTk5OSI6eyJuYW1lIjoibWNfc2licyIsIm51bWJlcnMiOlsiOTk5OSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJNZW1iZXIgc2VhcmNoaW5nIjp7Im5hbWUiOiJNZW1iZXIgc2VhcmNoaW5nIiwibnVtYmVycyI6WyI5MDIxMSJdfSwiOTAyMTEiOnsibmFtZSI6Ik1lbWJlciBzZWFyY2hpbmciLCJudW1iZXJzIjpbIjkwMjExIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwiOTg3NjUiOnsibnVtYmVycyI6WyI5ODc2NSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI4Njc1MzA5Ijp7Im51bWJlcnMiOlsiODY3NTMwOSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9fX07Cglib290X2RhdGEuc3RhcnRfbXMgPSBEYXRlLm5vdygpOwo8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvcm9sbHVwLWNvcmVfcmVxdWlyZWRfbGlicy4xZGViNzdmNDdjZDUyMWYyY2EyNS5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvbW9kZXJuLnZlbmRvci5lYjdkY2RiM2UzMWY4NWJjYzM4ZS5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvYXBwbGljYXRpb24uODkxZTY3NjI2OGFiZTNkMzdkZjQubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3JvbGx1cC1jb3JlX3JlcXVpcmVkX3RzLjg4ZDExZDg0YWRkMmUyNjBkMDYyLm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9UUy53ZWIuNTUzZjZkYmRjNDZlMmYwNjYzZmYubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3NpZ25hbHMuZjY0MTYwYjViY2ZjNmY5YjkzMmYubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3JvbGx1cC1jb3JlX3dlYi5mYzhmYTEwMmI1MTM4NGQ3NDAwMy5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvcm9sbHVwLXNlY29uZGFyeV9hX3JlcXVpcmVkLjczODhmYTliY2I0MDUzZTI0ZGRhLm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9yb2xsdXAtc2Vjb25kYXJ5X2JfcmVxdWlyZWQuOTQ3ZDEwNDdlZDMyYmIyNzA3YjEubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPlRTLmJvb3QoYm9vdF9kYXRhKTs8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvVFMud2ViLl80MDQuYWRlNWUxZGE0OTUwMTQ0YzZkODQubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3N0aWNreV9uYXYuYjU4MThiMmRkNDRlNmFlMDAwNDQubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L2Zvb3Rlci5mMTViM2NiZjQ2ODc3MTQ3ZjA2Ni5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+Ym9vdF9kYXRhLm5vX2xvZ2luID0gdHJ1ZTs8L3NjcmlwdD48c3R5bGU+LmNvbG9yXzlmNjllNzpub3QoLm51Yykge2NvbG9yOiM5RjY5RTc7fS5jb2xvcl80YmJlMmU6bm90KC5udWMpIHtjb2xvcjojNEJCRTJFO30uY29sb3JfZTczOTJkOm5vdCgubnVjKSB7Y29sb3I6I0U3MzkyRDt9LmNvbG9yXzNjOTg5Zjpub3QoLm51Yykge2NvbG9yOiMzQzk4OUY7fS5jb2xvcl82NzRiMWI6bm90KC5udWMpIHtjb2xvcjojNjc0QjFCO30uY29sb3JfZTk2Njk5Om5vdCgubnVjKSB7Y29sb3I6I0U5NjY5OTt9LmNvbG9yX2UwYTcyOTpub3QoLm51Yykge2NvbG9yOiNFMEE3Mjk7fS5jb2xvcl82ODRiNmM6bm90KC5udWMpIHtjb2xvcjojNjg0QjZDO30uY29sb3JfNWI4OWQ1Om5vdCgubnVjKSB7Y29sb3I6IzVCODlENTt9LmNvbG9yXzJiNjgzNjpub3QoLm51Yykge2NvbG9yOiMyQjY4MzY7fS5jb2xvcl85OWE5NDk6bm90KC5udWMpIHtjb2xvcjojOTlBOTQ5O30uY29sb3JfZGYzZGMwOm5vdCgubnVjKSB7Y29sb3I6I0RGM0RDMDt9LmNvbG9yXzRjYzA5MTpub3QoLm51Yykge2NvbG9yOiM0Q0MwOTE7fS5jb2xvcl85YjNiNDU6bm90KC5udWMpIHtjb2xvcjojOUIzQjQ1O30uY29sb3JfZDU4MjQ3Om5vdCgubnVjKSB7Y29sb3I6I0Q1ODI0Nzt9LmNvbG9yX2JiODZiNzpub3QoLm51Yykge2NvbG9yOiNCQjg2Qjc7fS5jb2xvcl81YTQ1OTI6bm90KC5udWMpIHtjb2xvcjojNUE0NTkyO30uY29sb3JfZGIzMTUwOm5vdCgubnVjKSB7Y29sb3I6I0RCMzE1MDt9LmNvbG9yXzIzNWU1Yjpub3QoLm51Yykge2NvbG9yOiMyMzVFNUI7fS5jb2xvcl85ZTM5OTc6bm90KC5udWMpIHtjb2xvcjojOUUzOTk3O30uY29sb3JfNTNiNzU5Om5vdCgubnVjKSB7Y29sb3I6IzUzQjc1OTt9LmNvbG9yX2MzODZkZjpub3QoLm51Yykge2NvbG9yOiNDMzg2REY7fS5jb2xvcl8zODVhODY6bm90KC5udWMpIHtjb2xvcjojMzg1QTg2O30uY29sb3JfYTYzMDI0Om5vdCgubnVjKSB7Y29sb3I6I0E2MzAyNDt9LmNvbG9yXzU4NzBkZDpub3QoLm51Yykge2NvbG9yOiM1ODcwREQ7fS5jb2xvcl9lYTI5Nzc6bm90KC5udWMpIHtjb2xvcjojRUEyOTc3O30uY29sb3JfNTBhMGNmOm5vdCgubnVjKSB7Y29sb3I6IzUwQTBDRjt9LmNvbG9yX2Q1NWFlZjpub3QoLm51Yykge2NvbG9yOiNENTVBRUY7fS5jb2xvcl9kMTcwN2Q6bm90KC5udWMpIHtjb2xvcjojRDE3MDdEO30uY29sb3JfNDM3NjFiOm5vdCgubnVjKSB7Y29sb3I6IzQzNzYxQjt9LmNvbG9yX2UwNmI1Njpub3QoLm51Yykge2NvbG9yOiNFMDZCNTY7fS5jb2xvcl84ZjRhMmI6bm90KC5udWMpIHtjb2xvcjojOEY0QTJCO30uY29sb3JfOTAyZDU5Om5vdCgubnVjKSB7Y29sb3I6IzkwMkQ1OTt9LmNvbG9yX2RlNWYyNDpub3QoLm51Yykge2NvbG9yOiNERTVGMjQ7fS5jb2xvcl9hMmE1ZGM6bm90KC5udWMpIHtjb2xvcjojQTJBNURDO30uY29sb3JfODI3MzI3Om5vdCgubnVjKSB7Y29sb3I6IzgyNzMyNzt9LmNvbG9yXzNjOGM2OTpub3QoLm51Yykge2NvbG9yOiMzQzhDNjk7fS5jb2xvcl84ZDRiODQ6bm90KC5udWMpIHtjb2xvcjojOEQ0Qjg0O30uY29sb3JfODRiMjJmOm5vdCgubnVjKSB7Y29sb3I6Izg0QjIyRjt9LmNvbG9yXzRlYzBkNjpub3QoLm51Yykge2NvbG9yOiM0RUMwRDY7fS5jb2xvcl9lMjNmOTk6bm90KC5udWMpIHtjb2xvcjojRTIzRjk5O30uY29sb3JfZTQ3NWRmOm5vdCgubnVjKSB7Y29sb3I6I0U0NzVERjt9LmNvbG9yXzYxOWE0Zjpub3QoLm51Yykge2NvbG9yOiM2MTlBNEY7fS5jb2xvcl9hNzJmNzk6bm90KC5udWMpIHtjb2xvcjojQTcyRjc5O30uY29sb3JfN2Q0MTRjOm5vdCgubnVjKSB7Y29sb3I6IzdENDE0Qzt9LmNvbG9yX2FiYTcyNzpub3QoLm51Yykge2NvbG9yOiNBQkE3Mjc7fS5jb2xvcl85NjVkMWI6bm90KC5udWMpIHtjb2xvcjojOTY1RDFCO30uY29sb3JfNGQ1ZTI2Om5vdCgubnVjKSB7Y29sb3I6IzRENUUyNjt9LmNvbG9yX2RkODUyNzpub3QoLm51Yykge2NvbG9yOiNERDg1Mjc7fS5jb2xvcl9iZDkzMzY6bm90KC5udWMpIHtjb2xvcjojQkQ5MzM2O30uY29sb3JfZTg1ZDcyOm5vdCgubnVjKSB7Y29sb3I6I0U4NUQ3Mjt9LmNvbG9yX2RjN2RiYjpub3QoLm51Yykge2NvbG9yOiNEQzdEQkI7fS5jb2xvcl9iYzM2NjM6bm90KC5udWMpIHtjb2xvcjojQkMzNjYzO30uY29sb3JfOWQ4ZWVlOm5vdCgubnVjKSB7Y29sb3I6IzlEOEVFRTt9LmNvbG9yXzg0NjliYzpub3QoLm51Yykge2NvbG9yOiM4NDY5QkM7fS5jb2xvcl83Mzc2OWQ6bm90KC5udWMpIHtjb2xvcjojNzM3NjlEO30uY29sb3JfYjE0Y2JjOm5vdCgubnVjKSB7Y29sb3I6I0IxNENCQzt9PC9zdHlsZT4KCjwhLS0gc2xhY2std3d3LWhodm0tbWFpbi1pYWQtdTBnZi8gMjAyMC0xMC0wOCAyMTozMTozMC8gdjU3MDNhYWI2MjNjNGY3ZTk2NTU5NTQ0OGZjMDAzYTc4NmE5MmI4MTMvIEI6SCAtLT4KCjwvYm9keT48L2h0bWw+ + recorded_at: Fri, 09 Oct 2020 04:31:29 GMT recorded_with: VCR 6.0.0 diff --git a/test/cassettes/self_get_nominal.yml b/test/cassettes/self_get_nominal.yml index 180e19a1..cba32dda 100644 --- a/test/cassettes/self_get_nominal.yml +++ b/test/cassettes/self_get_nominal.yml @@ -75,4 +75,60 @@ http_interactions: Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602212842,"response_metadata":{"next_cursor":""}}' recorded_at: Fri, 09 Oct 2020 03:07:22 GMT +- request: + method: get + uri: https://slack.com/api/https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 404 + message: Not Found + headers: + Date: + - Fri, 09 Oct 2020 04:31:29 GMT + Server: + - Apache + X-Xss-Protection: + - '0' + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Slack-Backend: + - r + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Vary: + - Accept-Encoding + Pragma: + - no-cache + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Robots-Tag: + - noindex,nofollow + Set-Cookie: + - b=6qupwq84f4g50ifed270z4adm; expires=Wed, 09-Oct-2030 04:31:29 GMT; Max-Age=315532800; + path=/; domain=.slack.com; secure; SameSite=None + - x=6qupwq84f4g50ifed270z4adm.1602217889; expires=Fri, 09-Oct-2020 04:46:29 + GMT; Max-Age=900; path=/; domain=.slack.com; secure; SameSite=None + Transfer-Encoding: + - chunked + Content-Type: + - text/html; charset=utf-8 + X-Via: + - haproxy-www-rog1,haproxy-edge-pdx-ts3v + body: + encoding: ASCII-8BIT + string: !binary |- + PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4tVVMiIGNsYXNzPSIiPjxoZWFkPjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC93ZWJwYWNrLm1hbmlmZXN0LmZmOGE2MzFkMzMzYzM5MmQ2Yzc5Lm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQ+d2luZG93LnRzX2VuZHBvaW50X3VybCA9ICJodHRwczpcL1wvc2xhY2suY29tXC9iZWFjb25cL3RpbWluZyI7KGZ1bmN0aW9uKGUpIHsKCXZhciBuPURhdGUubm93P0RhdGUubm93KCk6K25ldyBEYXRlLHI9ZS5wZXJmb3JtYW5jZXx8e30sdD1bXSxhPXt9LGk9ZnVuY3Rpb24oZSxuKXtmb3IodmFyIHI9MCxhPXQubGVuZ3RoLGk9W107YT5yO3IrKyl0W3JdW2VdPT1uJiZpLnB1c2godFtyXSk7cmV0dXJuIGl9LG89ZnVuY3Rpb24oZSxuKXtmb3IodmFyIHIsYT10Lmxlbmd0aDthLS07KXI9dFthXSxyLmVudHJ5VHlwZSE9ZXx8dm9pZCAwIT09biYmci5uYW1lIT1ufHx0LnNwbGljZShhLDEpfTtyLm5vd3x8KHIubm93PXIud2Via2l0Tm93fHxyLm1vek5vd3x8ci5tc05vd3x8ZnVuY3Rpb24oKXtyZXR1cm4oRGF0ZS5ub3c/RGF0ZS5ub3coKTorbmV3IERhdGUpLW59KSxyLm1hcmt8fChyLm1hcms9ci53ZWJraXRNYXJrfHxmdW5jdGlvbihlKXt2YXIgbj17bmFtZTplLGVudHJ5VHlwZToibWFyayIsc3RhcnRUaW1lOnIubm93KCksZHVyYXRpb246MH07dC5wdXNoKG4pLGFbZV09bn0pLHIubWVhc3VyZXx8KHIubWVhc3VyZT1yLndlYmtpdE1lYXN1cmV8fGZ1bmN0aW9uKGUsbixyKXtuPWFbbl0uc3RhcnRUaW1lLHI9YVtyXS5zdGFydFRpbWUsdC5wdXNoKHtuYW1lOmUsZW50cnlUeXBlOiJtZWFzdXJlIixzdGFydFRpbWU6bixkdXJhdGlvbjpyLW59KX0pLHIuZ2V0RW50cmllc0J5VHlwZXx8KHIuZ2V0RW50cmllc0J5VHlwZT1yLndlYmtpdEdldEVudHJpZXNCeVR5cGV8fGZ1bmN0aW9uKGUpe3JldHVybiBpKCJlbnRyeVR5cGUiLGUpfSksci5nZXRFbnRyaWVzQnlOYW1lfHwoci5nZXRFbnRyaWVzQnlOYW1lPXIud2Via2l0R2V0RW50cmllc0J5TmFtZXx8ZnVuY3Rpb24oZSl7cmV0dXJuIGkoIm5hbWUiLGUpfSksci5jbGVhck1hcmtzfHwoci5jbGVhck1hcmtzPXIud2Via2l0Q2xlYXJNYXJrc3x8ZnVuY3Rpb24oZSl7bygibWFyayIsZSl9KSxyLmNsZWFyTWVhc3VyZXN8fChyLmNsZWFyTWVhc3VyZXM9ci53ZWJraXRDbGVhck1lYXN1cmVzfHxmdW5jdGlvbihlKXtvKCJtZWFzdXJlIixlKX0pLGUucGVyZm9ybWFuY2U9ciwiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiYoZGVmaW5lLmFtZHx8ZGVmaW5lLmFqcykmJmRlZmluZSgicGVyZm9ybWFuY2UiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIHJ9KSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lCn0pKHdpbmRvdyk7PC9zY3JpcHQ+PHNjcmlwdD4KCihmdW5jdGlvbiAoKSB7CgkKCXdpbmRvdy5UU01hcmsgPSBmdW5jdGlvbiAobWFya19sYWJlbCkgewoJCWlmICghd2luZG93LnBlcmZvcm1hbmNlIHx8ICF3aW5kb3cucGVyZm9ybWFuY2UubWFyaykgcmV0dXJuOwoJCXBlcmZvcm1hbmNlLm1hcmsobWFya19sYWJlbCk7Cgl9OwoJd2luZG93LlRTTWFyaygnc3RhcnRfbG9hZCcpOwoKCQoJd2luZG93LlRTTWVhc3VyZUFuZEJlYWNvbiA9IGZ1bmN0aW9uIChtZWFzdXJlX2xhYmVsLCBzdGFydF9tYXJrX2xhYmVsKSB7CgkJaWYgKCF3aW5kb3cucGVyZm9ybWFuY2UgfHwgIXdpbmRvdy5wZXJmb3JtYW5jZS5tYXJrIHx8ICF3aW5kb3cucGVyZm9ybWFuY2UubWVhc3VyZSkgewoJCQlyZXR1cm47CgkJfQoKCQlwZXJmb3JtYW5jZS5tYXJrKHN0YXJ0X21hcmtfbGFiZWwgKyAnX2VuZCcpOwoKCQl0cnkgewoJCQlwZXJmb3JtYW5jZS5tZWFzdXJlKG1lYXN1cmVfbGFiZWwsIHN0YXJ0X21hcmtfbGFiZWwsIHN0YXJ0X21hcmtfbGFiZWwgKyAnX2VuZCcpOwoJCQl3aW5kb3cuVFNCZWFjb24obWVhc3VyZV9sYWJlbCwgcGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5TmFtZShtZWFzdXJlX2xhYmVsKVswXS5kdXJhdGlvbik7CgkJfSBjYXRjaCAoZSkgewoJCQkKCQl9Cgl9OwoKCQoJaWYgKCdzZW5kQmVhY29uJyBpbiBuYXZpZ2F0b3IpIHsKCQl3aW5kb3cuVFNCZWFjb24gPSBmdW5jdGlvbiAobGFiZWwsIHZhbHVlKSB7CgkJCXZhciBlbmRwb2ludF91cmwgPSB3aW5kb3cudHNfZW5kcG9pbnRfdXJsIHx8ICdodHRwczovL3NsYWNrLmNvbS9iZWFjb24vdGltaW5nJzsKCQkJbmF2aWdhdG9yLnNlbmRCZWFjb24oCgkJCQllbmRwb2ludF91cmwgKyAnP2RhdGE9JyArIGVuY29kZVVSSUNvbXBvbmVudChsYWJlbCArICc6JyArIHZhbHVlKSwKCQkJCScnCgkJCSk7CgkJfTsKCX0gZWxzZSB7CgkJd2luZG93LlRTQmVhY29uID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkgewoJCQl2YXIgZW5kcG9pbnRfdXJsID0gd2luZG93LnRzX2VuZHBvaW50X3VybCB8fCAnaHR0cHM6Ly9zbGFjay5jb20vYmVhY29uL3RpbWluZyc7CgkJCW5ldyBJbWFnZSgpLnNyYyA9IGVuZHBvaW50X3VybCArICc/ZGF0YT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGxhYmVsICsgJzonICsgdmFsdWUpOwoJCX07Cgl9Cn0pKCk7Cjwvc2NyaXB0PjxzY3JpcHQ+d2luZG93LlRTTWFyaygnc3RlcF9sb2FkJyk7PC9zY3JpcHQ+PG5vc2NyaXB0PjxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjA7IFVSTD0vYXBpL2h0dHBzOi8vc2xhY2suY29tL2FwaS91c2Vycy5saXN0P3Rva2VuPVNMQUNLX0FQSV9UT0tFTiZhbXA7bm9qc21vZGU9MSI+PC9ub3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+dmFyIHNhZmVfaG9zdHMgPSBbJ2FwcC5vcHRpbWl6ZWx5LmNvbScsICd0aW55c3BlY2suZGV2LnNsYWNrLmNvbSddOwoKaWYgKHNlbGYgIT09IHRvcCAmJiBzYWZlX2hvc3RzLmluZGV4T2YodG9wLmxvY2F0aW9uLmhvc3QpID09PSAtMSkgewoJd2luZG93LmRvY3VtZW50LndyaXRlKAoJCSdcdTAwM0NzdHlsZT5ib2R5ICoge2Rpc3BsYXk6bm9uZSAhaW1wb3J0YW50O31cdTAwM0Mvc3R5bGU+XHUwMDNDYSBocmVmPSIjIiBvbmNsaWNrPScgKwoJCQknInRvcC5sb2NhdGlvbi5ocmVmPXdpbmRvdy5sb2NhdGlvbi5ocmVmIiBzdHlsZT0iZGlzcGxheTpibG9jayAhaW1wb3J0YW50O3BhZGRpbmc6MTBweCI+R28gdG8gU2xhY2suY29tXHUwMDNDL2E+JwoJKTsKfQoKKGZ1bmN0aW9uKCkgewoJdmFyIHRpbWVyOwoJaWYgKHNlbGYgIT09IHRvcCAmJiBzYWZlX2hvc3RzLmluZGV4T2YodG9wLmxvY2F0aW9uLmhvc3QpID09PSAtMSkgewoJCXRpbWVyID0gd2luZG93LnNldEludGVydmFsKGZ1bmN0aW9uKCkgewoJCQlpZiAod2luZG93KSB7CgkJCQl0cnkgewoJCQkJCXZhciBwYWdlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFnZScpOwoJCQkJCXZhciBjbGllbnRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbGllbnQtdWknKTsKCQkJCQl2YXIgc2VjdGlvbkVscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ25hdiwgaGVhZGVyLCBzZWN0aW9uJyk7CgoJCQkJCXBhZ2VFbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHBhZ2VFbCk7CgkJCQkJY2xpZW50RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjbGllbnRFbCk7CgkJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBzZWN0aW9uRWxzLmxlbmd0aDsgaSsrKSB7CgkJCQkJCXNlY3Rpb25FbHNbaV0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzZWN0aW9uRWxzW2ldKTsKCQkJCQl9CgkJCQkJd2luZG93LlRTID0gbnVsbDsKCQkJCQl3aW5kb3cuVEQgPSBudWxsOwoJCQkJCXdpbmRvdy5jbGVhckludGVydmFsKHRpbWVyKTsKCQkJCX0gY2F0Y2ggKGUpIHt9CQoJCQl9CgkJfSwgMjAwKTsKCX0KfSkoKTs8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CndpbmRvdy5kYXRhTGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyIHx8IFtdOwp3aW5kb3cuZGF0YUxheWVyLnB1c2goewoJJ2d0bS5zdGFydCc6IERhdGUubm93KCksCgknZXZlbnQnIDogJ2d0bS5qcycsCgknc2VjdXJlX3BhZ2UnIDogZmFsc2UsCn0pOwp2YXIgZmlyc3RTY3JpcHQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF07CnZhciB0aGlzU2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CnRoaXNTY3JpcHQuYXN5bmMgPSB0cnVlOwp0aGlzU2NyaXB0LnNyYyA9ICcvL3d3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbS9ndG0uanM/aWQ9R1RNLUtIMkxQSyc7CmZpcnN0U2NyaXB0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXNTY3JpcHQsIGZpcnN0U2NyaXB0KTsKPC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZnVuY3Rpb24oZSkgewoJdmFyIGd0bURhdGFMYXllciA9IHdpbmRvdy5kYXRhTGF5ZXIgfHwgW107Cgl2YXIgZ3RtVGFncyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJypbZGF0YS1ndG0tY2xpY2tdJyk7Cgl2YXIgZ3RtQ2xpY2tIYW5kbGVyID0gZnVuY3Rpb24oYykgewoJCXZhciBndG1fZXZlbnRzID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2RhdGEtZ3RtLWNsaWNrJyk7CgkJaWYgKCFndG1fZXZlbnRzKSByZXR1cm47CgkJdmFyIGd0bV9ldmVudHNfYXJyID0gZ3RtX2V2ZW50cy5zcGxpdCgiLCIpOwoJCWZvcih2YXIgZT0wOyBlIDwgZ3RtX2V2ZW50c19hcnIubGVuZ3RoOyBlKyspIHsKCQkJdmFyIGV2ID0gZ3RtX2V2ZW50c19hcnJbZV0udHJpbSgpOwoJCQlndG1EYXRhTGF5ZXIucHVzaCh7ICdldmVudCc6IGV2IH0pOwoJCX0KCX07Cglmb3IodmFyIGc9MDsgZyA8IGd0bVRhZ3MubGVuZ3RoOyBnKyspewoJCXZhciBlbGVtID0gZ3RtVGFnc1tnXTsKCQllbGVtLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZ3RtQ2xpY2tIYW5kbGVyKTsKCX0KfSk7Cjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KKGZ1bmN0aW9uKGUsYyxiLGYsZCxnLGEpe2UuU2xhY2tCZWFjb25PYmplY3Q9ZDsKZVtkXT1lW2RdfHxmdW5jdGlvbigpeyhlW2RdLnE9ZVtkXS5xfHxbXSkucHVzaChbMSpuZXcgRGF0ZSgpLGFyZ3VtZW50c10pfTsKZVtkXS5sPTEqbmV3IERhdGUoKTtnPWMuY3JlYXRlRWxlbWVudChiKTthPWMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoYilbMF07CmcuYXN5bmM9MTtnLnNyYz1mO2EucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZyxhKQp9KSh3aW5kb3csZG9jdW1lbnQsInNjcmlwdCIsImh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9zbGFja19iZWFjb24uYmVkYzEyYzE2ZjI3OTUxOTkyNmQubWluLmpzIiwic2IiKTsKd2luZG93LnNiKCdzZXQnLCAndG9rZW4nLCAnMzMwN2Y0MzY5NjNlMDJkNGY5ZWI4NWNlNTE1OTc0NGMnKTsKd2luZG93LnNiKCd0cmFjaycsICdwYWdldmlldycpOwo8L3NjcmlwdD48bWV0YSBuYW1lPSJyZWZlcnJlciIgY29udGVudD0ibm8tcmVmZXJyZXIiPjxtZXRhIG5hbWU9InN1cGVyZmlzaCIgY29udGVudD0ibm9maXNoIj48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+dmFyIFRTX2xhc3RfbG9nX2RhdGUgPSBudWxsOwp2YXIgVFNNYWtlTG9nRGF0ZSA9IGZ1bmN0aW9uKCkgewoJdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKCXZhciB5ID0gZGF0ZS5nZXRGdWxsWWVhcigpOwoJdmFyIG1vID0gZGF0ZS5nZXRNb250aCgpKzE7Cgl2YXIgZCA9IGRhdGUuZ2V0RGF0ZSgpOwoKCXZhciB0aW1lID0gewoJICBoOiBkYXRlLmdldEhvdXJzKCksCgkgIG1pOiBkYXRlLmdldE1pbnV0ZXMoKSwKCSAgczogZGF0ZS5nZXRTZWNvbmRzKCksCgkgIG1zOiBkYXRlLmdldE1pbGxpc2Vjb25kcygpCgl9OwoKCU9iamVjdC5rZXlzKHRpbWUpLm1hcChmdW5jdGlvbihtb21lbnQsIGluZGV4KSB7CgkJaWYgKG1vbWVudCA9PSAnbXMnKSB7CgkJCWlmICh0aW1lW21vbWVudF0gPCAxMCkgewoJCQkJdGltZVttb21lbnRdID0gdGltZVttb21lbnRdKycwMCc7CgkJCX0gZWxzZSBpZiAodGltZVttb21lbnRdIDwgMTAwKSB7CgkJCQl0aW1lW21vbWVudF0gPSB0aW1lW21vbWVudF0rJzAnOwoJCQl9CgkJfSBlbHNlIGlmICh0aW1lW21vbWVudF0gPCAxMCkgewoJCQl0aW1lW21vbWVudF0gPSAnMCcgKyB0aW1lW21vbWVudF07CgkJfQoJfSk7CgoJdmFyIHN0ciA9IHkgKyAnLycgKyBtbyArICcvJyArIGQgKyAnICcgKyB0aW1lLmggKyAnOicgKyB0aW1lLm1pICsgJzonICsgdGltZS5zICsgJy4nICsgdGltZS5tczsKCWlmIChUU19sYXN0X2xvZ19kYXRlKSB7CgkJdmFyIGRpZmYgPSBkYXRlLVRTX2xhc3RfbG9nX2RhdGU7CgkJLy9zdHIrPSAnICgnK2RpZmYrJ21zKSc7Cgl9CglUU19sYXN0X2xvZ19kYXRlID0gZGF0ZTsKCXJldHVybiBzdHIrJyAnOwp9Cgp2YXIgcGFyc2VEZWVwTGlua1JlcXVlc3QgPSBmdW5jdGlvbihjb2RlKSB7Cgl2YXIgbSA9IGNvZGUubWF0Y2goLyJpZCI6IihbQ0RHXVtBLVowLTldezgsfSkiLyk7Cgl2YXIgaWQgPSBtID8gbVsxXSA6IG51bGw7CgoJbSA9IGNvZGUubWF0Y2goLyJ0ZWFtIjoiKFRbQS1aMC05XXs4LH0pIi8pOwoJdmFyIHRlYW0gPSBtID8gbVsxXSA6IG51bGw7CgoJbSA9IGNvZGUubWF0Y2goLyJtZXNzYWdlIjoiKFswLTldK1wuWzAtOV0rKSIvKTsKCXZhciBtZXNzYWdlID0gbSA/IG1bMV0gOiBudWxsOwoKCXJldHVybiB7IGlkOiBpZCwgdGVhbTogdGVhbSwgbWVzc2FnZTogbWVzc2FnZSB9Owp9CgppZiAoJ3JlbmRlcmVyRXZhbEFzeW5jJyBpbiB3aW5kb3cpIHsKCXZhciBvcmlnUmVuZGVyZXJFdmFsQXN5bmMgPSB3aW5kb3cucmVuZGVyZXJFdmFsQXN5bmM7Cgl3aW5kb3cucmVuZGVyZXJFdmFsQXN5bmMgPSBmdW5jdGlvbihibG9iKSB7CgkJdHJ5IHsKCQkJdmFyIGRhdGEgPSBKU09OLnBhcnNlKGRlY29kZVVSSUNvbXBvbmVudChhdG9iKGJsb2IpKSk7CgkJCWlmIChkYXRhLmNvZGUubWF0Y2goL2hhbmRsZURlZXBMaW5rLykpIHsKCQkJCXZhciByZXF1ZXN0ID0gcGFyc2VEZWVwTGlua1JlcXVlc3QoZGF0YS5jb2RlKTsKCQkJCWlmICghcmVxdWVzdC5pZCB8fCAhcmVxdWVzdC50ZWFtIHx8ICFyZXF1ZXN0Lm1lc3NhZ2UpIHJldHVybjsKCgkJCQlyZXF1ZXN0LmNtZCA9ICdjaGFubmVsJzsKCQkJCVRTU1NCLmhhbmRsZURlZXBMaW5rV2l0aEFyZ3MoSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpOwoJCQkJcmV0dXJuOwoJCQl9IGVsc2UgewoJCQkJb3JpZ1JlbmRlcmVyRXZhbEFzeW5jKGJsb2IpOwoJCQl9CgkJfSBjYXRjaCAoZSkgewoJCX0KCX0KfTwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij52YXIgVFNTU0IgPSB7CgljYWxsOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9Cn07PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24oKSB7Cgl2YXIgd2FzX1RTID0gd2luZG93LlRTOwoJZGVsZXRlIHdpbmRvdy5UUzsKCWlmICh3YXNfVFMpIHdpbmRvdy5UUyA9IHdhc19UUzsKfSk7PC9zY3JpcHQ+PHRpdGxlPlRoZXJlJ3MgYmVlbiBhIGdsaXRjaOKApiB8IFNsYWNrPC90aXRsZT48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vMzJlNjAvc3R5bGUvcm9sbHVwLXNsYWNrX2tpdF9sZWdhY3lfYWRhcHRlcnMuY3NzIiByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PGxpbmsgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2MxMTJiL3N0eWxlL3JvbGx1cC1wbGFzdGljLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9tb2Rlcm4udmVuZG9yLmRhNjc3YjkubWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9hcHBsaWNhdGlvbi4wM2QzZjk2Lm1pbi5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vNGVkMjlhL3N0eWxlL3JvbGx1cC1zbGFja19raXRfaGVscGVycy5jc3MiIHJlbD0ic3R5bGVzaGVldCIgaWQ9InNsYWNrX2tpdF9oZWxwZXJzX3N0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PGxpbmsgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzBjOTc0L3N0eWxlLzQwNC5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vNTcwMGEvc3R5bGUvc3RpY2t5X25hdi5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bGluayBocmVmPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vMmQ1Nzcvc3R5bGUvZm9vdGVyLmNzcyIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjxsaW5rIGhyZWY9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS83YTlhNzgvc3R5bGUvbGlicy9sYXRvLTItY29tcHJlc3NlZC5jc3MiIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48bWV0YSBwcm9wZXJ0eT0ib2c6dHlwZSIgY29udGVudD0id2Vic2l0ZSI+PG1ldGEgcHJvcGVydHk9Im9nOnNpdGVfbmFtZSIgY29udGVudD0iU2xhY2siPjxtZXRhIHByb3BlcnR5PSJvZzp0aXRsZSIgY29udGVudD0iVGhlcmUncyBiZWVuIGEgZ2xpdGNo4oCmIj48bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2UiIGNvbnRlbnQ9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS84MDU4OC9pbWcvNDA0LzQwNC1tZXRhLXRodW1iLmpwZyI+PG1ldGEgcHJvcGVydHk9Im9nOmRlc2NyaXB0aW9uIiBjb250ZW50PSJXZSdyZSBub3QgcXVpdGUgc3VyZSB3aGF0IHdlbnQgd3JvbmcuIFlvdSBjYW4gZ28gYmFjaywgb3IgdHJ5IGxvb2tpbmcgb24gb3VyICZsdDthIGhyZWY9JnF1b3Q7aHR0cDovL2dldC5zbGFjay5oZWxwJnF1b3Q7IHRhcmdldD0mcXVvdDtfYmxhbmsmcXVvdDsmZ3Q7SGVscCBDZW50ZXImbHQ7L2EmZ3Q7IGlmIHlvdSBuZWVkIGEgaGFuZC4iPjxtZXRhIHByb3BlcnR5PSJvZzp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vc2xhY2suY29tL2FwaS9odHRwczovL3NsYWNrLmNvbS9hcGkvdXNlcnMubGlzdCI+PGxpbmsgaWQ9ImZhdmljb24iIHJlbD0ic2hvcnRjdXQgaWNvbiIgaHJlZj0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L21hcmtldGluZy9pbWcvbWV0YS9mYXZpY29uLTMyLnBuZyIgc2l6ZXM9IjE2eDE2IDMyeDMyIDQ4eDQ4IiB0eXBlPSJpbWFnZS9wbmciPjwvaGVhZD48Ym9keSBjbGFzcz0iIGRlcHJlY2F0ZWQiPjxzY3JpcHQ+dmFyIHcgPSBNYXRoLm1heChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIHx8IDApOwppZiAodyA+IDE0NDApIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKCd3aWRlc2NyZWVuJyk7PC9zY3JpcHQ+PG5hdiBjbGFzcz0idG9wIHBlcnNpc3RlbnQiPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tLyIgY2xhc3M9ImxvZ28iIGRhdGEtcWE9ImxvZ28iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWxvZ28iIGFyaWEtbGFiZWw9IlNsYWNrIGhvbWVwYWdlIj48L2E+PHVsPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9pcyIgZGF0YS1xYT0icHJvZHVjdCIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X3Byb2R1Y3QiPlByb2R1Y3Q8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vcHJpY2luZz91aV9zdGVwPTU1JmFtcDt1aV9lbGVtZW50PTUiIGRhdGEtcWE9InByaWNpbmciIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9wcmljaW5nIj5QcmljaW5nPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2V0LnNsYWNrLmhlbHAvaGMvZW4tdXMiIGRhdGEtcWE9InN1cHBvcnQiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9zdXBwb3J0Ij5TdXBwb3J0PC9hPjwvbGk+PGxpIGNsYXNzPSJtb2JpbGVfYnRuIGRvd25sb2FkX3NsYWNrIj48YSBocmVmPSIvZ2V0IiBkYXRhLXFhPSJkb3dubG9hZF9zbGFjayIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X2Rvd25sb2FkIj5Eb3dubG9hZCBTbGFjazwvYT48L2xpPjxsaT48YSBkYXRhLWd0bS1jbGljaz0iU2lnblVwLG9wdG91dF9uYXZfY3JlYXRlX3RlYW0iIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2NyZWF0ZSIgY2xhc3M9IiIgZGF0YS1xYT0iY3JlYXRlX3RlYW0iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9jcmVhdGVfdGVhbSI+Q3JlYXRlIGEgbmV3IHdvcmtzcGFjZTwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9nZXQtc3RhcnRlZCMvZmluZCIgZGF0YS1ndG0tY2xpY2s9Im9wdG91dF9uYXZfZmluZF90ZWFtIiBkYXRhLXFhPSJmaW5kX3RlYW0iIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9maW5kX3RlYW0iPkZpbmQgeW91ciB3b3Jrc3BhY2U8L2E+PC9saT48bGkgY2xhc3M9InNpZ25faW4gaGlkZV9vbl9tb2JpbGUiPjxhIGRhdGEtZ3RtLWNsaWNrPSJvcHRvdXRfbmF2X3NpZ25pbiIgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vc2lnbmluIiBjbGFzcz0iYnRuX3N0aWNreSBidG5fZmlsbGVkIiBkYXRhLXFhPSJzaWduX2luIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfc2lnbl9pbiI+U2lnbiBpbjwvYT48L2xpPjxsaSBjbGFzcz0ibW9iaWxlX2J0biBtb2JpbGVfbWVudV9idG4iPjxhIGhyZWY9IiMiIGNsYXNzPSJidG5fc3RpY2t5IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfbW9iaWxlX21lbnVfYnRuIj5NZW51PC9hPjwvbGk+PC91bD48L25hdj48bmF2IGNsYXNzPSJtb2JpbGVfbWVudSBsb2FkaW5nIG1lbnVfc2Nyb2xsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PGRpdiBjbGFzcz0ibW9iaWxlX21lbnVfd3JhcHBlciI+PGRpdiBjbGFzcz0ibW9iaWxlX21lbnVfaGVhZGVyIj48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS8iIGNsYXNzPSJsb2dvIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfbG9nbyI+PC9hPjxhIGhyZWY9IiMiIGNsYXNzPSJjbG9zZSIgYXJpYS1sYWJlbD0iY2xvc2UiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9tZW51X2Nsb3NlIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiB0c19pY29uX3RpbWVzIj48L3RzLWljb24+PC9hPjwvZGl2Pjx1bD48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vaXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9wcm9kdWN0Ij5Qcm9kdWN0PC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaWNpbmc/dWlfc3RlcD01NSZhbXA7dWlfZWxlbWVudD01IiBjbGFzcz0ibW9iaWxlX25hdl9wcmljaW5nIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfcHJpY2luZyI+UHJpY2luZzwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL2dldC5zbGFjay5oZWxwL2hjL2VuLXVzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfc3VwcG9ydCI+U3VwcG9ydDwvYT48L2xpPjxsaT48YSBocmVmPSIvZ2V0IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1uYXZfZG93bmxvYWQiPkRvd25sb2FkIDxzcGFuIGNsYXNzPSJvcHRpb25hbF9kZXNrdG9wX25hdl9tZXNzYWdlIj50aGUgU2xhY2sgYXBwPC9zcGFuPjwvYT48L2xpPjwvdWw+PHVsIGNsYXNzPSJtb2JpbGVfbWVudV9mb290ZXIiPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9zaWduaW4iIGRhdGEtZ3RtLWNsaWNrPSJvcHRvdXRfbmF2X3NpZ25pbiIgdGFyZ2V0PSJfYmxhbmsiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PW5hdl9zaWduX2luIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiBzbWFsbCBmbG9hdF9ub25lIHRlYW1faWNvbiB0c19pY29uX3BsdXMgZGVmYXVsdCBzaWdudXBfaWNvbiI+PC90cy1pY29uPjxzcGFuIGNsYXNzPSJzd2l0Y2hlcl9sYWJlbCI+U2lnbiBpbjwvc3Bhbj48L2E+PC9saT48bGk+PGEgZGF0YS1ndG0tY2xpY2s9IlNpZ25VcCxvcHRvdXRfbmF2X2NyZWF0ZV90ZWFtIiBocmVmPSJodHRwczovL3NsYWNrLmNvbS9nZXQtc3RhcnRlZCMvY3JlYXRlIiBjbGFzcz0iIiB0YXJnZXQ9Il9ibGFuayIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9bmF2X2NyZWF0ZV90ZWFtIj48dHMtaWNvbiBjbGFzcz0idHNfaWNvbiBzbWFsbCBmbG9hdF9ub25lIHRlYW1faWNvbiBjLWljb24tLXNsYWNrIGRlZmF1bHQgc2lnbnVwX2ljb24iPjwvdHMtaWNvbj48c3BhbiBjbGFzcz0ic3dpdGNoZXJfbGFiZWwiPkNyZWF0ZSBhIG5ldyB3b3Jrc3BhY2U8L3NwYW4+PC9hPjwvbGk+PC91bD48L2Rpdj48L25hdj48ZGl2IGlkPSJwYWdlIiBjbGFzcz0iIj48ZGl2IGlkPSJwYWdlX2NvbnRlbnRzIiBkYXRhLXFhPSJwYWdlX2NvbnRlbnRzIiBjbGFzcz0iIj48ZGl2IGlkPSJwcmVsb2FkIj48L2Rpdj48ZGl2IGlkPSJjb250ZW50IiBkYXRhLWJhY2tncm91bmQ9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS84MDU4OC9pbWcvNDA0L21hcnJha2VzaC1tZWFkb3ctODAuanBnIj48aW1nIGlkPSJiYWNrZ3JvdW5kIiBzcmM9ImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEFRQUJBSUFBQUFBQUFQLy8veUg1QkFFQUFBQUFMQUFBQUFBQkFBRUFBQUlCUkFBNyI+PGRpdiBpZD0ic3ByaXRlLXdyYXBwZXIiPjxkaXYgY2xhc3M9InNwcml0ZSBwaWdneSBwaWdneV9jaGV3aW5nIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgY2hpY2tlbiBjaGlja2VuX3dhbGtfbHIiPjxkaXYgY2xhc3M9InN1Yl9zcHJpdGUiPjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBjaGlja2VuIGNoaWNrZW5fcGVja18yeCBmbGlwcGVkIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgcGlnZ3kgcGlnZ3lfd2FsayBwaWdneV93YWxrX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgY2hpY2tlbiBjaGlja2VuX3dhbGtfcmwgZmxpcHBlZCI+PGRpdiBjbGFzcz0ic3ViX3Nwcml0ZSI+PC9kaXY+PC9kaXY+PGRpdiBjbGFzcz0ic3ByaXRlIHBpZ2d5IHBpZ2d5X3dhbGsgZmxpcHBlZCBwaWdneV93YWxrX3JsIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9hbmdsZSBidXR0ZXJmbHlfYW5nbGVfbHIiPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X2FuZ2xlXzEgYnV0dGVyZmx5X2FuZ2xlXzFfbHIiPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X3Jvb2tlZCBidXR0ZXJmbHlfcm9va2VkX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9zaWRlIGJ1dHRlcmZseV9zaWRlX2xyIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9hbmdsZSBmbGlwcGVkIGJ1dHRlcmZseV9hbmdsZV9ybCBib3R0b20iPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X2FuZ2xlXzEgZmxpcHBlZCBidXR0ZXJmbHlfYW5nbGVfMV9ybCBib3R0b20iPjwvZGl2PjxkaXYgY2xhc3M9InNwcml0ZSBidXR0ZXJmbHkgYnV0dGVyZmx5X3Jvb2tlZCBmbGlwcGVkIGJ1dHRlcmZseV9yb29rZWRfcmwgYm90dG9tIj48L2Rpdj48ZGl2IGNsYXNzPSJzcHJpdGUgYnV0dGVyZmx5IGJ1dHRlcmZseV9zaWRlIGZsaXBwZWQgYnV0dGVyZmx5X3NpZGVfcmwgYm90dG9tIj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGlkPSJsb2FkZXIiPjw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+PHN2ZyB3aWR0aD0iMzJweCIgaGVpZ2h0PSIzMnB4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgY2xhc3M9InVpbC1oZWFydCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9MTAwIGhlaWdodD0xMDAgZmlsbD0ibm9uZSIgY2xhc3M9ImJrIj48L3JlY3Q+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTAgNTApIj48Zz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTAgLTUwKSI+PHBhdGggZD0iTTkwLDMwLjJjMC0xMS05LTIwLjEtMjAtMjAuMXMtMjAsOS4xLTIwLDIwLjJjMCwwLjIsMC0wLjMsMCwwLjdINTBjMC0xLDAtMC42LDAtMC44YzAtMTEtOS0yMC4xLTIwLTIwLjFzLTIwLDkuMS0yMCwyMC4yIGMwLDAuMiwwLTAuMywwLDAuN2gwYzAuMywyMCwzMCwzOS41LDQwLDU1YzEwLTE1LjUsMzkuNy0zNSw0MC01NWgwQzkwLDMwLDkwLDMwLjQsOTAsMzAuMnoiIGZpbGw9IiNmMDIiPjwvcGF0aD48L2c+PGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJzY2FsZSIgZnJvbT0iMS4zIiB0bz0iMC45IiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgY2FsY01vZGU9InNwbGluZSIgdmFsdWVzPSIxLjM7MC45OzEuMTswLjkiIGtleVRpbWVzPSIwOzAuMzswLjMwMTsxIiBrZXlTcGxpbmVzPSIwIDAuNzUgMC4yNSAxOzAgMSAwIDE7MCAuNzUgLjI1IDEiPjwvYW5pbWF0ZVRyYW5zZm9ybT48L2c+PC9nPjwvc3ZnPjwvZGl2PjxkaXYgY2xhc3M9ImNhcmQiPjxoMT48aSBjbGFzcz0idHNfaWNvbiB0c19pY29uX3dhcm5pbmcgbXVzdGFyZF95ZWxsb3ciPjwvaT5UaGVyZeKAmXMgYmVlbiBhIGdsaXRjaOKApjwvaDE+PHA+V2XigJlyZSBub3QgcXVpdGUgc3VyZSB3aGF0IHdlbnQgd3JvbmcuIFlvdSBjYW4gZ28gYmFjaywgb3IgdHJ5IGxvb2tpbmcgb24gb3VyIDxhIGhyZWY9Imh0dHA6Ly9nZXQuc2xhY2suaGVscC9oYy9lbi11cyIgdGFyZ2V0PSJfYmxhbmsiPkhlbHAgQ2VudGVyPC9hPiBpZiB5b3UgbmVlZCBhIGhhbmQuPC9wPjwvZGl2Pjxub3NjcmlwdD48c3R5bGU+I2xvYWRlciB7CgkJCQkJCWRpc3BsYXk6IG5vbmU7CgkJCQkJfTwvc3R5bGU+PC9ub3NjcmlwdD48c2NyaXB0PgovLyBmaXJlIDQwNAp3aW5kb3cuZGF0YUxheWVyID0gd2luZG93LmRhdGFMYXllciB8fCBbXTsKd2luZG93LmRhdGFMYXllci5wdXNoKHsKCSdldmVudCcgOiAnRXJyb3I0MDQnLAp9KTsKCihmdW5jdGlvbigpIHsKCS8vIHF1aWNrIGhhY2s6IDgtYml0IGFscGhhLWZyaWVuZGx5IGxvZ28KCXZhciBsb2dvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWRlcl9sb2dvJyk7Cgl2YXIgYWx0X3NyYyA9ICdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQVBBQUFBQklDQU1BQUFEL0VvaTRBQUFDK2xCTVZFVUFBQUFvRlNjcUlqRW9KVE1yTERRck1qZzFNRGs3TXpncU9EMDlOVG8vT0QxQ09qOUVQRUZGUFVOSVBVaE5QRW05SHlsSlFVYlBGMXhNUkVsaVBWRmRQMUN3SjFxOEtTcFBSMHpNSVZmTElWdVJNMVNySzFrd1VrNkxObGlHT0Zjc1ZWSEJMU2RUU2svUEpsNVZUVkl6V0UvTkswNi9OQ2pSSzJaWlVWYkNOeXJOTTBVeVlGVmNWRm5QTmt4ZlZsd3VabHJRTldoaFdGN0pQalprVzJIVU9uSEpSVGZGU0NwblgyUnFZbWRzWkduVlJIWElVU2h1Wld0eGFHN01WVExKV0N4MWJIRkxlVzRhakhSNGNIWGFVb04wY25aZ2dEVmVnRHM3aDJ0OGMza3ppMjRoa0hob2dqZUFkbnpiV29aN2VYMTBoallqbUhoN2hqalNjQ3lIZm9RMG1IbC9pVFF1bW9DRmlEVjRpMEdEZ1lXR2lUYlFkQzFIbFh6Z1pvNThqMFdIaFlsQW5YaUpoNHZnYlpMVWVUOHRwWDdVZkNwK2trNDZvMzNnYjVtTWlvNCtwbzJqa1RYZmRadVFqcExXaEN1U2tKU25sREE0cm9hdWxESTVyNGVWazVjOHNZbERyWitIb0dmamY2T1pscHFEb201QnRZMmNtWjdqaHFlQ3FYK2ZuYUdBcW9iY21TN09uaXRTdVpHaW9LVFZuaTVRdlp2bWo2MmxvNmZnb1N1cHBxcGZ3SjludmFyZXBqYm9sN05zdmJHdHFxOTJ2Yk55dnJtd3JiTGlxa0p0dzZScHdjaHZ3Y0t5cjdSd3hxYnJvYnB0eGN6aHNVNjJ0TGh2eDg1Nng4OSt5cXpsdFZtNnVMenNxY0IreTlUbnVHSyt1OERrdW1LSXo3anVzY2Jsdld2QnY4T1B6dExFd2NiSnc4S1YxTDdxdzNmdnVzekl4c3JNeDhXWDFkbk15Yzd0eDRIdXlZbWoyc1hSek1yeHd0UFB6ZEdqMmQvVXpzM1QwTlhqMFovczBKU28zdVRZMHRHeDM4enp5OXJYMU5udjFKNnkzK2JjMTlYbzJLeTQ0ZUs4NHREYjJOengyS2ZmMmRqejA5Kzg1dHJsM2J6ZjNPSHozTEhqM3R6RjV1bm00Ti9JNnVESTZlemw0dWYzNHIzcTVPUDU0T3JwNXV2NTVzZlU3ZkxWNytiNTZNL3Q2dS93NnVuYjhPLzY2UEQ3N2RyaDgrenc3dkwzOE52bTgvVDI4Ty93OHUvNTcvWDI4L2owOXZQdStQUDY5dWYrOXU3eitQdjg5dlg2K2UvNCt2ZjgrZjcyKy83Lyt2bjYvUG44L3Z2ZWd2MXVBQUFBQVhSU1RsTUFRT2JZWmdBQUNnZEpSRUZVZUFIbDJnVjRFMmtleC9ILzZudHBzYWJydnFVclNBNkh0bHg3Rzl6ZFlkMFh5WGFsMlNPNDB4VDNMbWx3RDFxNVd5UzR1eC9kWG5IYlNvcVVhVW1lNTZhWnladi9aTjdKTkpBVDZPZnhmYkR2emk5dk01TkFLYm1nTExtMGZKSjUwdnJyVUVhNDFwdmRKcDJDc21HNzJlTjNLQXYrTUZNcFRpZ0Q5cHE5L2hPanR2ZHRwNCtKaVcyWENjR1ExU29tT2lvNkptNElQTENsS0hnVkJGOFVFU1JETUF3bm9xS2dCRSs2QjBGWGx3aW1RakNZaUNnWEh0VGZ6Zi9aVGRjZ2dpUUlodmhBZ2wzSDF5MVlkOXdGVXIrYjVadStlMjdmam9NNUVCUTZJaGdEd1dBZ29pdWc2dUlFWTRrSkYwSENPY2xuMDNmUHBGdmMwdTlDRUZRaGd1RVFESDFMSDN4anNGRXcyS2Q0dlJrNXdOZFNTNEpSSEVrRVE0SWJuQTBxbk9PTUhoT1VOajMycCs2ZldMQWQ4UEFpZ2hyOE9SRmxnb3AvR3IyT3N6Yk4xelp2MGFMdGRBdDJOM2pCcHVBR253VVY2MUR3QXQ5Tjg3VTkrZG9TZ3l6WUJYaG9MLzFuZ2srRGlnVW9lREFIMkltZitvaTF2RjRXN0Z6d2doT0NHM3dTVkt3d3NqZGRmQzU5VHRzV1hzMm40ZUFjZUdqaFJCQWYzT0Nqb09JNERsN2dyWjNIWjMyQ2dpV2JYZzNCQ3piOGw0TTVJOFo1YTNuRFVDL2U5UHdjZUhoaFFRM3VTMFQ3UWYxRmpCd1Nhd1VLbTU1L0ZZSVkzRGU0d1hzZ2dFMy8vRzAvdmhiNXBnWHlONHZidkIxM0lRQk8rNWhXZFNQS2gxV0pialo4WTZGNjhPV04xaGxKeWJhZHVhRHM4aDdiMU1RWmkvWTdHTUU3QWN1MkhYWEtOajFZclAycVUrUEdqZWZnWHZtbTU2V2ZLNFlBT01aRUVFU2p0eFg1Q1hiWkRkNWZydnZVenY0ZmFJZ2tIclhqOS9nTnRvWVFFaG8zM001Sk4wMXJlYitnWE5tbVpiVnFVbDhpdnNLbk9zR3RQQkY4RGlJdTBmZFhSNldCTDFzVklsVmprVk1TdkJXOFpoQlIrZUdTVGROYVhnK0wwcWE3LzdRTkFwUklXR3BjbGdSL0NvSmxrVVRPNUFUc1pEU1JxM3NVM3kyaFdVd2xWRmVnaWkra3QybU16TFpnSThUYXpqK01NcHVYUW1Dc2hDMkJFY3gxSlV3ZEFFa3JSMWhDMHdEaTVjRkphQ29GOU9mdGx2a1dTdzhjek5oMDUvNThiWWw3RUlqTG9ZVE5LZzkyMUNZS3hnQ1ZyQ0Zzc1FBSlJMU1pNYSs2NHVtV3c5ZVcrQVgxeWpiZGthLzFPQUtCNkUzWXdqbDVjQ3BSZEJoRXlyOW1oandZOTliSWd4S3VIZlF5b2w3cE9iM2s0QWt6RXRDbXVWQmFPUHhvUVZIZXpxbHhranQrenp4N0E0L1RFUlk4Nml0aFJJR09ROCswTm9MYkdOUjdFOXhvcjJ6VHREWUh3RGtURjk4R2RiSUxVdVVLSGJrcGpKQ3dBa1l3YlBXOEhwc2xwcTVkbGlBZVR2aUdELytuaUUrVEZpVVBhVkxlYzFGUmNJWlM3d1dheTl6MGtoMDU2Rmxld0p2R20wb0ZyNEl4c2N0QUd0d1ZQWlFLSDVNTGd2MHh4R080NzZDcjJFRGd0TVdKcndrY3pPNkZMU2g0dG5UVGZPMVZGNGpPNCtDRkQvSllyUUNZeXFOZ1lkU2hReHhBY2JGRUZPZHpnZlg0RDl5b3ErSUEzaEFpU2xQb2hTVW9XTHJwaWQ1YWVJaE45NVdPVEMwWXpwcXVBSlpGUktHY01IbFJWQkZnbkpBL0hBVXplMkdlaGJucFRsLzkvS3VmNTlON0grQ3pnUEpXOVdBNWRFMVBBenFGTlpuKy83WlUzRnM3RjRCNWhXZlRXaVB2Rm1DWG1KdSsvNjk4OEc4Um9TSVROaGNFSHR3YlQ2UXV3V2VjSEsxY2kzcnI1b0hYUVF2V2c5YnlkZ0hta20vNjJ0eW1sYlhhV3VQOU5qdENDRmFsUTZLOVNEMll5OTV2MzMrV2s3d21yQUM1eEdPenloRVpRYWdvQnlERjgxSHZ2Q25mL21pa2ZEYjlEK21tOCtlMjE0b2FYZ3ZzalVlb2ZoSG5MM2huM3hvYWNSTWRySGw5MFp1dG5VUVV3Z0ZURXBFSmRZREVWVnJNM3dRNUJ4c1I1VTJQL0xMOUsxcXZodmRCV1c0NGtRdEw0cFNDMDJvVE5oUEFHdnFxQkpWZ1pCRkk1V3h4MytDZXVZdWU1Zm5kOU1ndURWNnM5SzRXV3d4KzdBa2pERFd5bWNFY0hvVHNaaU1adlcxbW1rcmtRbytDaitLY25HTDBQTjd2cGtkK3lOZnk2bWl4OXVCUFpqUmhlQ2xMZkFDQWc3a1lvaHlNTG1BVDFXQWtJaGNVK2QwMHJlVlYxV0wxMUk1cTFreGpYU2hZUEhhN0VtWHhBRmExS3p5RHNNUTVnY24vcGd0WC9wV3ZwU1NiYmdocTlwaWlOY1NIVFJhY0labEFWTFBldldNMCtBcW5FWkVPMkpJVnh5SGpmOU9GRzc2b3JLMlBlcVdiL2c1S29URERGQk1xdXdFS3c3ZUhVY1NqOXBpVDRwblhBZjJyOXhPUkpsZjlZY05VdEc5YlFKc3VLcW5sVlVPOTBrMXZnbExpN0orVzl4N1Z2c0hadEdlcUN6eVdvVk82a0Y3dk5hcHZjNUlBOU1TamZHYXBOODNYdmk5bXZZd25qVGY5QlFRZ3R4M3g0TkFuRDUvaVYrQlVWb01KdjgvVXF3VVBCNERMWWNTakxsZXFUYy9hTklDdnBlb3dOMTE1OG4wSVNETWl5a2JCbjZOdmFMemtaQjI4US9EdEg3RURKcHRETTkrRng0TUMxMmo2UEw3bDYwKytRR05sbTM1UFBLL0dYd1AvMXZTMm9nQjhENWVIUGozc2k4NW9QU0FHZk0zMmVJKzBLNERzVHl5QUVqYWZZNm9Kb1RiNjMvVFByZDk2OG9rbm5uaE9LL0cyejZickRUMEdhdlpyK0VGdEJDU09DRUxBSjloelBsVUJMMGNFZW11Sjc0Y2pUNE9ITTBsRFlqamdyY1g3bDQ0NndxRzRhYjcySGI2MnhMTzBWYjdwK3FoV21VdTR3WWxaVXlTN2hZdkczd0F3NEp1L2JQQW9pQ01laWU2NUVDckVJUHd5YnBIT1BXSW5maUJpa2gvYlhZSE45ZEU3VHoxQnZhYkYva3hyMy83Zyt4UlFoVWNXMWpVcDlmUlIyL0FxK0J6RndlaW5hQTBIQ0RJaWlmU1h1NklJb210bitGUmZEcDBDR2VnRkx4dDFLakFjRzFxdkFxMlZiL285ZCsyTEgzeHY1djBSeUZjTDVjcmZ4TUVKQUhCVFEwUmhKdnZwekxWRHFoQUJPcnF6eWhNbFZvRE4rQVV2RzNVdW81YVBlaE1IeXpmOTRsKytOZ3UyZ3pxT0tFcVVmNm1sSGZFakdmM2tZV29Ic0ZVV2pILzlweUN4cWFFUTlZcjQrbVZ1bXErbFNyVnBQVkdnNStUZjA4b3VSNVJaV1RjSVNFUW1Pc1hIQU5XQnNCOGJES0JWa2swL3I2VXFmN3l5TU1XTWxHYlRuSUV3UlRsWTM4U3phZVFkc3Z0YVd3aXpOeHNBanVMNWlISmZJaDVWT0tBbWE2azNXSnQrcGYzS2ZQejllSlZOSXh1amlKeUJBNEZPK2krMCtWNWpVNmIwL1RCK1dvMzF2Z204MCtpRW8xTHhwekVlK2VnSmhtelRmTzNpZkhDN2pvTlRvSFRzVFRRK2M3YURSdzJmZDVOWFdrbDJrQXFYaVdndGZqT2pJeExSVzhFdEV3ZkxIaFdIeDZXQngyS2FLOTkwMDduNVFLVTgwUFBwd2xSRDNYRHhBTllQendTdjVObzFkRHBkamFqVDRIRTJvYTVHdUdNeWJBWmUzeWJOOVBwbVRicGVBZXgwWW15b2VOcEhKMldEeU5rN0xpYWFGM2NZRUs1SjNRNG02OVk4MWl0WXR1ay9OYm9HbUdUVGx5QVF6c3Y3ajJZN1hLQ095OXAvOURJSGFoeFpPemVlZFVEZ3BNRm8wOC9VL014b3ZBSFlkV253STJ1eUZxdjRCTy9wbXQyTUpYNERERzk2a2hNZVdkY3E0K0JYbjNpNmVqZUZyeE9mTWxQcjRSRTJIaitURy9xUkVaRnUycm5RTEpwNUJ4NWxBOFhhV2dOM3UvQzNpV1didnJkUTdMMEVqN1pqM3pXczFYVGdwdnZBdTRpREo0Q1U4OGpDU2VhVTdVNTRuSXhtYlJweHdtTkdzdW5qOFBpVGJQb1FsQUY0MHhlaERQak5TSTJHc29BYmpSL0hsd1VYQjR1OUs2Q011UEdyZTgrN1hGQm0zTHB4NDVZVEhpdi9Cb3VZU0s5WVRUVG5BQUFBQUVsRlRrU3VRbUNDJzsKCWlmIChsb2dvKSB7CgkJbG9nbyA9IGxvZ28uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2ltZycpWzBdOwoJCWlmICghbG9nbykgcmV0dXJuOwoJCWxvZ28uc3JjID0gYWx0X3NyYzsKCX0KfSgpKTsKPC9zY3JpcHQ+PC9kaXY+PGRpdiBpZD0ib3ZlcmxheSI+PC9kaXY+PC9kaXY+PGZvb3RlciBkYXRhLXFhPSJmb290ZXIiPjxzZWN0aW9uIGNsYXNzPSJsaW5rcyI+PGRpdiBjbGFzcz0iZ3JpZCI+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF8xIj5Vc2luZyBTbGFjazwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2lzIiBkYXRhLXFhPSJwcm9kdWN0X2Zvb3RlciIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3Byb2R1Y3QiPlByb2R1Y3Q8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vZW50ZXJwcmlzZSIgZGF0YS1xYT0iZW50ZXJwcmlzZV9mb290ZXIiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9lbnRlcnByaXNlIj5FbnRlcnByaXNlPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaWNpbmc/dWlfc3RlcD0yOCZhbXA7dWlfZWxlbWVudD01IiBkYXRhLXFhPSJwcmljaW5nX2Zvb3RlciIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3ByaWNpbmciPlByaWNpbmc8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9nZXQuc2xhY2suaGVscC9oYy9lbi11cyIgZGF0YS1xYT0ic3VwcG9ydF9mb290ZXIiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zdXBwb3J0Ij5TdXBwb3J0PC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2d1aWRlcyIgZGF0YS1xYT0iZ2V0dGluZ19zdGFydGVkIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZ2V0dGluZ19zdGFydGVkIj5TbGFjayBHdWlkZXM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vYXBwcyIgZGF0YS1xYT0iYXBwX2RpcmVjdG9yeSIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2FwcF9kaXJlY3RvcnkiPkFwcCBEaXJlY3Rvcnk8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9hcGkuc2xhY2suY29tLyIgZGF0YS1xYT0iYXBpIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfYXBpIj5BUEk8L2E+PC9saT48L3VsPjwvZGl2PjxkaXYgY2xhc3M9ImNvbCBzcGFuXzFfb2ZfNCBuYXZfY29sIj48dWw+PGxpIGNsYXNzPSJjYXRfMiI+U2xhY2sgPHRzLWljb24gY2xhc3M9InRzX2ljb25faGVhcnQiPjwvdHMtaWNvbj48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9qb2JzIiBkYXRhLXFhPSJqb2JzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfam9icyI+Sm9iczwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9jdXN0b21lcnMiIGRhdGEtcWE9ImN1c3RvbWVycyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2N1c3RvbWVycyI+Q3VzdG9tZXJzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2RldmVsb3BlcnMiIGRhdGEtcWE9ImRldmVsb3BlcnMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9kZXZlbG9wZXJzIj5EZXZlbG9wZXJzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2V2ZW50cyIgZGF0YS1xYT0iZXZlbnRzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZXZlbnRzIj5FdmVudHM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFja2hxLmNvbS8iIGRhdGEtcWE9ImJsb2dfZm9vdGVyIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfYmxvZyI+QmxvZzwvYT48L2xpPjwvdWw+PC9kaXY+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF8zIj5MZWdhbDwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3ByaXZhY3ktcG9saWN5IiBkYXRhLXFhPSJwcml2YWN5IiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfcHJpdmFjeSI+UHJpdmFjeTwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9zZWN1cml0eSIgZGF0YS1xYT0ic2VjdXJpdHkiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zZWN1cml0eSI+U2VjdXJpdHk8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly9zbGFjay5jb20vdGVybXMtb2Ytc2VydmljZSIgZGF0YS1xYT0idG9zIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfdG9zIj5UZXJtcyBvZiBTZXJ2aWNlPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL3BvbGljaWVzIiBkYXRhLXFhPSJwb2xpY2llcyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX3BvbGljaWVzIj5Qb2xpY2llczwvYT48L2xpPjwvdWw+PC9kaXY+PGRpdiBjbGFzcz0iY29sIHNwYW5fMV9vZl80IG5hdl9jb2wiPjx1bD48bGkgY2xhc3M9ImNhdF80Ij5IYW5keSBMaW5rczwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2Rvd25sb2FkcyIgZGF0YS1xYT0iZG93bmxvYWRzIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfZG93bmxvYWRzIj5Eb3dubG9hZCBkZXNrdG9wIGFwcDwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbS9kb3dubG9hZHMiIGRhdGEtcWE9ImRvd25sb2Fkc19tb2JpbGUiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9kb3dubG9hZHNfbW9iaWxlIj5Eb3dubG9hZCBtb2JpbGUgYXBwPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2JyYW5kLWd1aWRlbGluZXMiIGRhdGEtcWE9ImJyYW5kX2d1aWRlbGluZXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9icmFuZF9ndWlkZWxpbmVzIj5CcmFuZCBHdWlkZWxpbmVzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2thdHdvcmsuY29tIiBkYXRhLXFhPSJzbGFja19hdF93b3JrIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfYXRfd29yayI+U2xhY2sgYXQgV29yazwvYT48L2xpPjxsaT48YSBocmVmPSJodHRwczovL3N0YXR1cy5zbGFjay5jb20vIiBkYXRhLXFhPSJzdGF0dXMiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zdGF0dXMiPlN0YXR1czwvYT48L2xpPjwvdWw+PC9kaXY+PC9kaXY+PC9zZWN0aW9uPjxkaXYgY2xhc3M9ImZvb3Rub3RlIj48c2VjdGlvbj48YSBocmVmPSJodHRwczovL3NsYWNrLmNvbSIgYXJpYS1sYWJlbD0iU2xhY2sgaG9tZXBhZ2UiIGRhdGEtY2xvZy1ldmVudD0iV0VCU0lURV9DTElDSyIgZGF0YS1jbG9nLXBhcmFtcz0iY2xpY2tfdGFyZ2V0PWZvb3Rlcl9zbGFja19pY29uIj48dHMtaWNvbiBjbGFzcz0iYy1pY29uLS1zbGFjayIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48dWw+PGxpPjxhIGhyZWY9Imh0dHBzOi8vc2xhY2suY29tL2hlbHAvY29udGFjdCIgZGF0YS1xYT0iY29udGFjdF91cyIgZGF0YS1jbG9nLWV2ZW50PSJXRUJTSVRFX0NMSUNLIiBkYXRhLWNsb2ctcGFyYW1zPSJjbGlja190YXJnZXQ9Zm9vdGVyX2NvbnRhY3RfdXMiPkNvbnRhY3QgVXM8L2E+PC9saT48bGk+PGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9TbGFja0hRIiBkYXRhLXFhPSJzbGFja190d2l0dGVyIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfdHdpdHRlciIgYXJpYS1sYWJlbD0iU2xhY2sgb24gVHdpdHRlciI+PHRzLWljb24gY2xhc3M9InRzX2ljb25fdHdpdHRlciIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48L2xpPjxsaSBjbGFzcz0ieXQiPjxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNZM1lFQ2dlQmNMQ3pJckZMUDRnYmx3IiBkYXRhLXFhPSJzbGFja195b3V0dWJlIiBkYXRhLWNsb2ctZXZlbnQ9IldFQlNJVEVfQ0xJQ0siIGRhdGEtY2xvZy1wYXJhbXM9ImNsaWNrX3RhcmdldD1mb290ZXJfc2xhY2tfeW91dHViZSIgYXJpYS1sYWJlbD0iU2xhY2sgb24gWW91VHViZSI+PHRzLWljb24gY2xhc3M9InRzX2ljb25feW91dHViZSIgYXJpYS1oaWRkZW4+PC90cy1pY29uPjwvYT48L2xpPjwvdWw+PC9zZWN0aW9uPjwvZGl2PjwvZm9vdGVyPjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KLyoqCiAqIEEgcGxhY2Vob2xkZXIgZnVuY3Rpb24gdGhhdCB0aGUgYnVpbGQgc2NyaXB0IHVzZXMgdG8KICogcmVwbGFjZSBmaWxlIHBhdGhzIHdpdGggdGhlaXIgQ0ROIHZlcnNpb25zLgogKgogKiBAcGFyYW0ge1N0cmluZ30gZmlsZV9wYXRoIC0gRmlsZSBwYXRoCiAqIEByZXR1cm5zIHtTdHJpbmd9CiAqLwpmdW5jdGlvbiB2dnYoZmlsZV9wYXRoKSB7CgkJIHZhciB2dnZfd2FybmluZyA9ICdZb3UgY2Fubm90IHVzZSB2dnYgb24gZHluYW1pYyB2YWx1ZXMuIFBsZWFzZSBtYWtlIHN1cmUgeW91IG9ubHkgcGFzcyBpbiBzdGF0aWMgZmlsZSBwYXRocy4nOyBpZiAod2luZG93LlRTICYmIHdpbmRvdy5UUy53YXJuKSB7IHdpbmRvdy5UUy53YXJuKHZ2dl93YXJuaW5nKTsgfSBlbHNlIHsgY29uc29sZS53YXJuKHZ2dl93YXJuaW5nKTsgfSAKCXJldHVybiBmaWxlX3BhdGg7Cn0KCnZhciBjZG5fdXJsID0gImh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tIjsKdmFyIHZ2dl9hYnNfdXJsID0gImh0dHBzOlwvXC9zbGFjay5jb21cLyI7CnZhciBpbmNfanNfc2V0dXBfZGF0YSA9IHsKCWVtb2ppX3NoZWV0czogewoJCWFwcGxlOiAnaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L2ltZy9lbW9qaV8yMDE3XzEyXzA2L3NoZWV0X2FwcGxlXzY0X2luZGV4ZWRfMjU2LnBuZycsCgkJZ29vZ2xlOiAnaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tLzgwNTg4L2ltZy9lbW9qaV8yMDE3XzEyXzA2L3NoZWV0X2dvb2dsZV82NF9pbmRleGVkXzI1Ni5wbmcnLAoJfSwKfTsKPC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgkvLyBjb21tb24gYm9vdF9kYXRhCgl2YXIgYm9vdF9kYXRhID0geyJhcGlfdXJsIjoiXC9hcGlcLyIsImFwcCI6IndlYiIsInVzZXJfaWQiOm51bGwsInRlYW1faWQiOiJUMDAwMDAwMDAiLCJ2aXNpdG9yX3VpZCI6IjZxdXB3cTg0ZjRnNTBpZmVkMjcwejRhZG0iLCJub19sb2dpbiI6dHJ1ZSwidmVyc2lvbl90cyI6IjE2MDIxOTk3ODMiLCJ2ZXJzaW9uX3VpZCI6IjU3MDNhYWI2MjNjNGY3ZTk2NTU5NTQ0OGZjMDAzYTc4NmE5MmI4MTMiLCJjYWNoZV92ZXJzaW9uIjoidjIxLW5vbWFkIiwiY2FjaGVfdHNfdmVyc2lvbiI6InYyLWJ1bm55IiwicmVkaXJfZG9tYWluIjoic2xhY2stcmVkaXIubmV0Iiwic2lnbmluX3VybCI6Imh0dHBzOlwvXC9zbGFjay5jb21cL3NpZ25pbiIsImFic19yb290X3VybCI6Imh0dHBzOlwvXC9zbGFjay5jb21cLyIsInRlYW1fdXJsIjoiIiwiaW1hZ2VfcHJveHlfdXJsIjoiaHR0cHM6XC9cL3NsYWNrLWltZ3MuY29tXC8iLCJiZWFjb25fdGltaW5nX3VybCI6Imh0dHBzOlwvXC9zbGFjay5jb21cL2JlYWNvblwvdGltaW5nIiwiYmVhY29uX2Vycm9yX3VybCI6Imh0dHBzOlwvXC9zbGFjay5jb21cL2JlYWNvblwvZXJyb3IiLCJjbG9nX3VybCI6ImNsb2dcL3RyYWNrXC8iLCJhcGlfdG9rZW4iOiIiLCJ2dnZfcGF0aHMiOnsibHpfc3RyaW5nIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cL2J2MS04XC9sei1zdHJpbmctMS40LjQud29ya2VyLjhkZTFiMDBkNjcwZmYzZGM3MDZhMC5qcyIsImNvZGVtaXJyb3IiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvYnYxLThcL2NvZGVtaXJyb3IubWluLjUyNmY5MzY5MjRlZWYxOGYwMGJiLm1pbi5qcyIsImNvZGVtaXJyb3JfYWRkb25fc2ltcGxlIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cL2J2MS04XC9jb2RlbWlycm9yX3NpbXBsZS45YmM3NmJiMzI2MGE1ZWQwZTVkYy5taW4uanMiLCJjb2RlbWlycm9yX2xvYWQiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvYnYxLThcL2NvZGVtaXJyb3JfbG9hZC5mMWEzN2Y0ZTQ4NmIyYzIyMTA1Yi5taW4uanMiLCJjb2RlbWlycm9yX2ZpbGVzIjp7ImphdmFzY3JpcHQiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvYnYxLThcL2NvZGVtaXJyb3JfbGFuZ19qYXZhc2NyaXB0LmIyOTVlZjg3NmVlZGFmZTgzYjM5Lm1pbi5qcyJ9fSwibm90aWZpY2F0aW9uX3NvdW5kcyI6W3sidmFsdWUiOiJiMi5tcDMiLCJsYWJlbCI6IkRpbmciLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2U5MVwvc291bmRzXC9wdXNoXC9iMi5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2IyLm9nZyJ9LHsidmFsdWUiOiJhbmltYWxfc3RpY2subXAzIiwibGFiZWwiOiJCb2luZyIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2FuaW1hbF9zdGljay5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2FuaW1hbF9zdGljay5vZ2cifSx7InZhbHVlIjoiYmVlbl90cmVlLm1wMyIsImxhYmVsIjoiRHJvcCIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2JlZW5fdHJlZS5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2JlZW5fdHJlZS5vZ2cifSx7InZhbHVlIjoiY29tcGxldGVfcXVlc3RfcmVxdWlyZW1lbnQubXAzIiwibGFiZWwiOiJUYS1kYSIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2NvbXBsZXRlX3F1ZXN0X3JlcXVpcmVtZW50Lm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvY29tcGxldGVfcXVlc3RfcmVxdWlyZW1lbnQub2dnIn0seyJ2YWx1ZSI6ImNvbmZpcm1fZGVsaXZlcnkubXAzIiwibGFiZWwiOiJQbGluayIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2NvbmZpcm1fZGVsaXZlcnkubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9jb25maXJtX2RlbGl2ZXJ5Lm9nZyJ9LHsidmFsdWUiOiJmbGl0dGVyYnVnLm1wMyIsImxhYmVsIjoiV293IiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvZmxpdHRlcmJ1Zy5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL2ZsaXR0ZXJidWcub2dnIn0seyJ2YWx1ZSI6ImhlcmVfeW91X2dvX2xpZ2h0ZXIubXAzIiwibGFiZWwiOiJIZXJlIHlvdSBnbyIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2hlcmVfeW91X2dvX2xpZ2h0ZXIubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9oZXJlX3lvdV9nb19saWdodGVyLm9nZyJ9LHsidmFsdWUiOiJoaV9mbG93ZXJzX2hpdC5tcDMiLCJsYWJlbCI6IkhpIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvaGlfZmxvd2Vyc19oaXQubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9oaV9mbG93ZXJzX2hpdC5vZ2cifSx7InZhbHVlIjoia25vY2tfYnJ1c2gubXAzIiwibGFiZWwiOiJLbm9jayBCcnVzaCIsInVybCI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC83ZTkxXC9zb3VuZHNcL3B1c2hcL2tub2NrX2JydXNoLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwva25vY2tfYnJ1c2gub2dnIn0seyJ2YWx1ZSI6InNhdmVfYW5kX2NoZWNrb3V0Lm1wMyIsImxhYmVsIjoiV2hvYSEiLCJ1cmwiOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvN2U5MVwvc291bmRzXC9wdXNoXC9zYXZlX2FuZF9jaGVja291dC5tcDMiLCJ1cmxfb2dnIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzQ2ZWJiXC9zb3VuZHNcL3B1c2hcL3NhdmVfYW5kX2NoZWNrb3V0Lm9nZyJ9LHsidmFsdWUiOiJpdGVtX3BpY2t1cC5tcDMiLCJsYWJlbCI6IllvaW5rIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdlOTFcL3NvdW5kc1wvcHVzaFwvaXRlbV9waWNrdXAubXAzIiwidXJsX29nZyI6Imh0dHBzOlwvXC9hLnNsYWNrLWVkZ2UuY29tXC80NmViYlwvc291bmRzXC9wdXNoXC9pdGVtX3BpY2t1cC5vZ2cifSx7InZhbHVlIjoiaHVtbXVzLm1wMyIsImxhYmVsIjoiSHVtbXVzIiwidXJsIjoiaHR0cHM6XC9cL2Euc2xhY2stZWRnZS5jb21cLzdmYTlcL3NvdW5kc1wvcHVzaFwvaHVtbXVzLm1wMyIsInVybF9vZ2ciOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvNDZlYmJcL3NvdW5kc1wvcHVzaFwvaHVtbXVzLm9nZyJ9LHsidmFsdWUiOiJub25lIiwibGFiZWwiOiJOb25lIn1dLCJhbGVydF9zb3VuZHMiOlt7InZhbHVlIjoiZnJvZy5tcDMiLCJsYWJlbCI6IkZyb2ciLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC9hMzRhXC9zb3VuZHNcL2Zyb2cubXAzIn1dLCJjYWxsX3NvdW5kcyI6W3sidmFsdWUiOiJjYWxsXC9hbGVydF92Mi5tcDMiLCJsYWJlbCI6IkFsZXJ0IiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC9hbGVydF92Mi5tcDMifSx7InZhbHVlIjoiY2FsbFwvaW5jb21pbmdfcmluZ192Mi5tcDMiLCJsYWJlbCI6IkluY29taW5nIHJpbmciLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL2luY29taW5nX3JpbmdfdjIubXAzIn0seyJ2YWx1ZSI6ImNhbGxcL291dGdvaW5nX3JpbmdfdjIubXAzIiwibGFiZWwiOiJPdXRnb2luZyByaW5nIiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC9vdXRnb2luZ19yaW5nX3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC9wb3BfdjIubXAzIiwibGFiZWwiOiJJbmNvbWluZyByZWFjdGlvbiIsInVybCI6Imh0dHBzOlwvXC9zbGFjay5nbG9iYWwuc3NsLmZhc3RseS5uZXRcLzA4ZjdcL3NvdW5kc1wvY2FsbFwvcG9wX3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC90aGV5X2xlZnRfY2FsbF92Mi5tcDMiLCJsYWJlbCI6IlRoZXkgbGVmdCBjYWxsIiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC90aGV5X2xlZnRfY2FsbF92Mi5tcDMifSx7InZhbHVlIjoiY2FsbFwveW91X2xlZnRfY2FsbF92Mi5tcDMiLCJsYWJlbCI6IllvdSBsZWZ0IGNhbGwiLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL3lvdV9sZWZ0X2NhbGxfdjIubXAzIn0seyJ2YWx1ZSI6ImNhbGxcL3RoZXlfam9pbmVkX2NhbGxfdjIubXAzIiwibGFiZWwiOiJUaGV5IGpvaW5lZCBjYWxsIiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC90aGV5X2pvaW5lZF9jYWxsX3YyLm1wMyJ9LHsidmFsdWUiOiJjYWxsXC95b3Vfam9pbmVkX2NhbGxfdjIubXAzIiwibGFiZWwiOiJZb3Ugam9pbmVkIGNhbGwiLCJ1cmwiOiJodHRwczpcL1wvc2xhY2suZ2xvYmFsLnNzbC5mYXN0bHkubmV0XC8wOGY3XC9zb3VuZHNcL2NhbGxcL3lvdV9qb2luZWRfY2FsbF92Mi5tcDMifSx7InZhbHVlIjoiY2FsbFwvY29uZmlybWF0aW9uX3YyLm1wMyIsImxhYmVsIjoiQ29uZmlybWF0aW9uIiwidXJsIjoiaHR0cHM6XC9cL3NsYWNrLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldFwvMDhmN1wvc291bmRzXC9jYWxsXC9jb25maXJtYXRpb25fdjIubXAzIn1dLCJjYWxsX3NvdW5kc192ZXJzaW9uIjoidjIiLCJpbWciOnsiYXBwX2ljb24iOiJodHRwczpcL1wvYS5zbGFjay1lZGdlLmNvbVwvODA1ODhcL2ltZ1wvc2xhY2tfZ3Jvd2xfaWNvbl92b2d1ZS5wbmcifSwicGFnZV9uZWVkc19lbnRlcnByaXNlIjpmYWxzZSwicGFnZV9uZWVkc19jdXN0b21fZW1vamkiOmZhbHNlLCJpc19kZXByZWNhdGVkX3dlYmNsaWVudF9icm93c2VyIjpmYWxzZSwiaXNfdW5zdXBwb3J0ZWRfd2ViY2xpZW50X2Jyb3dzZXIiOnRydWUsImRlZmF1bHRfdHoiOiJBbWVyaWNhXC9Mb3NfQW5nZWxlcyIsImZlYXR1cmVfZGlzcGxheV9lbWFpbF9hZGRyZXNzZXNfdG9fcmFkaW8iOmZhbHNlLCJmZWF0dXJlX2ljb25fYnV0dG9uX2FyaWFfbGFiZWxfaTE4biI6ZmFsc2UsImZlYXR1cmVfYWx0X2NoYW5uZWxzX3JlZHVjZXIiOmZhbHNlLCJmZWF0dXJlX2pzZl8xNjE5Ijp0cnVlLCJmZWF0dXJlX2Rlc2t0b3BfbGF6eV9sb2FkX2Vtb2ppIjpmYWxzZSwiZmVhdHVyZV9lZHVfODhfZ2EiOmZhbHNlLCJmZWF0dXJlX2V4cG9ydF9wcmVmX3RvX2Rpc2FibGUiOmZhbHNlLCJmZWF0dXJlX2FkZF9tZW1iZXJfc3RhdHNfYXBpIjpmYWxzZSwiZmVhdHVyZV9tZW1iZXJfYW5hbHl0aWNzX3Blcm1pc3Npb25zIjpmYWxzZSwiZmVhdHVyZV9idWxrX3VzZXJfcmVhY3RpdmF0aW9uX2dyaWQiOnRydWUsImZlYXR1cmVfYnVpbGRlcl9tdWx0aXN0ZXBfY29sbGFib3JhdG9yc19tb2RhbCI6ZmFsc2UsImZlYXR1cmVfYnVpbGRlcl9hbGxvd19jdXN0b21fdGltZV9zY2hlZHVsZWRfdHJpZ2dlciI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX3NjaGVkdWxlZF90cmlnZ2VyIjp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfbWVzc2FnZV9idXR0b25faGVscGVyX3RleHQiOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfY3JlYXRpb25fb3JnX3BvbGljeSI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX2V4dGVuc2lvbnMiOnRydWUsImZlYXR1cmVfYnVpbGRlcl9leHRlbnNpb25fc3RlcHNfcHJlZiI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX2FjY2Vzc19lcnJvcl9jb250ZW50IjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX3BhZ2luYXRlX3dvcmtmbG93c19saXN0IjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX3N0ZXBfbGlicmFyeSI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX3RlYW1fYXBwc190cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2J1aWxkZXJfYXBwc19jb2xsZWN0aW9uX2xpbmsiOmZhbHNlLCJmZWF0dXJlX2FwcHNfY2FuX3N1Ym1pdF93aXRoX3dvcmtmbG93X3N0ZXBzIjp0cnVlLCJmZWF0dXJlX2J1aWxkZXJfZmVlZGJhY2tfYnV0dG9uIjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX21lc3NhZ2Vfc3RlcF9yaWNoX3RleHQiOnRydWUsImZlYXR1cmVfY2hpbWVfYWNjZXNzX2NoZWNrIjp0cnVlLCJmZWF0dXJlX2FwcF92aWV3c192MSI6dHJ1ZSwiZmVhdHVyZV9hdWRpdF9sb2dzX3ZpZXciOmZhbHNlLCJmZWF0dXJlX2F1ZGl0X2xvZ3Nfdmlld193b3Jrc3BhY2UiOmZhbHNlLCJmZWF0dXJlX29yZ190ZWFtc19pbl9sb2NhbF9jb25maWciOnRydWUsImZlYXR1cmVfZGF0YV9sb2NhdGlvbl9uZXdfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9kZWZhdWx0X2Jyb3dzZXJfY29udHJvbF92MiI6dHJ1ZSwiZmVhdHVyZV9hY2Nlc3NpYmxlX3NlbGVjdHMiOnRydWUsImZlYXR1cmVfc2VsZWN0X29uX3RhYiI6dHJ1ZSwiZmVhdHVyZV9wcm9ub3Vuc19pbl9wcm9maWxlIjpmYWxzZSwiZmVhdHVyZV9idWlsZGVyX2Rpc2FibGVfZ2xvYmFsX3RyaWdnZXJzIjp0cnVlLCJmZWF0dXJlX3dvcmtmbG93X2J1aWxkZXJfZW5hYmxlZF9vcmdfc2V0dGluZyI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX2Nhbl9hY2Nlc3MiOmZhbHNlLCJmZWF0dXJlX2Fsd2F5c19zaG93X2FyY2hpdmVfY2hhbm5lbF9vcHRpb24iOnRydWUsImZlYXR1cmVfb3JnX2Rhc2hib2FyZF9nYW50cnlfYWNjZXNzIjpmYWxzZSwiZmVhdHVyZV9vcmdfZGFzaF9nYW50cnlfcmVkaXJlY3QiOmZhbHNlLCJmZWF0dXJlX29yZ19kYXNoYm9hcmRfZ2FudHJ5X2FwcHNfbWlncmF0aW9uIjpmYWxzZSwiZmVhdHVyZV9pbmZvX2JhcnJpZXJzIjpmYWxzZSwiZmVhdHVyZV9kYXkyX3NoYXJlX21vZGFsIjpmYWxzZSwiZmVhdHVyZV9ncmFudWxhcl9kbmQiOmZhbHNlLCJmZWF0dXJlX2N1c3RvbV9kbmRfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV9pbmZvcm1hdGl2ZV9hbm5vdW5jZV9vbmx5X2Zvb3Rlcl90cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2NvbnRleHRfYmFyX3R6X2lzc3VlcyI6ZmFsc2UsImZlYXR1cmVfbmV3eHBfNDQwMSI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80MjgxIjp0cnVlLCJmZWF0dXJlX25ld3hwXzM4NDgiOnRydWUsImZlYXR1cmVfZGF5MV9jb252byI6dHJ1ZSwiZmVhdHVyZV9kYXkxX2NvbWZ5X3NpZGViYXJfY29weSI6ZmFsc2UsImZlYXR1cmVfZGF5MV9jcmVhdG9yX2xhbmRpbmdfY29weSI6ZmFsc2UsImZlYXR1cmVfY2hhbm5lbF9icm93c2VyX2RheTEiOnRydWUsImZlYXR1cmVfYmFubmVyX2FwcF9yZWNzIjp0cnVlLCJmZWF0dXJlX2NvcHlfam9pbmVyX2Zsb3ciOnRydWUsImZlYXR1cmVfYXBwcm92ZWRfb3JncyI6ZmFsc2UsImZlYXR1cmVfbmV3eHBfMzI3OSI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80MTYwIjp0cnVlLCJmZWF0dXJlX25ld3hwXzQxNTMiOnRydWUsImZlYXR1cmVfbmV3eHBfNDIwMiI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80MzEzIjpmYWxzZSwiZmVhdHVyZV90aW55c3BlY2siOmZhbHNlLCJmZWF0dXJlX3FyX2NvZGVfaW52aXRlIjpmYWxzZSwiZmVhdHVyZV9nZW5lcmF0ZV9saWdodHdlaWdodF9kbV9saW5rIjpmYWxzZSwiZmVhdHVyZV9jb25uZWN0X2RtX2Vhcmx5X2FjY2VzcyI6dHJ1ZSwiZmVhdHVyZV9vbHVnX2VzY19jaGFubmVsc193b3JrIjp0cnVlLCJmZWF0dXJlX29sdWdfcmVtb3ZlX3JlcXVpcmVkX3dvcmtzcGFjZV9zZXR0aW5nIjpmYWxzZSwiZmVhdHVyZV9kYXRhX3RhYmxlX2luX29yZ19sZXZlbF91c2VyX2dyb3VwcyI6ZmFsc2UsImZlYXR1cmVfb3JnX3NldHRpbmdzX20xMW4iOmZhbHNlLCJmZWF0dXJlX2RlcHJlY2F0ZV9nZXRfbWVtYmVyX2J5X25hbWUiOmZhbHNlLCJmZWF0dXJlX3Vua25vd25fZmlsZXMiOnRydWUsImZlYXR1cmVfdW5rbm93bl9tZXNzYWdlcyI6dHJ1ZSwiZmVhdHVyZV9hZGRfbWVzc2FnZV9wZXJmIjpmYWxzZSwiZmVhdHVyZV9maXhfY3VzdG9tX2Vtb2ppX2Vycm9ycyI6dHJ1ZSwiZmVhdHVyZV9tb2Rlcm5fZGVsZXRlX2ZpbGUiOnRydWUsImZlYXR1cmVfY29weV9jaGFubmVsX2xpbmsiOnRydWUsImZlYXR1cmVfY29sbGFwc2VfcmVhY3Rpb25zIjpmYWxzZSwiZmVhdHVyZV9pYV9zdGF0dXNfYnV0dG9uIjp0cnVlLCJmZWF0dXJlX2Z1bGxfcHJvZmlsZV9saW5rIjp0cnVlLCJmZWF0dXJlX3ByaW50X3BkZiI6ZmFsc2UsImZlYXR1cmVfc2FmYXJpMTBfZGVwcmVjYXRpb24iOnRydWUsImZlYXR1cmVfc2FmYXJpMTBfZGVwcmVjYXRpb25fbW9kYWwiOnRydWUsImZlYXR1cmVfc2FmYXJpMTBfZGVwcmVjYXRpb25fYmxvY2siOmZhbHNlLCJmZWF0dXJlX2Rlc2t0b3A0NjBfZGVwcmVjYXRpb24iOmZhbHNlLCJmZWF0dXJlX2Rlc2t0b3A0NjBfZGVwcmVjYXRpb25fYmxvY2siOmZhbHNlLCJmZWF0dXJlX2VtYWlsX3dvcmtmbG93IjpmYWxzZSwiZmVhdHVyZV93aWRlcl9yZWFjdGlvbl90aXAiOmZhbHNlLCJmZWF0dXJlX2ZpbGVfcGlja2VyX3NlYXJjaCI6ZmFsc2UsImZlYXR1cmVfc29ydF9ieV9yZWNlbmN5X3Bvc3RfdjEiOmZhbHNlLCJmZWF0dXJlX3NlbmRfZmFpbGVkX3RvYXN0IjpmYWxzZSwiZmVhdHVyZV9hdWRpb19wbGF5ZXIiOmZhbHNlLCJmZWF0dXJlX2VhZ2VybHlfbWFya19icm9hZGNhc3RzIjpmYWxzZSwiZmVhdHVyZV9zaG93X3JlcGxpZXNfaW1tZWRpYXRlbHkiOmZhbHNlLCJmZWF0dXJlX2NvbXBvc2VyX2VzY2FwZV9oYXRjaCI6ZmFsc2UsImZlYXR1cmVfY29tcG9zZXJfZW1haWxfY2xhc3NpZmljYXRpb24iOmZhbHNlLCJmZWF0dXJlX2FtYXpvbl9hMTF5X2N1c3RvbV9zdGF0dXNfZW1vamkiOnRydWUsImZlYXR1cmVfYnllX3NsYWNrYm90X2hlbHAiOnRydWUsImZlYXR1cmVfYWxsX2RtX211dGVfYm90cyI6dHJ1ZSwiZmVhdHVyZV9maWxlX3RocmVhZHMiOnRydWUsImZlYXR1cmVfYnJvYWRjYXN0X2luZGljYXRvciI6dHJ1ZSwiZmVhdHVyZV9uZXdfcmVwbGllc19hZnRlcl9iY2FzdCI6dHJ1ZSwiZmVhdHVyZV9zb25pY19lbW9qaSI6dHJ1ZSwiZmVhdHVyZV9lbW9qaV8xMiI6ZmFsc2UsImZlYXR1cmVfZW1haWxfaW5nZXN0aW9uIjpmYWxzZSwiZmVhdHVyZV9hdHRhY2htZW50c19pbmxpbmUiOmZhbHNlLCJmZWF0dXJlX2ZpeF9maWxlcyI6dHJ1ZSwiZmVhdHVyZV9hYWFfYWRtaW5fYXBpcyI6dHJ1ZSwiZmVhdHVyZV9yZW1vdmVfYWN0aW9uc19mcm9tX3NpZGViYXIiOmZhbHNlLCJmZWF0dXJlX3Nob3J0Y3V0c192Ml9lZHVjYXRpb24iOnRydWUsImZlYXR1cmVfcGFkXzE1MzQiOmZhbHNlLCJmZWF0dXJlX3Nob3J0Y3V0c19tZW51X2NsZWFudXBfaTE4biI6ZmFsc2UsImZlYXR1cmVfYXBwX2xhdW5jaGVyX2FkZF9pY29uIjpmYWxzZSwiZmVhdHVyZV9hcHBfbGF1bmNoZXJfYmFubmVycyI6ZmFsc2UsImZlYXR1cmVfYXBwX2xhdW5jaGVyX3NlYXJjaF9wYWdpbmF0aW9uIjpmYWxzZSwiZmVhdHVyZV9jaGFubmVsX3NpZGViYXJfZHJhZnRzX3NlY3Rpb24iOnRydWUsImZlYXR1cmVfbmF2aWdhdGVfaGlzdG9yeSI6dHJ1ZSwiZmVhdHVyZV9pMThuX2RyYWZ0cyI6ZmFsc2UsImZlYXR1cmVfY29tcG9zZXJfdXJhX21wZG0iOmZhbHNlLCJmZWF0dXJlX3JlY2VudF9zdGF0dXNfZGVsZXRlIjpmYWxzZSwiZmVhdHVyZV9jb21wb3NlX2Zsb3ciOmZhbHNlLCJmZWF0dXJlX2NvbXBvc2VfZmxvd194d3MiOnRydWUsImZlYXR1cmVfZmFzdGVyX2NvdW50X2FsbF91bnJlYWRzIjp0cnVlLCJmZWF0dXJlX3NvbmljX3VzZXJfZ3JvdXBzIjpmYWxzZSwiZmVhdHVyZV9jaGFubmVsX3NlbGVjdG9yX2Zvcl90ZWFtX2d1ZXN0c191cGRhdGUiOmZhbHNlLCJmZWF0dXJlX3NrX2RhdGFfdGFibGVfYTExeSI6ZmFsc2UsImZlYXR1cmVfc2tfZGF0YV90YWJsZV9waW5uZWRfcm93c19hbmRfY29sdW1ucyI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcF9zeW1wdG9tX2V2ZW50cyI6ZmFsc2UsImZlYXR1cmVfZGF0YV9yZXNpZGVuY3lfZGVidWdnaW5nIjpmYWxzZSwiZmVhdHVyZV9uZXdfc3VidGVhbV9saW5rZWRfY2hhbm5lbF9saW1pdCI6dHJ1ZSwiZmVhdHVyZV9zdWJ0ZWFtX3VzZXJfbGltaXQiOnRydWUsImZlYXR1cmVfZW50X2FkbWluX2FwcHJvdmVkX2FwcHNfdjIiOnRydWUsImZlYXR1cmVfZGFzaGJvYXJkX3NvcnRhYmxlX2xpc3RzIjpmYWxzZSwiZmVhdHVyZV9za19sb2FkaW5nX2J1dHRvbl9tb3Rpb25zIjp0cnVlLCJmZWF0dXJlX3NrX2Jhc2VfaWNvbiI6ZmFsc2UsImZlYXR1cmVfc2tfYmFzaWNfc2VsZWN0X2FyaWFsYWJlbCI6ZmFsc2UsImZlYXR1cmVfc2tfcmVxdWlyZWRfYXJpYWxhYmVsIjpmYWxzZSwiZmVhdHVyZV9jZV9lbmdfY29ubmVjdF9kbXMiOnRydWUsImZlYXR1cmVfY2VfZW5nX3NlYXJjaF9kZW1vIjpmYWxzZSwiZmVhdHVyZV9jZV9lbmdfaGVscF92aXRlc3MiOmZhbHNlLCJmZWF0dXJlX2NlX2VuZ192ZXJpZmllZF90aWNrZXRzIjpmYWxzZSwiZmVhdHVyZV9hcHBfZGlyX3Bob2VuaXgiOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9vcmciOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19tdWx0aV9vcmdfbXBpbSI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbXVsdGlfb3JnX21waW1fZmUiOnRydWUsImZlYXR1cmVfY2hhdF9tcGltX29wZW5fcmVmYWN0b3JfZmVfY29weSI6dHJ1ZSwiZmVhdHVyZV9maW5kX2FuX2FkbWluX2Rpc2Nvbm5lY3RfZXhwbGFpbmVyIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbXVsdGlfb3JnX2ludml0ZXNfYmUiOmZhbHNlLCJmZWF0dXJlX3NsYWNrX2Nvbm5lY3RfaW52aXRlX3VuZnVybF9jb3B5IjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbGVnYWN5X3JlY29ubmVjdCI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbXVsdGlfb3JnX3FhX2xpbWl0X292ZXJyaWRlIjpmYWxzZSwiZmVhdHVyZV9tdWx0aV93b3Jrc3BhY2Vfc2hhcmVkX2NoYW5uZWxzX2JlIjpmYWxzZSwiZmVhdHVyZV9lc2NfdG9fbXdzY19wcm90b3R5cGVfYmUiOmZhbHNlLCJmZWF0dXJlX213c2NfeHdzX3RvX2VzYyI6ZmFsc2UsImZlYXR1cmVfcmV2b2tlX2VzY19pbnZpdGVzX2ZlIjpmYWxzZSwiZmVhdHVyZV9td3NjX2VzY190b194d3MiOmZhbHNlLCJmZWF0dXJlX3JlbW92ZV9kb3VibGVfcmluZ3MiOmZhbHNlLCJmZWF0dXJlX3JlbW92ZV9kb3VibGVfZGlhbW9uZHMiOmZhbHNlLCJmZWF0dXJlX2NoYW5uZWxzX3ZpZXdfaW5fbXNjIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfZW1vamlfZGVsaWdodCI6dHJ1ZSwiZmVhdHVyZV9jcmVhdGVfcHJpdmF0ZV9jX2NoYW5uZWxzIjpmYWxzZSwiZmVhdHVyZV9nZHByX3VzZXJfam9pbl90b3MiOnRydWUsImZlYXR1cmVfdXNlcl9pbnZpdGVfdG9zX2FwcmlsXzIwMTgiOnRydWUsImZlYXR1cmVfbm9fbW9yZV9nZXRfb3JpZ2luYXRpbmdfdGVhbV9mZSI6dHJ1ZSwiZmVhdHVyZV9yb2xlc19hcmVfZnJlc2hfcGhhc2VfMSI6ZmFsc2UsImZlYXR1cmVfY2hhbm5lbF9tZ210X21lc3NhZ2VfY291bnQiOmZhbHNlLCJmZWF0dXJlX2FvcHNfMzMyMF9yZXR1cm5fdXNlcl9pZHNfYW5kX2Vycm9yX3N0cmluZ3MiOnRydWUsImZlYXR1cmVfZnVubmVsX2Nha2UiOmZhbHNlLCJmZWF0dXJlX25ldWVfdHlwZSI6ZmFsc2UsImZlYXR1cmVfY3VzdF9hY3FfaTE4bl90d2Vha3MiOmZhbHNlLCJmZWF0dXJlX2V4cG9ydHNfY29weV91cGRhdGVzIjp0cnVlLCJmZWF0dXJlX3doaXRlbGlzdF96ZW5kZXNrX2NoYXRfd2lkZ2V0IjpmYWxzZSwiZmVhdHVyZV9jb21tZW5kYXRpb25zX3NweSI6dHJ1ZSwiZmVhdHVyZV94d3NfaTE4biI6ZmFsc2UsImZlYXR1cmVfdXNlX2ltZ3Byb3h5X3Jlc2l6aW5nIjp0cnVlLCJmZWF0dXJlX3NoYXJlX21lbnRpb25fY29tbWVudF9jbGVhbnVwIjpmYWxzZSwiZmVhdHVyZV9ib2FyZHNfaTE4biI6ZmFsc2UsImZlYXR1cmVfZGlzYWJsZV9ia19pbl90aHJlYWQiOmZhbHNlLCJmZWF0dXJlX25ld19sb2NhbGVfdG9hc3QiOnRydWUsImZlYXR1cmVfY2hhbm5lbF9leHBvcnRzIjpmYWxzZSwiZmVhdHVyZV9kb2NzX21lbnRpb25zX2FuZF9jaGFubmVscyI6ZmFsc2UsImZlYXR1cmVfY2FsbHNfc3VydmV5X3JlcXVlc3RfcmVzcG9uc2UiOnRydWUsImZlYXR1cmVfdG9rZW5faXBfd2hpdGVsaXN0Ijp0cnVlLCJmZWF0dXJlX3NpZGViYXJfdGhlbWVfdW5kbyI6dHJ1ZSwiZmVhdHVyZV9hbGxvd19pbnRyYV93b3JkX2Zvcm1hdHRpbmciOnRydWUsImZlYXR1cmVfaTE4bl9jaGFubmVsc192YWxpZGF0ZV9lbW9qaSI6dHJ1ZSwiZmVhdHVyZV9md19lbmdfbm9ybWFsaXphdGlvbiI6dHJ1ZSwiZmVhdHVyZV9zbGltX3Njcm9sbGJhciI6ZmFsc2UsImZlYXR1cmVfcHJpbWFyeV9zZWFyY2giOmZhbHNlLCJmZWF0dXJlX21vZGVybl9zb3VuZHMiOmZhbHNlLCJmZWF0dXJlX3F1aWNrX2NvcHlfY29kZV9ibG9ja3MiOnRydWUsImZlYXR1cmVfc3RlZXBsZV9jaHVyY2giOnRydWUsImZlYXR1cmVfc3RlZXBsZV9jaHVyY2hfbGluayI6dHJ1ZSwiZmVhdHVyZV9zdGVlcGxlX2NodXJjaF9leHQiOnRydWUsImZlYXR1cmVfc3Ryb2xsZXJzX3RvX3BlcmNoIjp0cnVlLCJmZWF0dXJlX2ZpbGVfYnJvd3Nlcl92MiI6ZmFsc2UsImZlYXR1cmVfcGVvcGxlX3NlYXJjaCI6ZmFsc2UsImZlYXR1cmVfcmVhY3RfbWVzc2FnZXMiOnRydWUsImZlYXR1cmVfZWRnZV91cGxvYWRfcHJveHlfY2hlY2siOmZhbHNlLCJmZWF0dXJlX3VucmVhZF9jb3VudHNfZGVsYXkiOnRydWUsImZlYXR1cmVfbGVnYWN5X2ZpbGVfdXBsb2FkX2FuYWx5dGljcyI6dHJ1ZSwiZmVhdHVyZV9tcGRtX2xpbWl0X2NoYW5uZWxfY3JlYXRpb24iOmZhbHNlLCJmZWF0dXJlX3NuaXBwZXRfbW9kZXNfaTE4biI6ZmFsc2UsImZlYXR1cmVfZWttX21lc3NhZ2VfcmV2b2NhdGlvbl9wb2xsaW5nX3Rlc3QiOmZhbHNlLCJmZWF0dXJlX3RlYW1fYWRtaW5zX2xpc3RfYXBpIjp0cnVlLCJmZWF0dXJlX21vdmVkX2RldGFpbHMiOmZhbHNlLCJmZWF0dXJlX2FsdF9tZW1iZXJzX3JlZHVjZXIiOmZhbHNlLCJmZWF0dXJlX21zX2xhdGVzdCI6dHJ1ZSwiZmVhdHVyZV9ndWVzdHNfdXNlX2VudGl0bGVtZW50cyI6dHJ1ZSwiZmVhdHVyZV9yb29tc19qb2luX2FwaSI6dHJ1ZSwiZmVhdHVyZV9yb29tc19qb2luX3VybCI6ZmFsc2UsImZlYXR1cmVfY2FsbHNfc2lwX2ludGVncmF0aW9uX2xhYmVscyI6ZmFsc2UsImZlYXR1cmVfdGFza3NfdjFfY29weSI6ZmFsc2UsImZlYXR1cmVfY2FsbHNfY29udmVyc2F0aW9ucyI6ZmFsc2UsImZlYXR1cmVfY3VzdG9tX3N0YXR1c19jYWxlbmRhcl9zeW5jX2NvcHkiOnRydWUsImZlYXR1cmVfY3VzdG9tX3N0YXR1c19jYWxlbmRhcl9zeW5jIjpmYWxzZSwiZmVhdHVyZV9tYXNrX3VuZG9jdW1lbnRlZF9lcnJvcnMiOmZhbHNlLCJmZWF0dXJlX2FwcF9hY3Rpb25zX2FkbWluX3BhZ2VzIjp0cnVlLCJmZWF0dXJlX2FwcF92aWV3c19yZW1pbmRlcnMiOnRydWUsImZlYXR1cmVfcmVtaW5kZXJzX29yZ19zaGFyZCI6ZmFsc2UsImZlYXR1cmVfcmVtaW5kZXJzX2dyaWRfbWlncmF0aW9uc19vcmdfc2hhcmQiOnRydWUsImZlYXR1cmVfYmxvY2tzX3JlbWluZGVyc19saXN0IjpmYWxzZSwiZmVhdHVyZV9tZXNzYWdlX2Jsb2NrcyI6ZmFsc2UsImZlYXR1cmVfc2lsZW5jZV9hcHBfZG1zIjpmYWxzZSwiZmVhdHVyZV9zZXRfdHpfYXV0b21hdGljYWxseSI6dHJ1ZSwiZmVhdHVyZV9jb25maXJtX2NsZWFyX2FsbF91bnJlYWRzX3ByZWYiOnRydWUsImZlYXR1cmVfYmxvY2tfbW91bnRzIjp0cnVlLCJmZWF0dXJlX2F0dGFjaG1lbnRzX3YyIjp0cnVlLCJmZWF0dXJlX2Jsb2NrX2tpdF9leHBhbmRhYmxlX2Jsb2NrIjpmYWxzZSwiZmVhdHVyZV9ncm91cF9ibG9jayI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X2RlZXBfbGlua3MiOnRydWUsImZlYXR1cmVfc2hvd19ibG9ja19raXRfaW5fc2hhcmVfZGlhbG9ncyI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X3VzZXJfYmxvY2siOmZhbHNlLCJmZWF0dXJlX2Jsb2NrX2tpdF9yYWRpb19idXR0b25zIjp0cnVlLCJmZWF0dXJlX21ya2R3bl9vbl9yYWRpb19idXR0b24iOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X3RhYmxlIjpmYWxzZSwiZmVhdHVyZV9jaGVja2JveGVzX3JhZGlvc19pbl9tZXNzYWdlcyI6dHJ1ZSwiZmVhdHVyZV9pbnB1dF9ibG9ja19wdGlfd2ZiX2Rpc3BhdGNoX2FjdGlvbiI6ZmFsc2UsImZlYXR1cmVfaW5wdXRfYmxvY2tzX2VtaXRfYWN0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9ibG9ja19raXRfZnVsbF9hY3Rpb25zX3N0YXRlIjp0cnVlLCJmZWF0dXJlX2lucHV0X2Jsb2Nrc19pbl9hcHBfaG9tZSI6dHJ1ZSwiZmVhdHVyZV9pbnB1dF9ibG9ja3NfaW5fbWVzc2FnZXMiOmZhbHNlLCJmZWF0dXJlX2Jsb2NrX2tpdF9mdWxsX3ZpZXdfc3RhdGUiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X2FjdGlvbl9zZWN0aW9uX2luX3ZpZXdfc3RhdGUiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X3N0YXRlX2luX2Jsb2Nrc19hY3Rpb25zIjp0cnVlLCJmZWF0dXJlX2Jsb2NrX2tpdF9lbXB0eV9zdGF0ZV90cmFuc2xhdGlvbl9mb3Jfdmlld19zdGF0ZSI6dHJ1ZSwiZmVhdHVyZV9tdWx0aXNlbGVjdHNfaW5fYWN0aW9uc19ibG9jayI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X3JhbmdlX2RhdGVwaWNrZXIiOmZhbHNlLCJmZWF0dXJlX2RlbGV0ZV9hcHBfaG9tZXNfYXNzb2NpYXRlZF93aXRoX2RlbGV0ZWRfc2VydmljZSI6ZmFsc2UsImZlYXR1cmVfYmxvY2tfa2l0X3RpbWVwaWNrZXIiOnRydWUsImZlYXR1cmVfYmxvY2tfa2l0X3RpbWVwaWNrZXJfcmVtaW5kIjp0cnVlLCJmZWF0dXJlX2Jsb2NrX2tpdF9kYXRlcGlja2VyX2lucHV0Ijp0cnVlLCJmZWF0dXJlX2Jsb2NrX2tpdF9hcHBfYmV0YSI6dHJ1ZSwiZmVhdHVyZV9hZGRfYXBwX2hvbWVfdGVhbV9uYW1lIjpmYWxzZSwiZmVhdHVyZV9iZWFjb25fanNfZXJyb3JzIjpmYWxzZSwiZmVhdHVyZV9iZWFjb25fanNfYWRtaW5fZXJyb3JzIjpmYWxzZSwiZmVhdHVyZV91c2VyX2FwcF9kaXNhYmxlX3NwZWVkX2J1bXAiOnRydWUsImZlYXR1cmVfdHJhY3Rvcl9zaGFyZWRfaW52aXRlX2xpbmsiOnRydWUsImZlYXR1cmVfbmV3eHBfMjExOSI6dHJ1ZSwiZmVhdHVyZV90cmFjdG9yX2JhY2t1cF9jaGFubmVsbmFtZV9jb3B5Ijp0cnVlLCJmZWF0dXJlX2RlZ3JhZGVkX3J0bV9hbHdheXNfZmFpbHMiOmZhbHNlLCJmZWF0dXJlX2FwcHNfbWFuYWdlX3Blcm1pc3Npb25zX3Njb3BlX2NoYW5nZXMiOnRydWUsImZlYXR1cmVfcmVtaW5kZXJfY3Jvc3Nfd29ya3NwYWNlIjp0cnVlLCJmZWF0dXJlX3AycCI6ZmFsc2UsImZlYXR1cmVfY2xhc3NpY19uYXYiOmZhbHNlLCJmZWF0dXJlX25ld19yZWFjdGlvbnMiOnRydWUsImZlYXR1cmVfcGFnZXNfZXhhbXBsZSI6ZmFsc2UsImZlYXR1cmVfc29uaWNfcGlucyI6ZmFsc2UsImZlYXR1cmVfc29uaWNfdmlkZW9fcGxhY2Vob2xkZXIiOnRydWUsImZlYXR1cmVfaWFwMSI6ZmFsc2UsImZlYXR1cmVfaWFfZ2EiOnRydWUsImZlYXR1cmVfaWFfZGVidWdfb2ZmIjpmYWxzZSwiZmVhdHVyZV9pYV9pMThuIjp0cnVlLCJmZWF0dXJlX2lhX3RoZW1lcyI6dHJ1ZSwiZmVhdHVyZV9pYV9tZW1iZXJfcHJvZmlsZSI6dHJ1ZSwiZmVhdHVyZV93b3Jrc3BhY2Vfc2NpbV9tYW5hZ2VtZW50IjpmYWxzZSwiZmVhdHVyZV91bmlmaWVkX21lbWJlciI6ZmFsc2UsImZlYXR1cmVfdHVybl9tcGRtX25vdGlmc19vbiI6dHJ1ZSwiZmVhdHVyZV9kZXNrdG9wX3JlbG9hZF9vbl9nZW5lcmljX2Vycm9yIjp0cnVlLCJmZWF0dXJlX2Rlc2t0b3BfZXh0ZW5kX2FwcF9tZW51IjpmYWxzZSwiZmVhdHVyZV9kZXNrdG9wX3Jlc3RhcnRfc2VydmljZV93b3JrZXIiOmZhbHNlLCJmZWF0dXJlX2Rlc2t0b3Bfc3lzdGVtX25vdGlmaWNhdGlvbl9wbGF5YmFjayI6ZmFsc2UsImZlYXR1cmVfYTExeV9keXNsZXhpYyI6ZmFsc2UsImZlYXR1cmVfZG9sb3JlcyI6ZmFsc2UsImZlYXR1cmVfZGVza3RvcF9mb3JjZV9wcm9kdWN0aW9uX2NoYW5uZWwiOmZhbHNlLCJmZWF0dXJlX2Rlc2t0b3BfbG9nc191cGxvYWQiOmZhbHNlLCJmZWF0dXJlX21hY29zX2Rpc2FibGVfaHciOnRydWUsImZlYXR1cmVfYXRfaGVyZV93YXJuaW5nIjpmYWxzZSwiZmVhdHVyZV9ib3RzX25vdF9tZW1iZXJzIjp0cnVlLCJmZWF0dXJlX3d0YV9zdG9wX2NyZWF0aW9uIjp0cnVlLCJmZWF0dXJlX20xMW5fY2hhbm5lbF9kZXRhaWxzIjpmYWxzZSwiZmVhdHVyZV9wbGF0Zm9ybV9kZXByZWNhdGlvbnNfZmUiOnRydWUsImZlYXR1cmVfY2hhbm5lbF9hY3Rpb25zIjp0cnVlLCJmZWF0dXJlX3Nob3J0Y3V0c19wcm9tcHQiOnRydWUsImZlYXR1cmVfbmV3X2NvbG9yX3BpY2tlcl9zdHJpbmdzIjpmYWxzZSwiZmVhdHVyZV9hY2Nlc3NpYmxlX2RpYWxvZ3MiOnRydWUsImZlYXR1cmVfYWNjZXNzaWJsZV9lbW9qaV9za2luX3RvbmVfcGlja2VyIjp0cnVlLCJmZWF0dXJlX2NhbGxzX2NsaXBib2FyZF9icm9hZGNhc3Rpbmdfb3B0aW4iOnRydWUsImZlYXR1cmVfc2NyZWVuX3NoYXJlX25lZWRzX2Flcm8iOmZhbHNlLCJmZWF0dXJlX2FjY2Vzc2libGVfZnNfZGlhbG9ncyI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX2hlYWRlcl9sYWJlbHMiOmZhbHNlLCJmZWF0dXJlX3RyYXBfa2Jfd2l0aGluX2ZzX21vZGFscyI6dHJ1ZSwiZmVhdHVyZV9tb2Rlcm5faW1hZ2Vfdmlld2VyIjp0cnVlLCJmZWF0dXJlX2Vtb2ppX2J5X2lkIjp0cnVlLCJmZWF0dXJlX21jX21pZ3JhdGlvbl9iYW5uZXIiOnRydWUsImZlYXR1cmVfYXJpYV9hcHBsaWNhdGlvbl9tb2RlIjpmYWxzZSwiZmVhdHVyZV91cGRhdGVfbXVsdGl3b3Jrc3BhY2VfY2hhbm5lbF9tb2RhbCI6dHJ1ZSwiZmVhdHVyZV9tb2Rlcm5fcmVxdWVzdF93b3Jrc3BhY2VfZGlhbG9nIjpmYWxzZSwiZmVhdHVyZV93b3Jrc3BhY2VfYXBwc19tYW5hZ2VfZ2FudHJ5IjpmYWxzZSwiZmVhdHVyZV93b3Jrc3BhY2VfYXBwc19tYW5hZ2VfZ2FudHJ5X3YyX3IxIjp0cnVlLCJmZWF0dXJlX2FwcF9hZG1pbl9idXR0b25zX3NwZWVkYnVtcCI6dHJ1ZSwiZmVhdHVyZV9hcHBfYWRtaW5fYnV0dG9uc19zcGVlZGJ1bXBfdjIiOmZhbHNlLCJmZWF0dXJlX21vZGVybl9wcm9maWxlX2ZsZXhwYW5lIjpmYWxzZSwiZmVhdHVyZV9zY2dfY29udmVyc2lvbl9jaGFubmVscyI6dHJ1ZSwiZmVhdHVyZV9lbnRlcnByaXNlX3JldGVudGlvbl9hbGxvd19vdmVycmlkZV9vbl9vcmdfbGV2ZWxfY2hhbm5lbHMiOmZhbHNlLCJmZWF0dXJlX2VudGVycHJpc2VfcmV0ZW50aW9uX2FkbWluX3JldGVudGlvbl9ieV9jY20iOmZhbHNlLCJmZWF0dXJlX2V4cG9ydHNfZmlsdGVyIjp0cnVlLCJmZWF0dXJlX3RyYWNrX3RpbWVfc3BlbnQiOnRydWUsImZlYXR1cmVfY2hhbm5lbF9pbnZpdGVfdG9rZW5pemF0aW9uIjp0cnVlLCJmZWF0dXJlX2ltcG9ydHNfY2FuY2VsIjp0cnVlLCJmZWF0dXJlX2VtYWlsX3dvcmtvYmplY3RfdWkiOmZhbHNlLCJmZWF0dXJlX2VtYWlsX25vdGlmeSI6ZmFsc2UsImZlYXR1cmVfZW1haWxfZm9yY2VfZG93bmxvYWQiOnRydWUsImZlYXR1cmVfb2ZmaWNlX2RpcmVjdG9yeSI6ZmFsc2UsImZlYXR1cmVfY2FsZW5kYXJfc2ltcGxlX2FnZW5kYV92aWV3IjpmYWxzZSwiZmVhdHVyZV90ZWFtX3RoZW1lcyI6ZmFsc2UsImZlYXR1cmVfdW5mdXJsX21ldGFkYXRhIjpmYWxzZSwiZmVhdHVyZV9wYXBlcmNsaXBfY29hY2htYXJrX2V4cGVyaW1lbnRzIjp0cnVlLCJmZWF0dXJlX3BsdXNfbWVudV9hZGRfYXBwc19saW5rIjpmYWxzZSwiZmVhdHVyZV9yZW5hbWVfY2hhbm5lbF9kaXNhYmxlX2ZlZWRiYWNrX2kxOG4iOmZhbHNlLCJmZWF0dXJlX3JlY2VudF9maWxlc19vbW5pcGlja2VyIjpmYWxzZSwiZmVhdHVyZV9yZWNlbnRfZGVza3RvcF9maWxlcyI6ZmFsc2UsImZlYXR1cmVfZW1haWxfZmlsZV91bmZ1cmxfZm9ybWF0Ijp0cnVlLCJmZWF0dXJlX2xpbmtfcHJvdG9jb2xfYmV0YSI6ZmFsc2UsImZlYXR1cmVfc3RyaXBlX2xpZ2h0X2xlZ2FjeV9wdXJjaGFzZV9tb2RlIjpmYWxzZSwiZmVhdHVyZV9jaGVja291dF9mb3JjZV9pbnRvX2xlZ2FjeSI6ZmFsc2UsImZlYXR1cmVfc29uaWNfcGxhY2Vob2xkZXJfbGFiZWxzIjpmYWxzZSwiZmVhdHVyZV9zb25pY19lc2NfY3JlYXRpb24iOmZhbHNlLCJmZWF0dXJlX2Rhbmdlcm91c2x5X2d1YXJkX2lhX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfaWFfY29udGV4dF9tZW51cyI6ZmFsc2UsImZlYXR1cmVfaWFfbGF5b3V0IjpmYWxzZSwiZmVhdHVyZV9taXNjX2lhX2ExMXlfdHJhbnNsYXRpb25zIjpmYWxzZSwiZmVhdHVyZV90aHJlYWRlZF9jYWxsX2Jsb2NrIjpmYWxzZSwiZmVhdHVyZV9lbmFibGVfcmVhZF90aW1lX3ZhbGlkYXRpb25zX2Zvcl9zaG9ydGN1dHMiOmZhbHNlLCJmZWF0dXJlX21lc3NhZ2VfYWN0aW9uc19pbl9hcHBfYWN0aW9uc19mcmFtZXdvcmtfY2xpZW50Ijp0cnVlLCJmZWF0dXJlX21lc3NhZ2VfYWN0aW9uc19pbl9hcHBfYWN0aW9uc19mcmFtZXdvcmtfZGV2ZWxvcGVyIjp0cnVlLCJmZWF0dXJlX3NsYWNrX21lc3NhZ2VfYXR0YWNobWVudF90b29sdGlwIjpmYWxzZSwiZmVhdHVyZV9lbnRlcnByaXNlX21vYmlsZV9kZXZpY2VfY2hlY2siOnRydWUsImZlYXR1cmVfbmV3eHBfNDQwMiI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfY3VzdG9tX2Vtb2ppc191cmwiOmZhbHNlLCJmZWF0dXJlX25ld19jb3B5X2Zvcl9pZGVudGl0eV9iYXNpYyI6ZmFsc2UsImZlYXR1cmVfc29uaWNfbGVhdmVfd29ya3NwYWNlX2RpYWxvZyI6ZmFsc2UsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX25ld191c2VyX3RyaWFsIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19pbnZpdGVyX3RyaWFsIjpmYWxzZSwiZmVhdHVyZV9zY19pbnZpdGVfam9pbl9wZW5kaW5nX2NoYW5uZWxfYWN0aW9uIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfbXVsdGlfZW1haWxfaW52aXRlIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc185MF9kYXlfdHJpYWwiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzXzkwX2RheV90cmlhbF9pbnZpdGVyIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfZGF5MV9jcmVhdG9yIjpmYWxzZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfaGFwcGllcl9wYXRocyI6ZmFsc2UsImZlYXR1cmVfbGF0ZV9wYXltZW50X3N1Y2Nlc3Nfbm90aWZpY2F0aW9uIjpmYWxzZSwiZmVhdHVyZV9hdXN0cmFsaWFfdGF4X2NoYW5nZV9ub3RpZmljYXRpb24iOmZhbHNlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsX2ludml0ZXNfdjIiOnRydWUsImZlYXR1cmVfYmV0dGVyX2ludml0ZXNfY2FsbF92Ml9hcGkiOnRydWUsImZlYXR1cmVfc2hhcmVkX2NoYW5uZWxzX2ludml0ZV9jcmVhdGVfZWR1Y2F0aW9uIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19pbnZpdGVfZW1haWxfYm91bmNlX25vdGlmaWNhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9zaGFyZWRfY2hhbm5lbHNfaW52aXRlX2VtYWlsX3JlbWluZGVyIjp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc19jb250ZW50Ijp0cnVlLCJmZWF0dXJlX3NoYXJlZF9jaGFubmVsc190cmlhbF9lZHUiOnRydWUsImZlYXR1cmVfdXNlcl9pbnZpdGVfZW1haWxfYm91bmNlX25vdGlmaWNhdGlvbl90cmFuc2xhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9wYWlkX29uYm9hcmRpbmdfcGFnZXVwZGF0ZSI6dHJ1ZSwiZmVhdHVyZV90cmFjZV93ZWJhcHBfaW5pdCI6dHJ1ZSwiZmVhdHVyZV90cmFjZV9qcV9pbml0Ijp0cnVlLCJmZWF0dXJlX3RyaWFsX2VuZF9sMTBuIjp0cnVlLCJmZWF0dXJlX3RyaWFsX2VuZGluZ19lbWFpbF91cGRhdGVzIjp0cnVlLCJmZWF0dXJlX3dvcmtzcGFjZV9tZW51X3BsYW5faW5mbyI6dHJ1ZSwiZmVhdHVyZV9wYXJ0bmVyX3Rlcm1zX2kxOG4iOmZhbHNlLCJmZWF0dXJlX3BhcnRuZXJfZmFxX2kxOG4iOnRydWUsImZlYXR1cmVfaGlnaGxpZ2h0X3BhaWRfZmVhdHVyZXMiOmZhbHNlLCJmZWF0dXJlX3RyaWFsX2V4cGlyYXRpb25fZGF0ZV9pMThuIjp0cnVlLCJmZWF0dXJlX3N0cmlwZV9jb21wbGV0ZWx5X2Rvd25fYmFubmVyIjpmYWxzZSwiZmVhdHVyZV9mYWlyX2JpbGxpbmdfZGV0YWlsX2ludm9pY2Vfc3RhdGVtZW50cyI6ZmFsc2UsImZlYXR1cmVfY2hlY2tvdXRfemlwX2F1dG9jb21wbGV0ZV90cmFuc2xhdGlvbnMiOnRydWUsImZlYXR1cmVfYmlsbGluZ19tZW1iZXJfZW1haWxfdXBkYXRlcyI6ZmFsc2UsImZlYXR1cmVfZmFpcl9iaWxsaW5nX2JhY2tlbmRfcmVmYWN0b3IiOnRydWUsImZlYXR1cmVfdWFlX3RheF9pZF9jb2xsZWN0aW9uIjp0cnVlLCJmZWF0dXJlX2NoaWxlX3RheF9pZF9jb2xsZWN0aW9uIjp0cnVlLCJmZWF0dXJlX2tzYV90YXhfaWRfY29sbGVjdGlvbiI6dHJ1ZSwiZmVhdHVyZV9pbmRvbmVzaWFfdGF4X2NoYW5nZV9ub3RpZmljYXRpb24iOmZhbHNlLCJmZWF0dXJlX2luZG9uZXNpYV90YXhfYXNzZXNzbWVudCI6ZmFsc2UsImZlYXR1cmVfY2FwaXRhbGl6ZV9zaW5nbGVfY2hhbm5lbF9zdGF0dXMiOnRydWUsImZlYXR1cmVfZW50ZXJwcmlzZV9hbmFseXRpY3NfMjAxOV9xM19lbmhhbmNlbWVudHMiOmZhbHNlLCJmZWF0dXJlX21vZGVybml6ZV9vcmdfZGFzaF9jaGFydHMiOnRydWUsImZlYXR1cmVfbW9kZXJuaXplX29yZ190ZWFtX2FuYWx5dGljcyI6ZmFsc2UsImZlYXR1cmVfbWVzc2FnZXNfZnJvbV9hcHBzX2FuYWx5dGljcyI6ZmFsc2UsImZlYXR1cmVfb3JnX2xldmVsX2FwcHMiOmZhbHNlLCJmZWF0dXJlX29yZ19sZXZlbF9hcHBzX2N1c3RvbSI6ZmFsc2UsImZlYXR1cmVfb3JnX2xldmVsX2FwcHNfYWRtaW5fYmV0YSI6ZmFsc2UsImZlYXR1cmVfc3NvX3ZhbGlkYXRlX2F1ZGllbmNlIjp0cnVlLCJmZWF0dXJlX2NoYW5uZWxfc2VjdGlvbnMiOnRydWUsImZlYXR1cmVfY2hhbm5lbF9zZWN0aW9uc19zaWRlYmFyX2JlaGF2aW9yX3VpIjpmYWxzZSwiZmVhdHVyZV9hbmFseXRpY3Nfc2NpbV9maWVsZHNfcGFpZCI6ZmFsc2UsImZlYXR1cmVfZ29vZ2xlX2RpcmVjdG9yeV9pbnZpdGVzIjpmYWxzZSwiZmVhdHVyZV9taWdyYXRlX2dvb2dsZV9kaXJlY3RvcnlfYXBpcyI6dHJ1ZSwiZmVhdHVyZV9zZWFyY2hfcmVzdWx0c192aXJ0dWFsaXplZCI6ZmFsc2UsImZlYXR1cmVfc2hvd19lbWFpbF9mb3J3YXJkZWRfYnkiOmZhbHNlLCJmZWF0dXJlX25ld19lbm91Z2hfcGVyaW9kaWNfcmVsb2FkcyI6ZmFsc2UsImZlYXR1cmVfYnVpbGRlcl93b3JrZmxvd19hY3Rpdml0eSI6dHJ1ZSwiZmVhdHVyZV9idWlsZGVyX2V4cG9ydF9mb3JtX2Nzdl9hZG1pbiI6dHJ1ZSwiZmVhdHVyZV9oZWFkZXJfYmxvY2siOnRydWUsImZlYXR1cmVfaGVhZGVyX2Jsb2NrX2JrYiI6dHJ1ZSwiZmVhdHVyZV9yYXRlX2xpbWl0X2FwcF9jcmVhdGlvbiI6dHJ1ZSwiZmVhdHVyZV9naXBoeV9zaG9ydGN1dCI6ZmFsc2UsImZlYXR1cmVfZG93bmxvYWRfZmluZGVyX3VwZGF0ZSI6dHJ1ZSwiZmVhdHVyZV9zaGFyZV9tb2RhbF9kaWFsb2ciOmZhbHNlLCJmZWF0dXJlX29uZWRyaXZlX2Vycm9yX3RyYW5zbGF0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9jaGFubmVsX3NpZGViYXJfc3VtbWFyeSI6ZmFsc2UsImZlYXR1cmVfYnJvd3Nlcl9waWNrZXIiOmZhbHNlLCJmZWF0dXJlX2VkdV8xMDEiOnRydWUsImZlYXR1cmVfbmV3eHBfNDY4OCI6dHJ1ZSwiZmVhdHVyZV9hcHBfZGlyX2dyYW5fYm90X3N1Ym1pdCI6dHJ1ZSwiZmVhdHVyZV9hcHBfZGlyX3dvcmtmbG93X3N0ZXBzIjp0cnVlLCJmZWF0dXJlX2FwcF9kaXJfd29ya2Zsb3dfc3RlcHNfcHJvbW8iOnRydWUsImZlYXR1cmVfYXBwX2xpc3RpbmdfcmVmcmVzaCI6dHJ1ZSwiZmVhdHVyZV9hcHBfbGlzdGluZ19yZWZyZXNoX3Njb3BlcyI6dHJ1ZSwiZmVhdHVyZV9hcHBfbGlzdGluZ19yZWZyZXNoX29yZ19kZXBsb3lzIjpmYWxzZSwiZmVhdHVyZV9hcHBfbGlzdGluZ19yZWZyZXNoX3B0XzIiOnRydWUsImZlYXR1cmVfaGNfdXBkYXRlZF90aXRsZSI6ZmFsc2UsImZlYXR1cmVfcGFyc2VjX21ldGhvZHMiOmZhbHNlLCJmZWF0dXJlX3NvdWxfc2VhcmNoZXJzIjpmYWxzZSwiZmVhdHVyZV9zbmRfcXVlcnlfcmVmaW5lbWVudHMiOnRydWUsImZlYXR1cmVfZW1haWxfY2xhc3NpZmljYXRpb24iOnRydWUsImZlYXR1cmVfcHJpbWFyeV9vd25lcl9jb25zaXN0ZW50X3JvbGVzIjp0cnVlLCJmZWF0dXJlX2ludml0ZV90b19jaGFubmVsX2J5X2VtYWlsX3VpIjp0cnVlLCJmZWF0dXJlX2VkdV8xMTAiOnRydWUsImZlYXR1cmVfc2l3c19saW5rcyI6ZmFsc2UsImZlYXR1cmVfbG9jYWxlX2l0X0lUIjpmYWxzZSwiZmVhdHVyZV9sb2NhbGVfa29fS1IiOnRydWUsImZlYXR1cmVfbG9jYWxlX3J1X1JVIjpmYWxzZSwiZmVhdHVyZV9sb2NhbGVfemhfQ04iOmZhbHNlLCJmZWF0dXJlX2xvY2FsZV96aF9UVyI6ZmFsc2UsImZlYXR1cmVfc2VhcmNoX2ZpbHRlcl9maWxlX2F0dGFjaG1lbnRzIjpmYWxzZSwiZmVhdHVyZV9tcGRtX2F1ZGllbmNlX2V4cGFuc2lvbiI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF80MzEyIjpmYWxzZSwiZmVhdHVyZV9jZV9lbmdfc2VhcmNoX3plbmRlc2tfYXBpIjpmYWxzZSwiZmVhdHVyZV9ia19lcnJvcl9tZXNzYWdpbmciOnRydWUsImZlYXR1cmVfbGFyZ2VfZW1vamlfaW5fdG9vbHRpcCI6dHJ1ZSwiZmVhdHVyZV9uZXd4cF8zNzk1IjpmYWxzZSwiZmVhdHVyZV9uZXdfbm90aWZpY2F0aW9uc19zdHJpbmciOmZhbHNlLCJmZWF0dXJlX2FwcHNfZXZlbnRfYXV0aG9yaXphdGlvbnNfbGlzdF9lbmRwb2ludF9hN2U1MWYiOnRydWUsImZlYXR1cmVfZ3VhcmRfY2hhbm5lbF9kZXRhaWxzX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfdmVyaWZpZWRfb3Jnc19mZSI6ZmFsc2UsImZlYXR1cmVfcmVmaW5lX3lvdXJfc2VhcmNoX2kxOG4iOnRydWUsImZlYXR1cmVfbmV3eHBfNDU5NyI6dHJ1ZSwiZmVhdHVyZV9maWxlX2FjdGlvbnNfZml4IjpmYWxzZSwiZmVhdHVyZV9pbmxpbmVfZmVlZGJhY2siOmZhbHNlLCJmZWF0dXJlX2VkdV8xODIiOnRydWUsImZlYXR1cmVfY3JlZGl0X2Jhbm5lcl9iYXNpY190cmFuc2xhdGlvbnMiOmZhbHNlLCJmZWF0dXJlX2lkcl9iYWNrZmlsbHMiOmZhbHNlLCJmZWF0dXJlX2VkdV8xODciOnRydWUsImZlYXR1cmVfYWRkX3RvX2NoYW5uZWxfcHJvdG90eXBlIjpmYWxzZSwiZmVhdHVyZV9zdHJpcGVfaGFja19taWdyYXRpb24iOmZhbHNlLCJmZWF0dXJlX3BhaWRfYmVuZWZpdHNfYWxlcnRfdHJhbnNsYXRpb25zIjp0cnVlLCJmZWF0dXJlX3BsYW5fYmVuZWZpdHNfZGF5X29uZV90cmlhbF9oZWFkZXJfdXBkYXRlX2kxOG4iOnRydWUsImZlYXR1cmVfdHJpYWxfYXdhcmVuZXNzX3RyYW5zbGF0aW9ucyI6dHJ1ZSwiZmVhdHVyZV9jYWxsc19sb2NhdGlvbl93YXJuaW5nX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfZXNjX3dob19jYW5fcmVxdWVzdF9wcmVmIjpmYWxzZSwiZmVhdHVyZV9zaWRlYmFyX3RyaWFsX2JhZGdlX3RyYW5zbGF0aW9ucyI6ZmFsc2UsImZlYXR1cmVfZmVhdHVyZV9jb250ZXh0X21lbnVfa2V5Ym9hcmRfc2hvcnRjdXQiOmZhbHNlLCJmZWF0dXJlX2VkdV8xOTYiOmZhbHNlLCJmZWF0dXJlX2ludGVyYWN0aXZlX3NlcGFyYXRvcnMiOmZhbHNlLCJmZWF0dXJlX3NlYXJjaF9hcmlhX2luaXRpYWxfc3RhdGUiOmZhbHNlLCJmZWF0dXJlX2ZyZWVfdHJpYWxfY2hhdCI6ZmFsc2UsImZlYXR1cmVfdWtfdmF0X2htcmNfdmFsaWRhdGlvbiI6ZmFsc2UsImNsaWVudF9sb2dzIjp7IjAiOnsibnVtYmVycyI6WyIwIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjIiOnsibnVtYmVycyI6WyIyIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjQiOnsibnVtYmVycyI6WyI0Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjUiOnsibnVtYmVycyI6WyI1Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjIzIjp7Im51bWJlcnMiOlsiMjMiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwic291bmRzIjp7Im5hbWUiOiJzb3VuZHMiLCJudW1iZXJzIjpbIjM3Il19LCIzNyI6eyJuYW1lIjoic291bmRzIiwibnVtYmVycyI6WyIzNyJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIjQ3Ijp7Im51bWJlcnMiOlsiNDciXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNDgiOnsibnVtYmVycyI6WyI0OCJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJNZXNzYWdlIEhpc3RvcnkiOnsibmFtZSI6Ik1lc3NhZ2UgSGlzdG9yeSIsIm51bWJlcnMiOlsiNTgiXX0sIjU4Ijp7Im5hbWUiOiJNZXNzYWdlIEhpc3RvcnkiLCJudW1iZXJzIjpbIjU4Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwiNjciOnsibnVtYmVycyI6WyI2NyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI3MiI6eyJudW1iZXJzIjpbIjcyIl0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjczIjp7Im51bWJlcnMiOlsiNzMiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiODIiOnsibnVtYmVycyI6WyI4MiJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI4OCI6eyJudW1iZXJzIjpbIjg4Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjkxIjp7Im51bWJlcnMiOlsiOTEiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiOTMiOnsibnVtYmVycyI6WyI5MyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI5NiI6eyJudW1iZXJzIjpbIjk2Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjk5Ijp7Im51bWJlcnMiOlsiOTkiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiQ2hhbm5lbCBNYXJraW5nIChNUykiOnsibmFtZSI6IkNoYW5uZWwgTWFya2luZyAoTVMpIiwibnVtYmVycyI6WyIxNDEiXX0sIjE0MSI6eyJuYW1lIjoiQ2hhbm5lbCBNYXJraW5nIChNUykiLCJudW1iZXJzIjpbIjE0MSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIkNoYW5uZWwgTWFya2luZyAoQ2xpZW50KSI6eyJuYW1lIjoiQ2hhbm5lbCBNYXJraW5nIChDbGllbnQpIiwibnVtYmVycyI6WyIxNDIiXX0sIjE0MiI6eyJuYW1lIjoiQ2hhbm5lbCBNYXJraW5nIChDbGllbnQpIiwibnVtYmVycyI6WyIxNDIiXSwidXNlcl9mYWNpbmciOnRydWV9LCJDbG9zZSBPbGQgSU1zIChDbGllbnQpIjp7Im5hbWUiOiJDbG9zZSBPbGQgSU1zIChDbGllbnQpIiwibnVtYmVycyI6WyIyMjEiXX0sIjIyMSI6eyJuYW1lIjoiQ2xvc2UgT2xkIElNcyAoQ2xpZW50KSIsIm51bWJlcnMiOlsiMjIxIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwiMzY1Ijp7Im51bWJlcnMiOlsiMzY1Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjM4OSI6eyJudW1iZXJzIjpbIjM4OSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI0MzgiOnsibnVtYmVycyI6WyI0MzgiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNDQ0Ijp7Im51bWJlcnMiOlsiNDQ0Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjQ4MSI6eyJudW1iZXJzIjpbIjQ4MSJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI0ODgiOnsibnVtYmVycyI6WyI0ODgiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNTI5Ijp7Im51bWJlcnMiOlsiNTI5Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjU1MiI6eyJudW1iZXJzIjpbIjU1MiJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJkYXNoYm9hcmQiOnsibmFtZSI6ImRhc2hib2FyZCIsIm51bWJlcnMiOlsiNjY2Il19LCI2NjYiOnsibmFtZSI6ImRhc2hib2FyZCIsIm51bWJlcnMiOlsiNjY2Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjY2NyI6eyJudW1iZXJzIjpbIjY2NyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCI3NzMiOnsibnVtYmVycyI6WyI3NzMiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiNzc3Ijp7Im51bWJlcnMiOlsiNzc3Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sIjc5NCI6eyJudW1iZXJzIjpbIjc5NCJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJDbGllbnQgUmVzcG9uc2l2ZW5lc3MiOnsibmFtZSI6IkNsaWVudCBSZXNwb25zaXZlbmVzcyIsInVzZXJfZmFjaW5nIjpmYWxzZSwibnVtYmVycyI6WyI4MDgiXX0sIjgwOCI6eyJuYW1lIjoiQ2xpZW50IFJlc3BvbnNpdmVuZXNzIiwidXNlcl9mYWNpbmciOmZhbHNlLCJudW1iZXJzIjpbIjgwOCJdfSwiTWVzc2FnZSBQYW5lIFNjcm9sbGluZyI6eyJuYW1lIjoiTWVzc2FnZSBQYW5lIFNjcm9sbGluZyIsIm51bWJlcnMiOlsiODg4Il19LCI4ODgiOnsibmFtZSI6Ik1lc3NhZ2UgUGFuZSBTY3JvbGxpbmciLCJudW1iZXJzIjpbIjg4OCJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIlVucmVhZCBiYW5uZXIgYW5kIGRpdmlkZXIiOnsibmFtZSI6IlVucmVhZCBiYW5uZXIgYW5kIGRpdmlkZXIiLCJudW1iZXJzIjpbIjk5OSJdfSwiOTk5Ijp7Im5hbWUiOiJVbnJlYWQgYmFubmVyIGFuZCBkaXZpZGVyIiwibnVtYmVycyI6WyI5OTkiXSwidXNlcl9mYWNpbmciOnRydWV9LCIxMDAwIjp7Im51bWJlcnMiOlsiMTAwMCJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJEdXBsaWNhdGUgYmFkZ2VzIChkZXNrdG9wIGFwcCBpY29ucykiOnsibmFtZSI6IkR1cGxpY2F0ZSBiYWRnZXMgKGRlc2t0b3AgYXBwIGljb25zKSIsIm51bWJlcnMiOlsiMTcwMSJdfSwiMTcwMSI6eyJuYW1lIjoiRHVwbGljYXRlIGJhZGdlcyAoZGVza3RvcCBhcHAgaWNvbnMpIiwibnVtYmVycyI6WyIxNzAxIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwiTWVtYmVycyI6eyJuYW1lIjoiTWVtYmVycyIsIm51bWJlcnMiOlsiMTk3NSJdfSwiMTk3NSI6eyJuYW1lIjoiTWVtYmVycyIsIm51bWJlcnMiOlsiMTk3NSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sImxhenkgbG9hZGluZyI6eyJuYW1lIjoibGF6eSBsb2FkaW5nIiwibnVtYmVycyI6WyIxOTg5Il19LCIxOTg5Ijp7Im5hbWUiOiJsYXp5IGxvYWRpbmciLCJudW1iZXJzIjpbIjE5ODkiXSwidXNlcl9mYWNpbmciOnRydWV9LCJ0aGluX2NoYW5uZWxfbWVtYmVyc2hpcCI6eyJuYW1lIjoidGhpbl9jaGFubmVsX21lbWJlcnNoaXAiLCJudW1iZXJzIjpbIjE5OTAiXX0sIjE5OTAiOnsibmFtZSI6InRoaW5fY2hhbm5lbF9tZW1iZXJzaGlwIiwibnVtYmVycyI6WyIxOTkwIl0sInVzZXJfZmFjaW5nIjp0cnVlfSwic3RhdHMiOnsibmFtZSI6InN0YXRzIiwibnVtYmVycyI6WyIxOTkxIl19LCIxOTkxIjp7Im5hbWUiOiJzdGF0cyIsIm51bWJlcnMiOlsiMTk5MSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIm1zIjp7Im5hbWUiOiJtcyIsIm51bWJlcnMiOlsiMTk5NiJdfSwiMTk5NiI6eyJuYW1lIjoibXMiLCJudW1iZXJzIjpbIjE5OTYiXSwidXNlcl9mYWNpbmciOnRydWV9LCJzaGFyZWRfY2hhbm5lbHNfY29ubmVjdGlvbiI6eyJuYW1lIjoic2hhcmVkX2NoYW5uZWxzX2Nvbm5lY3Rpb24iLCJudW1iZXJzIjpbIjE5OTkiXX0sIjE5OTkiOnsibmFtZSI6InNoYXJlZF9jaGFubmVsc19jb25uZWN0aW9uIiwibnVtYmVycyI6WyIxOTk5Il0sInVzZXJfZmFjaW5nIjpmYWxzZX0sImRuZCI6eyJuYW1lIjoiZG5kIiwibnVtYmVycyI6WyIyMDAyIl19LCIyMDAyIjp7Im5hbWUiOiJkbmQiLCJudW1iZXJzIjpbIjIwMDIiXSwidXNlcl9mYWNpbmciOnRydWV9LCIyMDAzIjp7Im51bWJlcnMiOlsiMjAwMyJdLCJ1c2VyX2ZhY2luZyI6ZmFsc2V9LCJUaHJlYWRzIjp7Im5hbWUiOiJUaHJlYWRzIiwibnVtYmVycyI6WyIyMDA0Il19LCIyMDA0Ijp7Im5hbWUiOiJUaHJlYWRzIiwibnVtYmVycyI6WyIyMDA0Il0sInVzZXJfZmFjaW5nIjp0cnVlfSwiMjAwNSI6eyJudW1iZXJzIjpbIjIwMDUiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiUmVhY3Rpb25zIjp7Im5hbWUiOiJSZWFjdGlvbnMiLCJudW1iZXJzIjpbIjIwMDYiXX0sIjIwMDYiOnsibmFtZSI6IlJlYWN0aW9ucyIsIm51bWJlcnMiOlsiMjAwNiJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIlRTU1NCLmZvY3VzVGFiQW5kU3dpdGNoVG9DaGFubmVsIjp7Im5hbWUiOiJUU1NTQi5mb2N1c1RhYkFuZFN3aXRjaFRvQ2hhbm5lbCIsIm51bWJlcnMiOlsiMjAwNyJdfSwiMjAwNyI6eyJuYW1lIjoiVFNTU0IuZm9jdXNUYWJBbmRTd2l0Y2hUb0NoYW5uZWwiLCJudW1iZXJzIjpbIjIwMDciXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiUHJlc2VuY2UgRGV0ZWN0aW9uIjp7Im5hbWUiOiJQcmVzZW5jZSBEZXRlY3Rpb24iLCJudW1iZXJzIjpbIjIwMTciXX0sIjIwMTciOnsibmFtZSI6IlByZXNlbmNlIERldGVjdGlvbiIsIm51bWJlcnMiOlsiMjAxNyJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIm1jX3NpYnMiOnsibmFtZSI6Im1jX3NpYnMiLCJudW1iZXJzIjpbIjk5OTkiXX0sIjk5OTkiOnsibmFtZSI6Im1jX3NpYnMiLCJudW1iZXJzIjpbIjk5OTkiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiTWVtYmVyIHNlYXJjaGluZyI6eyJuYW1lIjoiTWVtYmVyIHNlYXJjaGluZyIsIm51bWJlcnMiOlsiOTAyMTEiXX0sIjkwMjExIjp7Im5hbWUiOiJNZW1iZXIgc2VhcmNoaW5nIiwibnVtYmVycyI6WyI5MDIxMSJdLCJ1c2VyX2ZhY2luZyI6dHJ1ZX0sIjk4NzY1Ijp7Im51bWJlcnMiOlsiOTg3NjUiXSwidXNlcl9mYWNpbmciOmZhbHNlfSwiODY3NTMwOSI6eyJudW1iZXJzIjpbIjg2NzUzMDkiXSwidXNlcl9mYWNpbmciOmZhbHNlfX19OwoJYm9vdF9kYXRhLnN0YXJ0X21zID0gRGF0ZS5ub3coKTsKPC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3JvbGx1cC1jb3JlX3JlcXVpcmVkX2xpYnMuMWRlYjc3ZjQ3Y2Q1MjFmMmNhMjUubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L21vZGVybi52ZW5kb3IuZWI3ZGNkYjNlMzFmODViY2MzOGUubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L2FwcGxpY2F0aW9uLjg5MWU2NzYyNjhhYmUzZDM3ZGY0Lm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9yb2xsdXAtY29yZV9yZXF1aXJlZF90cy44OGQxMWQ4NGFkZDJlMjYwZDA2Mi5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvVFMud2ViLjU1M2Y2ZGJkYzQ2ZTJmMDY2M2ZmLm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9zaWduYWxzLmY2NDE2MGI1YmNmYzZmOWI5MzJmLm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9yb2xsdXAtY29yZV93ZWIuZmM4ZmExMDJiNTEzODRkNzQwMDMubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L3JvbGx1cC1zZWNvbmRhcnlfYV9yZXF1aXJlZC43Mzg4ZmE5YmNiNDA1M2UyNGRkYS5taW4uanMiIG9ubG9hZD0id2luZG93Ll9jZG4gPyBfY2RuLm9rKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBvbmVycm9yPSJ3aW5kb3cuX2NkbiA/IF9jZG4uZmFpbGVkKHRoaXMsIGFyZ3VtZW50cykgOiBudWxsIiBjcm9zc29yaWdpbj0iYW5vbnltb3VzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwczovL2Euc2xhY2stZWRnZS5jb20vYnYxLTgvcm9sbHVwLXNlY29uZGFyeV9iX3JlcXVpcmVkLjk0N2QxMDQ3ZWQzMmJiMjcwN2IxLm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij5UUy5ib290KGJvb3RfZGF0YSk7PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cHM6Ly9hLnNsYWNrLWVkZ2UuY29tL2J2MS04L1RTLndlYi5fNDA0LmFkZTVlMWRhNDk1MDE0NGM2ZDg0Lm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9zdGlja3lfbmF2LmI1ODE4YjJkZDQ0ZTZhZTAwMDQ0Lm1pbi5qcyIgb25sb2FkPSJ3aW5kb3cuX2NkbiA/IF9jZG4ub2sodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIG9uZXJyb3I9IndpbmRvdy5fY2RuID8gX2Nkbi5mYWlsZWQodGhpcywgYXJndW1lbnRzKSA6IG51bGwiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHBzOi8vYS5zbGFjay1lZGdlLmNvbS9idjEtOC9mb290ZXIuZjE1YjNjYmY0Njg3NzE0N2YwNjYubWluLmpzIiBvbmxvYWQ9IndpbmRvdy5fY2RuID8gX2Nkbi5vayh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgb25lcnJvcj0id2luZG93Ll9jZG4gPyBfY2RuLmZhaWxlZCh0aGlzLCBhcmd1bWVudHMpIDogbnVsbCIgY3Jvc3NvcmlnaW49ImFub255bW91cyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmJvb3RfZGF0YS5ub19sb2dpbiA9IHRydWU7PC9zY3JpcHQ+PHN0eWxlPi5jb2xvcl85ZjY5ZTc6bm90KC5udWMpIHtjb2xvcjojOUY2OUU3O30uY29sb3JfNGJiZTJlOm5vdCgubnVjKSB7Y29sb3I6IzRCQkUyRTt9LmNvbG9yX2U3MzkyZDpub3QoLm51Yykge2NvbG9yOiNFNzM5MkQ7fS5jb2xvcl8zYzk4OWY6bm90KC5udWMpIHtjb2xvcjojM0M5ODlGO30uY29sb3JfNjc0YjFiOm5vdCgubnVjKSB7Y29sb3I6IzY3NEIxQjt9LmNvbG9yX2U5NjY5OTpub3QoLm51Yykge2NvbG9yOiNFOTY2OTk7fS5jb2xvcl9lMGE3Mjk6bm90KC5udWMpIHtjb2xvcjojRTBBNzI5O30uY29sb3JfNjg0YjZjOm5vdCgubnVjKSB7Y29sb3I6IzY4NEI2Qzt9LmNvbG9yXzViODlkNTpub3QoLm51Yykge2NvbG9yOiM1Qjg5RDU7fS5jb2xvcl8yYjY4MzY6bm90KC5udWMpIHtjb2xvcjojMkI2ODM2O30uY29sb3JfOTlhOTQ5Om5vdCgubnVjKSB7Y29sb3I6Izk5QTk0OTt9LmNvbG9yX2RmM2RjMDpub3QoLm51Yykge2NvbG9yOiNERjNEQzA7fS5jb2xvcl80Y2MwOTE6bm90KC5udWMpIHtjb2xvcjojNENDMDkxO30uY29sb3JfOWIzYjQ1Om5vdCgubnVjKSB7Y29sb3I6IzlCM0I0NTt9LmNvbG9yX2Q1ODI0Nzpub3QoLm51Yykge2NvbG9yOiNENTgyNDc7fS5jb2xvcl9iYjg2Yjc6bm90KC5udWMpIHtjb2xvcjojQkI4NkI3O30uY29sb3JfNWE0NTkyOm5vdCgubnVjKSB7Y29sb3I6IzVBNDU5Mjt9LmNvbG9yX2RiMzE1MDpub3QoLm51Yykge2NvbG9yOiNEQjMxNTA7fS5jb2xvcl8yMzVlNWI6bm90KC5udWMpIHtjb2xvcjojMjM1RTVCO30uY29sb3JfOWUzOTk3Om5vdCgubnVjKSB7Y29sb3I6IzlFMzk5Nzt9LmNvbG9yXzUzYjc1OTpub3QoLm51Yykge2NvbG9yOiM1M0I3NTk7fS5jb2xvcl9jMzg2ZGY6bm90KC5udWMpIHtjb2xvcjojQzM4NkRGO30uY29sb3JfMzg1YTg2Om5vdCgubnVjKSB7Y29sb3I6IzM4NUE4Njt9LmNvbG9yX2E2MzAyNDpub3QoLm51Yykge2NvbG9yOiNBNjMwMjQ7fS5jb2xvcl81ODcwZGQ6bm90KC5udWMpIHtjb2xvcjojNTg3MEREO30uY29sb3JfZWEyOTc3Om5vdCgubnVjKSB7Y29sb3I6I0VBMjk3Nzt9LmNvbG9yXzUwYTBjZjpub3QoLm51Yykge2NvbG9yOiM1MEEwQ0Y7fS5jb2xvcl9kNTVhZWY6bm90KC5udWMpIHtjb2xvcjojRDU1QUVGO30uY29sb3JfZDE3MDdkOm5vdCgubnVjKSB7Y29sb3I6I0QxNzA3RDt9LmNvbG9yXzQzNzYxYjpub3QoLm51Yykge2NvbG9yOiM0Mzc2MUI7fS5jb2xvcl9lMDZiNTY6bm90KC5udWMpIHtjb2xvcjojRTA2QjU2O30uY29sb3JfOGY0YTJiOm5vdCgubnVjKSB7Y29sb3I6IzhGNEEyQjt9LmNvbG9yXzkwMmQ1OTpub3QoLm51Yykge2NvbG9yOiM5MDJENTk7fS5jb2xvcl9kZTVmMjQ6bm90KC5udWMpIHtjb2xvcjojREU1RjI0O30uY29sb3JfYTJhNWRjOm5vdCgubnVjKSB7Y29sb3I6I0EyQTVEQzt9LmNvbG9yXzgyNzMyNzpub3QoLm51Yykge2NvbG9yOiM4MjczMjc7fS5jb2xvcl8zYzhjNjk6bm90KC5udWMpIHtjb2xvcjojM0M4QzY5O30uY29sb3JfOGQ0Yjg0Om5vdCgubnVjKSB7Y29sb3I6IzhENEI4NDt9LmNvbG9yXzg0YjIyZjpub3QoLm51Yykge2NvbG9yOiM4NEIyMkY7fS5jb2xvcl80ZWMwZDY6bm90KC5udWMpIHtjb2xvcjojNEVDMEQ2O30uY29sb3JfZTIzZjk5Om5vdCgubnVjKSB7Y29sb3I6I0UyM0Y5OTt9LmNvbG9yX2U0NzVkZjpub3QoLm51Yykge2NvbG9yOiNFNDc1REY7fS5jb2xvcl82MTlhNGY6bm90KC5udWMpIHtjb2xvcjojNjE5QTRGO30uY29sb3JfYTcyZjc5Om5vdCgubnVjKSB7Y29sb3I6I0E3MkY3OTt9LmNvbG9yXzdkNDE0Yzpub3QoLm51Yykge2NvbG9yOiM3RDQxNEM7fS5jb2xvcl9hYmE3Mjc6bm90KC5udWMpIHtjb2xvcjojQUJBNzI3O30uY29sb3JfOTY1ZDFiOm5vdCgubnVjKSB7Y29sb3I6Izk2NUQxQjt9LmNvbG9yXzRkNWUyNjpub3QoLm51Yykge2NvbG9yOiM0RDVFMjY7fS5jb2xvcl9kZDg1Mjc6bm90KC5udWMpIHtjb2xvcjojREQ4NTI3O30uY29sb3JfYmQ5MzM2Om5vdCgubnVjKSB7Y29sb3I6I0JEOTMzNjt9LmNvbG9yX2U4NWQ3Mjpub3QoLm51Yykge2NvbG9yOiNFODVENzI7fS5jb2xvcl9kYzdkYmI6bm90KC5udWMpIHtjb2xvcjojREM3REJCO30uY29sb3JfYmMzNjYzOm5vdCgubnVjKSB7Y29sb3I6I0JDMzY2Mzt9LmNvbG9yXzlkOGVlZTpub3QoLm51Yykge2NvbG9yOiM5RDhFRUU7fS5jb2xvcl84NDY5YmM6bm90KC5udWMpIHtjb2xvcjojODQ2OUJDO30uY29sb3JfNzM3NjlkOm5vdCgubnVjKSB7Y29sb3I6IzczNzY5RDt9LmNvbG9yX2IxNGNiYzpub3QoLm51Yykge2NvbG9yOiNCMTRDQkM7fTwvc3R5bGU+Cgo8IS0tIHNsYWNrLXd3dy1oaHZtLW1haW4taWFkLTJ2ajYvIDIwMjAtMTAtMDggMjE6MzE6MjkvIHY1NzAzYWFiNjIzYzRmN2U5NjU1OTU0NDhmYzAwM2E3ODZhOTJiODEzLyBCOkggLS0+Cgo8L2JvZHk+PC9odG1sPg== + recorded_at: Fri, 09 Oct 2020 04:31:29 GMT recorded_with: VCR 6.0.0 From a25ba367cd14c583ffe800a0ba68c954e396871d Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 22:12:20 -0700 Subject: [PATCH 85/92] fixed indentation --- lib/user.rb | 1 - test/cassettes/channel_history.yml | 75 ------------------------------ 2 files changed, 76 deletions(-) delete mode 100644 test/cassettes/channel_history.yml diff --git a/lib/user.rb b/lib/user.rb index 52434606..320f2b34 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -21,6 +21,5 @@ def self.list_all def details return "ID: #{@slack_id} \nName: #{@name} \nReal Name: #{@real_name} \nStatus: #{@status_text} \nEmoji: #{@status_emoji}" end - end end \ No newline at end of file diff --git a/test/cassettes/channel_history.yml b/test/cassettes/channel_history.yml deleted file mode 100644 index 898f139a..00000000 --- a/test/cassettes/channel_history.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://slack.com/api/conversations.history?channel=C01BL0GSPP1&token=SLACK_API_TOKEN - body: - encoding: US-ASCII - string: '' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 09 Oct 2020 02:23:18 GMT - Server: - - Apache - X-Slack-Req-Id: - - ad77de7e299e39a8f1b90e4bcc8c8b82 - X-Oauth-Scopes: - - chat:write,channels:manage,groups:write,channels:read,users:read,channels:history,groups:history,im:history - Access-Control-Expose-Headers: - - x-slack-req-id, retry-after - Access-Control-Allow-Origin: - - "*" - X-Slack-Backend: - - r - X-Content-Type-Options: - - nosniff - Expires: - - Mon, 26 Jul 1997 05:00:00 GMT - Cache-Control: - - private, no-cache, no-store, must-revalidate - X-Xss-Protection: - - '0' - X-Accepted-Oauth-Scopes: - - channels:history,groups:history,mpim:history,im:history,read - Access-Control-Allow-Headers: - - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, - x-b3-sampled, x-b3-flags - Vary: - - Accept-Encoding - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - Referrer-Policy: - - no-referrer - Content-Length: - - '577' - Content-Type: - - application/json; charset=utf-8 - X-Via: - - haproxy-www-1obv,haproxy-edge-pdx-rgh8 - body: - encoding: ASCII-8BIT - string: '{"ok":true,"messages":[{"bot_id":"B01BU12FUEA","type":"message","text":"make - Chidi choose a puppy","user":"U01BL0TC86B","ts":"1602195554.001100","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water - - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"bot_id":"B01BU12FUEA","type":"message","text":"flatten - penises","user":"U01BL0TC86B","ts":"1602192941.000900","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water - - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"type":"message","subtype":"channel_join","ts":"1602189817.000700","user":"U01CDBMR333","text":"<@U01CDBMR333> - has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_join","ts":"1602189744.000400","user":"U01BL0TC86B","text":"<@U01BL0TC86B> - has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_topic","ts":"1602116354.000200","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> - set the channel topic: torture Chidi","topic":"torture Chidi"},{"type":"message","subtype":"channel_join","ts":"1601951182.000500","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> - has joined the channel"},{"type":"message","subtype":"channel_join","ts":"1601951127.000200","user":"U01C6TTNL6Q","text":"<@U01C6TTNL6Q> - has joined the channel"}],"has_more":false,"pin_count":0,"channel_actions_ts":null,"channel_actions_count":0}' - recorded_at: Fri, 09 Oct 2020 02:23:17 GMT -recorded_with: VCR 6.0.0 From 37190c4322d0b0b3f5f69a4a2b004b99ab6d4b52 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 22:13:13 -0700 Subject: [PATCH 86/92] added argument error to send_message --- lib/workspace.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index c0f50b3d..66b6efdf 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -11,12 +11,10 @@ def initialize @channels = Channel.list_all end - #user name, real name, slack Id def list_users return @users.map{|user| {id: user.slack_id, name: user.name, real_name: user.real_name} } end - #topic, member count, slack ID, topic["value"] def list_channels return @channels.map{|channel| {id: channel.slack_id, name: channel.name, topic: channel.topic, member_count: channel.member_count}} end @@ -32,12 +30,12 @@ def show_details(recipient) end def send_message(message, recipient) + raise ArgumentError.new("recipient must be of Recipient class") unless recipient.is_a? Recipient recipient.send_message(message) end def conversation_history(channel) return channel.channel_history end - end end \ No newline at end of file From e9a82ef5a66f0b367e420f55dad37bedbdac1200 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 22:13:58 -0700 Subject: [PATCH 87/92] refactored recipient test --- test/recipient_test.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 148386d1..c6666b68 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -28,16 +28,15 @@ it "raises SlackAPIError for bad API call" do VCR.use_cassette("self.get API error") do - expect{SlackCLI::Recipient.get("https://slack.com/api/users.list", {token: "sggreg"})}.must_raise SlackCLI::SlackAPIError + expect{SlackCLI::Recipient.get("users.list", {token: "sggreg"})}.must_raise SlackCLI::SlackAPIError end end it "returns HTTParty::Response for succesful calls" do VCR.use_cassette("self.get nominal") do - expect(SlackCLI::Recipient.get("https://slack.com/api/users.list", {token: ENV["SLACK_API_TOKEN"]})).must_be_instance_of HTTParty::Response + expect(SlackCLI::Recipient.get("users.list", {token: ENV["SLACK_API_TOKEN"]})).must_be_instance_of HTTParty::Response end end - end describe 'details' do From 43bb11e4e7474df601c5d40092bc8177fc1bfdd6 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 22:15:16 -0700 Subject: [PATCH 88/92] refactored test for changes in send_message and conversation_history --- test/workspace_test.rb | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 60745ebe..d207dbac 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -1,7 +1,6 @@ require_relative 'test_helper' describe 'Workspace' do - before do VCR.use_cassette("user_channel_find") do @workspace = SlackCLI::Workspace.new @@ -35,7 +34,6 @@ end describe "select method" do - it "raises ArgumentError if name or id isn't provided" do VCR.use_cassette("invalid_select") do expect{@workspace.select(SlackCLI::User, nil)}.must_raise ArgumentError @@ -76,49 +74,62 @@ end describe "send_message method" do + before do + VCR.use_cassette("Create test channel & user") do + @channel = SlackCLI::Channel.select("C01BL0GSPP1") + @user = SlackCLI::User.select("iris.lux0") + end + end + it "can send a valid message to user" do VCR.use_cassette("slack-posts-user") do - response = @workspace.send_message("Test Test Test", "U01C6TTNL6Q") + response = @workspace.send_message("Test Test Test", @user) expect(response).must_equal true end end it "can send a valid message to channel" do VCR.use_cassette("slack-posts-channel") do - response = @workspace.send_message("Test Test Test", "C01BU0NRFHC") + response = @workspace.send_message("Test Test Test", @channel) expect(response).must_equal true end end it "returns an error if no recipient selected" do VCR.use_cassette("slack-posts-no-recipient") do - expect{@workspace.send_message("Test Test Test", nil)}.must_raise SlackCLI::SlackAPIError + expect{@workspace.send_message("Test Test Test", nil)}.must_raise ArgumentError end end it "returns an error if wrong channel selected" do VCR.use_cassette("slack-posts-wrong-channel") do - expect{@workspace.send_message("Test Test Test", "2i3nfidl")}.must_raise SlackCLI::SlackAPIError + expect{@workspace.send_message("Test Test Test", "2i3nfidl")}.must_raise ArgumentError end end end describe "conversation history method" do + before do + VCR.use_cassette("Create test channel") do + @channel = SlackCLI::Channel.select("C01BL0GSPP1") + end + end + it "returns an Array" do VCR.use_cassette("channel_history") do - expect(@workspace.conversation_history("C01BL0GSPP1")).must_be_instance_of Array + expect(@workspace.conversation_history(@channel)).must_be_instance_of Array end end it "returns an Array of Strings" do VCR.use_cassette("channel_history") do - expect(@workspace.conversation_history("C01BL0GSPP1").first).must_be_instance_of String + expect(@workspace.conversation_history(@channel).first).must_be_instance_of String end end it "returns accurate information" do VCR.use_cassette("channel_history") do - expect(@workspace.conversation_history("C01BL0GSPP1").first).must_equal "make Chidi choose a puppy" + expect(@workspace.conversation_history(@channel).first).must_equal "make Chidi choose a puppy" end end end From d9bb93e4a1d44c8c1be2634cde643423fab5f804 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Thu, 8 Oct 2020 22:15:43 -0700 Subject: [PATCH 89/92] new cassettes --- test/cassettes/Create_test_channel.yml | 73 +++++++ test/cassettes/Create_test_channel_user.yml | 218 ++++++++++++++++++++ test/cassettes/channel_history.yml | 75 +++++++ test/cassettes/slack-posts-channel.yml | 67 ++++++ 4 files changed, 433 insertions(+) create mode 100644 test/cassettes/Create_test_channel.yml create mode 100644 test/cassettes/Create_test_channel_user.yml create mode 100644 test/cassettes/channel_history.yml diff --git a/test/cassettes/Create_test_channel.yml b/test/cassettes/Create_test_channel.yml new file mode 100644 index 00000000..8d22709c --- /dev/null +++ b/test/cassettes/Create_test_channel.yml @@ -0,0 +1,73 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:47:03 GMT + Server: + - Apache + X-Slack-Req-Id: + - b43914cd4e772d9c21953e590b9299fc + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '758' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-49je,haproxy-edge-iad-qh1k + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":4},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4},{"id":"C01C2B4BJ30","name":"jasons-bud-hole","is_channel":true,"is_group":false,"is_im":false,"created":1602195856,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"jasons-bud-hole","is_shared":false,"parent_conversation":null,"creator":"U01BL0TC86B","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"boooortles","creator":"U01C0N8RAUS","last_set":1602195936},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":4},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4}],"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 04:47:03 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/Create_test_channel_user.yml b/test/cassettes/Create_test_channel_user.yml new file mode 100644 index 00000000..fc3b341b --- /dev/null +++ b/test/cassettes/Create_test_channel_user.yml @@ -0,0 +1,218 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:56:20 GMT + Server: + - Apache + X-Slack-Req-Id: + - 34b825a29e684d2a84411f00fb0b24d8 + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '758' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-17hf,haproxy-edge-pdx-mprq + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":4},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4},{"id":"C01C2B4BJ30","name":"jasons-bud-hole","is_channel":true,"is_group":false,"is_im":false,"created":1602195856,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"jasons-bud-hole","is_shared":false,"parent_conversation":null,"creator":"U01BL0TC86B","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"boooortles","creator":"U01C0N8RAUS","last_set":1602195936},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":4},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4}],"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 04:56:20 GMT +- request: + method: get + uri: https://slack.com/api/conversations.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:56:20 GMT + Server: + - Apache + X-Slack-Req-Id: + - 5ebbb0466a34f732d0ffca3235e24911 + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '758' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-5fg6,haproxy-edge-pdx-iofq + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01BL0GSPP1","name":"good-place-simulation","is_channel":true,"is_group":false,"is_im":false,"created":1601951127,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"good-place-simulation","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"torture + Chidi","creator":"U01C0N8RAUS","last_set":1602116354},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C6TTNL6Q","last_set":1601951127},"previous_names":[],"num_members":4},{"id":"C01BU0NRFHC","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4},{"id":"C01C2B4BJ30","name":"jasons-bud-hole","is_channel":true,"is_group":false,"is_im":false,"created":1602195856,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"jasons-bud-hole","is_shared":false,"parent_conversation":null,"creator":"U01BL0TC86B","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"boooortles","creator":"U01C0N8RAUS","last_set":1602195936},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":4},{"id":"C01CDB91LJV","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601950932,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C6TTNL6Q","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01CDB91DEV"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C6TTNL6Q","last_set":1601950932},"previous_names":[],"num_members":4}],"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 04:56:20 GMT +- request: + method: get + uri: https://slack.com/api/users.list?token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:58:14 GMT + Server: + - Apache + X-Slack-Req-Id: + - 1b8dd9b4d491790feb6601fcb920f003 + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1318' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-2t0q,haproxy-edge-pdx-9hgy + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01CDB91DEV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BL0TC86B","team_id":"T01CDB91DEV","name":"water_jessica_api_pro","deleted":false,"color":"3c989f","real_name":"Water + - Jessica - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Jessica - API Project","real_name_normalized":"Water - Jessica - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g16790b5cf92","api_app_id":"A01CDBH820Z","always_active":false,"bot_id":"B01BU12FUEA","image_24":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/16790b5cf92fa710fe62124d8e396ca0.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951747},{"id":"U01C0N8RAUS","team_id":"T01CDB91DEV","name":"jwinchan","deleted":false,"color":"4bbe2e","real_name":"Jessica + Chan","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jessica + Chan","real_name_normalized":"Jessica Chan","display_name":"Jessica (she.her)","display_name_normalized":"Jessica + (she.her)","fields":null,"status_text":"Working remotely","status_emoji":":house_with_garden:","status_expiration":1602226799,"avatar_hash":"g39037b8a717","first_name":"Jessica","last_name":"Chan","image_24":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/39037b8a71732985894324596ea039a4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0002-512.png","status_text_canonical":"Working + remotely","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1602143803},{"id":"U01C6TTNL6Q","team_id":"T01CDB91DEV","name":"iris.lux0","deleted":false,"color":"9f69e7","real_name":"iris.lux0","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"iris.lux0","real_name_normalized":"iris.lux0","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g8d593922863","image_24":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/8d593922863357982e4c3f1edcec6c86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601950931},{"id":"U01CDBMR333","team_id":"T01CDB91DEV","name":"water_iris_api_projec","deleted":false,"color":"e7392d","real_name":"Water + - Iris - API Project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight + Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Water + - Iris - API Project","real_name_normalized":"Water - Iris - API Project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9e7948e1649","api_app_id":"A01CDBH7333","always_active":false,"bot_id":"B01C0UMPS1Z","image_24":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9e7948e164991118159e70f2290c14d9.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png","status_text_canonical":"","team":"T01CDB91DEV"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1601951694}],"cache_ts":1602219494,"response_metadata":{"next_cursor":""}}' + recorded_at: Fri, 09 Oct 2020 04:58:14 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/channel_history.yml b/test/cassettes/channel_history.yml new file mode 100644 index 00000000..adef8a88 --- /dev/null +++ b/test/cassettes/channel_history.yml @@ -0,0 +1,75 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.history?channel=C01BL0GSPP1&token=SLACK_API_TOKEN + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:47:04 GMT + Server: + - Apache + X-Slack-Req-Id: + - f8f8d560089d65a0629a7ebce0c07bcc + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:history,groups:history,mpim:history,im:history,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '577' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-c8nh,haproxy-edge-iad-hgpb + body: + encoding: ASCII-8BIT + string: '{"ok":true,"messages":[{"bot_id":"B01BU12FUEA","type":"message","text":"make + Chidi choose a puppy","user":"U01BL0TC86B","ts":"1602195554.001100","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water + - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"bot_id":"B01BU12FUEA","type":"message","text":"flatten + penises","user":"U01BL0TC86B","ts":"1602192941.000900","team":"T01CDB91DEV","bot_profile":{"id":"B01BU12FUEA","deleted":false,"name":"Water + - Jessica - API Project","updated":1601951747,"app_id":"A01CDBH820Z","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}},{"type":"message","subtype":"channel_join","ts":"1602189817.000700","user":"U01CDBMR333","text":"<@U01CDBMR333> + has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_join","ts":"1602189744.000400","user":"U01BL0TC86B","text":"<@U01BL0TC86B> + has joined the channel","inviter":"U01C0N8RAUS"},{"type":"message","subtype":"channel_topic","ts":"1602116354.000200","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> + set the channel topic: torture Chidi","topic":"torture Chidi"},{"type":"message","subtype":"channel_join","ts":"1601951182.000500","user":"U01C0N8RAUS","text":"<@U01C0N8RAUS> + has joined the channel"},{"type":"message","subtype":"channel_join","ts":"1601951127.000200","user":"U01C6TTNL6Q","text":"<@U01C6TTNL6Q> + has joined the channel"}],"has_more":false,"pin_count":0,"channel_actions_ts":null,"channel_actions_count":0}' + recorded_at: Fri, 09 Oct 2020 04:47:04 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/slack-posts-channel.yml b/test/cassettes/slack-posts-channel.yml index cf297f8e..e75f84d0 100644 --- a/test/cassettes/slack-posts-channel.yml +++ b/test/cassettes/slack-posts-channel.yml @@ -132,4 +132,71 @@ http_interactions: encoding: ASCII-8BIT string: '{"ok":false,"error":"channel_not_found"}' recorded_at: Fri, 09 Oct 2020 00:10:10 GMT +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=SLACK_API_TOKEN&text=Test%20Test%20Test&channel=C01BL0GSPP1&as_user=true + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Fri, 09 Oct 2020 04:56:21 GMT + Server: + - Apache + X-Slack-Req-Id: + - 502e7179fe507af05dd002fb4b0dff53 + X-Oauth-Scopes: + - chat:write,users:read,channels:read,channels:history,groups:history + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '333' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-oxoh,haproxy-edge-pdx-ttqn + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"C01BL0GSPP1","ts":"1602219381.001200","message":{"bot_id":"B01C0UMPS1Z","type":"message","text":"Test + Test Test","user":"U01CDBMR333","ts":"1602219381.001200","team":"T01CDB91DEV","bot_profile":{"id":"B01C0UMPS1Z","deleted":false,"name":"Water + - Iris - API Project","updated":1601951694,"app_id":"A01CDBH7333","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01CDB91DEV"}}}' + recorded_at: Fri, 09 Oct 2020 04:56:21 GMT recorded_with: VCR 6.0.0 From a16f7c0c4f216a7c7ee9f6a5693128e6799f758c Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Fri, 9 Oct 2020 00:25:27 -0700 Subject: [PATCH 90/92] added line to give workspace info --- lib/slack.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/slack.rb b/lib/slack.rb index b3c09f96..efbd1770 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -7,8 +7,9 @@ def main Dotenv.load - puts "Welcome to the Ada Slack CLI!" + puts "Welcome to the Ada Slack CLI!\n\n" workspace = SlackCLI::Workspace.new + puts "This workspace has #{workspace.list_channels.length} channels and #{workspace.list_users.length} users." option = nil current_selection = nil From 4c981ef981a006bb421d8c732210817a8848a1d6 Mon Sep 17 00:00:00 2001 From: Jessica Chan Date: Fri, 9 Oct 2020 01:43:49 -0700 Subject: [PATCH 91/92] modified workspace info statement --- lib/slack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack.rb b/lib/slack.rb index efbd1770..399a3236 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -9,7 +9,7 @@ def main puts "Welcome to the Ada Slack CLI!\n\n" workspace = SlackCLI::Workspace.new - puts "This workspace has #{workspace.list_channels.length} channels and #{workspace.list_users.length} users." + puts "This workspace has #{workspace.channels.length} channels and #{workspace.users.length} users." option = nil current_selection = nil From dbce3f4196392e0d460784653f9c268442c0a580 Mon Sep 17 00:00:00 2001 From: Iris Lux Date: Wed, 4 Nov 2020 11:27:55 -0800 Subject: [PATCH 92/92] test --- lib/user.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/user.rb b/lib/user.rb index 320f2b34..f95e8dc5 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -2,7 +2,10 @@ module SlackCLI class User < Recipient - + # + # TEST TEST TEST TES TEST + # + # attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:)