signalk-cli 3.0.0__tar.gz → 3.0.1__tar.gz
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.
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/PKG-INFO +45 -7
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/README.md +44 -6
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/pyproject.toml +10 -4
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/pyproject.toml.orig +9 -5
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/_arrow.py +1 -1
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/_cli.py +2 -2
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/cli.py +2 -2
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/__init__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/__main__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/errors.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/__init__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/__main__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/_results.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/_time.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/api.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/history/output.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/net.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/py.typed +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/stream/__init__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/stream/__main__.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/stream/api.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/stream/cli.py +0 -0
- {signalk_cli-3.0.0 → signalk_cli-3.0.1}/src/signalk_cli/stream/output.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: signalk-cli
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: Query SignalK v2 APIs and export data as CSV, JSON or Apache Arrow Feather from command line or as a Python API
|
|
5
5
|
Keywords: signalk,sailing,marine,boating,nmea,dataframe,cli,pyarrow,nanoarrow
|
|
6
6
|
Author: jey burrows
|
|
@@ -30,6 +30,11 @@ Provides-Extra: arrow
|
|
|
30
30
|
Provides-Extra: feather
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
|
|
33
|
+
---
|
|
34
|
+
title: SignalK CLI
|
|
35
|
+
description: Command line access to SignalK APIs and streaming data, for piping within console, or export to CSV, JSON or Apache Arrow Feather for dataframe analysis.
|
|
36
|
+
---
|
|
37
|
+
|
|
33
38
|
# SignalK CLI
|
|
34
39
|
|
|
35
40
|
[](https://github.com/rhizomatics)
|
|
@@ -47,7 +52,31 @@ Description-Content-Type: text/markdown
|
|
|
47
52
|
|
|
48
53
|
Query and explore NMEA and other boat data from SignalK APIs using the command line or the Python API. Export data as CSV, Apache Arrow Feather, or JSON or use as dataframes in scripts or data notebooks.
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
`signalk_cli` goes beyond raw API data extraction to automatically handle metrics and 'wide' tables that bring together aggregates like 'max' or 'avg' into separate columns for simpler queries. It also has an analysis tools to summarize data variability.
|
|
56
|
+
|
|
57
|
+
<!-- termynal -->
|
|
58
|
+
```
|
|
59
|
+
$ uv run --with signalk-cli signalk_cli.history list-providers
|
|
60
|
+
provider,isDefault
|
|
61
|
+
kip,False
|
|
62
|
+
signalk-parquet,True
|
|
63
|
+
|
|
64
|
+
uv run --with signalk-cli signalk_cli.history query 'environment.outside.wind.gust:max' 'environment.wind.speedApparent:avg' --duration P7D --resolution 1m
|
|
65
|
+
timestamp,path,value
|
|
66
|
+
2026-10-03T09:11:00Z,environment.wind.speedApparent,5.8
|
|
67
|
+
2026-10-03T09:12:00Z,environment.outside.wind.gust,45.36699999999996
|
|
68
|
+
2026-10-03T09:12:00Z,environment.wind.speedApparent,5.8
|
|
69
|
+
2026-10-03T09:13:00Z,environment.outside.wind.gust,15.317000000000009
|
|
70
|
+
|
|
71
|
+
uv run --with signalk-cli signalk_cli.stream deltas 'environment.outside.wind.*' --follow
|
|
72
|
+
timestamp,context,source,path,value
|
|
73
|
+
2026-10-03T09:08:21.042Z,vessels.urn:mrn:signalk:uuid:64f1567b-2fc2-474f-8b23-4e9c43b61ffb,simulator.0,environment.outside.wind.gust,44.29449999999997
|
|
74
|
+
2026-10-03T09:08:23.042Z,vessels.urn:mrn:signalk:uuid:64f1567b-2fc2-474f-8b23-4e9c43b61ffb,simulator.0,environment.outside.wind.gust,45.29449999999997
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## APIs supported:
|
|
51
80
|
|
|
52
81
|
### [SignalK v2 History API](https://demo.signalk.org/documentation/Developing/REST_APIs/History_API.html).
|
|
53
82
|
|
|
@@ -98,7 +127,7 @@ cd signalk-cli
|
|
|
98
127
|
uv sync
|
|
99
128
|
```
|
|
100
129
|
|
|
101
|
-
##
|
|
130
|
+
## Use without Installing
|
|
102
131
|
|
|
103
132
|
Use `uv` to run without installing the module permanently, for example:
|
|
104
133
|
|
|
@@ -110,6 +139,12 @@ uv run --with signalk-cli signalk_cli.history list-providers
|
|
|
110
139
|
uv run --with signalk-cli signalk_cli.stream deltas navigation.position --follow
|
|
111
140
|
```
|
|
112
141
|
|
|
142
|
+
Wildcards to follow multiple paths need to be quoted
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
uv run --with signalk-cli signalk_cli.stream deltas 'environment.outside.wind.*' --follow
|
|
146
|
+
```
|
|
147
|
+
|
|
113
148
|
## Python library
|
|
114
149
|
|
|
115
150
|
Everything the CLI does is also available from Python, returning tables that load straight into polars, pandas, pyarrow or DuckDB:
|
|
@@ -154,6 +189,7 @@ Commands:
|
|
|
154
189
|
query Query history and write results as CSV, Feather, or JSON.
|
|
155
190
|
```
|
|
156
191
|
|
|
192
|
+
|
|
157
193
|
## Commands
|
|
158
194
|
|
|
159
195
|
|
|
@@ -473,11 +509,9 @@ python -m signalk_cli.stream deltas [OPTIONS] [PATH...]
|
|
|
473
509
|
```
|
|
474
510
|
|
|
475
511
|
By default, prints the next delta message and exits — useful for a quick check.
|
|
476
|
-
Use `--follow` to keep tailing until interrupted with Ctrl-C, optionally capped
|
|
477
|
-
with `--count`.
|
|
512
|
+
Use `--follow` to keep tailing until interrupted with Ctrl-C, optionally capped with `--count`.
|
|
478
513
|
|
|
479
|
-
**PATH** arguments are sent verbatim to the server as an explicit subscription,
|
|
480
|
-
one per path. They may be literal SignalK paths (e.g. `navigation.speedOverGround`)
|
|
514
|
+
**PATH** arguments are sent verbatim to the server as an explicit subscription, one per path. They may be literal SignalK paths (e.g. `navigation.speedOverGround`)
|
|
481
515
|
or use the SignalK subscription wildcard `*`, matched server-side per the
|
|
482
516
|
[Subscription Protocol](https://signalk.org/specification/1.8.2/doc/subscription_protocol.html)
|
|
483
517
|
— unlike `history`'s PATH patterns, which the client resolves by matching
|
|
@@ -621,3 +655,7 @@ Typical combinations:
|
|
|
621
655
|
## Default caching
|
|
622
656
|
|
|
623
657
|
The default history provider is fetched from the server once and cached per host in `~/.cache/signalk-history-cli/`. Pass `--no-cache` to force a fresh lookup, or `--provider <id>` to target a specific provider explicitly.
|
|
658
|
+
|
|
659
|
+
## Too Much Streaming Data
|
|
660
|
+
|
|
661
|
+
If the data is too noisy, like GPS positions with dubious centimeter differences, then [signalk-delta-squelch-plugin](https://github.com/rhizomatics/signalk-delta-squelch-plugin) can cut this down hugely, and also filter out GPS glitches that suggest your boat moves at warp speed.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: SignalK CLI
|
|
3
|
+
description: Command line access to SignalK APIs and streaming data, for piping within console, or export to CSV, JSON or Apache Arrow Feather for dataframe analysis.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# SignalK CLI
|
|
2
7
|
|
|
3
8
|
[](https://github.com/rhizomatics)
|
|
@@ -15,7 +20,31 @@
|
|
|
15
20
|
|
|
16
21
|
Query and explore NMEA and other boat data from SignalK APIs using the command line or the Python API. Export data as CSV, Apache Arrow Feather, or JSON or use as dataframes in scripts or data notebooks.
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
`signalk_cli` goes beyond raw API data extraction to automatically handle metrics and 'wide' tables that bring together aggregates like 'max' or 'avg' into separate columns for simpler queries. It also has an analysis tools to summarize data variability.
|
|
24
|
+
|
|
25
|
+
<!-- termynal -->
|
|
26
|
+
```
|
|
27
|
+
$ uv run --with signalk-cli signalk_cli.history list-providers
|
|
28
|
+
provider,isDefault
|
|
29
|
+
kip,False
|
|
30
|
+
signalk-parquet,True
|
|
31
|
+
|
|
32
|
+
uv run --with signalk-cli signalk_cli.history query 'environment.outside.wind.gust:max' 'environment.wind.speedApparent:avg' --duration P7D --resolution 1m
|
|
33
|
+
timestamp,path,value
|
|
34
|
+
2026-10-03T09:11:00Z,environment.wind.speedApparent,5.8
|
|
35
|
+
2026-10-03T09:12:00Z,environment.outside.wind.gust,45.36699999999996
|
|
36
|
+
2026-10-03T09:12:00Z,environment.wind.speedApparent,5.8
|
|
37
|
+
2026-10-03T09:13:00Z,environment.outside.wind.gust,15.317000000000009
|
|
38
|
+
|
|
39
|
+
uv run --with signalk-cli signalk_cli.stream deltas 'environment.outside.wind.*' --follow
|
|
40
|
+
timestamp,context,source,path,value
|
|
41
|
+
2026-10-03T09:08:21.042Z,vessels.urn:mrn:signalk:uuid:64f1567b-2fc2-474f-8b23-4e9c43b61ffb,simulator.0,environment.outside.wind.gust,44.29449999999997
|
|
42
|
+
2026-10-03T09:08:23.042Z,vessels.urn:mrn:signalk:uuid:64f1567b-2fc2-474f-8b23-4e9c43b61ffb,simulator.0,environment.outside.wind.gust,45.29449999999997
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## APIs supported:
|
|
19
48
|
|
|
20
49
|
### [SignalK v2 History API](https://demo.signalk.org/documentation/Developing/REST_APIs/History_API.html).
|
|
21
50
|
|
|
@@ -66,7 +95,7 @@ cd signalk-cli
|
|
|
66
95
|
uv sync
|
|
67
96
|
```
|
|
68
97
|
|
|
69
|
-
##
|
|
98
|
+
## Use without Installing
|
|
70
99
|
|
|
71
100
|
Use `uv` to run without installing the module permanently, for example:
|
|
72
101
|
|
|
@@ -78,6 +107,12 @@ uv run --with signalk-cli signalk_cli.history list-providers
|
|
|
78
107
|
uv run --with signalk-cli signalk_cli.stream deltas navigation.position --follow
|
|
79
108
|
```
|
|
80
109
|
|
|
110
|
+
Wildcards to follow multiple paths need to be quoted
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
uv run --with signalk-cli signalk_cli.stream deltas 'environment.outside.wind.*' --follow
|
|
114
|
+
```
|
|
115
|
+
|
|
81
116
|
## Python library
|
|
82
117
|
|
|
83
118
|
Everything the CLI does is also available from Python, returning tables that load straight into polars, pandas, pyarrow or DuckDB:
|
|
@@ -122,6 +157,7 @@ Commands:
|
|
|
122
157
|
query Query history and write results as CSV, Feather, or JSON.
|
|
123
158
|
```
|
|
124
159
|
|
|
160
|
+
|
|
125
161
|
## Commands
|
|
126
162
|
|
|
127
163
|
|
|
@@ -441,11 +477,9 @@ python -m signalk_cli.stream deltas [OPTIONS] [PATH...]
|
|
|
441
477
|
```
|
|
442
478
|
|
|
443
479
|
By default, prints the next delta message and exits — useful for a quick check.
|
|
444
|
-
Use `--follow` to keep tailing until interrupted with Ctrl-C, optionally capped
|
|
445
|
-
with `--count`.
|
|
480
|
+
Use `--follow` to keep tailing until interrupted with Ctrl-C, optionally capped with `--count`.
|
|
446
481
|
|
|
447
|
-
**PATH** arguments are sent verbatim to the server as an explicit subscription,
|
|
448
|
-
one per path. They may be literal SignalK paths (e.g. `navigation.speedOverGround`)
|
|
482
|
+
**PATH** arguments are sent verbatim to the server as an explicit subscription, one per path. They may be literal SignalK paths (e.g. `navigation.speedOverGround`)
|
|
449
483
|
or use the SignalK subscription wildcard `*`, matched server-side per the
|
|
450
484
|
[Subscription Protocol](https://signalk.org/specification/1.8.2/doc/subscription_protocol.html)
|
|
451
485
|
— unlike `history`'s PATH patterns, which the client resolves by matching
|
|
@@ -589,3 +623,7 @@ Typical combinations:
|
|
|
589
623
|
## Default caching
|
|
590
624
|
|
|
591
625
|
The default history provider is fetched from the server once and cached per host in `~/.cache/signalk-history-cli/`. Pass `--no-cache` to force a fresh lookup, or `--provider <id>` to target a specific provider explicitly.
|
|
626
|
+
|
|
627
|
+
## Too Much Streaming Data
|
|
628
|
+
|
|
629
|
+
If the data is too noisy, like GPS positions with dubious centimeter differences, then [signalk-delta-squelch-plugin](https://github.com/rhizomatics/signalk-delta-squelch-plugin) can cut this down hugely, and also filter out GPS glitches that suggest your boat moves at warp speed.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "signalk-cli"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.1"
|
|
4
4
|
description = "Query SignalK v2 APIs and export data as CSV, JSON or Apache Arrow Feather from command line or as a Python API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -62,11 +62,12 @@ dev = [
|
|
|
62
62
|
"pytest-xdist",
|
|
63
63
|
"mypy",
|
|
64
64
|
"coverage",
|
|
65
|
+
"bandit",
|
|
65
66
|
"genbadge[all]",
|
|
66
67
|
"icdiff",
|
|
67
68
|
"codespell",
|
|
68
|
-
"polars>=1.44.2,<
|
|
69
|
-
"duckdb>=1.5.5,<
|
|
69
|
+
"polars>=1.44.2,<3.0.0",
|
|
70
|
+
"duckdb>=1.5.5,<3.0.0",
|
|
70
71
|
"pandas>=3.0.6,<4.0.0",
|
|
71
72
|
]
|
|
72
73
|
docs = [
|
|
@@ -77,8 +78,11 @@ docs = [
|
|
|
77
78
|
"mkdocs-pagetree-plugin",
|
|
78
79
|
"mkdocs-coverage",
|
|
79
80
|
"pymdown-extensions",
|
|
81
|
+
"mkdocs-homepage-copier",
|
|
80
82
|
"mkdocs-meta-descriptions-plugin",
|
|
81
83
|
"pngquant",
|
|
84
|
+
"termynal",
|
|
85
|
+
"pillow>=13.0.0",
|
|
82
86
|
"mkdocs-htmlproofer-plugin",
|
|
83
87
|
"mkdocs-llmstxt>=0.5.0,<0.6.0",
|
|
84
88
|
"mkdocstrings[python]>=1.0.6,<2.0.0",
|
|
@@ -143,6 +147,8 @@ exclude-newer = "7 days"
|
|
|
143
147
|
add-bounds = "major"
|
|
144
148
|
|
|
145
149
|
[tool.uv.exclude-newer-package]
|
|
150
|
+
certifi = false
|
|
151
|
+
pillow = false
|
|
146
152
|
uv_build = "2 days"
|
|
147
153
|
|
|
148
154
|
[tool.uv.build-backend]
|
|
@@ -150,5 +156,5 @@ module-root = "src"
|
|
|
150
156
|
module-name = "signalk_cli"
|
|
151
157
|
|
|
152
158
|
[build-system]
|
|
153
|
-
requires = ["uv_build>=0.12.0
|
|
159
|
+
requires = ["uv_build>=0.12.0"]
|
|
154
160
|
build-backend = "uv_build"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "signalk-cli"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.1"
|
|
4
4
|
description = "Query SignalK v2 APIs and export data as CSV, JSON or Apache Arrow Feather from command line or as a Python API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -47,11 +47,12 @@ dev = [
|
|
|
47
47
|
"pytest-xdist",
|
|
48
48
|
"mypy",
|
|
49
49
|
"coverage",
|
|
50
|
+
"bandit",
|
|
50
51
|
"genbadge[all]",
|
|
51
52
|
"icdiff",
|
|
52
53
|
"codespell",
|
|
53
|
-
"polars>=1.44.2,<
|
|
54
|
-
"duckdb>=1.5.5,<
|
|
54
|
+
"polars>=1.44.2,<3.0.0",
|
|
55
|
+
"duckdb>=1.5.5,<3.0.0",
|
|
55
56
|
"pandas>=3.0.6,<4.0.0",
|
|
56
57
|
]
|
|
57
58
|
|
|
@@ -63,8 +64,11 @@ docs=[
|
|
|
63
64
|
"mkdocs-pagetree-plugin",
|
|
64
65
|
"mkdocs-coverage",
|
|
65
66
|
"pymdown-extensions",
|
|
67
|
+
"mkdocs-homepage-copier",
|
|
66
68
|
"mkdocs-meta-descriptions-plugin",
|
|
67
69
|
"pngquant",
|
|
70
|
+
"termynal",
|
|
71
|
+
"pillow>=13.0.0",
|
|
68
72
|
"mkdocs-htmlproofer-plugin",
|
|
69
73
|
"mkdocs-llmstxt>=0.5.0,<0.6.0",
|
|
70
74
|
"mkdocstrings[python]>=1.0.6,<2.0.0",
|
|
@@ -136,11 +140,11 @@ allowed-unresolved-imports = ["pyarrow", "pyarrow.**"]
|
|
|
136
140
|
compile-bytecode = true
|
|
137
141
|
managed = true
|
|
138
142
|
exclude-newer = "7 days"
|
|
139
|
-
exclude-newer-package = {"uv_build"="2 days"}
|
|
143
|
+
exclude-newer-package = {certifi=false, pillow=false,"uv_build"="2 days"}
|
|
140
144
|
add-bounds = "major"
|
|
141
145
|
|
|
142
146
|
[build-system]
|
|
143
|
-
requires = ["uv_build>=0.12.0
|
|
147
|
+
requires = ["uv_build>=0.12.0"]
|
|
144
148
|
build-backend = "uv_build"
|
|
145
149
|
|
|
146
150
|
|
|
@@ -31,7 +31,7 @@ def _epoch_us(ts: str | datetime | None) -> int | None:
|
|
|
31
31
|
return round(dt.timestamp() * 1_000_000)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def infer_column(values: Sequence[Any]) -> tuple[list, Any]:
|
|
34
|
+
def infer_column(values: Sequence[Any]) -> tuple[list[str | float | bool | None], Any]:
|
|
35
35
|
"""Pick one Arrow type for a column of JSON values: float64, bool, or string.
|
|
36
36
|
|
|
37
37
|
Numbers (and nulls) become float64, booleans stay bool, and anything else
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import contextlib
|
|
4
4
|
import io
|
|
5
5
|
import logging
|
|
6
|
-
from collections.abc import
|
|
6
|
+
from collections.abc import Generator
|
|
7
7
|
|
|
8
8
|
import click
|
|
9
9
|
|
|
@@ -38,7 +38,7 @@ def bare_option(f):
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
@contextlib.contextmanager
|
|
41
|
-
def stderr_ctx(bare: bool) ->
|
|
41
|
+
def stderr_ctx(bare: bool) -> Generator[None]:
|
|
42
42
|
"""Route library log messages to stderr for one command, or discard them all if bare."""
|
|
43
43
|
handler = _ClickHandler()
|
|
44
44
|
previous_level = logger.level
|
|
@@ -5,7 +5,7 @@ import csv
|
|
|
5
5
|
import json
|
|
6
6
|
import re
|
|
7
7
|
import sys
|
|
8
|
-
from collections.abc import
|
|
8
|
+
from collections.abc import Generator
|
|
9
9
|
from datetime import UTC, datetime
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from urllib.parse import urlparse
|
|
@@ -92,7 +92,7 @@ def _client(
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
@contextlib.contextmanager
|
|
95
|
-
def _exit_on_error(doing: str) ->
|
|
95
|
+
def _exit_on_error(doing: str) -> Generator[None]:
|
|
96
96
|
"""Report a failed request as 'Error <doing>: <message>' and exit 1."""
|
|
97
97
|
try:
|
|
98
98
|
yield
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|