xbl_gamercard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0fca948f8e0a789a7d3650815079ae763bb4e70
4
+ data.tar.gz: ef0b5d37d04bce9a44fd55d99b3c82d21adb865b
5
+ SHA512:
6
+ metadata.gz: 1e4053142d5238336cde23561df576eaff0d73a783bc12de9faa595932c8d44b8c4a1405b6e0b108483c95ee7267cac8ed198ee7820a95a40a672bdbb2f46ca5
7
+ data.tar.gz: 81d6ab0fa905aa3a4384c540799bae641cefd04d7d138c38602f7bfb39f9a34b8ab6e8ba6d48a8a1cb04aa393f68796df3e3a14adef0d78efaa477935fcde960
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xbl_gamercard.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Hsiu-Fan Wang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Hsiu-Fan Wang
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # XblGamercard
2
+
3
+ XBox Live gamercard and Live profile scraper. Scrapes Microsoft's sites, trading one kind of reliability (not relying on xboxleaders API) for another (having to scrape potentially changing output).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'xbl_gamercard'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install xbl_gamercard
18
+
19
+ ## Usage
20
+
21
+ There are two main classes, `XblGamercard::Gamercard` and `XblGamercard::LiveProfile`, representing two different views with slightly different data.
22
+
23
+ * Gamercard (Example: http://gamercard.xbox.com/en-US/Major%20Nelson.card)
24
+ * Live profile (Example: https://live.xbox.com/en-US/Profile?Gamertag=Major+Nelson)
25
+
26
+ Gamercard is the only one that reliably returns recent games, while Live profile is the only one that returns "presence". Both otherwise return largely the same set of data, name, bio, gamerscore, so forth. You can either call `.fetch(gamertag)` to use `Net::HTTP` to load the page and then parse it, or simply call `new` with the response body (if you have specific HTTP request-ing needs).
27
+
28
+ ## Examples
29
+
30
+ ```ruby
31
+ gamercard = XblGamercard::Gamercard.fetch("major nelson")
32
+ # You can also have used:
33
+ # response = Net::HTTP.get_response(URI(XblGamercard::Gamercard.url_for(gamertag)))
34
+ # gamercard = XblGamerCard::Gamercard.new(response.body)
35
+ gamercard.gamertag # Returns "Major Nelson"
36
+ gamercard.icon_url # Returns "http://avatar.xboxlive.com/avatar/Major%20Nelson/avatarpic-l.png"
37
+ gamercard.gamerscore # Returns 66947
38
+ gamercard.motto
39
+ gamercard.name
40
+ gamercard.bio
41
+ # Gamercard specific! You can get a list of recently played games:
42
+ game = gamercard.played_games[0]
43
+ game.title
44
+ game.icon_url
45
+ game.earned_gamerscore
46
+ game.available_gamerscore
47
+ game.earned_archievements
48
+ game.available_achievements
49
+ game.percentage_complete
50
+ ```
51
+
52
+ The Live profile page is pretty similar, except for the addition of a `presence` and `avatar_image_url` method.
53
+
54
+ ```ruby
55
+ profile = XblGamercard::LiveProfile.fetch("major nelson")
56
+ # You can also have used:
57
+ # response = Net::HTTP.get_response(URI(XblGamercard::LiveProfile.url_for(gamertag)))
58
+ # profile = XblGamerCard::LiveProfile.new(response.body)
59
+ profile.gamertag # Returns "Major Nelson"
60
+ profile.icon_url # Returns "http://avatar.xboxlive.com/avatar/Major%20Nelson/avatarpic-l.png"
61
+ profile.avatar_image_url # Returns "https://avatar-ssl.xboxlive.com/avatar/Major%20Nelson/avatar-body.png"
62
+ profile.gamerscore # Returns 66947
63
+ profile.presence # Returns something like "Last seen 2/28/2014 playing Xbox.com"
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it (http://github.com/hfwang/xbl_gamercard/fork)
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
73
+
74
+ ## See Also
75
+
76
+ There is a ton of prior art out there. This gem scrapes the public profile pages, while I found the others deficient in a variety of ways.
77
+
78
+ * https://github.com/hypomodern/gamercard - Only scrapes the Live profile page (which no longer shows played games)
79
+ * https://github.com/greendog99/xbox_live - Actually uses mechanize to login, potentially flakey.
80
+
81
+ Xboxleaders (http://xboxleaders.github.io/) based gems, which is pretty slow/unreliable. :cry:
82
+ * https://github.com/barisbalic/gamertag
83
+ * https://github.com/Keithbsmiley/xboxleaders-gem
84
+ * https://github.com/nevern02/xbox_leaders
85
+ * https://github.com/nicolasiensen/xbox-live
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new
7
+ rescue LoadError => e
8
+ task :spec do
9
+ abort "Please run `gem install rspec` to install RSpec."
10
+ end
11
+ end
12
+
13
+ task :test => :spec
14
+ task :default => :spec
@@ -0,0 +1,8 @@
1
+ require "xbl_gamercard/version"
2
+ require "xbl_gamercard/micro_scraper"
3
+ require "xbl_gamercard/gamercard"
4
+ require "xbl_gamercard/gamercard_game"
5
+ require "xbl_gamercard/live_profile"
6
+
7
+ module XblGamercard
8
+ end
@@ -0,0 +1,44 @@
1
+ require "net/http"
2
+ require "nokogiri"
3
+ require "uri"
4
+
5
+ module XblGamercard
6
+ class Gamercard
7
+ include XblGamercard::MicroScraper
8
+
9
+ attr_accessor :element
10
+
11
+ def initialize(html)
12
+ @element = Nokogiri::HTML(html)
13
+ end
14
+
15
+ extract_text("#Gamertag")
16
+ extract_int("#Gamerscore")
17
+ extract_text("#Location")
18
+ extract_text("#Motto")
19
+ extract_text("#Name")
20
+ extract_text("#Bio")
21
+ extract("#Gamerpic", :as => :icon_url) { |e| e["src"] }
22
+
23
+ def played_games
24
+ return element.css("ol#PlayedGames>li").select { |e|
25
+ # This is annoyingly hard to express using MicroScraper on older
26
+ # versions of Nokogiri...
27
+ e["class"] != "Unplayed"
28
+ }.map { |e|
29
+ XblGamercard::GamercardGame.new(e)
30
+ }
31
+ end
32
+
33
+ def self.fetch(gamertag)
34
+ uri = URI(self.url_for(gamertag))
35
+ contents = Net::HTTP.get_response(uri)
36
+ return self.new(contents.body)
37
+ end
38
+
39
+ def self.url_for(gamertag)
40
+ # Use URI.escape because we actually want percent encoding (%20 for space instead of +)
41
+ return "http://gamercard.xbox.com/en-US/#{URI.escape(gamertag)}.card"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ module XblGamercard
2
+ class GamercardGame
3
+ include XblGamercard::MicroScraper
4
+ attr_accessor :element
5
+
6
+ def initialize(element)
7
+ @element = element
8
+ end
9
+
10
+ extract_text ".Title"
11
+ extract_text ".LastPlayed"
12
+ extract_int ".EarnedGamerscore"
13
+ extract_int ".AvailableGamerscore"
14
+ extract_int ".EarnedAchievements"
15
+ extract_int ".AvailableAchievements"
16
+ # Text is actually something like "99%", but to_i results in 99
17
+ extract_int ".PercentageComplete"
18
+ extract("img", :as => :icon_url) { |e| e["src"] }
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ require "net/https"
2
+ require "nokogiri"
3
+ require "uri"
4
+ require "cgi"
5
+
6
+ module XblGamercard
7
+ class LiveProfile
8
+ include XblGamercard::MicroScraper
9
+
10
+ attr_accessor :element
11
+
12
+ def initialize(html)
13
+ @element = Nokogiri::HTML(html)
14
+ end
15
+
16
+ extract("article.profile.you", :as => :gamertag) { |e| e["data-gamertag"] }
17
+ extract("article.profile.you img.gamerpic", :as => "icon_url") { |e| e["src"] }
18
+ extract_text "article.profile.you .basics .name .value", :as => :name
19
+ extract_text "article.profile.you .location .value", :as => :location
20
+ extract_text "article.profile.you .bio .value", :as => :bio
21
+ extract(".motto") { |e| e.nil? ? "" : e.text.strip }
22
+ extract_int "article.profile.you .basics .gamerscore"
23
+
24
+ extract_text ".links .presence"
25
+
26
+ def avatar_image_url
27
+ "https://avatar-ssl.xboxlive.com/avatar/#{URI.escape(gamertag)}/avatar-body.png"
28
+ end
29
+
30
+ def self.fetch(gamertag)
31
+ uri = URI(self.url_for(gamertag))
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+ http.use_ssl = true
34
+
35
+ request = Net::HTTP::Get.new(uri.request_uri)
36
+
37
+ response = http.request(request)
38
+ return self.new(response.body)
39
+ end
40
+
41
+ def self.url_for(gamertag)
42
+ return "https://live.xbox.com/en-US/Profile?Gamertag=#{CGI.escape(gamertag)}"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,83 @@
1
+ module XblGamercard
2
+ # Really simple scraper DSL for objects that have a root node and want to
3
+ # extract data from the root node's children.
4
+ #
5
+ # The class must have a method called `element` that returns the root node.
6
+ #
7
+ # The various extract methods all take a CSS selector, and optionally a hash
8
+ # of options and a block. The block is applied to the first node (for extract
9
+ # methods), or mapped to each node (for extract_all methods).
10
+ #
11
+ # Options are:
12
+ # * <tt>:as</tt> - The name of the method that is generated.
13
+ # * <tt>:from</tt> - The name of the method that returns the root element.
14
+ #
15
+ # class XblGamercard
16
+ # include XblGamercard::Microscraper
17
+ #
18
+ # # The following are all equivalent
19
+ # extract("#Gamertag", :as => "gamertag") { |e| e.text }
20
+ # extract_text "#Gamertag"
21
+ #
22
+ # extract_int "#Gamerscore"
23
+ # extract_text("#Gamerscore", &:to_i)
24
+ # extract("#Gamerscore") { |e| e.text.to_i }
25
+ module MicroScraper
26
+ module ClassMethods
27
+ # Specifies a field that is simply extracted from the document
28
+ def extract(selector, opts=nil, &block)
29
+ opts = opts.nil? ? {} : opts.dup
30
+ opts[:as] ||= ClassMethods.field_name(selector)
31
+ opts[:from] ||= :element
32
+
33
+ define_method(opts[:as]) do
34
+ elem = send(opts[:from]).css(selector)[0]
35
+
36
+ next block.call(elem) if block
37
+ next elem
38
+ end
39
+ end
40
+
41
+ def extract_text(selector, opts=nil, &block)
42
+ extract(selector, opts) do |elem|
43
+ next block.call(elem.text) if block
44
+ next elem.text
45
+ end
46
+ end
47
+
48
+ def extract_int(selector, opts=nil, &block)
49
+ extract_text(selector, opts) do |elem|
50
+ next block.call(elem.to_i) if block
51
+ next elem.to_i
52
+ end
53
+ end
54
+
55
+ # Specifies a field that returns an array of matched elements
56
+ def extract_all(selector, opts=nil, &block)
57
+ opts = opts.nil? ? {} : opts.dup
58
+ opts[:as] ||= ClassMethods.field_name(selector)
59
+ opts[:from] ||= :element
60
+
61
+ define_method(opts[:as]) do
62
+ elems = send(opts[:from]).css(selector).to_a
63
+
64
+ next elems.map { |e| block.call(e) } if block
65
+ next elems
66
+ end
67
+ end
68
+
69
+ def self.field_name(selector)
70
+ word = selector.split(/[\W]/).last
71
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
72
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
73
+ word.tr!("-", "_")
74
+ word.downcase!
75
+ word
76
+ end
77
+ end
78
+
79
+ def self.included(base)
80
+ base.extend(ClassMethods)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module XblGamercard
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,181 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://gamercard.xbox.com/en-US/rider2710.card
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Host:
17
+ - gamercard.xbox.com
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Cache-Control:
24
+ - private
25
+ Content-Type:
26
+ - text/html; charset=utf-8
27
+ X-Ua-Compatible:
28
+ - IE=edge
29
+ X-Content-Type-Options:
30
+ - nosniff
31
+ Vary:
32
+ - Accept-Encoding
33
+ Date:
34
+ - Mon, 03 Mar 2014 05:37:02 GMT
35
+ Content-Length:
36
+ - '6124'
37
+ Connection:
38
+ - keep-alive
39
+ body:
40
+ encoding: ASCII-8BIT
41
+ string: !binary |-
42
+ DQo8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEu
43
+ MCBUcmFuc2l0aW9uYWwvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0
44
+ bWwxL0RURC94aHRtbDEtdHJhbnNpdGlvbmFsLmR0ZCI+DQo8aHRtbCB4bWxu
45
+ cz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgbGFuZz0iZW5nIj4N
46
+ CiAgICA8aGVhZD4NCiAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiB0
47
+ eXBlPSJ0ZXh0L2NzcyIgaHJlZj0iL0NvbnRlbnQvR2FtZXJjYXJkL2RlZmF1
48
+ bHQvZ2FtZXJjYXJkLmNzcyIgLz4NCiAgICAgICAgPG1ldGEgbmFtZT0icm9i
49
+ b3RzIiBjb250ZW50PSJub2luZGV4LG5vZm9sbG93IiAvPg0KICAgICAgICA8
50
+ bWV0YSBuYW1lPSJjYXRlZ29yeSIgY29udGVudD0iR2FtZXJjYXJkIiAvPg0K
51
+ ICAgICAgICA8YmFzZSB0YXJnZXQ9Il90b3AiIC8+DQogICAgICAgIDx0aXRs
52
+ ZT5yaWRlcjI3MTA8L3RpdGxlPg0KICAgIDwvaGVhZD4NCiAgICA8Ym9keT4N
53
+ CiAgICAgICAgPGRpdiBjbGFzcz0iWGJjR2FtZXJjYXJkIEdvbGQgTWFsZSAi
54
+ Pg0KICAgICAgICAgICAgDQogICAgICAgICAgICA8YSBpZD0iR2FtZXJ0YWci
55
+ IGhyZWY9Imh0dHA6Ly9saXZlLnhib3guY29tL2VuLVVTL1Byb2ZpbGU/R2Ft
56
+ ZXJ0YWc9cmlkZXIyNzEwIj5yaWRlcjI3MTA8L2E+DQogICAgICAgICAgICA8
57
+ YSBocmVmPSJodHRwOi8vbGl2ZS54Ym94LmNvbS9lbi1VUy9Qcm9maWxlP0dh
58
+ bWVydGFnPXJpZGVyMjcxMCI+DQogICAgICAgICAgICAgICAgPGltZyBpZD0i
59
+ R2FtZXJwaWMiIHNyYz0iaHR0cDovL2F2YXRhci54Ym94bGl2ZS5jb20vYXZh
60
+ dGFyL3JpZGVyMjcxMC9hdmF0YXJwaWMtbC5wbmciIGFsdD0icmlkZXIyNzEw
61
+ IiB0aXRsZT0icmlkZXIyNzEwIi8+DQogICAgICAgICAgICA8L2E+DQogICAg
62
+ ICAgICAgICA8ZGl2IGNsYXNzPSJSZXBDb250YWluZXIiPg0KICAgICAgICAg
63
+ ICAgICAgIDxsYWJlbD5SZXA8L2xhYmVsPg0KICAgICAgICAgICAgICAgIA0K
64
+ ICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJTdGFyIEZ1bGwiPjwv
65
+ ZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJTdGFyIEZ1
66
+ bGwiPjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJT
67
+ dGFyIEZ1bGwiPjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNs
68
+ YXNzPSJTdGFyIEZ1bGwiPjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8
69
+ ZGl2IGNsYXNzPSJTdGFyIEZ1bGwiPjwvZGl2Pg0KICAgICAgICAgICAgPC9k
70
+ aXY+DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJHYW1lcnNjb3JlQ29udGFp
71
+ bmVyIj4NCiAgICAgICAgICAgICAgICA8bGFiZWw+PC9sYWJlbD4NCiAgICAg
72
+ ICAgICAgICAgICA8ZGl2IGlkPSJHYW1lcnNjb3JlIj43NjQyPC9kaXY+DQog
73
+ ICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9IkxvY2F0
74
+ aW9uIj48L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9Ik1vdHRvIj5GYXN0
75
+ ICZhbXA7IEJ1bGJvdXM8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9Ik5h
76
+ bWUiPjwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iQmlvIj48L2Rpdj4N
77
+ Cg0KICAgICAgICAgICAgDQogICAgICAgICAgICA8b2wgaWQ9IlBsYXllZEdh
78
+ bWVzIiA+DQogICAgICAgICAgICANCiAgICAgICAgICAgICAgICA8bGkgPg0K
79
+ ICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgPGEg
80
+ aHJlZj0iaHR0cDovL2xpdmUueGJveC5jb20vZW4tVVMvQWN0aXZpdHkvRGV0
81
+ YWlscz90aXRsZUlkPTEwOTYxNTczNzkmYW1wO2NvbXBhcmVUbz1yaWRlcjI3
82
+ MTAiPg0KICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz0iaHR0cDov
83
+ L3RpbGVzLnhib3guY29tL3RpbGVzL05YL09xLzBtZHNiMkpoYkE5RUNnUUpH
84
+ Z1lmVmd4UUwybGpiMjR2TUM4NE1EQXdJQUFBQUFBQUFQMkZjeW89LmpwZyIg
85
+ YWx0PSJDT0Q6IEJsYWNrIE9wcyBJSSIgdGl0bGU9IkNPRDogQmxhY2sgT3Bz
86
+ IElJIiAvPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0i
87
+ VGl0bGUiPkNPRDogQmxhY2sgT3BzIElJPC9zcGFuPg0KICAgICAgICAgICAg
88
+ ICAgICAgICAgICA8c3BhbiBjbGFzcz0iTGFzdFBsYXllZCI+Mi81LzIwMTQ8
89
+ L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJF
90
+ YXJuZWRHYW1lcnNjb3JlIj4xMDU8L3NwYW4+DQogICAgICAgICAgICAgICAg
91
+ ICAgICAgIDxzcGFuIGNsYXNzPSJBdmFpbGFibGVHYW1lcnNjb3JlIj4yMDAw
92
+ PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0i
93
+ RWFybmVkQWNoaWV2ZW1lbnRzIj43PC9zcGFuPg0KICAgICAgICAgICAgICAg
94
+ ICAgICAgICA8c3BhbiBjbGFzcz0iQXZhaWxhYmxlQWNoaWV2ZW1lbnRzIj45
95
+ MDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9
96
+ IlBlcmNlbnRhZ2VDb21wbGV0ZSI+NyU8L3NwYW4+DQogICAgICAgICAgICAg
97
+ ICAgICAgIDwvYT4NCiAgICAgICAgICAgICAgICA8L2xpPg0KICAgICAgICAg
98
+ ICAgDQogICAgICAgICAgICAgICAgPGxpID4NCiAgICAgICAgICAgICAgICAg
99
+ ICAgDQogICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly9saXZl
100
+ Lnhib3guY29tL2VuLVVTL0FjdGl2aXR5L0RldGFpbHM/dGl0bGVJZD0xNDgw
101
+ NjU5NTQ4JmFtcDtjb21wYXJlVG89cmlkZXIyNzEwIj4NCiAgICAgICAgICAg
102
+ ICAgICAgICAgICAgPGltZyBzcmM9Imh0dHA6Ly90aWxlcy54Ym94LmNvbS90
103
+ aWxlcy9XUy96WS8xbWRzYjJKaGJBOUVDZ1VBR3dFZVhGb0FMMmxqYjI0dk1D
104
+ ODRNREF3SUFBQUFBQUFBUG4zTEVZPS5qcGciIGFsdD0iS2luZWN0IFBhcnR5
105
+ IiB0aXRsZT0iS2luZWN0IFBhcnR5IiAvPg0KICAgICAgICAgICAgICAgICAg
106
+ ICAgICA8c3BhbiBjbGFzcz0iVGl0bGUiPktpbmVjdCBQYXJ0eTwvc3Bhbj4N
107
+ CiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9Ikxhc3RQbGF5
108
+ ZWQiPjEvMTUvMjAxNDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAg
109
+ PHNwYW4gY2xhc3M9IkVhcm5lZEdhbWVyc2NvcmUiPjMwMDwvc3Bhbj4NCiAg
110
+ ICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9IkF2YWlsYWJsZUdh
111
+ bWVyc2NvcmUiPjQwMDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAg
112
+ PHNwYW4gY2xhc3M9IkVhcm5lZEFjaGlldmVtZW50cyI+MTU8L3NwYW4+DQog
113
+ ICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJBdmFpbGFibGVB
114
+ Y2hpZXZlbWVudHMiPjIwPC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAg
115
+ ICA8c3BhbiBjbGFzcz0iUGVyY2VudGFnZUNvbXBsZXRlIj43NSU8L3NwYW4+
116
+ DQogICAgICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgICAgICAgICA8
117
+ L2xpPg0KICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgPGxpID4NCiAg
118
+ ICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIDxhIGhy
119
+ ZWY9Imh0dHA6Ly9saXZlLnhib3guY29tL2VuLVVTL0FjdGl2aXR5L0RldGFp
120
+ bHM/dGl0bGVJZD0xMDk2MTU3MjY5JmFtcDtjb21wYXJlVG89cmlkZXIyNzEw
121
+ Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9Imh0dHA6Ly90
122
+ aWxlcy54Ym94LmNvbS90aWxlcy9SWC8wdy8xV2RzYjJKaGJBOUVDZ1FKR2dZ
123
+ ZlZscFdMMmxqYjI0dk1DODRNREF3SUFBQUFBQUFBUG9mZlZvPS5qcGciIGFs
124
+ dD0iQ2FsbCBvZiBEdXR5IEJsYWNrIE9wcyIgdGl0bGU9IkNhbGwgb2YgRHV0
125
+ eSBCbGFjayBPcHMiIC8+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFu
126
+ IGNsYXNzPSJUaXRsZSI+Q2FsbCBvZiBEdXR5IEJsYWNrIE9wczwvc3Bhbj4N
127
+ CiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9Ikxhc3RQbGF5
128
+ ZWQiPjEvMTUvMjAxNDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAg
129
+ PHNwYW4gY2xhc3M9IkVhcm5lZEdhbWVyc2NvcmUiPjE1MDwvc3Bhbj4NCiAg
130
+ ICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9IkF2YWlsYWJsZUdh
131
+ bWVyc2NvcmUiPjE3MDA8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAg
132
+ IDxzcGFuIGNsYXNzPSJFYXJuZWRBY2hpZXZlbWVudHMiPjEzPC9zcGFuPg0K
133
+ ICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iQXZhaWxhYmxl
134
+ QWNoaWV2ZW1lbnRzIj43MTwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAg
135
+ ICAgPHNwYW4gY2xhc3M9IlBlcmNlbnRhZ2VDb21wbGV0ZSI+MTglPC9zcGFu
136
+ Pg0KICAgICAgICAgICAgICAgICAgICA8L2E+DQogICAgICAgICAgICAgICAg
137
+ PC9saT4NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIDxsaSA+DQog
138
+ ICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICA8YSBo
139
+ cmVmPSJodHRwOi8vbGl2ZS54Ym94LmNvbS9lbi1VUy9BY3Rpdml0eS9EZXRh
140
+ aWxzP3RpdGxlSWQ9MTQ4MDY1NzI3OCZhbXA7Y29tcGFyZVRvPXJpZGVyMjcx
141
+ MCI+DQogICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPSJodHRwOi8v
142
+ dGlsZXMueGJveC5jb20vdGlsZXMvbG8vREQvMEdkc2IySmhiQTlFQ2dVQUd3
143
+ RWZWMWdHTDJsamIyNHZNQzg0TURBd0lBQUFBQUFBQVAtc2dJaz0uanBnIiBh
144
+ bHQ9IkJhdHRsZWZpZWxkIDE5NDPihKIiIHRpdGxlPSJCYXR0bGVmaWVsZCAx
145
+ OTQz4oSiIiAvPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFz
146
+ cz0iVGl0bGUiPkJhdHRsZWZpZWxkIDE5NDPihKI8L3NwYW4+DQogICAgICAg
147
+ ICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJMYXN0UGxheWVkIj4xLzYv
148
+ MjAxNDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xh
149
+ c3M9IkVhcm5lZEdhbWVyc2NvcmUiPjE5MDwvc3Bhbj4NCiAgICAgICAgICAg
150
+ ICAgICAgICAgICAgPHNwYW4gY2xhc3M9IkF2YWlsYWJsZUdhbWVyc2NvcmUi
151
+ PjIwMDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xh
152
+ c3M9IkVhcm5lZEFjaGlldmVtZW50cyI+MTE8L3NwYW4+DQogICAgICAgICAg
153
+ ICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJBdmFpbGFibGVBY2hpZXZlbWVu
154
+ dHMiPjEyPC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBj
155
+ bGFzcz0iUGVyY2VudGFnZUNvbXBsZXRlIj45MSU8L3NwYW4+DQogICAgICAg
156
+ ICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgICAgICAgICA8L2xpPg0KICAg
157
+ ICAgICAgICAgDQogICAgICAgICAgICAgICAgPGxpID4NCiAgICAgICAgICAg
158
+ ICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHA6
159
+ Ly9saXZlLnhib3guY29tL2VuLVVTL0FjdGl2aXR5L0RldGFpbHM/dGl0bGVJ
160
+ ZD0xMTYxODg5ODA3JmFtcDtjb21wYXJlVG89cmlkZXIyNzEwIj4NCiAgICAg
161
+ ICAgICAgICAgICAgICAgICAgPGltZyBzcmM9Imh0dHA6Ly90aWxlcy54Ym94
162
+ LmNvbS90aWxlcy83bi9sUy8xV2RzYjJKaGJBOUVDZ1FOR3dFZlZsOEZMMmxq
163
+ YjI0dk1DODRNREF3SUFBQUFBQUFBUHA5ZWZFPS5qcGciIGFsdD0iVGhlIE9y
164
+ YW5nZSBCb3giIHRpdGxlPSJUaGUgT3JhbmdlIEJveCIgLz4NCiAgICAgICAg
165
+ ICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9IlRpdGxlIj5UaGUgT3Jhbmdl
166
+ IEJveDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xh
167
+ c3M9Ikxhc3RQbGF5ZWQiPjEvNi8yMDE0PC9zcGFuPg0KICAgICAgICAgICAg
168
+ ICAgICAgICAgICA8c3BhbiBjbGFzcz0iRWFybmVkR2FtZXJzY29yZSI+MzU8
169
+ L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJB
170
+ dmFpbGFibGVHYW1lcnNjb3JlIj4xMDAwPC9zcGFuPg0KICAgICAgICAgICAg
171
+ ICAgICAgICAgICA8c3BhbiBjbGFzcz0iRWFybmVkQWNoaWV2ZW1lbnRzIj41
172
+ PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0i
173
+ QXZhaWxhYmxlQWNoaWV2ZW1lbnRzIj45OTwvc3Bhbj4NCiAgICAgICAgICAg
174
+ ICAgICAgICAgICAgPHNwYW4gY2xhc3M9IlBlcmNlbnRhZ2VDb21wbGV0ZSI+
175
+ NSU8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAg
176
+ ICAgICAgICA8L2xpPg0KICAgICAgICAgICAgDQogICAgICAgICAgICA8L29s
177
+ Pg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgDQogICAgPC9ib2R5Pg0KPC9o
178
+ dG1sPg==
179
+ http_version:
180
+ recorded_at: Mon, 03 Mar 2014 05:37:02 GMT
181
+ recorded_with: VCR 2.8.0