hglib 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.md +9 -0
- data/README.md +1 -0
- data/lib/hglib/extension/topic.rb +215 -0
- data/lib/hglib/repo.rb +2 -1
- data/lib/hglib/server.rb +1 -1
- data/lib/hglib.rb +1 -1
- data/spec/hglib/extension/gpg_spec.rb +1 -1
- data/spec/hglib/repo/id_spec.rb +1 -1
- data/spec/hglib/repo_spec.rb +13 -13
- data/spec/spec_helper.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +22 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56dd5ffa23837596f0d3248677aceb3cf20e836fdb915cd58fb32d74afbee746
|
4
|
+
data.tar.gz: 9a45cc618c6a9925f8aa54dbb89aae95bef02755fd9eee64285e134080015b17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7162090406ec2fcb10bb6ff5450dc7a7b5a2a315cf405309519edb7c86d41ad9d4c8ed1aa8ec2f351e6d31c06d6bc7dc62f396acb537b3e198ad1319244a3aa1
|
7
|
+
data.tar.gz: fe4e915b74ecd0ae0e430e4db7a103deb424db4fc472aa059efe364b3e8b56ccefa781804613c6f0920bfa263f37339949f3a572afa7ddd5c08a233af430fbcb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# Release History for hglib
|
2
2
|
|
3
3
|
---
|
4
|
+
|
5
|
+
## v0.8.0 [2020-01-21] Michael Granger <ged@FaerieMUD.org>
|
6
|
+
|
7
|
+
Improvements:
|
8
|
+
|
9
|
+
- Fixes for 2.7 and 2.5.
|
10
|
+
- Including the mistakenly-omitted `topic` extension
|
11
|
+
|
12
|
+
|
4
13
|
## v0.7.0 [2020-01-08] Michael Granger <ged@FaerieMUD.org>
|
5
14
|
|
6
15
|
Changes:
|
data/README.md
CHANGED
@@ -18,6 +18,7 @@ docs
|
|
18
18
|
This is a client library for the Mercurial distributed revision control tool
|
19
19
|
that uses the [Command Server][cmdserver] for efficiency.
|
20
20
|
|
21
|
+
[![builds.sr.ht status](https://builds.sr.ht/~ged/hglib.svg)](https://builds.sr.ht/~ged/hglib?)
|
21
22
|
|
22
23
|
### Examples
|
23
24
|
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'hglib/extension' unless defined?( Hglib::Extension )
|
5
|
+
require 'hglib/mixins'
|
6
|
+
|
7
|
+
|
8
|
+
# Extension module for the Mercurial `topic` extension
|
9
|
+
module Hglib::Extension::Topic
|
10
|
+
extend Hglib::Extension
|
11
|
+
|
12
|
+
|
13
|
+
# A topic in an Hglib::Repo.
|
14
|
+
class Entry
|
15
|
+
extend Hglib::MethodUtilities
|
16
|
+
include Hglib::Inspection
|
17
|
+
|
18
|
+
### Create a new Entry for the specified +repo+ given an +entryhash+ like that
|
19
|
+
### returned by the JSON template for the `topics` command.
|
20
|
+
def initialize( repo, entryhash )
|
21
|
+
@repo = repo
|
22
|
+
|
23
|
+
@name = entryhash[:topic]
|
24
|
+
@active = entryhash[:active]
|
25
|
+
@changeset_count = entryhash[:changesetcount]
|
26
|
+
@branch = entryhash[:"branches+"]
|
27
|
+
@last_touched = entryhash[:lasttouched]
|
28
|
+
@user_touched = entryhash[:usertouched]
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
######
|
33
|
+
public
|
34
|
+
######
|
35
|
+
|
36
|
+
##
|
37
|
+
# The Hglib::Repo of the repository the topic belongs to
|
38
|
+
attr_reader :repo
|
39
|
+
|
40
|
+
##
|
41
|
+
# The name of the topic
|
42
|
+
attr_reader :name
|
43
|
+
|
44
|
+
##
|
45
|
+
# The name of the branch the topic is on
|
46
|
+
attr_reader :branch
|
47
|
+
|
48
|
+
##
|
49
|
+
# Whether or not the entry is current active
|
50
|
+
attr_predicate :active
|
51
|
+
|
52
|
+
##
|
53
|
+
# The number of changesets belonging to the topic
|
54
|
+
attr_reader :changeset_count
|
55
|
+
alias_method :changesetcount, :changeset_count
|
56
|
+
|
57
|
+
##
|
58
|
+
# The human description of when the topic last had changesets added to it
|
59
|
+
# (if it was fetched)
|
60
|
+
attr_reader :last_touched
|
61
|
+
alias_method :lasttouched, :last_touched
|
62
|
+
|
63
|
+
##
|
64
|
+
# The name of the last user to add changesets to the topic (if it was fetched)
|
65
|
+
attr_reader :user_touched
|
66
|
+
alias_method :usertouched, :user_touched
|
67
|
+
alias_method :touched_by, :user_touched
|
68
|
+
|
69
|
+
|
70
|
+
### Return the entry as a String (in a similar form to the regular `hg topics` output)
|
71
|
+
def to_s
|
72
|
+
rval = String.new( encoding: 'utf-8' )
|
73
|
+
rval << "%s (" % [ self.name ]
|
74
|
+
rval << "%s" % [ self.last_touched ] if self.last_touched
|
75
|
+
rval << " by %s" % [ self.user_touched ] if self.user_touched
|
76
|
+
rval << ', ' if self.last_touched || self.user_touched
|
77
|
+
rval << "%d changesets)" % [ self.changeset_count ]
|
78
|
+
rval << " [active]" if self.active?
|
79
|
+
rval.freeze
|
80
|
+
|
81
|
+
return rval
|
82
|
+
end
|
83
|
+
alias_method :inspect_details, :to_s
|
84
|
+
|
85
|
+
|
86
|
+
### Return the changesets that belong to this topic as
|
87
|
+
### Hglib::Extension::Topic::StackEntry objects.
|
88
|
+
def stack
|
89
|
+
return self.repo.stack( self.name )
|
90
|
+
end
|
91
|
+
|
92
|
+
end # class Entry
|
93
|
+
|
94
|
+
|
95
|
+
# A changeset in a topic
|
96
|
+
class StackEntry
|
97
|
+
extend Hglib::MethodUtilities
|
98
|
+
include Hglib::Inspection
|
99
|
+
|
100
|
+
|
101
|
+
### Create a new StackEntry for the specified +repo+ given an +entryhash+ like that
|
102
|
+
### returned by the JSON template for the `topics` command.
|
103
|
+
def initialize( repo, entryhash )
|
104
|
+
@repo = repo
|
105
|
+
|
106
|
+
@description = entryhash[:desc]
|
107
|
+
@is_entry = entryhash[:isentry]
|
108
|
+
@node = entryhash[:node]
|
109
|
+
@stack_index = entryhash[:stack_index]
|
110
|
+
@state = entryhash[:state]
|
111
|
+
@symbol = entryhash[:symbol]
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
######
|
116
|
+
public
|
117
|
+
######
|
118
|
+
|
119
|
+
##
|
120
|
+
# The Hglib::Repo of the repository the changeset belongs to
|
121
|
+
attr_reader :repo
|
122
|
+
|
123
|
+
##
|
124
|
+
# The changeset description
|
125
|
+
attr_reader :description
|
126
|
+
alias_method :desc, :description
|
127
|
+
|
128
|
+
##
|
129
|
+
# True if the changeset is an entry(?)
|
130
|
+
# :TODO: Figure out what this means
|
131
|
+
attr_predicate :is_entry
|
132
|
+
alias_method :entry?, :is_entry?
|
133
|
+
|
134
|
+
##
|
135
|
+
# The node identifier of the changeset
|
136
|
+
attr_reader :node
|
137
|
+
|
138
|
+
##
|
139
|
+
# The index of the changeset in the topic it is currently in
|
140
|
+
attr_reader :stack_index
|
141
|
+
|
142
|
+
##
|
143
|
+
# An array of states that apply to this changeset(?)
|
144
|
+
# :TODO: Figure out what these mean
|
145
|
+
attr_reader :state
|
146
|
+
|
147
|
+
##
|
148
|
+
# A character that represents the changeset's (state?)
|
149
|
+
# :TODO: Figure out what this means
|
150
|
+
attr_reader :symbol
|
151
|
+
|
152
|
+
|
153
|
+
### Return the entry as a String (in a similar form to the regular `hg topics` output)
|
154
|
+
def to_s
|
155
|
+
displayed_states = self.state - ['clean']
|
156
|
+
|
157
|
+
rval = String.new( encoding: 'utf-8' )
|
158
|
+
rval << %{s%d%s "%s"} % [ self.stack_index, self.symbol, self.description ]
|
159
|
+
rval << " (%s)" % [ displayed_states.join(', ') ] unless displayed_states.empty?
|
160
|
+
rval.freeze
|
161
|
+
|
162
|
+
return rval
|
163
|
+
end
|
164
|
+
alias_method :inspect_details, :to_s
|
165
|
+
|
166
|
+
end # class StackEntry
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
repo_commands do
|
171
|
+
|
172
|
+
### Return an Hglib::Extension::Topic::Entry object for each topic in the
|
173
|
+
### repo.
|
174
|
+
def topics( **options )
|
175
|
+
raise ArgumentError, ":list option is implemented with the #stack method" if
|
176
|
+
options[:list]
|
177
|
+
|
178
|
+
options[:age] = true
|
179
|
+
options[:verbose] = true
|
180
|
+
response = self.server.run_with_json_template( :topics, nil, **options )
|
181
|
+
|
182
|
+
return response.map do |entryhash|
|
183
|
+
Hglib::Extension::Topic::Entry.new( self, entryhash )
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
### Operate on a topic, either the one with the given +name+ or the current one
|
189
|
+
### if +name+ is not given.
|
190
|
+
def topic( name=nil, **options )
|
191
|
+
options[:current] = true unless name || options[:clear]
|
192
|
+
result = self.server.run( :topics, name, **options )
|
193
|
+
return result.chomp
|
194
|
+
rescue Hglib::CommandError => err
|
195
|
+
# Running `topic --current` with no active topic is an error apparently, so
|
196
|
+
# if that's the reason for it being raised just return nil instead.
|
197
|
+
raise( err ) unless err.message.match?( /no active topic/i )
|
198
|
+
return nil
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
### Return an Array of all changesets in a topic as
|
203
|
+
### Hglib::Extension::Topic::StackEntry objects.
|
204
|
+
def stack( topic=nil, **options )
|
205
|
+
response = self.server.run_with_json_template( :stack, topic, **options )
|
206
|
+
|
207
|
+
return response.map do |entryhash|
|
208
|
+
Hglib::Extension::Topic::StackEntry.new( self, entryhash )
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end # module Hglib::Extension::Topic
|
215
|
+
|
data/lib/hglib/repo.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'uri'
|
4
5
|
require 'json'
|
5
6
|
require 'loggability'
|
6
7
|
|
@@ -303,7 +304,7 @@ class Hglib::Repo
|
|
303
304
|
|
304
305
|
return string[0 .. (maxlength / 2) - 3 ] +
|
305
306
|
' ... ' +
|
306
|
-
string[ -((maxlength / 2) -3) .. ]
|
307
|
+
string[ -((maxlength / 2) -3) .. -1 ]
|
307
308
|
end
|
308
309
|
|
309
310
|
end # class Hglib::Repo
|
data/lib/hglib/server.rb
CHANGED
data/lib/hglib.rb
CHANGED
@@ -23,7 +23,7 @@ RSpec.describe Hglib::Extension::GPG do
|
|
23
23
|
|
24
24
|
it "can sign a revision" do
|
25
25
|
expect( server ).to receive( :run ).
|
26
|
-
with( :sign, nil,
|
26
|
+
with( :sign, nil, any_args ).
|
27
27
|
and_return( "signing 2:2b937981802a\n" )
|
28
28
|
|
29
29
|
expect( repo.sign ).to eq( "signing 2:2b937981802a" )
|
data/spec/hglib/repo/id_spec.rb
CHANGED
@@ -13,7 +13,7 @@ RSpec.describe Hglib::Repo::Id, :requires_binary do
|
|
13
13
|
Pathname( Dir.mktmpdir(['hglib', 'repodir']) )
|
14
14
|
end
|
15
15
|
let( :repo ) { Hglib.init(repo_dir) }
|
16
|
-
let( :fake_sha ) {
|
16
|
+
let( :fake_sha ) { SecureRandom.bytes(20).unpack1('h*') }
|
17
17
|
|
18
18
|
|
19
19
|
it "can be created for an empty repo" do
|
data/spec/hglib/repo_spec.rb
CHANGED
@@ -23,7 +23,7 @@ RSpec.describe Hglib::Repo do
|
|
23
23
|
repo = described_class.new( repo_dir )
|
24
24
|
|
25
25
|
expect( server ).to receive( :run_with_json_template ).
|
26
|
-
with( :status,
|
26
|
+
with( :status, any_args ).
|
27
27
|
and_return( [] )
|
28
28
|
|
29
29
|
result = repo.status
|
@@ -36,7 +36,7 @@ RSpec.describe Hglib::Repo do
|
|
36
36
|
repo = described_class.new( repo_dir )
|
37
37
|
|
38
38
|
expect( server ).to receive( :run_with_json_template ).
|
39
|
-
with( :status,
|
39
|
+
with( :status, any_args ).
|
40
40
|
and_return([
|
41
41
|
{
|
42
42
|
path: "lib/hglib/repo.rb",
|
@@ -73,7 +73,7 @@ RSpec.describe Hglib::Repo do
|
|
73
73
|
repo = described_class.new( repo_dir )
|
74
74
|
|
75
75
|
expect( server ).to receive( :run_with_json_template ).
|
76
|
-
with( :identify, nil,
|
76
|
+
with( :identify, nil, any_args ).
|
77
77
|
and_return( [{
|
78
78
|
bookmarks: ["v1.1", "live", "master"],
|
79
79
|
branch: "default",
|
@@ -96,7 +96,7 @@ RSpec.describe Hglib::Repo do
|
|
96
96
|
repo = described_class.new( repo_dir )
|
97
97
|
|
98
98
|
expect( server ).to receive( :run_with_json_template ).
|
99
|
-
with( :identify, nil,
|
99
|
+
with( :identify, nil, any_args ).
|
100
100
|
and_return( [{
|
101
101
|
bookmarks: ["v1.1", "live", "master"],
|
102
102
|
branch: "default",
|
@@ -116,7 +116,7 @@ RSpec.describe Hglib::Repo do
|
|
116
116
|
repo = described_class.new( repo_dir )
|
117
117
|
|
118
118
|
expect( server ).to receive( :run_with_json_template ).
|
119
|
-
with( :identify, nil,
|
119
|
+
with( :identify, nil, any_args ).
|
120
120
|
and_return( [{
|
121
121
|
bookmarks: ["v1.1", "live", "master"],
|
122
122
|
branch: "default",
|
@@ -173,7 +173,7 @@ RSpec.describe Hglib::Repo do
|
|
173
173
|
it "can fetch a diff of the current working copy of the repository" do
|
174
174
|
repo = described_class.new( repo_dir )
|
175
175
|
|
176
|
-
expect( server ).to receive( :run ).with( :diff,
|
176
|
+
expect( server ).to receive( :run ).with( :diff, any_args ).
|
177
177
|
and_return( "the diff" )
|
178
178
|
|
179
179
|
result = repo.diff
|
@@ -185,7 +185,7 @@ RSpec.describe Hglib::Repo do
|
|
185
185
|
it "can fetch a diff of particular files" do
|
186
186
|
repo = described_class.new( repo_dir )
|
187
187
|
|
188
|
-
expect( server ).to receive( :run ).with( :diff, 'README.md', 'Rakefile',
|
188
|
+
expect( server ).to receive( :run ).with( :diff, 'README.md', 'Rakefile', any_args ).
|
189
189
|
and_return( "two files diff" )
|
190
190
|
|
191
191
|
result = repo.diff( 'README.md', 'Rakefile' )
|
@@ -197,7 +197,7 @@ RSpec.describe Hglib::Repo do
|
|
197
197
|
it "can add all new files to the repository" do
|
198
198
|
repo = described_class.new( repo_dir )
|
199
199
|
|
200
|
-
expect( server ).to receive( :run ).with( :add,
|
200
|
+
expect( server ).to receive( :run ).with( :add, any_args )
|
201
201
|
|
202
202
|
result = repo.add
|
203
203
|
expect( result ).to be_truthy
|
@@ -266,7 +266,7 @@ RSpec.describe Hglib::Repo do
|
|
266
266
|
repo = described_class.new( repo_dir )
|
267
267
|
|
268
268
|
expect( server ).to receive( :run ).
|
269
|
-
with( :sign, nil,
|
269
|
+
with( :sign, nil, any_args ).
|
270
270
|
and_return( "signing 47:66d4e21b7018\n" )
|
271
271
|
|
272
272
|
result = repo.sign
|
@@ -281,7 +281,7 @@ RSpec.describe Hglib::Repo do
|
|
281
281
|
repo = described_class.new( repo_dir )
|
282
282
|
|
283
283
|
expect( server ).to receive( :run ).
|
284
|
-
with( :phase, nil,
|
284
|
+
with( :phase, nil, any_args ).
|
285
285
|
and_return( "18: draft\n" )
|
286
286
|
|
287
287
|
result = repo.phase
|
@@ -294,7 +294,7 @@ RSpec.describe Hglib::Repo do
|
|
294
294
|
repo = described_class.new( repo_dir )
|
295
295
|
|
296
296
|
expect( server ).to receive( :run ).
|
297
|
-
with( :phase, '41c796d06fa398573ecec464238b827bfe75c7cd',
|
297
|
+
with( :phase, '41c796d06fa398573ecec464238b827bfe75c7cd', any_args ).
|
298
298
|
and_return( "12: draft\n" )
|
299
299
|
|
300
300
|
result = repo.phase( '41c796d06fa398573ecec464238b827bfe75c7cd' )
|
@@ -320,7 +320,7 @@ RSpec.describe Hglib::Repo do
|
|
320
320
|
repo = described_class.new( repo_dir )
|
321
321
|
|
322
322
|
expect( server ).to receive( :run ).
|
323
|
-
with( :phase, '13:10',
|
323
|
+
with( :phase, '13:10', any_args ).
|
324
324
|
and_return( "13: secret\n12: draft\n11: public\n10: public\n" )
|
325
325
|
|
326
326
|
result = repo.phase( '13:10' )
|
@@ -398,7 +398,7 @@ RSpec.describe Hglib::Repo do
|
|
398
398
|
repo = described_class.new( repo_dir )
|
399
399
|
|
400
400
|
expect( server ).to receive( :run ).
|
401
|
-
with( :phase, nil,
|
401
|
+
with( :phase, nil, any_args ).
|
402
402
|
and_return( "18: draft\n" ).
|
403
403
|
at_least( :once )
|
404
404
|
|
data/spec/spec_helper.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hglib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
34
34
|
jBZSA+N+xUTgUWpXjjwsLZjzJkhWATJWq+krNXcqpwXo6HsjmdUxoFMt63RBb+sI
|
35
35
|
XrxOxp8o0uOkU7FdLSGsyqJ2LzsR4obN
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date: 2020-01-
|
37
|
+
date: 2020-01-21 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: loggability
|
@@ -50,20 +50,34 @@ dependencies:
|
|
50
50
|
- - "~>"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '0.11'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: e2mmap
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0.1'
|
60
|
+
type: :runtime
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0.1'
|
53
67
|
- !ruby/object:Gem::Dependency
|
54
68
|
name: rake-deveiate
|
55
69
|
requirement: !ruby/object:Gem::Requirement
|
56
70
|
requirements:
|
57
71
|
- - "~>"
|
58
72
|
- !ruby/object:Gem::Version
|
59
|
-
version: '0.
|
73
|
+
version: '0.7'
|
60
74
|
type: :development
|
61
75
|
prerelease: false
|
62
76
|
version_requirements: !ruby/object:Gem::Requirement
|
63
77
|
requirements:
|
64
78
|
- - "~>"
|
65
79
|
- !ruby/object:Gem::Version
|
66
|
-
version: '0.
|
80
|
+
version: '0.7'
|
67
81
|
- !ruby/object:Gem::Dependency
|
68
82
|
name: simplecov
|
69
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,7 @@ files:
|
|
108
122
|
- lib/hglib/config.rb
|
109
123
|
- lib/hglib/extension.rb
|
110
124
|
- lib/hglib/extension/gpg.rb
|
125
|
+
- lib/hglib/extension/topic.rb
|
111
126
|
- lib/hglib/mixins.rb
|
112
127
|
- lib/hglib/repo.rb
|
113
128
|
- lib/hglib/repo/bookmark.rb
|
@@ -139,16 +154,16 @@ require_paths:
|
|
139
154
|
- lib
|
140
155
|
required_ruby_version: !ruby/object:Gem::Requirement
|
141
156
|
requirements:
|
142
|
-
- - "
|
157
|
+
- - "~>"
|
143
158
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
159
|
+
version: '2.5'
|
145
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
161
|
requirements:
|
147
162
|
- - ">="
|
148
163
|
- !ruby/object:Gem::Version
|
149
164
|
version: '0'
|
150
165
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
166
|
+
rubygems_version: 3.1.2
|
152
167
|
signing_key:
|
153
168
|
specification_version: 4
|
154
169
|
summary: This is a client library for the Mercurial distributed revision control tool
|
metadata.gz.sig
CHANGED
Binary file
|