video_info 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +63 -63
  4. data/lib/video_info/providers/vkontakte.rb +75 -16
  5. data/lib/video_info/version.rb +1 -1
  6. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_invalid_video/{_available_ → available_}/.yml +2 -2
  7. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_private_video/available_/.yml +382 -0
  8. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_redirect/available_/.yml +210 -0
  9. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_redirect_to_main_page_for_auth/available_/.yml +46 -0
  10. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_valid_video/available_/.yml +1655 -0
  11. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/description/.yml +387 -0
  12. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/duration/.yml +389 -0
  13. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/embed_code/.yml +387 -0
  14. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/embed_url/.yml +388 -0
  15. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/height/.yml +392 -0
  16. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/keywords/.yml +388 -0
  17. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/title/.yml +388 -0
  18. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/view_count/.yml +388 -0
  19. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/width/.yml +389 -0
  20. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video-54799401_165822734/title/.yml +636 -0
  21. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/description/.yml +522 -0
  22. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/duration/.yml +522 -0
  23. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/embed_code/.yml +522 -0
  24. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/embed_url/.yml +521 -0
  25. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/height/.yml +522 -0
  26. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/keywords/.yml +522 -0
  27. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/title/.yml +523 -0
  28. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/view_count/.yml +522 -0
  29. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/width/.yml +522 -0
  30. data/spec/lib/video_info/providers/vkontakte_spec.rb +77 -91
  31. metadata +50 -26
  32. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_valid_video/_available_/.yml +0 -1163
  33. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video-54799401_165822734/_title/.yml +0 -1474
  34. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_description/.yml +0 -1163
  35. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_duration/.yml +0 -1163
  36. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_embed_code/.yml +0 -1163
  37. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_embed_url/.yml +0 -1163
  38. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_height/.yml +0 -1163
  39. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_keywords/.yml +0 -1163
  40. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_title/.yml +0 -1163
  41. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_view_count/.yml +0 -1163
  42. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_width/.yml +0 -1163
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f40dace9501dc0754efd519f98cf23d6eb037281
4
- data.tar.gz: d486727f7fc75c2246d80686d9ccf44c1f8aa15b
3
+ metadata.gz: d3f2c0c33951520e7ff278cf2a7b266b4e36b198
4
+ data.tar.gz: 5f2039ecb7c7806f98fecbac674e9bc42f6df4d0
5
5
  SHA512:
6
- metadata.gz: faad587f1bfea1c7a37a9d134521b13e3ba7bfd892eda1e6dce7ab3a5b44510f3f7770957206a9139105fa77f3c664daef9134f52e1148a094b13e638b935d5d
7
- data.tar.gz: f0d1f569b0ddafab94d51b0ebef7f0e8a4ec0f1f47cbde0f1fead7a68ee9ceb052b7908c65f053679959e274d72868d63be79a5c0062bbfbb790ded3efab8db3
6
+ metadata.gz: f4fb805ce04d7ff0a250cbec4c56a605e3d1b0b63d4e7e9796b2309e7179a60dd61d0230e249267d1edb882b81cf0670fa53233d25b700bf49e326ec933ca84c
7
+ data.tar.gz: 8ae8fdd233abdc27c6bb2c1d146c957b5458c17d9819ffa0cd1e5510354eb895f75cc1a389d54d98089d0d59912e8b4cd38c12f0b7265c69e80805ebf737b4cb
@@ -4,6 +4,7 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1.0
7
+ - 2.2.0
7
8
  - jruby
8
9
  - rbx
