aspera-cli 4.25.5 → 4.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +14 -8
- data/CONTRIBUTING.md +11 -2
- data/lib/aspera/api/node.rb +25 -12
- data/lib/aspera/ascp/installation.rb +23 -24
- data/lib/aspera/cli/plugins/server.rb +1 -1
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +29 -19
- data/lib/aspera/keychain/macos_security.rb +1 -1
- data/lib/aspera/preview/utils.rb +2 -2
- data/lib/aspera/rest.rb +31 -0
- data/lib/aspera/sync/operations.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +1 -1
- 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: 8e8b3ed2906ef470b3617e60b438089f57c5b3d0e1770649e2ba1a64d413d32d
|
|
4
|
+
data.tar.gz: e09b6b5d455c77ea355ba617577b82a1c51e60afab2e8431e62dcf8d9e7785c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb3f5becd29ffc54c7746868a47b3e8841cde1566abb0b5ea97d9c4bb7768f9f85c4cf96cbd3e52b6a1724f4be0eb817ea03282a4070e5cf32a9d06fb6a3aab5
|
|
7
|
+
data.tar.gz: f8f03f1a45d50b92e01d39f734bdebebf94e1640c695751a3122106797d9c4d223e544050cd854cb026daa736589440666d5ccd2453b50c9a39a6df5fadccc8e
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- markdownlint-configure-file { "no-duplicate-heading": { "siblings_only": true } } -->
|
|
4
4
|
|
|
5
|
+
## 4.25.6
|
|
6
|
+
|
|
7
|
+
Released: 2026-04-08
|
|
8
|
+
|
|
9
|
+
### Issues Fixed
|
|
10
|
+
|
|
11
|
+
* `node`: #253 fix `node transfer list` infinite loop with `once_only`.
|
|
12
|
+
|
|
5
13
|
## 4.25.5
|
|
6
14
|
|
|
7
15
|
Released: 2026-03-25
|
|
@@ -14,9 +22,7 @@ Released: 2026-03-25
|
|
|
14
22
|
|
|
15
23
|
* `config`: Fixed `preset update` with dot-path options.
|
|
16
24
|
* `sync`: #251 in `admin` command: Fixed database path on Windows: Use `~private-asp` instead of `.private-asp`.
|
|
17
|
-
* `httpgw`: #252 HTTPGW transfer showed success even
|
|
18
|
-
|
|
19
|
-
### Breaking Changes
|
|
25
|
+
* `httpgw`: #252 HTTPGW transfer showed success even when error code `403` was returned. Now raises error with message.
|
|
20
26
|
|
|
21
27
|
## 4.25.4
|
|
22
28
|
|
|
@@ -115,7 +121,7 @@ Released: 2026-01-21
|
|
|
115
121
|
### Issues Fixed
|
|
116
122
|
|
|
117
123
|
* `aoc`: Restored command `admin workspace shared_folder :id list` which was since 4.11.0.
|
|
118
|
-
* `direct`: When using `ascp4
|
|
124
|
+
* `direct`: When using `ascp4`, do not set env var: `ASPERA_TEST_REDIS_DISABLE`, else it fails with: `Failed to initialize application`.
|
|
119
125
|
* `shares`: Properly detect using `/node_api/ping` endpoint instead of `/app`.
|
|
120
126
|
|
|
121
127
|
### Breaking Changes
|
|
@@ -194,7 +200,7 @@ Released: 2025-09-30
|
|
|
194
200
|
* `console`: Removed options `filter_from` and `filter_to`. Use standard option `query` instead.
|
|
195
201
|
* `sync`: Removed option `sync_info`. Replaced with positional parameters. Streamlined command line interface. Applies to all plugins with `sync` command.
|
|
196
202
|
* `async`: Removed option `sync_name`. Replaced with percent selector `%name:`.
|
|
197
|
-
* `aoc`: `files download` using gen4 API
|
|
203
|
+
* `aoc`: `files download` using gen4 API no longer requires providing the containing folder in first position, and then only file names. Now, directly provide the path to all files.
|
|
198
204
|
* `logger`: Log is simplified, date is removed by default. Use `--log_format=standard` to revert to standard Ruby logger. See option `log_format` for details.
|
|
199
205
|
|
|
200
206
|
## 4.23.0
|
|
@@ -208,7 +214,7 @@ Released: 2025-08-11
|
|
|
208
214
|
|
|
209
215
|
### Issues Fixed
|
|
210
216
|
|
|
211
|
-
* `server`: #209: missing home folder for transfer user shall not cause an error.
|
|
217
|
+
* `server`: #209: a missing home folder for the transfer user shall not cause an error.
|
|
212
218
|
* `direct`: #205: `kill` blocks `cmd` on Windows.
|
|
213
219
|
|
|
214
220
|
### Breaking Changes
|
|
@@ -924,7 +930,7 @@ Released: 2021-02-03
|
|
|
924
930
|
|
|
925
931
|
## 0.11.2
|
|
926
932
|
|
|
927
|
-
* Fixes on multi-session: Progress
|
|
933
|
+
* Fixes on multi-session: Progress bar and transfer spec param for `direct`.
|
|
928
934
|
|
|
929
935
|
## 0.11.1
|
|
930
936
|
|
|
@@ -995,7 +1001,7 @@ Released: 2021-02-03
|
|
|
995
1001
|
|
|
996
1002
|
## 0.10.6
|
|
997
1003
|
|
|
998
|
-
* FaspManager: Transfer spec `authentication` no
|
|
1004
|
+
* FaspManager: Transfer spec `authentication` is no longer needed for local transfer to use Aspera public keys. Public keys will be used if there is a token and no key or password is provided.
|
|
999
1005
|
* Gem version requirements made more open.
|
|
1000
1006
|
|
|
1001
1007
|
## 0.10.5
|
data/CONTRIBUTING.md
CHANGED
|
@@ -114,6 +114,8 @@ The following environment variables and macros control specific build behaviors:
|
|
|
114
114
|
| `ENABLE_COVERAGE` | set/unset | Enables test coverage analysis when defined. |
|
|
115
115
|
| `SIGNING_KEY` | File path | Path to the signing key used for building the gem file. |
|
|
116
116
|
| `SIGNING_KEY_PEM` | PEM Value | The PEM content of the signing key. |
|
|
117
|
+
| `DRY_RUN` | `1` | Simulates execution without performing actual operations (git, gh commands). |
|
|
118
|
+
| `DEBUG` | `1` | Shows stack trace on errors during documentation generation. |
|
|
117
119
|
|
|
118
120
|
These values can be set as standard environment variables or passed directly to the `rake` command.
|
|
119
121
|
|
|
@@ -156,7 +158,7 @@ tlmgr install fvextra selnolig lualatex-math
|
|
|
156
158
|
rake doc:check_links
|
|
157
159
|
```
|
|
158
160
|
|
|
159
|
-
- Debug the generation process: `
|
|
161
|
+
- Debug the generation process: `DEBUG=1`.
|
|
160
162
|
|
|
161
163
|
- Build the documentation:
|
|
162
164
|
|
|
@@ -254,6 +256,13 @@ bundle exec rake container:test
|
|
|
254
256
|
bundle exec rake doc:check_links
|
|
255
257
|
```
|
|
256
258
|
|
|
259
|
+
- **Check release procedure**:
|
|
260
|
+
|
|
261
|
+
```shell
|
|
262
|
+
bundle exec rake release:run DRY_RUN=1
|
|
263
|
+
git restore lib/aspera/cli/version.rb CHANGELOG.md docs/README.md
|
|
264
|
+
```
|
|
265
|
+
|
|
257
266
|
### Automated Release Process
|
|
258
267
|
|
|
259
268
|
Releases are managed through the GitHub Actions UI via the **New Release on GitHub** workflow (`.github/workflows/release.yml`).
|
|
@@ -313,4 +322,4 @@ This triggers the `.github/workflows/deploy.yml` action to publish to RubyGems.
|
|
|
313
322
|
- [rest-client](https://github.com/rest-client/rest-client)
|
|
314
323
|
- [oauth2](https://github.com/oauth-xx/oauth2)
|
|
315
324
|
- Integrate `thor` <http://whatisthor.com/> or another standard Ruby CLI framework.
|
|
316
|
-
- Explore [Traveling Ruby](https://github.com/phusion/traveling-ruby) for distribution.
|
|
325
|
+
- Explore [Traveling Ruby](https://github.com/phusion/traveling-ruby) for distribution, or [truby Traveling Ruby](https://github.com/trubygems/traveling-ruby).
|
data/lib/aspera/api/node.rb
CHANGED
|
@@ -530,32 +530,45 @@ module Aspera
|
|
|
530
530
|
Aspera.assert_type(query, Hash, NilClass){'query'}
|
|
531
531
|
Aspera.assert(!call_args.key?(:query))
|
|
532
532
|
query = {} if query.nil?
|
|
533
|
-
query[:iteration_token] = iteration[0] unless iteration.nil?
|
|
533
|
+
query[:iteration_token] = iteration[0] unless iteration.nil? || iteration[0].nil?
|
|
534
534
|
max = query.delete(RestList::MAX_ITEMS)
|
|
535
|
+
# Return empty list immediately if max is 0
|
|
536
|
+
return [] if max&.zero?
|
|
535
537
|
item_list = []
|
|
536
538
|
loop do
|
|
537
539
|
data, http = read(subpath, query, **call_args, ret: :both)
|
|
538
540
|
Aspera.assert_type(data, Array){"Expected data to be an Array, got: #{data.class}"}
|
|
539
541
|
# no data
|
|
540
542
|
break if data.empty?
|
|
541
|
-
# get next iteration token from link
|
|
542
|
-
next_iteration_token = nil
|
|
543
|
-
link_info = http['Link']
|
|
544
|
-
unless link_info.nil?
|
|
545
|
-
m = link_info.match(/<([^>]+)>/)
|
|
546
|
-
Aspera.assert(m){"Cannot parse iteration in Link: #{link_info}"}
|
|
547
|
-
next_iteration_token = Rest.query_to_h(URI.parse(m[1]).query)['iteration_token']
|
|
548
|
-
end
|
|
549
|
-
# same as last iteration: stop
|
|
550
|
-
break if next_iteration_token&.eql?(query[:iteration_token])
|
|
551
|
-
query[:iteration_token] = next_iteration_token
|
|
552
543
|
item_list.concat(data)
|
|
544
|
+
# Check if we reached the max limit
|
|
553
545
|
if max&.<=(item_list.length)
|
|
554
546
|
item_list = item_list.slice(0, max)
|
|
555
547
|
break
|
|
556
548
|
end
|
|
549
|
+
# Update progress spinner
|
|
550
|
+
RestParameters.instance.spinner_cb.call(item_list.length)
|
|
551
|
+
# Parse Link header according to RFC 8288 to extract next iteration token
|
|
552
|
+
next_url = Rest.parse_link_header(http['Link'], rel: 'next')
|
|
553
|
+
next_iteration_token = nil
|
|
554
|
+
if next_url
|
|
555
|
+
begin
|
|
556
|
+
parsed_uri = URI.parse(next_url)
|
|
557
|
+
query_params = Rest.query_to_h(parsed_uri.query) if parsed_uri.query
|
|
558
|
+
next_iteration_token = query_params['iteration_token'] if query_params
|
|
559
|
+
rescue URI::InvalidURIError => e
|
|
560
|
+
Log.log.warn{"Invalid URI in Link header: #{next_url} - #{e.message}"}
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
# Stop if no next token
|
|
557
564
|
break if next_iteration_token.nil?
|
|
565
|
+
# Stop if same token as current (infinite loop protection)
|
|
566
|
+
break if next_iteration_token.eql?(query[:iteration_token])
|
|
567
|
+
# Update token for next iteration
|
|
568
|
+
query[:iteration_token] = next_iteration_token
|
|
558
569
|
end
|
|
570
|
+
# Signal completion
|
|
571
|
+
RestParameters.instance.spinner_cb.call(action: :success)
|
|
559
572
|
# save iteration token if needed
|
|
560
573
|
iteration[0] = query[:iteration_token] unless iteration.nil?
|
|
561
574
|
item_list
|
|
@@ -178,33 +178,32 @@ module Aspera
|
|
|
178
178
|
# Folder, PVCL, version, license information
|
|
179
179
|
def ascp_info_from_log
|
|
180
180
|
data = {}
|
|
181
|
+
_, stderr, status = Environment.secure_execute(path(:ascp), '-DDL-', mode: :capture, exception: false)
|
|
181
182
|
# read PATHs from ascp directly, and pvcl modules as well
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
data['ascp_version'] = Regexp.last_match(1)
|
|
204
|
-
end
|
|
183
|
+
last_line = ''
|
|
184
|
+
stderr.lines do |line|
|
|
185
|
+
line.chomp!
|
|
186
|
+
# Skip lines that may have accents
|
|
187
|
+
next unless line.valid_encoding?
|
|
188
|
+
last_line = line
|
|
189
|
+
case line
|
|
190
|
+
when /^DBG Path ([^ ]+) (dir|file) +: (.*)$/
|
|
191
|
+
data[Regexp.last_match(1)] = Regexp.last_match(3)
|
|
192
|
+
when /^DBG Added module group:"(?<module>[^"]+)" name:"(?<scheme>[^"]+)", version:"(?<version>[^"]+)" interface:"(?<interface>[^"]+)"$/
|
|
193
|
+
c = Regexp.last_match.named_captures.symbolize_keys
|
|
194
|
+
data[c[:interface]] ||= {}
|
|
195
|
+
data[c[:interface]][c[:module]] ||= []
|
|
196
|
+
data[c[:interface]][c[:module]].push("#{c[:scheme]} v#{c[:version]}")
|
|
197
|
+
when %r{^DBG License result \(/license/(\S+)\): (.+)$}
|
|
198
|
+
data[Regexp.last_match(1)] = Regexp.last_match(2)
|
|
199
|
+
when /^LOG (.+) version ([0-9.]+)$/
|
|
200
|
+
data['product_name'] = Regexp.last_match(1)
|
|
201
|
+
data['product_version'] = Regexp.last_match(2)
|
|
202
|
+
when /^LOG Initializing FASP version ([^,]+),/
|
|
203
|
+
data['ascp_version'] = Regexp.last_match(1)
|
|
205
204
|
end
|
|
206
|
-
raise last_line if !thread.value.exitstatus.eql?(1) && !data.key?('root')
|
|
207
205
|
end
|
|
206
|
+
raise last_line if !status.exitstatus.eql?(1) && !data.key?('root')
|
|
208
207
|
return data
|
|
209
208
|
end
|
|
210
209
|
|
|
@@ -32,7 +32,7 @@ module Aspera
|
|
|
32
32
|
|
|
33
33
|
class LocalExecutor
|
|
34
34
|
def execute(ascmd_path, input:)
|
|
35
|
-
|
|
35
|
+
Environment.secure_execute(ascmd_path, mode: :capture, stdin_data: input, binmode: true, exception: false).first
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
data/lib/aspera/cli/version.rb
CHANGED
data/lib/aspera/environment.rb
CHANGED
|
@@ -84,22 +84,31 @@ module Aspera
|
|
|
84
84
|
"'#{str.gsub("'", %q('\'\''))}'"
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
#
|
|
87
|
+
# Executes a command without invoking a shell.
|
|
88
88
|
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
# - :background -> Process.spawn, return pid
|
|
92
|
-
# - :capture -> Open3.capture3, return stdout
|
|
89
|
+
# The command is provided as an array to avoid shell interpolation and
|
|
90
|
+
# ensure safer execution.
|
|
93
91
|
#
|
|
94
|
-
# @param cmd [Array
|
|
95
|
-
# @param mode [:execute
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
# @
|
|
101
|
-
#
|
|
102
|
-
# @
|
|
92
|
+
# @param cmd [Array<#to_s>] The executable and its arguments.
|
|
93
|
+
# @param mode [:execute, :background, :capture] The execution strategy:
|
|
94
|
+
# - `:execute` Uses {Kernel.system}. Returns `true`, `false`, or `nil`.
|
|
95
|
+
# - `:background` Uses {Process.spawn}. Returns the spawned process PID.
|
|
96
|
+
# - `:capture` Uses {Open3.capture3}. Returns captured output and status.
|
|
97
|
+
#
|
|
98
|
+
# @param kwargs [Hash] Additional options forwarded to the underlying call.
|
|
99
|
+
#
|
|
100
|
+
# @option kwargs [Hash{String => String}] :env Environment variables to set for the process.
|
|
101
|
+
# @option kwargs [Boolean] :exception (false) When `true` in `:capture` mode,
|
|
102
|
+
# raises an error if the command exits with a non-zero status.
|
|
103
|
+
# @option kwargs [Boolean] :close_others (true) When `true` in `:background` mode,
|
|
104
|
+
# closes all other file descriptors in the child process.
|
|
105
|
+
#
|
|
106
|
+
# @return [Boolean, nil] For `:execute` mode (`true`, `false`, or `nil`).
|
|
107
|
+
# @return [Integer] For `:background` mode (process ID).
|
|
108
|
+
# @return [Array(String, String, Process::Status)] For `:capture` mode
|
|
109
|
+
# (`stdout`, `stderr`, `status`).
|
|
110
|
+
#
|
|
111
|
+
# @raise [RuntimeError] If `:exception` is `true` and the process fails in `:capture` mode.
|
|
103
112
|
def secure_execute(*cmd, mode: :execute, **kwargs)
|
|
104
113
|
cmd = cmd.map(&:to_s)
|
|
105
114
|
Aspera.assert(cmd.size.positive?, type: ArgumentError){'executable must be present'}
|
|
@@ -128,11 +137,12 @@ module Aspera
|
|
|
128
137
|
# https://docs.ruby-lang.org/en/master/Process.html#module-Process-label-Execution+Options
|
|
129
138
|
argv = [kwargs.delete(:env)].compact + cmd
|
|
130
139
|
exception = kwargs.delete(:exception){true}
|
|
131
|
-
|
|
132
|
-
Log.
|
|
133
|
-
Log.
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
result = Open3.capture3(*argv, **kwargs)
|
|
141
|
+
Log.dump(:stdout, result[0], level: :trace1)
|
|
142
|
+
Log.dump(:stderr, result[1], level: :trace1)
|
|
143
|
+
Log.dump(:status, result[2])
|
|
144
|
+
raise "Process failed: #{result[2].exitstatus} (#{result[1]})" if exception && !result[2].success?
|
|
145
|
+
result
|
|
136
146
|
else Aspera.error_unreachable_line
|
|
137
147
|
end
|
|
138
148
|
end
|
|
@@ -57,7 +57,7 @@ module Aspera
|
|
|
57
57
|
command_args.push(v.shellescape) unless v.empty?
|
|
58
58
|
end
|
|
59
59
|
command_args.push(last_opt) unless last_opt.nil?
|
|
60
|
-
|
|
60
|
+
Environment.secure_execute(*command_args, mode: :capture).first
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def key_chains(output)
|
data/lib/aspera/preview/utils.rb
CHANGED
|
@@ -51,11 +51,11 @@ module Aspera
|
|
|
51
51
|
Environment.secure_execute(command_sym.to_s, *command_args.map(&:to_s), out: File::NULL, err: File::NULL)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
# Execute external command and
|
|
54
|
+
# Execute external command and get stdout
|
|
55
55
|
# @return [String]
|
|
56
56
|
def external_capture(command_sym, command_args)
|
|
57
57
|
Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'}
|
|
58
|
-
|
|
58
|
+
Environment.secure_execute(command_sym.to_s, *command_args.map(&:to_s), mode: :capture).first
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def ffmpeg(gl_p: FFMPEG_DEFAULT_PARAMS, in_p: [], in_f:, out_p: [], out_f:)
|
data/lib/aspera/rest.rb
CHANGED
|
@@ -150,6 +150,37 @@ module Aspera
|
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
+
# Parse Link header according to RFC 8288 to extract a specific relation
|
|
154
|
+
# @param link_header [String, nil] The Link header value
|
|
155
|
+
# @param rel [String] The relation to look for (default: 'next')
|
|
156
|
+
# @return [String, nil] The URL of the link with the specified relation, or nil
|
|
157
|
+
def parse_link_header(link_header, rel: 'next')
|
|
158
|
+
return if link_header.nil? || link_header.empty?
|
|
159
|
+
# RFC 8288: Link header format is: <URI>; param1=value1; param2=value2, <URI2>; ...
|
|
160
|
+
# We look for the link with the specified rel
|
|
161
|
+
link_header.split(',').each do |link_part|
|
|
162
|
+
link_part = link_part.strip
|
|
163
|
+
# Extract URL between < and >
|
|
164
|
+
url_match = link_part.match(/<([^>]+)>/)
|
|
165
|
+
next unless url_match
|
|
166
|
+
url = url_match[1]
|
|
167
|
+
# Extract parameters after the URL
|
|
168
|
+
params_str = link_part[url_match.end(0)..-1]
|
|
169
|
+
# Check if this link has the specified rel (with or without quotes, case insensitive)
|
|
170
|
+
next unless /;\s*rel\s*=\s*"?#{Regexp.escape(rel)}"?/i.match?(params_str)
|
|
171
|
+
return url
|
|
172
|
+
end
|
|
173
|
+
# Fallback: if no rel found and looking for 'next', try the first link (backward compatibility)
|
|
174
|
+
if rel.eql?('next')
|
|
175
|
+
first_link = link_header.split(',').first&.strip
|
|
176
|
+
if first_link
|
|
177
|
+
url_match = first_link.match(/<([^>]+)>/)
|
|
178
|
+
return url_match[1] if url_match
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
nil
|
|
182
|
+
end
|
|
183
|
+
|
|
153
184
|
# Start a HTTP/S session, also used for web sockets
|
|
154
185
|
# @param base_url [String] Base url of HTTP/S session
|
|
155
186
|
# @return [Net::HTTP] A started HTTP session
|
|
@@ -197,7 +197,7 @@ module Aspera
|
|
|
197
197
|
raise Error, 'Missing either local_db_dir or local_dir'
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
|
-
stdout = Environment.secure_execute(*arguments, mode: :capture)
|
|
200
|
+
stdout = Environment.secure_execute(*arguments, mode: :capture).first
|
|
201
201
|
return parse_status(stdout)
|
|
202
202
|
end
|
|
203
203
|
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
metadata.gz.sig
CHANGED
|
Binary file
|