hcs-core 0.1.292__tar.gz → 0.1.294__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.
- {hcs_core-0.1.292 → hcs_core-0.1.294}/PKG-INFO +3 -2
- hcs_core-0.1.294/hcs_core/__init__.py +1 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/_init.py +2 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/cli_processor.py +2 -2
- hcs_core-0.1.294/hcs_core/ctxp/telemetry.py +145 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/pyproject.toml +2 -1
- hcs_core-0.1.292/hcs_core/__init__.py +0 -1
- hcs_core-0.1.292/hcs_core/ctxp/telemetry.py +0 -102
- {hcs_core-0.1.292 → hcs_core-0.1.294}/.gitignore +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/README.md +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/built_in_cmds/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/built_in_cmds/_ut.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/built_in_cmds/context.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/built_in_cmds/profile.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/cli_options.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/cmd_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/config.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/context.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/data_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/dispatcher.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/duration.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/extension.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/fn_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/fstore.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/jsondot.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/logger.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/profile.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/profile_store.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/recent.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/state.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/task_schd.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/template_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/timeutil.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/ctxp/var_template.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/actions.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/base_provider.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/context.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/core.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/dag.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/helper.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/kop.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/provider/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/provider/dev/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/provider/dev/_prepare.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/provider/dev/dummy.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/plan/provider/dev/fibonacci.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/auth.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/cli_options.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/client_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/csp.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/ez_client.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/hcs_client.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/init.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/login_support.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/payload_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/requtil.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/sglib/utils.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/__init__.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/check_license.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/duration.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/exit.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/hcs_constants.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/job_view.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/pki_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/query_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/scheduler.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/ssl_util.py +0 -0
- {hcs_core-0.1.292 → hcs_core-0.1.294}/hcs_core/util/versions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hcs-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.294
|
|
4
4
|
Summary: Horizon Cloud Service CLI module.
|
|
5
5
|
Project-URL: Homepage, https://github.com/euc-eng/hcs-cli
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/euc-eng/hcs-cli/issues
|
|
@@ -15,7 +15,7 @@ Classifier: Operating System :: OS Independent
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Requires-Dist: authlib>=1.6.0
|
|
18
|
-
Requires-Dist: click>=8.
|
|
18
|
+
Requires-Dist: click>=8.1.8
|
|
19
19
|
Requires-Dist: coloredlogs>=15.0.1
|
|
20
20
|
Requires-Dist: cryptography>=45.0.5
|
|
21
21
|
Requires-Dist: graphviz>=0.21
|
|
@@ -42,6 +42,7 @@ Requires-Dist: bandit; extra == 'dev'
|
|
|
42
42
|
Requires-Dist: black; extra == 'dev'
|
|
43
43
|
Requires-Dist: build; extra == 'dev'
|
|
44
44
|
Requires-Dist: flake8; extra == 'dev'
|
|
45
|
+
Requires-Dist: hatch; extra == 'dev'
|
|
45
46
|
Requires-Dist: mypy; extra == 'dev'
|
|
46
47
|
Requires-Dist: pylint; extra == 'dev'
|
|
47
48
|
Requires-Dist: pytest; extra == 'dev'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.294"
|
|
@@ -43,6 +43,7 @@ def init(app_name: str, store_path: str = user_home, config_path: str = "./confi
|
|
|
43
43
|
global _initialized_app_name
|
|
44
44
|
if _initialized_app_name == app_name:
|
|
45
45
|
return
|
|
46
|
+
|
|
46
47
|
if _initialized_app_name is not None:
|
|
47
48
|
raise ValueError(f"App {app_name} already initialized with {_initialized_app_name}")
|
|
48
49
|
_initialized_app_name = app_name
|
|
@@ -79,6 +80,7 @@ def app_name():
|
|
|
79
80
|
|
|
80
81
|
def init_cli(main_cli: click.Group, commands_dir: str = "./cmds"):
|
|
81
82
|
try:
|
|
83
|
+
telemetry.start(_initialized_app_name)
|
|
82
84
|
ret = cli_processor.init(main_cli, commands_dir)
|
|
83
85
|
telemetry.end()
|
|
84
86
|
return ret
|
|
@@ -188,9 +188,9 @@ def _default_io(cmd: click.Command):
|
|
|
188
188
|
"exclude_field": kwargs.pop("exclude_field"),
|
|
189
189
|
}
|
|
190
190
|
ctx = click.get_current_context()
|
|
191
|
-
from .telemetry import
|
|
191
|
+
from .telemetry import update as telemetry_update
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
telemetry_update(ctx.command_path, ctx.params)
|
|
194
194
|
|
|
195
195
|
if io_args["output"] == "table":
|
|
196
196
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
import httpx
|
|
9
|
+
from yumako import env
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
_record = None
|
|
14
|
+
_enabled = None
|
|
15
|
+
_app_name = ""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def disable():
|
|
19
|
+
global _enabled
|
|
20
|
+
_enabled = False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _is_disabled():
|
|
24
|
+
global _enabled
|
|
25
|
+
if _enabled is None:
|
|
26
|
+
_enabled = env.bool("HCS_CLI_TELEMETRY", True)
|
|
27
|
+
return not _enabled
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _get_version():
|
|
31
|
+
try:
|
|
32
|
+
from importlib.metadata import version
|
|
33
|
+
|
|
34
|
+
return version("hcs-cli")
|
|
35
|
+
except Exception as e:
|
|
36
|
+
log.debug(f"Failed to get hcs-cli version: {e}")
|
|
37
|
+
return "unknown"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _get_record():
|
|
41
|
+
global _record
|
|
42
|
+
if _record is None:
|
|
43
|
+
_record = {
|
|
44
|
+
"@timestamp": datetime.now(timezone.utc).isoformat(timespec="milliseconds"),
|
|
45
|
+
"app": _app_name,
|
|
46
|
+
"command": None,
|
|
47
|
+
"options": [],
|
|
48
|
+
"return": -1,
|
|
49
|
+
"error": None,
|
|
50
|
+
"time_ms": -1,
|
|
51
|
+
"version": _get_version(),
|
|
52
|
+
"env": {
|
|
53
|
+
"python_version": sys.version,
|
|
54
|
+
"platform": sys.platform,
|
|
55
|
+
"executable": sys.executable,
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
return _record
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def start(app_name: str = None):
|
|
62
|
+
if _is_disabled():
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
global _app_name
|
|
66
|
+
_app_name = app_name
|
|
67
|
+
_get_record()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def update(cmd_path: str, params: dict):
|
|
71
|
+
if _is_disabled():
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
record = _get_record()
|
|
75
|
+
record["command"] = cmd_path
|
|
76
|
+
record["options"] = [k.replace("_", "-") for k, v in params.items() if v]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def end(return_code: int = 0, error: Exception = None):
|
|
80
|
+
if _is_disabled():
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
record = _get_record()
|
|
84
|
+
if error:
|
|
85
|
+
if isinstance(error, click.exceptions.Exit):
|
|
86
|
+
return_code = error.exit_code
|
|
87
|
+
elif isinstance(error, SystemExit):
|
|
88
|
+
return_code = error.code
|
|
89
|
+
else:
|
|
90
|
+
record["error"] = str(error)
|
|
91
|
+
if return_code == 0:
|
|
92
|
+
return_code = 1
|
|
93
|
+
record["return"] = return_code
|
|
94
|
+
record["time_ms"] = int((time.time() - datetime.fromisoformat(record["@timestamp"]).timestamp()) * 1000)
|
|
95
|
+
|
|
96
|
+
_fix_missing_commands(record)
|
|
97
|
+
_injest(record)
|
|
98
|
+
return record
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _fix_missing_commands(record):
|
|
102
|
+
if record["command"]:
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
args = sys.argv[1:]
|
|
106
|
+
|
|
107
|
+
# this does not work for all cases, but only as best effort.
|
|
108
|
+
options_started = False
|
|
109
|
+
options = record["options"]
|
|
110
|
+
command = [_app_name]
|
|
111
|
+
for arg in args:
|
|
112
|
+
if arg.startswith("-"):
|
|
113
|
+
options_started = True
|
|
114
|
+
|
|
115
|
+
if options_started:
|
|
116
|
+
if arg.startswith("--"):
|
|
117
|
+
options.append(arg[2:])
|
|
118
|
+
elif arg.startswith("-"):
|
|
119
|
+
options.append(arg[1:])
|
|
120
|
+
else:
|
|
121
|
+
# value. For privacy no logging.
|
|
122
|
+
continue
|
|
123
|
+
else:
|
|
124
|
+
command.append(arg)
|
|
125
|
+
|
|
126
|
+
record["command"] = " ".join(command)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _injest(doc):
|
|
130
|
+
|
|
131
|
+
# print('TELEMETRY end', json.dumps(doc, indent=4), flush=True)
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
response = httpx.post(
|
|
135
|
+
f"https://collie.omnissa.com/es/hcs-cli/_doc",
|
|
136
|
+
auth=("append_user", "public"),
|
|
137
|
+
headers={"Content-Type": "application/json"},
|
|
138
|
+
content=json.dumps(doc),
|
|
139
|
+
timeout=4,
|
|
140
|
+
verify=False,
|
|
141
|
+
)
|
|
142
|
+
response.raise_for_status()
|
|
143
|
+
except Exception as e:
|
|
144
|
+
log.debug(f"Telemetry ingestion failed: {e}", exc_info=True)
|
|
145
|
+
return
|
|
@@ -24,7 +24,7 @@ dynamic = ["version"]
|
|
|
24
24
|
|
|
25
25
|
dependencies = [
|
|
26
26
|
"Authlib>=1.6.0",
|
|
27
|
-
"click>=8.
|
|
27
|
+
"click>=8.1.8",
|
|
28
28
|
"coloredlogs>=15.0.1",
|
|
29
29
|
"cryptography>=45.0.5",
|
|
30
30
|
"graphviz>=0.21",
|
|
@@ -60,6 +60,7 @@ dev = [
|
|
|
60
60
|
"pytest",
|
|
61
61
|
"ruff",
|
|
62
62
|
"flake8",
|
|
63
|
+
"hatch",
|
|
63
64
|
]
|
|
64
65
|
|
|
65
66
|
[project.urls]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.292"
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
import sys
|
|
4
|
-
import time
|
|
5
|
-
from datetime import datetime, timezone
|
|
6
|
-
|
|
7
|
-
import click
|
|
8
|
-
import httpx
|
|
9
|
-
from yumako import env
|
|
10
|
-
|
|
11
|
-
log = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
_record = None
|
|
14
|
-
_enabled = None
|
|
15
|
-
_version = None
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def disable():
|
|
19
|
-
global _enabled
|
|
20
|
-
_enabled = False
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def _is_disabled():
|
|
24
|
-
global _enabled
|
|
25
|
-
if _enabled is None:
|
|
26
|
-
_enabled = env.bool("HCS_CLI_TELEMETRY", True)
|
|
27
|
-
return not _enabled
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _get_version():
|
|
31
|
-
global _version
|
|
32
|
-
if _version is None:
|
|
33
|
-
try:
|
|
34
|
-
from importlib.metadata import version
|
|
35
|
-
|
|
36
|
-
_version = version("hcs-cli")
|
|
37
|
-
except Exception as e:
|
|
38
|
-
log.debug(f"Failed to get hcs-cli version: {e}")
|
|
39
|
-
_version = "unknown"
|
|
40
|
-
return _version
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def start(cmd_path: str, params: dict):
|
|
44
|
-
if _is_disabled():
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
global _record
|
|
48
|
-
_record = {
|
|
49
|
-
"@timestamp": datetime.now(timezone.utc).isoformat(timespec="milliseconds"),
|
|
50
|
-
"command": cmd_path,
|
|
51
|
-
"options": [k.replace("_", "-") for k, v in params.items() if v],
|
|
52
|
-
"return": -1,
|
|
53
|
-
"error": None,
|
|
54
|
-
"time_ms": -1,
|
|
55
|
-
"version": _get_version(),
|
|
56
|
-
"env": {
|
|
57
|
-
"python_version": sys.version,
|
|
58
|
-
"platform": sys.platform,
|
|
59
|
-
"executable": sys.executable,
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def end(return_code: int = 0, error: Exception = None):
|
|
65
|
-
if _is_disabled():
|
|
66
|
-
return
|
|
67
|
-
|
|
68
|
-
if _record is None:
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
if error:
|
|
72
|
-
if isinstance(error, click.exceptions.Exit):
|
|
73
|
-
return_code = error.exit_code
|
|
74
|
-
elif isinstance(error, SystemExit):
|
|
75
|
-
return_code = error.code
|
|
76
|
-
else:
|
|
77
|
-
_record["error"] = str(error)
|
|
78
|
-
if return_code == 0:
|
|
79
|
-
return_code = 1
|
|
80
|
-
_record["return"] = return_code
|
|
81
|
-
_record["time_ms"] = int((time.time() - datetime.fromisoformat(_record["@timestamp"]).timestamp()) * 1000)
|
|
82
|
-
|
|
83
|
-
# print('TELEMETRY end', json.dumps(_record, indent=4), flush=True)
|
|
84
|
-
|
|
85
|
-
_injest(_record)
|
|
86
|
-
return _record
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def _injest(doc):
|
|
90
|
-
try:
|
|
91
|
-
response = httpx.post(
|
|
92
|
-
f"https://collie.omnissa.com/es/hcs-cli/_doc",
|
|
93
|
-
auth=("append_user", "public"),
|
|
94
|
-
headers={"Content-Type": "application/json"},
|
|
95
|
-
content=json.dumps(doc),
|
|
96
|
-
timeout=4,
|
|
97
|
-
verify=False,
|
|
98
|
-
)
|
|
99
|
-
response.raise_for_status()
|
|
100
|
-
except Exception as e:
|
|
101
|
-
log.debug(f"Telemetry ingestion failed: {e}", exc_info=True)
|
|
102
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|