9
10
  matrix:
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/video_info.png)](http://badge.fury.io/rb/video_info) [![Build Status](https://travis-ci.org/thibaudgg/video_info.png?branch=master)](https://travis-ci.org/thibaudgg/video_info) [![Dependency Status](https://gemnasium.com/thibaudgg/video_info.png)](https://gemnasium.com/thibaudgg/video_info) [![Code Climate](https://codeclimate.com/github/thibaudgg/video_info.png)](https://codeclimate.com/github/thibaudgg/video_info) [![Coverage Status](https://coveralls.io/repos/thibaudgg/video_info/badge.png?branch=master)](https://coveralls.io/r/thibaudgg/video_info)
4
4
 
5
- Simple Ruby Gem to get video info from Dailymotion, Vimeo (with playlist support), VK and YouTube (with playlist support).
5
+ Simple Ruby Gem to get video info from Dailymotion, VK, Vimeo (with playlist), Wistia and YouTube (with playlist).
6
6
 
7
7
  Tested against Ruby 1.9.3, 2.0.0, 2.1.0 and the latest versions of JRuby & Rubinius.
8
8
 
@@ -17,87 +17,87 @@ Usage
17
17
  -----
18
18
 
19
19
  ``` ruby
20
- video = VideoInfo.new("http://www.dailymotion.com/video/x7lni3")
20
+ video = VideoInfo.new('http://www.dailymotion.com/video/x7lni3')
21
21
  # video.available? => true
22
- # video.video_id => "x7lni3"
23
- # video.provider => "Dailymotion"
24
- # video.title => "Mario Kart (Rémi Gaillard)"
25
- # video.description => "Super Rémi Kart est un jeu vidéo de course développé et édité par N'Importe Quoi TV."
22
+ # video.video_id => 'x7lni3'
23
+ # video.provider => 'Dailymotion'
24
+ # video.title => 'Mario Kart (Rémi Gaillard)'
25
+ # video.description => 'Super Rémi Kart est un jeu vidéo de course développé et édité par N'Importe Quoi TV.'
26
26
  # video.duration => 136 (in seconds)
27
27
  # video.date => Mon Mar 03 16:29:31 UTC 2008
28
- # video.thumbnail_small => "http://s2.dmcdn.net/BgWxI/x60-kbf.jpg"
29
- # video.thumbnail_medium => "http://s2.dmcdn.net/BgWxI/x240-b83.jpg"
30
- # video.thumbnail_large => "http://s2.dmcdn.net/BgWxI/x720-YcV.jpg"
31
- # video.embed_url => "http://www.dailymotion.com/embed/video/x7lni3"
32
- # video.embed_code => "'<iframe src="//www.dailymotion.com/embed/video/x7lni3" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
28
+ # video.thumbnail_small => 'http://s2.dmcdn.net/BgWxI/x60-kbf.jpg'
29
+ # video.thumbnail_medium => 'http://s2.dmcdn.net/BgWxI/x240-b83.jpg'
30
+ # video.thumbnail_large => 'http://s2.dmcdn.net/BgWxI/x720-YcV.jpg'
31
+ # video.embed_url => 'http://www.dailymotion.com/embed/video/x7lni3'
32
+ # video.embed_code => "<iframe src='//www.dailymotion.com/embed/video/x7lni3' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
33
33
 
34
34
  video = VideoInfo.new("http://vimeo.com/898029")
35
35
  # video.available? => true
36
- # video.video_id => "898029"
37
- # video.provider => "Vimeo"
38
- # video.title => "Cherry Bloom - King Of The Knife"
39
- # video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
40
- # video.keywords => "alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin"
36
+ # video.video_id => '898029'
37
+ # video.provider => 'Vimeo'
38
+ # video.title => 'Cherry Bloom - King Of The Knife'
39
+ # video.description => 'The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net'
40
+ # video.keywords => 'alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin'
41
41
  # video.duration => 175 (in seconds)
42
42
  # video.date => Mon Apr 14 13:10:39 +0200 2008
43
43
  # video.width => 640
44
44
  # video.height => 360
45
- # video.thumbnail_small => "http://b.vimeocdn.com/ts/343/731/34373130_100.jpg"
46
- # video.thumbnail_medium => "http://b.vimeocdn.com/ts/343/731/34373130_200.jpg"
47
- # video.thumbnail_large => "http://b.vimeocdn.com/ts/343/731/34373130_640.jpg"
48
- # video.embed_url => "http://player.vimeo.com/video/898029"
49
- # video.embed_code => "'<iframe src="//player.vimeo.com/video/898029?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0" frameborder="0"></iframe>'"
45
+ # video.thumbnail_small => 'http://b.vimeocdn.com/ts/343/731/34373130_100.jpg'
46
+ # video.thumbnail_medium => 'http://b.vimeocdn.com/ts/343/731/34373130_200.jpg'
47
+ # video.thumbnail_large => 'http://b.vimeocdn.com/ts/343/731/34373130_640.jpg'
48
+ # video.embed_url => 'http://player.vimeo.com/video/898029'
49
+ # video.embed_code => "<iframe src='//player.vimeo.com/video/898029?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0' frameborder='0'></iframe>"
50
50
 
51
51
  video = VideoInfo.new("http://fast.wistia.com/embed/medias/pxonqr42is")
52
52
  # video.available? => true
53
- # video.provider => "Wistia"
54
- # video.video_id => "pxonqr42is"
55
- # video.title => "Understanding Analytics"
53
+ # video.provider => 'Wistia'
54
+ # video.video_id => 'pxonqr42is'
55
+ # video.title => 'Understanding Analytics'
56
56
  # video.duration => 250 (in seconds)
57
57
  # video.width => 960
58
58
  # video.height => 568
59
- # video.thumbnail_small => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
60
- # video.thumbnail_medium => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
61
- # video.thumbnail_large => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
62
- # video.embed_url => "//fast.wistia.net/embed/iframe/pxonqr42is"
63
- # video.embed_code => "'<iframe src="//fast.wistia.net/embed/iframe/pxonqr42is" frameborder="0"></iframe>'"
59
+ # video.thumbnail_small => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
60
+ # video.thumbnail_medium => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
61
+ # video.thumbnail_large => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
62
+ # video.embed_url => '//fast.wistia.net/embed/iframe/pxonqr42is'
63
+ # video.embed_code => "<iframe src='//fast.wistia.net/embed/iframe/pxonqr42is' frameborder='0'></iframe>"
64
64
 
65
65
  video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4")
66
66
  # video.available? => true
67
- # video.video_id => "mZqGqE0D0n4"
68
- # video.provider => "YouTube"
69
- # video.title => "Cherry Bloom - King Of The Knife"
70
- # video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
67
+ # video.video_id => 'mZqGqE0D0n4'
68
+ # video.provider => 'YouTube'
69
+ # video.title => 'Cherry Bloom - King Of The Knife'
70
+ # video.description => 'The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net'
71
71
  # video.duration => 175 (in seconds)
72
72
  # video.date => Sat Apr 12 22:25:35 UTC 2008
73
- # video.thumbnail_small => "http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg"
74
- # video.thumbnail_medium => "http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg"
75
- # video.thumbnail_large => "http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg"
76
- # video.embed_url => "http://www.youtube.com/embed/mZqGqE0D0n4"
77
- # video.embed_code => "'<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
73
+ # video.thumbnail_small => 'http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg'
74
+ # video.thumbnail_medium => 'http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg'
75
+ # video.thumbnail_large => 'http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg'
76
+ # video.embed_url => 'http://www.youtube.com/embed/mZqGqE0D0n4'
77
+ # video.embed_code => "<iframe src='//www.youtube.com/embed/mZqGqE0D0n4' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
78
78
 
79
79
  playlist = VideoInfo.new("http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr")
80
80
  # playlist.available? => true
81
- # playlist.playlist_id => "PL9hW1uS6HUftLdHI6RIsaf"
82
- # playlist.provider => "YouTube"
83
- # playlist.title => "YouTube Policy and Copyright"
84
- # playlist.thumbnail_small => "http://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg"
85
- # playlist.thumbnail_medium => "http://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg"
86
- # playlist.thumbnail_large => "http://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg"
87
- # playlist.embed_url => "http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr"
88
- # playlist.embed_code => "<iframe src="//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr" frameborder="0" allowfullscreen="allowfullscreen"></iframe>"
81
+ # playlist.playlist_id => 'PL9hW1uS6HUftLdHI6RIsaf'
82
+ # playlist.provider => 'YouTube'
83
+ # playlist.title => 'YouTube Policy and Copyright'
84
+ # playlist.thumbnail_small => 'http://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg'
85
+ # playlist.thumbnail_medium => 'http://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg'
86
+ # playlist.thumbnail_large => 'http://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg'
87
+ # playlist.embed_url => 'http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr'
88
+ # playlist.embed_code => "<iframe src='//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
89
89
  # playlist.videos => [VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), VideoInfo.new('http://www.youtube.com/watch?v=6c3mHikRz0I'), VideoInfo.new('http://www.youtube.com/watch?v=OQVHWsTHcoc')]
90
90
 
91
91
  playlist = VideoInfo.new("http://vimeo.com/album/2755718")
92
92
  # playlist.available? => true
93
- # playlist.playlist_id => "2755718"
94
- # playlist.provider => "Vimeo"
95
- # playlist.title => "The Century Of Self"
96
- # playlist.thumbnail_small => "http://b.vimeocdn.com/ts/443/595/443595474_100.jpg"
97
- # playlist.thumbnail_medium => "http://b.vimeocdn.com/ts/443/595/443595474_200.jpg"
98
- # playlist.thumbnail_large => "http://b.vimeocdn.com/ts/443/595/443595474_640.jpg"
99
- # playlist.embed_url => "player.vimeo.com/hubnut/album/2755718"
100
- # playlist.embed_code => "<iframe src="//player.vimeo.com/hubnut/album/2755718?autoplay=0&byline=0&portrait=0&title=0" frameborder="0"></iframe>"
93
+ # playlist.playlist_id => '2755718'
94
+ # playlist.provider => 'Vimeo'
95
+ # playlist.title => 'The Century Of Self'
96
+ # playlist.thumbnail_small => 'http://b.vimeocdn.com/ts/443/595/443595474_100.jpg'
97
+ # playlist.thumbnail_medium => 'http://b.vimeocdn.com/ts/443/595/443595474_200.jpg'
98
+ # playlist.thumbnail_large => 'http://b.vimeocdn.com/ts/443/595/443595474_640.jpg'
99
+ # playlist.embed_url => 'player.vimeo.com/hubnut/album/2755718'
100
+ # playlist.embed_code => "<iframe src='//player.vimeo.com/hubnut/album/2755718?autoplay=0&byline=0&portrait=0&title=0' frameborder='0'></iframe>"
101
101
  # playlist.videos => [VideoInfo.new('http://vimeo.com/67977038'), VideoInfo.new('http://vimeo.com/68843810'), VideoInfo.new('http://vimeo.com/69949597'), VideoInfo.new('http://vimeo.com/70388245')]
102
102
  ```
103
103
 
@@ -105,16 +105,16 @@ Options
105
105
  -------
106
106
 
107
107
  ``` ruby
108
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "User-Agent" => "My YouTube Mashup Robot/1.0")
109
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/")
110
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/",
111
- "User-Agent" => "My YouTube Mashup Robot/1.0")
108
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'User-Agent' => 'My YouTube Mashup Robot/1.0')
109
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'Referer' => 'http://my-youtube-mashup.com/')
110
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'Referer' => 'http://my-youtube-mashup.com/',
111
+ 'User-Agent' => 'My YouTube Mashup Robot/1.0')
112
112
  ```
113
113
  You can also use **symbols** instead of strings (any non-word (`/[^a-z]/i`) character would be converted to hyphen).
114
114
 
115
115
  ``` ruby
116
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", :referer => "http://my-youtube-mashup.com/",
117
- user_agent: "My YouTube Mashup Robot/1.0")
116
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', referer: 'http://my-youtube-mashup.com/',
117
+ user_agent: 'My YouTube Mashup Robot/1.0')
118
118
  ```
119
119
 
120
120
  User-Agent when empty defaults to "VideoInfo/VERSION" - where version is current VideoInfo version, e.g. **"VideoInfo/0.2.7"**.
@@ -124,10 +124,10 @@ It supports all openURI header fields (options), for more information see: [open
124
124
  You can also include an `iframe_attributes` or `url_attributes` hash to the `embed_code` method to include arbitrary attributes in the iframe embed code or as additional URL params:
125
125
 
126
126
  ``` ruby
127
- VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4").embed_code(iframe_attributes: { width: 800, height: 600, "data-key" => "value" })
128
- => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen" width="800" height="600" data-key="value"></iframe>
127
+ VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4').embed_code(iframe_attributes: { width: 800, height: 600, 'data-key' => 'value' })
128
+ => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen" width="800" height="600" data-key="value"></iframe>'
129
129
 
130
- 'VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4").embed_code(url_attributes: { autoplay: 1 })
130
+ 'VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4').embed_code(url_attributes: { autoplay: 1 })
131
131
  => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4?autoplay=1" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'
132
132
  ```
133
133
 
@@ -1,14 +1,22 @@
1
1
  # encoding: UTF-8
2
2
  require 'htmlentities'
3
- require 'iconv' if RUBY_VERSION.to_i < 2
3
+ require 'net/http'
4
4
 
5
5
  class VideoInfo
6
6
  module Providers
7
7
  class Vkontakte < Provider
8
8
  attr_accessor :video_owner
9
9
 
10
+ def initialize(url, options = {})
11
+ super(url, options)
12
+ @url.strip!
13
+ end
14
+
10
15
  def self.usable?(url)
11
- url =~ /(vk\.com)|(vkontakte\.ru)/
16
+ url.strip!
17
+ vkontakte = !!(url =~ /\A(http|https):\/\/(vk\.com)|(vkontakte\.ru)\z/)
18
+ valid = !!(url =~ /\A#{URI::regexp(['http', 'https'])}\z/)
19
+ vkontakte && valid
12
20
  end
13
21
 
14
22
  def provider
@@ -16,7 +24,7 @@ class VideoInfo
16
24
  end
17
25
 
18
26
  def description
19
- content = data[/<meta name="description" content="(.*)" \/>/, 1]
27
+ content = data[/"desc":"(.*?)",/, 1]
20
28
  HTMLEntities.new.decode(content)
21
29
  end
22
30
  alias_method :keywords, :description
@@ -26,7 +34,7 @@ class VideoInfo
26
34
  360 => 480,
27
35
  480 => 640,
28
36
  720 => 1280
29
- }[height]
37
+ }[height].to_i
30
38
  end
31
39
 
32
40
  def height
@@ -34,36 +42,87 @@ class VideoInfo
34
42
  end
35
43
 
36
44
  def title
37
- data[/<title>(.*)<\/title>/, 1].gsub(' | ВКонтакте', '')
45
+ data[/\="mv_title">(.*)<\/div>/, 1].gsub(' | ВКонтакте', '')
38
46
  end
39
47
 
40
48
  def view_count
41
- data[/mv_num_views\\">.*?(\d+)/, 1].to_i
49
+ data[/mv_views_count_number\">.*?(\d+)/, 1].to_i
42
50
  end
43
51
 
44
52
  def embed_url
45
- "//vk.com/video_ext.php?oid=#{video_owner}&id=#{video_id}&hash=#{_data_hash}"
53
+ youtube = data[
54
+ /iframe\ id=\"video_player\".*src=\"(.*)\"\ frameborder=/, 1
55
+ ]
56
+ if youtube
57
+ VideoInfo::Providers::Youtube.new(
58
+ URI.unescape(youtube.gsub(/\\/, ''))
59
+ ).embed_url
60
+ else
61
+ "//vk.com/video_ext.php?oid=#{video_owner}" +
62
+ "&id=#{video_id}&hash=#{_data_hash}"
63
+ end
46
64
  end
47
65
 
48
66
  def duration
49
67
  data[/"duration":(\d+)/, 1].to_i
50
68
  end
51
69
 
70
+ def available?
71
+ !%w[403 404 302 401].include?(_response_code)
72
+ end
73
+
52
74
  private
53
75
 
76
+ def _make_request(url, options)
77
+ request = Net::HTTP::Post.new(url.path)
78
+ request.body = URI.encode_www_form(options)
79
+ conn = Net::HTTP.new(url.host, url.port)
80
+ conn.use_ssl = true
81
+ resp = conn.request(request)
82
+ resp.body.force_encoding('cp1251').encode('UTF-8', undef: :replace)
83
+ end
84
+
54
85
  def _set_data_from_api
55
- uri = open(url, options)
56
- if RUBY_VERSION.to_i < 2
57
- Iconv.iconv('utf-8', 'cp1251', uri.read)[0]
86
+ url = URI('https://vk.com/al_video.php')
87
+ options['act'] = 'show'
88
+ options['al'] = '1'
89
+ options['video'] = "#{@video_owner}_#{@video_id}"
90
+ _make_request(url, options)
91
+ end
92
+
93
+ def _error_found?(response)
94
+ title = response.body[
95
+ /<title>(.*)<\/title>/, 1
96
+ ].force_encoding(
97
+ 'cp1251'
98
+ ).encode(
99
+ 'UTF-8', undef: :replace
100
+ )
101
+ !!title.index('Ошибка')
102
+ end
103
+
104
+ def _get_response_code(response)
105
+ if response.header['location'] == '/'
106
+ '401'
107
+ elsif response.code == '302'
108
+ '302'
109
+ elsif _error_found? response
110
+ '403'
58
111
  else
59
- uri.read.encode('UTF-8')
112
+ response.code
60
113
  end
61
114
  end
62
115
 
63
116
  def _response_code
64
- response = nil
65
- Net::HTTP.start(_api_base, 80) { |http| response = http.get(_api_path) }
66
- response.code
117
+ response = Net::HTTP.get_response(_api_base, _api_path, 80)
118
+ code = _get_response_code response
119
+ if code == '302'
120
+ _get_response_code Net::HTTP.get_response(
121
+ URI.parse(response.header['location'])
122
+ )
123
+ else
124
+ code
125
+ end
67
126
  end
68
127
 
69
128
  def _api_base
@@ -75,7 +134,7 @@ class VideoInfo
75
134
  end
76
135
 
77
136
  def _data_hash
78
- data[/hash2\\":\\"(\w+)/, 1]
137
+ data[/"hash2":"(\w+)/, 1]
79
138
  end
80
139
 
81
140
  def _set_video_id_from_url
@@ -83,7 +142,7 @@ class VideoInfo
83
142
  end
84
143
 
85
144
  def _url_regex
86
- /(?:vkontakte\.ru\/video|vk\.com\/video)(-?\d+_\d+)/i
145
+ /(?:vkontakte\.ru\/video|vk\.com\/video|vk\.com\/.*?=video)(-?\d+_\d+)/i
87
146
  end
88
147
 
89
148
  def _default_iframe_attributes
@@ -1,3 +1,3 @@
1
1
  class VideoInfo
2
- VERSION = '2.4.0'
2
+ VERSION = '2.4.1'
3
3
  end
@@ -21,7 +21,7 @@ http_interactions:
21
21
  Server:
22
22
  - Apache
23
23
  Date:
24
- - Tue, 09 Dec 2014 19:27:32 GMT
24
+ - Sun, 08 Mar 2015 12:11:00 GMT
25
25
  Content-Type:
26
26
  - text/html
27
27
  Content-Length:
@@ -42,5 +42,5 @@ http_interactions:
42
42
  </body>
43
43
  </html>
44
44
  http_version:
45
- recorded_at: Tue, 09 Dec 2014 19:27:32 GMT
45
+ recorded_at: Sun, 08 Mar 2015 12:11:00 GMT
46
46
  recorded_with: VCR 2.9.3
@@ -0,0 +1,382 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://vk.com/video9491528_165193133
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
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - Apache
23
+ Date:
24
+ - Sun, 08 Mar 2015 15:03:48 GMT
25
+ Content-Type:
26
+ - text/html; charset=windows-1251
27
+ Content-Length:
28
+ - '5374'
29
+ Connection:
30
+ - keep-alive
31
+ X-Powered-By:
32
+ - PHP/3.11903
33
+ Set-Cookie:
34
+ - remixlang=0; expires=Wed, 02 Mar 2016 22:20:23 GMT; path=/; domain=.vk.com
35
+ Pragma:
36
+ - no-cache
37
+ Cache-Control:
38
+ - no-store
39
+ X-Frame-Options:
40
+ - deny
41
+ body:
42
+ encoding: ASCII-8BIT
43
+ string: !binary |-
44
+ PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAg
45
+ U3RyaWN0Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQv
46
+ eGh0bWwxLXN0cmljdC5kdGQiPgo8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53
47
+ My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9InJ1IiBsYW5nPSJydSI+Cjxo
48
+ ZWFkPgo8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRl
49
+ bnQ9IklFPWVkZ2UiIC8+CjxsaW5rIHJlbD0ic2hvcnRjdXQgaWNvbiIgaHJl
50
+ Zj0iL2ltYWdlcy9mYXZpY29ubmV3Lmljbz8zIiAvPgoKPGxpbmsgcmVsPSJh
51
+ cHBsZS10b3VjaC1pY29uIiBocmVmPSIvaW1hZ2VzL3NhZmFyaV82MC5wbmci
52
+ Pgo8bGluayByZWw9ImFwcGxlLXRvdWNoLWljb24iIHNpemVzPSI3Nng3NiIg
53
+ aHJlZj0iL2ltYWdlcy9zYWZhcmlfNzYucG5nIj4KPGxpbmsgcmVsPSJhcHBs
54
+ ZS10b3VjaC1pY29uIiBzaXplcz0iMTIweDEyMCIgaHJlZj0iL2ltYWdlcy9z
55
+ YWZhcmlfMTIwLnBuZyI+CjxsaW5rIHJlbD0iYXBwbGUtdG91Y2gtaWNvbiIg
56
+ c2l6ZXM9IjE1MngxNTIiIGhyZWY9Ii9pbWFnZXMvc2FmYXJpXzE1Mi5wbmci
57
+ PgoKPG1ldGEgaHR0cC1lcXVpdj0iY29udGVudC10eXBlIiBjb250ZW50PSJ0
58
+ ZXh0L2h0bWw7IGNoYXJzZXQ9d2luZG93cy0xMjUxIiAvPgo8bWV0YSBuYW1l
59
+ PSJkZXNjcmlwdGlvbiIgY29udGVudD0iIiAvPgoKPHRpdGxlPs746OHq4CB8
60
+ IMLK7u3y4Ory5TwvdGl0bGU+Cgo8bm9zY3JpcHQ+PG1ldGEgaHR0cC1lcXVp
61
+ dj0icmVmcmVzaCIgY29udGVudD0iMDsgVVJMPS9iYWRicm93c2VyLnBocCI+
62
+ PC9ub3NjcmlwdD4KCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4K
63
+ dmFyIHZrID0gewogIGFkc19yb3RhdGVfaW50ZXJ2YWw6IDEyMDAwMCwKICBh
64
+ bDogcGFyc2VJbnQoJzQnKSB8fCA0LAogIGlkOiAwLAogIGludG5hdDogJycg
65
+ PyB0cnVlIDogZmFsc2UsCiAgaG9zdDogJ3ZrLmNvbScsCiAgbGFuZzogMCwK
66
+ ICBydGw6IHBhcnNlSW50KCcnKSB8fCAwLAogIHZlcnNpb246IDE3MDczLAog
67
+ IHN0RG9tYWluczogMywKICB6ZXJvOiBmYWxzZSwKICBjb250bGVuOiA1NTA1
68
+ LAogIGxvZ2luc2NoZW1lOiAnaHR0cHMnLAogIGlwX2g6ICcyODA1YWU2ODk3
69
+ OWIzYzQ4NTInLAogIHZjX2g6ICcyY2ViOTk5ZjU1YmU1MzI4NjY4NTk1Yzk5
70
+ MmM3NzhkMicsCiAgbmF2UHJlZml4OiAnLycsCiAgZHQ6IHBhcnNlSW50KCcw
71
+ JykgfHwgMCwKICBmczogcGFyc2VJbnQoJzExJykgfHwgMTEsCiAgdHM6IDE0
72
+ MjU4MjcwMjgsCiAgdHo6IDEwODAwLAogIHBkOiAwLAogIHBhZHM6IDEsCiAg
73
+ dGltZTogWzIwMTUsIDMsIDgsIDE4LCAzLCA0OF0KfQoKd2luZG93LmxvY0Rv
74
+ bWFpbiA9IHZrLmhvc3QubWF0Y2goL1thLXpBLVpdK1wuW2EtekEtWl0rXC4/
75
+ JC8pWzBdOwp2YXIgX3VhID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2Vy
76
+ Q2FzZSgpOwppZiAoL29wZXJhL2kudGVzdChfdWEpIHx8ICEvbXNpZSA2L2ku
77
+ dGVzdChfdWEpIHx8IGRvY3VtZW50LmRvbWFpbiAhPSBsb2NEb21haW4pIGRv
78
+ Y3VtZW50LmRvbWFpbiA9IGxvY0RvbWFpbjsKdmFyIF9fX2h0ZXN0ID0gKGxv
79
+ Y2F0aW9uLnRvU3RyaW5nKCkubWF0Y2goLyMoLiopLykgfHwge30pWzFdIHx8
80
+ ICcnLCBfX190bzsKaWYgKHZrLmFsICE9IDEgJiYgX19faHRlc3QubGVuZ3Ro
81
+ ICYmIF9fX2h0ZXN0LnN1YnN0cigwLCAxKSA9PSB2ay5uYXZQcmVmaXgpIHsK
82
+ ICBpZiAodmsuYWwgIT0gMyB8fCB2ay5uYXZQcmVmaXggIT0gJyEnKSB7CiAg
83
+ ICBfX190byA9IF9fX2h0ZXN0LnJlcGxhY2UoL14oXC98ISkvLCAnJyk7CiAg
84
+ ICBpZiAoX19fdG8ubWF0Y2goL14oW15cP10qXC5waHB8bG9naW4pKFteYS16
85
+ MC05XC5dfCQpLykpIF9fX3RvID0gJyc7CiAgICBsb2NhdGlvbi5yZXBsYWNl
86
+ KGxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIGxvY2F0aW9uLmhvc3QgKyAn
87
+ LycgKyBfX190byk7CiAgfQp9Cgp2YXIgU3RhdGljRmlsZXMgPSB7CiAgJ2Nv
88
+ bW1vbi5qcycgOiB7djogMTExNn0sCiAgJ2NvbW1vbi5jc3MnOiB7djogNDkz
89
+ fSwKICAnaWU2LmNzcycgICA6IHt2OiAyNn0sCiAgJ2llNy5jc3MnICAgOiB7
90
+ djogMTh9CiAgLCdsYW5nMF8wLmpzJzp7djo2NTk1fSwndmlkZW8uY3NzJzp7
91
+ djoxNDB9LCd2aWRlby5qcyc6e3Y6MTYyfSwnaW5kZXhlci5qcyc6e3Y6MTl9
92
+ LCd1aV9jb250cm9scy5qcyc6e3Y6MTc4fSwndWlfY29udHJvbHMuY3NzJzp7
93
+ djo1OX0sJ3ZpZGVvdmlldy5qcyc6e3Y6MjQ2fSwndmlkZW92aWV3LmNzcyc6
94
+ e3Y6MTQ0fSwndmlkZW9fdXBsb2FkLmpzJzp7djoxOX0sJ3NlYXJjaC5qcyc6
95
+ e3Y6MTEyfSwncXNvcnRlci5qcyc6e3Y6Mjl9LCdwYWdlLmNzcyc6e3Y6NzI1
96
+ fSwncGFnZS5qcyc6e3Y6ODY4fSwndW5jb21tb24uY3NzJzp7djo5MH0KfQo8
97
+ L3NjcmlwdD4KCjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9j
98
+ c3MiIGhyZWY9Imh0dHA6Ly9zdDAudmsubWUvY3NzL2FsL2NvbW1vbi5jc3M/
99
+ NDkzIiAvPgo8IS0tW2lmIGx0ZSBJRSA2XT48c3R5bGUgdHlwZT0idGV4dC9j
100
+ c3MiIG1lZGlhPSJzY3JlZW4iPi8qIDwhW0NEQVRBWyAqLyBAaW1wb3J0IHVy
101
+ bChodHRwOi8vc3QwLnZrLm1lL2Nzcy9hbC9pZTYuY3NzPzI2KTsgLyogXV0+
102
+ ICovPC9zdHlsZT48IVtlbmRpZl0tLT4KPCEtLVtpZiBJRSA3XT48c3R5bGUg
103
+ dHlwZT0idGV4dC9jc3MiIG1lZGlhPSJzY3JlZW4iPi8qIDwhW0NEQVRBWyAq
104
+ LyBAaW1wb3J0IHVybChodHRwOi8vc3QwLnZrLm1lL2Nzcy9hbC9pZTcuY3Nz
105
+ PzE4KTsgLyogXV0+ICovPC9zdHlsZT48IVtlbmRpZl0tLT4KPGxpbmsgdHlw
106
+ ZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cDovL3N0
107
+ MC52ay5tZS9jc3MvYWwvdmlkZW8uY3NzPzE0MCI+PC9saW5rPjxsaW5rIHR5
108
+ cGU9InRleHQvY3NzIiByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHA6Ly9z
109
+ dDAudmsubWUvY3NzL3VpX2NvbnRyb2xzLmNzcz81OSI+PC9saW5rPjxsaW5r
110
+ IHR5cGU9InRleHQvY3NzIiByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHA6
111
+ Ly9zdDAudmsubWUvY3NzL2FsL3ZpZGVvdmlldy5jc3M/MTQ0Ij48L2xpbms+
112
+ PGxpbmsgdHlwZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0i
113
+ aHR0cDovL3N0MC52ay5tZS9jc3MvYWwvcGFnZS5jc3M/NzI1Ij48L2xpbms+
114
+ PGxpbmsgdHlwZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0i
115
+ aHR0cDovL3N0MC52ay5tZS9jc3MvYWwvdW5jb21tb24uY3NzPzkwIj48L2xp
116
+ bms+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iL2pzL2xv
117
+ YWRlcl9uYXYxNzA3M18wLmpzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRl
118
+ eHQvamF2YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QyLnZrLm1lL2pzL2FsL2Nv
119
+ bW1vbi5qcz8xMTE2XzEzNCI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0
120
+ L2phdmFzY3JpcHQiIHNyYz0iL2pzL2xhbmcwXzAuanM/NjU5NSI+PC9zY3Jp
121
+ cHQ+PG1ldGEgbmFtZT0icm9ib3RzIiBjb250ZW50PSJub2luZGV4IiAvPjxz
122
+ Y3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9zdDIu
123
+ dmsubWUvanMvYWwvdmlkZW8uanM/MTYyIj48L3NjcmlwdD48c2NyaXB0IHR5
124
+ cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QzLnZrLm1lL2pz
125
+ L2FsL2luZGV4ZXIuanM/MTkiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4
126
+ dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9zdDMudmsubWUvanMvbGliL3Vp
127
+ X2NvbnRyb2xzLmpzPzE3OCI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0
128
+ L2phdmFzY3JpcHQiIHNyYz0iaHR0cDovL3N0MS52ay5tZS9qcy9hbC92aWRl
129
+ b3ZpZXcuanM/MjQ2Ij48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2
130
+ YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QyLnZrLm1lL2pzL2FsL3ZpZGVvX3Vw
131
+ bG9hZC5qcz8xOSI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFz
132
+ Y3JpcHQiIHNyYz0iaHR0cDovL3N0Mi52ay5tZS9qcy9hbC9zZWFyY2guanM/
133
+ MTEyIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIg
134
+ c3JjPSJodHRwOi8vc3QxLnZrLm1lL2pzL2FsL3Fzb3J0ZXIuanM/MjkiPjwv
135
+ c2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0
136
+ dHA6Ly9zdDEudmsubWUvanMvYWwvcGFnZS5qcz84NjgiPjwvc2NyaXB0PgoK
137
+ PC9oZWFkPgoKPGJvZHkgb25yZXNpemU9Im9uQm9keVJlc2l6ZSgpIiBjbGFz
138
+ cz0iaXNfcnRsIGZvbnRfZGVmYXVsdCBwYWRzICI+CiAgPGRpdiBpZD0ic3lz
139
+ dGVtX21zZyIgY2xhc3M9ImZpeGVkIj48L2Rpdj4KICA8ZGl2IGlkPSJ1dGls
140
+ cyI+PC9kaXY+CgogIDxkaXYgaWQ9ImxheWVyX2JnIiBjbGFzcz0iZml4ZWQi
141
+ PjwvZGl2PjxkaXYgaWQ9ImxheWVyX3dyYXAiIGNsYXNzPSJzY3JvbGxfZml4
142
+ X3dyYXAgZml4ZWQiPjxkaXYgaWQ9ImxheWVyIj48L2Rpdj48L2Rpdj4KICA8
143
+ ZGl2IGlkPSJib3hfbGF5ZXJfYmciIGNsYXNzPSJmaXhlZCI+PC9kaXY+PGRp
144
+ diBpZD0iYm94X2xheWVyX3dyYXAiIGNsYXNzPSJzY3JvbGxfZml4X3dyYXAg
145
+ Zml4ZWQiPjxkaXYgaWQ9ImJveF9sYXllciI+PGRpdiBpZD0iYm94X2xvYWRl
146
+ ciI+PGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj48ZGl2IGNsYXNzPSJiYWNr
147
+ Ij48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4KCiAgPGRpdiBpZD0ic3RsX2xl
148
+ ZnQiPjwvZGl2PjxkaXYgaWQ9InN0bF9zaWRlIj48L2Rpdj4KCiAgPHNjcmlw
149
+ dCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmRvbVN0YXJ0ZWQoKTs8L3Njcmlw
150
+ dD4KCiAgPGRpdiBjbGFzcz0ic2Nyb2xsX2ZpeF93cmFwIiBpZD0icGFnZV93
151
+ cmFwIj48ZGl2IGlkPSJyZWdfYmFyIiBjbGFzcz0idG9wX2luZm9fd3JhcCBm
152
+ aXhlZCI+CiAgPGRpdiBjbGFzcz0ic2Nyb2xsX2ZpeCI+CiAgICA8ZGl2IGlk
153
+ PSJyZWdfYmFyX2NvbnRlbnQiPgogICAgICDP8Ojx7uXk6O3/6fLl8fwsIPfy
154
+ 7uH7IOLx5ePk4CDu8fLg4uDy/PH/IOIg6u7t8uDq8uUg8SDk8PPn/P/s6CDo
155
+ IOHr6Ofq6OzoCiAgICAgIDxkaXYgY2xhc3M9ImJ1dHRvbl9ibHVlIiBpZD0i
156
+ cmVnX2Jhcl9idXR0b24iPjxhIGNsYXNzPSJidXR0b25fbGluayIgaHJlZj0i
157
+ L2pvaW4iIG9uY2xpY2s9InJldHVybiAhc2hvd0JveCgnam9pbi5waHAnLCB7
158
+ YWN0OiAnYm94JywgZnJvbTogbmF2LnN0ckxvY30sIHt9LCBldmVudCkiPjxi
159
+ dXR0b24gaWQ9InJlZ19iYXJfYnRuIj48c3BhbiBpZD0icmVnX2Jhcl93aXRo
160
+ X2FyciI+x+Dw5ePo8fLw6PDu4uDy/PH/PC9zcGFuPjwvYnV0dG9uPjwvYT48
161
+ L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPGRpdj48ZGl2IGNs
162
+ YXNzPSJzY3JvbGxfZml4Ij4KICA8ZGl2IGlkPSJwYWdlX2xheW91dCIgc3R5
163
+ bGU9IndpZHRoOiA3OTFweDsiPgogICAgPGRpdiBpZD0icGFnZV9oZWFkZXIi
164
+ IGNsYXNzPSJwX2hlYWQgcF9oZWFkX2wwIj4KICAgICAgPGRpdiBjbGFzcz0i
165
+ YmFjayI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9ImxlZnQiPjwvZGl2Pgog
166
+ ICAgICA8ZGl2IGNsYXNzPSJyaWdodCI+PC9kaXY+CiAgICAgIDxkaXYgY2xh
167
+ c3M9ImNvbnRlbnQiPgogICAgICAgIDxkaXYgaWQ9InRvcF9uYXYiIGNsYXNz
168
+ PSJoZWFkX25hdiI+CiAgPGRpdiBpZD0idG9wX2xvZ29fZG93biIgY2xhc3M9
169
+ ImZsX2wiPjwvZGl2PgogIDxhIGlkPSJ0b3BfaG9tZV9saW5rIiBjbGFzcz0i
170
+ dG9wX2hvbWVfbGluayBmbF9sIiBocmVmPSIvIiBvbm1vdXNlZG93bj0iYWRk
171
+ Q2xhc3MoJ3RvcF9sb2dvX2Rvd24nLCd0bGRfZCcpOyIgb25jbGljaz0icmV0
172
+ dXJuIG5hdi5nbyh0aGlzLCBldmVudCk7Ij48L2E+CiAgPGRpdiBpZD0idG9w
173
+ X2xpbmtzIj4KICAgIDxkaXYgY2xhc3M9ImZsX3IiIGlkPSJ0b3BfbWVudV93
174
+ cmFwIiBzdHlsZT0iIj4KICAgICAgPGEgaWQ9InRvcF9yZWdfbGluayIgY2xh
175
+ c3M9ImZsX3IgdG9wX25hdl9saW5rIiBocmVmPSIvam9pbiIgc3R5bGU9IiIg
176
+ b25jbGljaz0icmV0dXJuICFzaG93Qm94KCdqb2luLnBocCcsIHthY3Q6ICdi
177
+ b3gnLCBmcm9tOiBuYXYuc3RyTG9jfSwge30sIGV2ZW50KSIgb25tb3VzZWRv
178
+ d249InRuQWN0aXZlKHRoaXMpIj7w5ePo8fLw4Pbo/zwvYT4KICAgICAgPGEg
179
+ aWQ9InRvcF9zd2l0Y2hfbGFuZyIgY2xhc3M9ImZsX3IgdG9wX25hdl9saW5r
180
+ IiAgc3R5bGU9ImRpc3BsYXk6IG5vbmU7IiBvbmNsaWNrPSJhamF4LnBvc3Qo
181
+ J2FsX2luZGV4LnBocCcsIHthY3Q6ICdjaGFuZ2VfbGFuZycsIGxhbmdfaWQ6
182
+ IDMsIGhhc2g6ICcnfSk7IiBvbm1vdXNlZG93bj0idG5BY3RpdmUodGhpcyki
183
+ PlN3aXRjaCB0byBFbmdsaXNoPC9hPgogICAgPC9kaXY+CiAgICA8YSBjbGFz
184
+ cz0iZmxfbCB0b3BfbmF2X2xpbmsiIGhyZWY9IiIgaWQ9InRvcF9iYWNrX2xp
185
+ bmsiIG9uY2xpY2s9InJldHVybiBuYXYuZ28odGhpcywgZXZlbnQsIHtiYWNr
186
+ OiB0cnVlfSkiIG9ubW91c2Vkb3duPSJ0bkFjdGl2ZSh0aGlzKSI+PC9hPgog
187
+ IDwvZGl2Pgo8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8
188
+ ZGl2IGlkPSJzaWRlX2JhciIgY2xhc3M9ImZsX2wiIHN0eWxlPSIiPgogICAg
189
+ ICA8ZGl2IGlkPSJxdWlja19sb2dpbiI+CiAgPGZvcm0gbWV0aG9kPSJQT1NU
190
+ IiBuYW1lPSJsb2dpbiIgaWQ9InF1aWNrX2xvZ2luX2Zvcm0iIGFjdGlvbj0i
191
+ aHR0cHM6Ly9sb2dpbi52ay5jb20vP2FjdD1sb2dpbiIgb25zdWJtaXQ9Imlm
192
+ ICh2a2xvZ2luKSB7cmV0dXJuIHRydWV9IGVsc2Uge3F1aWNrX2xvZ2luKCk7
193
+ cmV0dXJuIGZhbHNlO30iPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFt
194
+ ZT0iYWN0IiB2YWx1ZT0ibG9naW4iIC8+CiAgICA8aW5wdXQgdHlwZT0iaGlk
195
+ ZGVuIiBuYW1lPSJyb2xlIiB2YWx1ZT0iYWxfZnJhbWUiIC8+CiAgICA8aW5w
196
+ dXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJleHBpcmUiIGlkPSJxdWlja19leHBp
197
+ cmVfaW5wdXQiIHZhbHVlPSIiIC8+CiAgICA8aW5wdXQgdHlwZT0iaGlkZGVu
198
+ IiBuYW1lPSJjYXB0Y2hhX3NpZCIgaWQ9InF1aWNrX2NhcHRjaGFfc2lkIiB2
199
+ YWx1ZT0iIiAvPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY2Fw
200
+ dGNoYV9rZXkiIGlkPSJxdWlja19jYXB0Y2hhX2tleSIgdmFsdWU9IiIgLz4K
201
+ ICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Il9vcmlnaW4iIHZhbHVl
202
+ PSJodHRwOi8vdmsuY29tIiAvPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIg
203
+ bmFtZT0iaXBfaCIgdmFsdWU9IjI4MDVhZTY4OTc5YjNjNDg1MiIgLz4KICAg
204
+ IDxkaXYgY2xhc3M9ImxhYmVsIj7S5evl9O7tIOjr6CBlbWFpbDwvZGl2Pgog
205
+ ICAgPGRpdiBjbGFzcz0ibGFiZWxlZCI+PGlucHV0IHR5cGU9InRleHQiIG5h
206
+ bWU9ImVtYWlsIiBjbGFzcz0idGV4dCIgaWQ9InF1aWNrX2VtYWlsIiAvPjwv
207
+ ZGl2PgogICAgPGRpdiBjbGFzcz0ibGFiZWwiPs/g8O7r/DwvZGl2PgogICAg
208
+ PGRpdiBjbGFzcz0ibGFiZWxlZCI+PGlucHV0IHR5cGU9InBhc3N3b3JkIiBu
209
+ YW1lPSJwYXNzIiBjbGFzcz0idGV4dCIgaWQ9InF1aWNrX3Bhc3MiIG9ua2V5
210
+ dXA9InRvZ2dsZSgncXVpY2tfZXhwaXJlJywgISF0aGlzLnZhbHVlKTt0b2dn
211
+ bGUoJ3F1aWNrX2ZvcmdvdCcsICF0aGlzLnZhbHVlKSIgLz48L2Rpdj4KICAg
212
+ IDxpbnB1dCB0eXBlPSJzdWJtaXQiIGNsYXNzPSJzdWJtaXQiIC8+CiAgPC9m
213
+ b3JtPgogIDxidXR0b24gY2xhc3M9ImZsYXRfYnV0dG9uIGJ1dHRvbl93aWRl
214
+ IGJ1dHRvbl9iaWciIGlkPSJxdWlja19sb2dpbl9idXR0b24iPsLu6fLoPC9i
215
+ dXR0b24+CiAgPGJ1dHRvbiBjbGFzcz0iZmxhdF9idXR0b24gYnV0dG9uX3dp
216
+ ZGUgYnV0dG9uX2JpZyIgaWQ9InF1aWNrX3JlZ19idXR0b24iIHN0eWxlPSIi
217
+ IG9uY2xpY2s9InRvcC5zaG93Qm94KCdqb2luLnBocCcsIHthY3Q6ICdib3gn
218
+ LCBmcm9tOiBuYXYuc3RyTG9jfSkiPtDl4+jx8vDg9uj/PC9idXR0b24+CiAg
219
+ PGRpdiBjbGFzcz0iY2xlYXIgZm9yZ290Ij48YSBpZD0icXVpY2tfZm9yZ290
220
+ IiBocmVmPSIvcmVzdG9yZSIgdGFyZ2V0PSJfdG9wIj7H4OH76+gg7+Dw7uv8
221
+ PzwvYT48ZGl2IGNsYXNzPSJjaGVja2JveCB0YV9sIiBpZD0icXVpY2tfZXhw
222
+ aXJlIiBvbmNsaWNrPSJjaGVja2JveCh0aGlzKTtnZSgncXVpY2tfZXhwaXJl
223
+ X2lucHV0JykudmFsdWU9aXNDaGVja2VkKHRoaXMpPzE6Jyc7Ij48ZGl2Pjwv
224
+ ZGl2Ptfz5u7pIOru7O/8/vLl8DwvZGl2PjwvZGl2Pgo8L2Rpdj4KICAgIDwv
225
+ ZGl2PgoKICAgIDxkaXYgaWQ9InBhZ2VfYm9keSIgY2xhc3M9ImZsX3IiIHN0
226
+ eWxlPSJ3aWR0aDogNjMxcHg7Ij4KICAgICAgPGRpdiBpZD0iaGVhZGVyX3dy
227
+ YXAyIj4KICAgICAgICA8ZGl2IGlkPSJoZWFkZXJfd3JhcDEiPgogICAgICAg
228
+ ICAgPGRpdiBpZD0iaGVhZGVyIiBzdHlsZT0iIj4KICAgICAgICAgICAgPGgx
229
+ IGlkPSJ0aXRsZSI+zvjo4ergPC9oMT4KICAgICAgICAgIDwvZGl2PgogICAg
230
+ ICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBpZD0id3JhcF9i
231
+ ZXR3ZWVuIj48L2Rpdj4KICAgICAgPGRpdiBpZD0id3JhcDMiPjxkaXYgaWQ9
232
+ IndyYXAyIj4KICA8ZGl2IGlkPSJ3cmFwMSI+CiAgICA8ZGl2IGlkPSJjb250
233
+ ZW50Ij48ZGl2IGNsYXNzPSJtZXNzYWdlX3BhZ2UiPgogIDxkaXYgY2xhc3M9
234
+ InRpdGxlIj7O+Ojh6uA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJib2R5Ij4KICAg
235
+ IM746OHq4CDk7vHy8+/gCiAgICA8ZGl2IGNsYXNzPSJidXR0b25fYmx1ZSI+
236
+ PGJ1dHRvbiBpZD0ibXNnX2JhY2tfYnV0dG9uIj7N4Ofg5DwvYnV0dG9uPjwv
237
+ ZGl2PgogIDwvZGl2Pgo8L2Rpdj48L2Rpdj4KICA8L2Rpdj4KPC9kaXY+PC9k
238
+ aXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJmb290ZXJfd3JhcCIgY2xh
239
+ c3M9ImZsX3IiIHN0eWxlPSJ3aWR0aDogNjYxcHg7Ij4KICAgICAgPGRpdiBp
240
+ ZD0iYm90dG9tX25hdiI+CiAgPGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL2Fi
241
+ b3V0Ij7uIPHg6fLlPC9hPgogIDxhIGNsYXNzPSJibmF2X2EiIGhyZWY9Ii9z
242
+ dXBwb3J0P2FjdD1uZXciIG9uY2xpY2s9InJldHVybiBuYXYuZ28odGhpcywg
243
+ ZXZlbnQpOyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij7v7uzu+fw8L2E+CiAg
244
+ PGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL3Rlcm1zIj7v8ODi6OvgPC9hPgog
245
+ IDxhIGNsYXNzPSJibmF2X2EiIGhyZWY9Ii9hZHMiPvDl6uvg7OA8L2E+CiAg
246
+ PGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL3Blb3BsZSI+6/7k6DwvYT48YSBj
247
+ bGFzcz0iYm5hdl9hIiBocmVmPSIvY29tbXVuaXRpZXMiPvHu7uH55fHy4uA8
248
+ L2E+CiAgPGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL2RldiI+8ODn8ODh7vL3
249
+ 6Org7DwvYT4KICA8YSBjbGFzcz0iYm5hdl9hIiBocmVmPSIvam9icyIgc3R5
250
+ bGU9ImRpc3BsYXk6IG5vbmU7Ij7i4Org7fHo6DwvYT4KPC9kaXY+CjxkaXYg
251
+ aWQ9ImZvb3RlciIgY2xhc3M9ImNsZWFyIj4KICA8ZGl2IGNsYXNzPSJjb3B5
252
+ X2xhbmciPjxhIGhyZWY9Ii9hYm91dCI+wsru7fLg6vLlPC9hPiAmY29weTsg
253
+ MjAxNSA8YSBjbGFzcz0iYm5hdl9sYW5nIiBvbmNsaWNrPSJhamF4LnBvc3Qo
254
+ J2FsX2luZGV4LnBocCcsIHthY3Q6ICdjaGFuZ2VfbGFuZycsIGxhbmdfaWQ6
255
+ IDMsIGhhc2g6ICdiZjQyMDQyZjg2OTJkNzkzZjMnfSkiPkVuZ2xpc2g8L2E+
256
+ PGEgY2xhc3M9ImJuYXZfbGFuZyIgb25jbGljaz0iYWpheC5wb3N0KCdhbF9p
257
+ bmRleC5waHAnLCB7YWN0OiAnY2hhbmdlX2xhbmcnLCBsYW5nX2lkOiAwLCBo
258
+ YXNoOiAnYmY0MjA0MmY4NjkyZDc5M2YzJ30pIj7Q8/Hx6ujpPC9hPjxhIGNs
259
+ YXNzPSJibmF2X2xhbmciIG9uY2xpY2s9ImFqYXgucG9zdCgnYWxfaW5kZXgu
260
+ cGhwJywge2FjdDogJ2NoYW5nZV9sYW5nJywgbGFuZ19pZDogMSwgaGFzaDog
261
+ J2JmNDIwNDJmODY5MmQ3OTNmMyd9KSI+0+rw4L/t8fzq4DwvYT48YSBjbGFz
262
+ cz0iYm5hdl9sYW5nIiBvbmNsaWNrPSJpZiAodmsuYWwpIHsgc2hvd0JveCgn
263
+ bGFuZy5waHAnLCB7YWN0OiAnbGFuZ19kaWFsb2cnLCBhbGw6IDF9LCB7cGFy
264
+ YW1zOiB7ZGFyazogdHJ1ZSwgYm9keVN0eWxlOiAncGFkZGluZzogMHB4J30s
265
+ IG5vcmVsb2FkOiB0cnVlfSk7IH0gZWxzZSB7IGNoYW5nZUxhbmcoMSk7IH0g
266
+ cmV0dXJuIGZhbHNlOyI+4vHlIP/n++roICZyYXF1bzs8L2E+PC9kaXY+CiAg
267
+ CiAgPGRpdj4KICAgIAogICAgCiAgPC9kaXY+CjwvZGl2PgogICAgPC9kaXY+
268
+ CiAgICA8ZGl2IGNsYXNzPSJjbGVhciI+PC9kaXY+CiAgPC9kaXY+CjwvZGl2
269
+ PjwvZGl2Pjxub3NjcmlwdD48ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0
270
+ ZTtsZWZ0Oi0xMDAwMHB4OyI+CjxpbWcgc3JjPSIvL3RvcC1md3oxLm1haWwu
271
+ cnUvY291bnRlcj9pZD0yNTc5NDM3O2pzPW5hIiBzdHlsZT0iYm9yZGVyOjA7
272
+ IiBoZWlnaHQ9IjEiIHdpZHRoPSIxIiBhbHQ9ItDl6fLo7eNATWFpbC5ydSIg
273
+ Lz4KPC9kaXY+PC9ub3NjcmlwdD48L2Rpdj4KICA8ZGl2IGNsYXNzPSJwcm9n
274
+ cmVzcyIgaWQ9Imdsb2JhbF9wcmciPjwvZGl2PgoKICA8c2NyaXB0IHR5cGU9
275
+ InRleHQvamF2YXNjcmlwdCI+CiAgICBpZiAocGFyZW50ICYmIHBhcmVudCAh
276
+ PSB3aW5kb3cgJiYgKGJyb3dzZXIubXNpZSB8fCBicm93c2VyLm9wZXJhIHx8
277
+ IGJyb3dzZXIubW96aWxsYSB8fCBicm93c2VyLmNocm9tZSB8fCBicm93c2Vy
278
+ LnNhZmFyaSB8fCBicm93c2VyLmlwaG9uZSkpIHsKICAgICAgZG9jdW1lbnQu
279
+ Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXS5pbm5lckhUTUwgPSAn
280
+ JzsKICAgIH0gZWxzZSB7CiAgICAgIGRvbVJlYWR5KCk7CiAgICAgIHVwZGF0
281
+ ZU1vbmV5KDApOwpnU2VhcmNoLmluaXQoKTsKaWYgKHdpbmRvdy5xQXJyICYm
282
+ IHFBcnJbNV0pIHFBcnJbNV0gPSBbNSwgIu/uIPLu4uDw4OwiLCAiIiwgImdv
283
+ b2RzIiwgMHgwMDAwMDEwMF07CmlmIChicm93c2VyLmlwaG9uZSB8fCBicm93
284
+ c2VyLmlwYWQgfHwgYnJvd3Nlci5pcG9kKSB7CiAgc2V0U3R5bGUoYm9keU5v
285
+ ZGUsIHt3ZWJraXRUZXh0U2l6ZUFkanVzdDogJ25vbmUnfSk7Cn12YXIgcWYg
286
+ PSBnZSgncXVpY2tfbG9naW5fZm9ybScpLCBxbCA9IGdlKCdxdWlja19sb2dp
287
+ bicpLCBxZSA9IGdlKCdxdWlja19lbWFpbCcpLCBxcCA9IGdlKCdxdWlja19w
288
+ YXNzJyk7CnZhciBxbGIgPSBnZSgncXVpY2tfbG9naW5fYnV0dG9uJyksIHBy
289
+ Z0J0biA9IHFsYjsKCnZhciBxaW5pdCA9IGZ1bmN0aW9uKCkgewogIHNldFRp
290
+ bWVvdXQoZnVuY3Rpb24oKSB7CiAgICBxbC5pbnNlcnRCZWZvcmUoY2UoJ2Rp
291
+ dicsIHtpbm5lckhUTUw6ICc8aWZyYW1lIGNsYXNzPSJ1cGxvYWRfZnJhbWUi
292
+ IGlkPSJxdWlja19sb2dpbl9mcmFtZSIgbmFtZT0icXVpY2tfbG9naW5fZnJh
293
+ bWUiPjwvaWZyYW1lPid9KSwgcWYpOwogICAgcWYudGFyZ2V0ID0gJ3F1aWNr
294
+ X2xvZ2luX2ZyYW1lJzsKICB9LCAxKTsKfQoKaWYgKHdpbmRvdy50b3AgJiYg
295
+ d2luZG93LnRvcCAhPSB3aW5kb3cpIHsKICB3aW5kb3cub25sb2FkID0gcWlu
296
+ aXQ7Cn0gZWxzZSB7CiAgc2V0VGltZW91dChxaW5pdCwgMCk7Cn0KCnFmLm9u
297
+ c3VibWl0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKCFnZSgncXVpY2tfbG9naW5f
298
+ ZnJhbWUnKSkgcmV0dXJuIGZhbHNlOwogIGlmICghdHJpbShxZS52YWx1ZSkp
299
+ IHsKICAgIG5vdGFCZW5lKHFlKTsKICAgIHJldHVybiBmYWxzZTsKICB9IGVs
300
+ c2UgaWYgKCF0cmltKHFwLnZhbHVlKSkgewogICAgbm90YUJlbmUocXApOwog
301
+ ICAgcmV0dXJuIGZhbHNlOwogIH0KICBsb2NrQnV0dG9uKHdpbmRvdy5fX3Fm
302
+ QnRuID0gcHJnQnRuKTsKICBwcmdCdG4gPSBxbGI7CiAgY2xlYXJUaW1lb3V0
303
+ KF9fcWxUaW1lcik7CiAgX19xbFRpbWVyID0gc2V0VGltZW91dChsb2dpblN1
304
+ Ym1pdEVycm9yLCAzMDAwMCk7CiAgZG9tRkMoZG9tUFMocWYpKS5vbmxvYWQg
305
+ PSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dChfX3FsVGltZXIpOwog
306
+ ICAgX19xbFRpbWVyID0gc2V0VGltZW91dChsb2dpblN1Ym1pdEVycm9yLCAy
307
+ NTAwKTsKICB9CiAgcmV0dXJuIHRydWU7Cn0KCndpbmRvdy5sb2dpblN1Ym1p
308
+ dEVycm9yID0gZnVuY3Rpb24oKSB7CiAgc2hvd0Zhc3RCb3goJ8/w5eTz7/Dl
309
+ 5uTl7ehlJywgJ83lIPPk4OXy8f8g7/Du6fLoIODi8u7w6Ofg9uj+IO/uIOfg
310
+ +ej55e3t7uzzIPHu5eTo7eXt6P4uINfg+eUg4vHl4+4g/fLuIO/w7ujx9e7k
311
+ 6PIsIOru4+TgIO3gIMLg+OXsIOru7O/8/vLl8OUg8/Hy4O3u4uvl7fsg7eXv
312
+ 8ODi6Ov87fvlIPLl6vP56OUg5ODy4CDoIOLw5ez/LiDP7ubg6/Pp8fLgLCDv
313
+ 8O7i5fD88uUg7eDx8vDu6eroIOTg8vsg6CDi8OXs5e3oIOIg8ejx8uXs5SDo
314
+ IO/l8OXn4O/z8fLo8uUg4fDg8+fl8C4nKTsKfQp3aW5kb3cuZm9jdXNMb2dp
315
+ bklucHV0ID0gZnVuY3Rpb24oKSB7CiAgc2Nyb2xsVG9Ub3AoMCk7CiAgbm90
316
+ YUJlbmUoJ3F1aWNrX2VtYWlsJyk7Cn0Kd2luZG93LmNoYW5nZVF1aWNrUmVn
317
+ QnV0dG9uID0gZnVuY3Rpb24obm9TaG93KSB7CiAgaWYgKG5vU2hvdykgewog
318
+ ICAgaGlkZSgndG9wX3JlZ19saW5rJywgJ3F1aWNrX3JlZ19idXR0b24nKTsK
319
+ ICAgIHNob3coJ3RvcF9zZWFyY2hfbGluaycpOwogIH0gZWxzZSB7CiAgICBo
320
+ aWRlKCd0b3Bfc2VhcmNoX2xpbmsnKTsKICAgIHNob3coJ3RvcF9yZWdfbGlu
321
+ aycsICdxdWlja19yZWdfYnV0dG9uJyk7CiAgfQogIHRvZ2dsZSgndG9wX3N3
322
+ aXRjaF9sYW5nJywgbm9TaG93ICYmIHdpbmRvdy5sYW5nQ29uZmlnICYmIHdp
323
+ bmRvdy5sYW5nQ29uZmlnLmlkICE9IDMpOwp9CndpbmRvdy5zdWJtaXRRdWlj
324
+ a0xvZ2luRm9ybSA9IGZ1bmN0aW9uKGVtYWlsLCBwYXNzLCBvcHRzKSB7CiAg
325
+ c2V0UXVpY2tMb2dpbkRhdGEoZW1haWwsIHBhc3MsIG9wdHMpOwogIGlmIChv
326
+ cHRzICYmIG9wdHMucHJnKSBwcmdCdG4gPSBvcHRzLnByZzsKICBpZiAocWYu
327
+ b25zdWJtaXQoKSkgcWYuc3VibWl0KCk7Cn0Kd2luZG93LnNldFF1aWNrTG9n
328
+ aW5EYXRhID0gZnVuY3Rpb24oZW1haWwsIHBhc3MsIG9wdHMpIHsKICBpZiAo
329
+ ZW1haWwgIT09IHVuZGVmaW5lZCkgZ2UoJ3F1aWNrX2VtYWlsJykudmFsdWUg
330
+ PSBlbWFpbDsKICBpZiAocGFzcyAhPT0gdW5kZWZpbmVkKSBnZSgncXVpY2tf
331
+ cGFzcycpLnZhbHVlID0gcGFzczsKICB2YXIgcGFyYW1zID0gb3B0cyAmJiBv
332
+ cHRzLnBhcmFtcyB8fCB7fTsKICBmb3IgKHZhciBpIGluIHBhcmFtcykgewog
333
+ ICAgdmFyIGVsID0gZ2UoJ3F1aWNrX2xvZ2luXycgKyBpKTsKICAgIGlmIChl
334
+ bCkgewogICAgICB2YWwoZWwsIHBhcmFtc1tpXSk7CiAgICB9IGVsc2Ugewog
335
+ ICAgICBxZi5hcHBlbmRDaGlsZChjZSgnaW5wdXQnLCB7dHlwZTogJ2hpZGRl
336
+ bicsIG5hbWU6IGksIGlkOiAncXVpY2tfbG9naW5fJyArIGksIHZhbHVlOiBw
337
+ YXJhbXNbaV19KSk7CiAgICB9CiAgfQp9CgppZiAocWxiKSB7CiAgcWxiLm9u
338
+ Y2xpY2sgPSBmdW5jdGlvbigpIHsgaWYgKHFmLm9uc3VibWl0KCkpIHFmLnN1
339
+ Ym1pdCgpOyB9Owp9CgppZiAoYnJvd3Nlci5vcGVyYV9tb2JpbGUpIHNob3co
340
+ J3F1aWNrX2V4cGlyZScpOwoKaWYgKDEpIHsKICBoaWRlKCdzdXBwb3J0X2xp
341
+ bmtfdGQnKTsKfQp2YXIgdHNfaW5wdXQgPSBnZSgndHNfaW5wdXQnKSwgb2xk
342
+ RkYgPSBicm93c2VyLm1vemlsbGEgJiYgcGFyc2VJbnQoYnJvd3Nlci52ZXJz
343
+ aW9uKSA8IDg7CmlmIChicm93c2VyLm1vemlsbGEgJiYgIW9sZEZGKSB7CiAg
344
+ c2V0U3R5bGUodHNfaW5wdXQsIHtwYWRkaW5nOiAodmsucnRsID8gJzNweCAy
345
+ MHB4IDZweCA0MHB4JyA6ICczcHggNDFweCA2cHggMjBweCcpfSk7Cn0KcGxh
346
+ Y2Vob2xkZXJTZXR1cCh0c19pbnB1dCwge2JhY2s6IGZhbHNlLCByZWxvYWQ6
347
+ IHRydWV9KTsKaWYgKGJyb3dzZXIub3BlcmEgfHwgYnJvd3Nlci5tc2llIHx8
348
+ IGJyb3dzZXIubW96aWxsYSkgewogIHNldFN0eWxlKHRzX2lucHV0LCB7cGFk
349
+ ZGluZzogKHZrLnJ0bCA/ICc0cHggMjBweCA1cHggNDBweCcgOiAnNHB4IDQx
350
+ cHggNXB4IDIwcHgnKX0pOwp9IGVsc2UgaWYgKGJyb3dzZXIuY2hyb21lIHx8
351
+ IGJyb3dzZXIuc2FmYXJpKSB7CiAgc2V0U3R5bGUodHNfaW5wdXQsIHtwYWRk
352
+ aW5nOiAodmsucnRsID8gJzRweCAyMXB4IDVweCA0MHB4JyA6ICc0cHggNDBw
353
+ eCA1cHggMjFweCcpfSk7Cn0KClRvcFNlYXJjaC5pbml0KCk7CmlmIChicm93
354
+ c2VyLm1zaWU4IHx8IGJyb3dzZXIubXNpZTcpIHsKICB2YXIgc3QgPSB7Ym9y
355
+ ZGVyOiAnMXB4IHNvbGlkICNhNmI2YzYnfTsKICBpZiAoaGFzQ2xhc3MoZ2Uo
356
+ J3RzX3dyYXAnKSwgJ3ZrJykpIHsKICAgIGlmICh2ay5ydGwpIHN0LmxlZnQg
357
+ PSAnMXB4JzsKICAgIGVsc2Ugc3QucmlnaHQgPSAnMHB4JzsKICB9IGVsc2Ug
358
+ ewogICAgaWYgKHZrLnJ0bCkgc3QucmlnaHQgPSAnMTQ2cHgnOwogICAgZWxz
359
+ ZSBzdC5sZWZ0ID0gJzE0NnB4JzsKICB9CiAgc2V0U3R5bGUoZ2UoJ3RzX2Nv
360
+ bnRfd3JhcCcpLCBzdCk7Cn0Kd2luZG93LnRzSGludHNFbmFibGVkID0gMTsK
361
+ c2V0VGltZW91dCh6TmF2LnBiaW5kKHt9LCB7cXVldWU6MX0pLCAwKTsKaGFu
362
+ ZGxlUGFnZVBhcmFtcyh7ImlkIjowLCJwYWRzIjoxLCJub19hZHMiOjEsImxv
363
+ YyI6Ij9hY3Q9cyZvaWQ9OTQ5MTUyOCZ2aWQ9MTY1MTkzMTMzIiwid3JhcF9w
364
+ YWdlIjoxLCJ3aWR0aCI6NzkxLCJ3aWR0aF9kZWMiOjE2MCwid2lkdGhfZGVj
365
+ X2Zvb3RlciI6MTMwLCJib2R5X2NsYXNzIjoiaXNfcnRsIGZvbnRfZGVmYXVs
366
+ dCBwYWRzICIsImNvdW50ZXJzIjoiIiwicHZiaWciOjAsInB2ZGFyayI6MX0p
367
+ O2FkZEV2ZW50KGRvY3VtZW50LCAnY2xpY2snLCBvbkRvY3VtZW50Q2xpY2sp
368
+ O2dlKCdtc2dfYmFja19idXR0b24nKS5vbmNsaWNrID0gZnVuY3Rpb24oKSB7
369
+ CiAgaGlzdG9yeS5nbygtMSk7Cn07CjsoZnVuY3Rpb24gKGQsIHcpIHsKdmFy
370
+ IHRzID0gZC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTsgdHMudHlwZSA9ICJ0
371
+ ZXh0L2phdmFzY3JpcHQiOyB0cy5hc3luYyA9IHRydWU7CnRzLnNyYyA9IChk
372
+ LmxvY2F0aW9uLnByb3RvY29sID09ICJodHRwczoiID8gImh0dHBzOiIgOiAi
373
+ aHR0cDoiKSArICIvL3RvcC1md3oxLm1haWwucnUvanMvY29kZS5qcyI7CnZh
374
+ ciBmID0gZnVuY3Rpb24gKCkge3ZhciBzID0gZC5nZXRFbGVtZW50c0J5VGFn
375
+ TmFtZSgic2NyaXB0IilbMF07IHMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUo
376
+ dHMsIHMpO307CmlmICh3Lm9wZXJhID09ICJbb2JqZWN0IE9wZXJhXSIpIHsg
377
+ ZC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZiwgZmFs
378
+ c2UpOyB9IGVsc2UgeyBmKCk7IH0KfSkoZG9jdW1lbnQsIHdpbmRvdyk7CiAg
379
+ ICB9CiAgPC9zY3JpcHQ+CjwvYm9keT4KCjwvaHRtbD4=
380
+ http_version:
381
+ recorded_at: Sun, 08 Mar 2015 15:03:49 GMT
382
+ recorded_with: VCR 2.9.3