ethon 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/CHANGELOG.md +13 -1
- data/README.md +5 -1
- data/ethon.gemspec +1 -1
- data/lib/ethon/curls/infos.rb +2 -1
- data/lib/ethon/curls/options.rb +9 -9
- data/lib/ethon/easy.rb +2 -0
- data/lib/ethon/easy/callbacks.rb +8 -1
- data/lib/ethon/easy/response_callbacks.rb +49 -1
- data/lib/ethon/multi/options.rb +6 -6
- data/lib/ethon/version.rb +1 -1
- data/spec/ethon/easy/http_spec.rb +19 -0
- data/spec/ethon/easy/response_callbacks_spec.rb +63 -18
- data/spec/ethon/easy_spec.rb +12 -0
- metadata +17 -7
- checksums.yaml +0 -15
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,19 @@
|
|
2
2
|
|
3
3
|
## Master
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/typhoeus/ethon/compare/v0.6.
|
5
|
+
[Full Changelog](https://github.com/typhoeus/ethon/compare/v0.6.2...master)
|
6
|
+
|
7
|
+
## 0.6.2
|
8
|
+
|
9
|
+
[Full Changelog](https://github.com/typhoeus/ethon/compare/v0.6.1...v0.6.2)
|
10
|
+
|
11
|
+
The changelog entries are coming soon!
|
12
|
+
|
13
|
+
## 0.6.1
|
14
|
+
|
15
|
+
[Full Changelog](https://github.com/typhoeus/ethon/compare/v0.6.0...v0.6.1)
|
16
|
+
|
17
|
+
The changelog entries are coming soon!
|
6
18
|
|
7
19
|
## 0.6.0
|
8
20
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Ethon [![Build Status](https://secure.travis-ci.org/typhoeus/ethon.png?branch=master)](http://travis-ci.org/typhoeus/ethon)
|
1
|
+
# Ethon [![Build Status](https://secure.travis-ci.org/typhoeus/ethon.png?branch=master)](http://travis-ci.org/typhoeus/ethon) [![Gem Version](https://badge.fury.io/rb/ethon.png)](http://badge.fury.io/rb/ethon)
|
2
2
|
|
3
3
|
In Greek mythology, Ethon, the son of Typhoeus and Echidna, is a gigantic eagle. So much for the history.
|
4
4
|
In the modern world, Ethon is a very basic libcurl wrapper using ffi.
|
@@ -90,3 +90,7 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
90
90
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
91
91
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
92
92
|
OTHER DEALINGS IN THE SOFTWARE.
|
93
|
+
|
94
|
+
|
95
|
+
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/typhoeus/ethon/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
96
|
+
|
data/ethon.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.description = "Very lightweight libcurl wrapper."
|
16
16
|
|
17
17
|
s.required_rubygems_version = ">= 1.3.6"
|
18
|
-
s.
|
18
|
+
s.license = 'MIT'
|
19
19
|
|
20
20
|
s.add_dependency('ffi', ['>= 1.3.0'])
|
21
21
|
s.add_dependency('mime-types', ['~> 1.18'])
|
data/lib/ethon/curls/infos.rb
CHANGED
@@ -105,7 +105,8 @@ module Ethon
|
|
105
105
|
# @return [ String ] The info.
|
106
106
|
def get_info_string(option, handle)
|
107
107
|
if easy_getinfo(handle, option, string_ptr) == :ok
|
108
|
-
string_ptr.read_pointer
|
108
|
+
ptr=string_ptr.read_pointer
|
109
|
+
ptr.null? ? nil : ptr.read_string
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
data/lib/ethon/curls/options.rb
CHANGED
@@ -10,7 +10,7 @@ module Ethon
|
|
10
10
|
raise NameError, "Ethon::Curls::Options unknown type #{type}." unless respond_to?("#{type.to_s.downcase}_options")
|
11
11
|
opthash=send("#{type.to_s.downcase}_options")
|
12
12
|
raise Errors::InvalidOption.new(option) unless opthash.include?(option)
|
13
|
-
|
13
|
+
|
14
14
|
case opthash[option][:type]
|
15
15
|
when :none
|
16
16
|
return if value.nil?
|
@@ -78,7 +78,7 @@ module Ethon
|
|
78
78
|
|
79
79
|
send("#{type}_setopt_#{func}", handle, opthash[option][:opt], value)
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
OPTION_TYPE_BASE = {
|
83
83
|
:long => 0,
|
84
84
|
:objectpoint => 10000,
|
@@ -125,7 +125,7 @@ module Ethon
|
|
125
125
|
elsif not opts.is_a? Hash then
|
126
126
|
raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash."
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
when :bitmask
|
130
130
|
if opts.is_a? Array then
|
131
131
|
if opts.last.is_a? Hash then
|
@@ -151,14 +151,14 @@ module Ethon
|
|
151
151
|
opts[k]=v.map { |b| opts[b] }.inject :|
|
152
152
|
end
|
153
153
|
end
|
154
|
-
|
154
|
+
|
155
155
|
when :buffer
|
156
156
|
raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash." unless opts.is_a? Integer
|
157
|
-
|
157
|
+
|
158
158
|
else
|
159
159
|
raise ArgumentError, "Ethon::Curls::Options #{ftype} #{name} Expected no opts." unless opts.nil?
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
opthash=const_get("#{ftype.to_s.upcase}_OPTIONS")
|
163
163
|
opthash[name]={:type=>type, :opt=>OPTION_TYPE_BASE[OPTION_TYPE_MAP[type]]+num, :opts=>opts}
|
164
164
|
end
|
@@ -178,12 +178,12 @@ module Ethon
|
|
178
178
|
end
|
179
179
|
>
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
# Curl multi options, refer
|
183
183
|
# Defined @ https://github.com/bagder/curl/blob/master/include/curl/multi.h
|
184
184
|
# Documentation @ http://curl.haxx.se/libcurl/c/curl_multi_setopt.html
|
185
185
|
option_type :multi
|
186
|
-
|
186
|
+
|
187
187
|
option :multi, :socketfunction, :callback, 1
|
188
188
|
option :multi, :socketdata, :cbdata, 2
|
189
189
|
option :multi, :pipelining, :bool, 3
|
@@ -280,7 +280,7 @@ module Ethon
|
|
280
280
|
option :easy, :username, :string, 173
|
281
281
|
option :easy, :password, :string, 174
|
282
282
|
option :easy, :proxyusername, :string, 175
|
283
|
-
option :easy, :proxypassword, :string, 176
|
283
|
+
option :easy, :proxypassword, :string, 176
|
284
284
|
option :easy, :httpauth, :bitmask, 107, [:none, :basic, :digest, :gssnegotiate, :ntlm, :digest_ie, :ntlm_wb, {:only => 1<<31, :any => ~0x10, :anysafe => ~0x11, :auto => 0x1f}]
|
285
285
|
option :easy, :tlsauth_type, :enum, 206, [:none, :srp]
|
286
286
|
option :easy, :tlsauth_username, :string, 204
|
data/lib/ethon/easy.rb
CHANGED
data/lib/ethon/easy/callbacks.rb
CHANGED
@@ -24,6 +24,7 @@ module Ethon
|
|
24
24
|
Curl.set_option(:debugfunction, debug_callback, handle)
|
25
25
|
@response_body = ""
|
26
26
|
@response_headers = ""
|
27
|
+
@headers_called = false
|
27
28
|
@debug_info = Ethon::Easy::DebugInfo.new
|
28
29
|
end
|
29
30
|
|
@@ -35,7 +36,13 @@ module Ethon
|
|
35
36
|
# @return [ Proc ] The callback.
|
36
37
|
def body_write_callback
|
37
38
|
@body_write_callback ||= proc {|stream, size, num, object|
|
38
|
-
@
|
39
|
+
unless @headers_called
|
40
|
+
@headers_called = true
|
41
|
+
headers
|
42
|
+
end
|
43
|
+
if :unyielded == body(chunk = stream.read_string(size * num))
|
44
|
+
@response_body << chunk
|
45
|
+
end
|
39
46
|
size * num
|
40
47
|
}
|
41
48
|
end
|
@@ -22,6 +22,28 @@ module Ethon
|
|
22
22
|
# #=> []
|
23
23
|
module ResponseCallbacks
|
24
24
|
|
25
|
+
# Set on_headers callback.
|
26
|
+
#
|
27
|
+
# @example Set on_headers.
|
28
|
+
# request.on_headers { p "yay" }
|
29
|
+
#
|
30
|
+
# @param [ Block ] block The block to execute.
|
31
|
+
def on_headers(&block)
|
32
|
+
@on_headers ||= []
|
33
|
+
@on_headers << block if block_given?
|
34
|
+
@on_headers
|
35
|
+
end
|
36
|
+
|
37
|
+
# Execute on_headers callbacks.
|
38
|
+
#
|
39
|
+
# @example Execute on_headers.
|
40
|
+
# request.headers
|
41
|
+
def headers
|
42
|
+
if defined?(@on_headers) and not @on_headers.nil?
|
43
|
+
@on_headers.each{ |callback| callback.call(self) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
25
47
|
# Set on_complete callback.
|
26
48
|
#
|
27
49
|
# @example Set on_complete.
|
@@ -39,10 +61,36 @@ module Ethon
|
|
39
61
|
# @example Execute on_completes.
|
40
62
|
# request.complete
|
41
63
|
def complete
|
42
|
-
if @on_complete
|
64
|
+
if defined?(@on_complete) and not @on_complete.nil?
|
43
65
|
@on_complete.each{ |callback| callback.call(self) }
|
44
66
|
end
|
45
67
|
end
|
68
|
+
|
69
|
+
# Set on_body callback.
|
70
|
+
#
|
71
|
+
# @example Set on_body.
|
72
|
+
# request.on_body { |chunk| p "yay" }
|
73
|
+
#
|
74
|
+
# @param [ Block ] block The block to execute.
|
75
|
+
def on_body(&block)
|
76
|
+
@on_body ||= []
|
77
|
+
@on_body << block if block_given?
|
78
|
+
@on_body
|
79
|
+
end
|
80
|
+
|
81
|
+
# Execute on_body callbacks.
|
82
|
+
#
|
83
|
+
# @example Execute on_body.
|
84
|
+
# request.body("This data came from HTTP.")
|
85
|
+
#
|
86
|
+
# @return [ Object ] If there are no on_body callbacks, returns the symbol :unyielded.
|
87
|
+
def body(chunk)
|
88
|
+
if defined?(@on_body) and not @on_body.nil?
|
89
|
+
@on_body.each{ |callback| callback.call(chunk, self) }
|
90
|
+
else
|
91
|
+
:unyielded
|
92
|
+
end
|
93
|
+
end
|
46
94
|
end
|
47
95
|
end
|
48
96
|
end
|
data/lib/ethon/multi/options.rb
CHANGED
@@ -14,7 +14,7 @@ module Ethon
|
|
14
14
|
#
|
15
15
|
# @return [ void ]
|
16
16
|
def maxconnects=(value)
|
17
|
-
Curl.set_option(:maxconnects, value_for(value, :int), handle)
|
17
|
+
Curl.set_option(:maxconnects, value_for(value, :int), handle, :multi)
|
18
18
|
end
|
19
19
|
|
20
20
|
# Sets pipelining option.
|
@@ -26,7 +26,7 @@ module Ethon
|
|
26
26
|
#
|
27
27
|
# @return [ void ]
|
28
28
|
def pipelining=(value)
|
29
|
-
Curl.set_option(:pipelining, value_for(value, :bool), handle)
|
29
|
+
Curl.set_option(:pipelining, value_for(value, :bool), handle, :multi)
|
30
30
|
end
|
31
31
|
|
32
32
|
# Sets socketdata option.
|
@@ -38,7 +38,7 @@ module Ethon
|
|
38
38
|
#
|
39
39
|
# @return [ void ]
|
40
40
|
def socketdata=(value)
|
41
|
-
Curl.set_option(:socketdata, value_for(value, :string), handle)
|
41
|
+
Curl.set_option(:socketdata, value_for(value, :string), handle, :multi)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Sets socketfunction option.
|
@@ -50,7 +50,7 @@ module Ethon
|
|
50
50
|
#
|
51
51
|
# @return [ void ]
|
52
52
|
def socketfunction=(value)
|
53
|
-
Curl.set_option(:socketfunction, value_for(value, :string), handle)
|
53
|
+
Curl.set_option(:socketfunction, value_for(value, :string), handle, :multi)
|
54
54
|
end
|
55
55
|
|
56
56
|
# Sets timerdata option.
|
@@ -62,7 +62,7 @@ module Ethon
|
|
62
62
|
#
|
63
63
|
# @return [ void ]
|
64
64
|
def timerdata=(value)
|
65
|
-
Curl.set_option(:timerdata, value_for(value, :string), handle)
|
65
|
+
Curl.set_option(:timerdata, value_for(value, :string), handle, :multi)
|
66
66
|
end
|
67
67
|
|
68
68
|
# Sets timerfunction option.
|
@@ -74,7 +74,7 @@ module Ethon
|
|
74
74
|
#
|
75
75
|
# @return [ void ]
|
76
76
|
def timerfunction=(value)
|
77
|
-
Curl.set_option(:timerfunction, value_for(value, :string), handle)
|
77
|
+
Curl.set_option(:timerfunction, value_for(value, :string), handle, :multi)
|
78
78
|
end
|
79
79
|
|
80
80
|
private
|
data/lib/ethon/version.rb
CHANGED
@@ -31,6 +31,25 @@ describe Ethon::Easy::Http do
|
|
31
31
|
easy.perform
|
32
32
|
expect(easy.response_body).to include("\"REQUEST_METHOD\":\"#{action.to_s.upcase}\"")
|
33
33
|
end
|
34
|
+
|
35
|
+
it "streams the response body from the #{action.to_s.upcase} request" do
|
36
|
+
bytes_read = 0
|
37
|
+
easy.on_body { |chunk, response| bytes_read += chunk.bytesize }
|
38
|
+
easy.http_request(url, action, options)
|
39
|
+
easy.perform
|
40
|
+
content_length = ((easy.response_headers =~ /Content-Length: (\d+)/) && $1.to_i)
|
41
|
+
expect(bytes_read).to eq(content_length)
|
42
|
+
expect(easy.response_body).to eq("")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "notifies when headers are ready" do
|
46
|
+
headers = []
|
47
|
+
easy.on_headers { |r| headers << r.response_headers }
|
48
|
+
easy.http_request(url, action, options)
|
49
|
+
easy.perform
|
50
|
+
expect(headers).to eq([easy.response_headers])
|
51
|
+
expect(headers.first).to match(/Content-Length: (\d+)/)
|
52
|
+
end
|
34
53
|
end
|
35
54
|
end
|
36
55
|
|
@@ -3,29 +3,31 @@ require 'spec_helper'
|
|
3
3
|
describe Ethon::Easy::ResponseCallbacks do
|
4
4
|
let(:easy) { Ethon::Easy.new }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
[:on_complete, :on_headers, :on_body].each do |callback_type|
|
7
|
+
describe "##{callback_type}" do
|
8
|
+
it "responds" do
|
9
|
+
expect(easy).to respond_to("#{callback_type}")
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
context "when no block given" do
|
13
|
+
it "returns @#{callback_type}" do
|
14
|
+
expect(easy.send("#{callback_type}")).to eq([])
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
context "when block given" do
|
19
|
+
it "stores" do
|
20
|
+
easy.send(callback_type) { p 1 }
|
21
|
+
expect(easy.instance_variable_get("@#{callback_type}")).to have(1).items
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
context "when multiple blocks given" do
|
26
|
+
it "stores" do
|
27
|
+
easy.send(callback_type) { p 1 }
|
28
|
+
easy.send(callback_type) { p 2 }
|
29
|
+
expect(easy.instance_variable_get("@#{callback_type}")).to have(2).items
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -47,4 +49,47 @@ describe Ethon::Easy::ResponseCallbacks do
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
52
|
+
|
53
|
+
describe "#headers" do
|
54
|
+
before do
|
55
|
+
easy.on_headers {|r| String.new(r.url) }
|
56
|
+
end
|
57
|
+
|
58
|
+
it "executes blocks and passes self" do
|
59
|
+
String.should_receive(:new).with(easy.url)
|
60
|
+
easy.headers
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when @on_headers nil" do
|
64
|
+
it "doesn't raise" do
|
65
|
+
easy.instance_variable_set(:@on_headers, nil)
|
66
|
+
expect{ easy.headers }.to_not raise_error(NoMethodError)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#body" do
|
72
|
+
before do
|
73
|
+
@chunk = nil
|
74
|
+
@r = nil
|
75
|
+
easy.on_body { |chunk, r| @chunk = chunk ; @r = r }
|
76
|
+
end
|
77
|
+
|
78
|
+
it "executes blocks and passes self" do
|
79
|
+
easy.body("the chunk")
|
80
|
+
expect(@r).to be(easy)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "executes blocks and passes chunk" do
|
84
|
+
easy.body("the chunk")
|
85
|
+
expect(@chunk).to eq("the chunk")
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when @on_body nil" do
|
89
|
+
it "doesn't raise" do
|
90
|
+
easy.instance_variable_set(:@on_body, nil)
|
91
|
+
expect{ easy.body("the chunk") }.to_not raise_error(NoMethodError)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
50
95
|
end
|
data/spec/ethon/easy_spec.rb
CHANGED
@@ -82,6 +82,18 @@ describe Ethon::Easy do
|
|
82
82
|
easy.reset
|
83
83
|
expect(easy.on_complete).to be_empty
|
84
84
|
end
|
85
|
+
|
86
|
+
it "resets on_headers" do
|
87
|
+
easy.on_headers { p 1 }
|
88
|
+
easy.reset
|
89
|
+
expect(easy.on_headers).to be_empty
|
90
|
+
end
|
91
|
+
|
92
|
+
it "resets on_body" do
|
93
|
+
easy.on_body { p 1 }
|
94
|
+
easy.reset
|
95
|
+
expect(easy.on_body).to be_empty
|
96
|
+
end
|
85
97
|
end
|
86
98
|
|
87
99
|
describe "#mirror" do
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ethon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Hans Hasselberg
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-12-19 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: ffi
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: mime-types
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -146,27 +151,32 @@ files:
|
|
146
151
|
- spec/support/localhost_server.rb
|
147
152
|
- spec/support/server.rb
|
148
153
|
homepage: https://github.com/typhoeus/ethon
|
149
|
-
licenses:
|
150
|
-
|
154
|
+
licenses:
|
155
|
+
- MIT
|
151
156
|
post_install_message:
|
152
157
|
rdoc_options: []
|
153
158
|
require_paths:
|
154
159
|
- lib
|
155
160
|
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
156
162
|
requirements:
|
157
163
|
- - ! '>='
|
158
164
|
- !ruby/object:Gem::Version
|
159
165
|
version: '0'
|
166
|
+
segments:
|
167
|
+
- 0
|
168
|
+
hash: 1717729668424310423
|
160
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
161
171
|
requirements:
|
162
172
|
- - ! '>='
|
163
173
|
- !ruby/object:Gem::Version
|
164
174
|
version: 1.3.6
|
165
175
|
requirements: []
|
166
|
-
rubyforge_project:
|
167
|
-
rubygems_version:
|
176
|
+
rubyforge_project:
|
177
|
+
rubygems_version: 1.8.23
|
168
178
|
signing_key:
|
169
|
-
specification_version:
|
179
|
+
specification_version: 3
|
170
180
|
summary: Libcurl wrapper.
|
171
181
|
test_files:
|
172
182
|
- spec/ethon/curl_spec.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
N2ZhYTYzYzNiNDAwMzdkYzk5YTcxYzEyMmNkZTI1ODliMGM4ZTViZg==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzYwYmM2OTAzM2UyOTQ5YjMzNTRkNTc3NDE5ZjdiMTNmMGY3MmYxZg==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZDJmYzExYjM4N2NkODQxMWE2YTMzNjAyNjg0MzFlMDFiZDI1ZDFiYzFlMWU2
|
10
|
-
ZDU5ZjM5YTNlZDk4NTJkYTMxNzYwMzgwZDY1MWFkOTA1Y2FhNDJhZmVlMzVm
|
11
|
-
NGMwODBlOTE0YjUyNjhjMTdiMDdmNDM2M2E5ZDQxNDdlOWMwOTc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YmVkMmY3NjFkZTY0YTUzOWYyZGU2YjRlMjgwNDk4ZDkzMjk0MzI0ZTYxNWRh
|
14
|
-
MDU3ZDliMGQ0ZTAwYTg0YmQ0NGVjNTJmZjM2YzNmZDg0MGY3NWU3MzMzYjdi
|
15
|
-
YTIxMmQxMmI0OGY0N2ExYzAyOWY4YTU0YThmYWY0MWZlYmUzZWI=
|