ert 18.0.0__py3-none-any.whl → 18.0.3__py3-none-any.whl
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.
- ert/config/parsing/config_schema.py +3 -3
- ert/config/parsing/config_schema_item.py +11 -7
- ert/config/parsing/schema_item_type.py +1 -0
- ert/gui/main.py +7 -5
- ert/shared/version.py +3 -3
- ert/storage/local_storage.py +21 -20
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/METADATA +1 -1
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/RECORD +13 -13
- everest/api/everest_data_api.py +14 -1
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/WHEEL +0 -0
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/entry_points.txt +0 -0
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/licenses/COPYING +0 -0
- {ert-18.0.0.dist-info → ert-18.0.3.dist-info}/top_level.txt +0 -0
|
@@ -4,8 +4,8 @@ from .config_schema_deprecations import deprecated_keywords_list
|
|
|
4
4
|
from .config_schema_item import (
|
|
5
5
|
SchemaItem,
|
|
6
6
|
Varies,
|
|
7
|
+
existing_file_keyword,
|
|
7
8
|
existing_path_inline_keyword,
|
|
8
|
-
existing_path_keyword,
|
|
9
9
|
float_keyword,
|
|
10
10
|
int_keyword,
|
|
11
11
|
path_keyword,
|
|
@@ -318,8 +318,8 @@ def init_user_config_schema() -> ConfigSchemaDict:
|
|
|
318
318
|
surface_keyword(),
|
|
319
319
|
field_keyword(),
|
|
320
320
|
single_arg_keyword(ConfigKeys.ECLBASE),
|
|
321
|
-
|
|
322
|
-
|
|
321
|
+
existing_file_keyword(ConfigKeys.DATA_FILE),
|
|
322
|
+
existing_file_keyword(ConfigKeys.GRID),
|
|
323
323
|
path_keyword(ConfigKeys.REFCASE),
|
|
324
324
|
int_keyword(ConfigKeys.RANDOM_SEED),
|
|
325
325
|
num_realizations_keyword(),
|
|
@@ -155,9 +155,9 @@ class SchemaItem:
|
|
|
155
155
|
f"value as argument {index + 1!r}",
|
|
156
156
|
token,
|
|
157
157
|
)
|
|
158
|
-
|
|
159
158
|
case (
|
|
160
159
|
SchemaItemType.PATH
|
|
160
|
+
| SchemaItemType.EXISTING_FILE
|
|
161
161
|
| SchemaItemType.EXISTING_PATH
|
|
162
162
|
| SchemaItemType.EXISTING_PATH_INLINE
|
|
163
163
|
):
|
|
@@ -166,10 +166,14 @@ class SchemaItem:
|
|
|
166
166
|
path = os.path.normpath(
|
|
167
167
|
os.path.join(os.path.dirname(token.filename), token)
|
|
168
168
|
)
|
|
169
|
-
if val_type
|
|
170
|
-
SchemaItemType.
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
if val_type != SchemaItemType.PATH:
|
|
170
|
+
if val_type == SchemaItemType.EXISTING_FILE and not os.path.isfile(
|
|
171
|
+
str(path)
|
|
172
|
+
):
|
|
173
|
+
raise ConfigValidationError.with_context(
|
|
174
|
+
f"{self.kw} {token} is not a file.",
|
|
175
|
+
token,
|
|
176
|
+
)
|
|
173
177
|
if not os.path.exists(str(path)):
|
|
174
178
|
err = f'Cannot find file or directory "{token.value}". '
|
|
175
179
|
if path != token:
|
|
@@ -343,8 +347,8 @@ def path_keyword(keyword: str) -> SchemaItem:
|
|
|
343
347
|
return SchemaItem(kw=keyword, type_map=[SchemaItemType.PATH])
|
|
344
348
|
|
|
345
349
|
|
|
346
|
-
def
|
|
347
|
-
return SchemaItem(kw=keyword, type_map=[SchemaItemType.
|
|
350
|
+
def existing_file_keyword(keyword: str) -> SchemaItem:
|
|
351
|
+
return SchemaItem(kw=keyword, type_map=[SchemaItemType.EXISTING_FILE])
|
|
348
352
|
|
|
349
353
|
|
|
350
354
|
def existing_path_inline_keyword(
|
|
@@ -9,6 +9,7 @@ class SchemaItemType(StrEnum):
|
|
|
9
9
|
POSITIVE_FLOAT = "POSITIVE_FLOAT"
|
|
10
10
|
PATH = "PATH"
|
|
11
11
|
EXISTING_PATH = "EXISTING_PATH"
|
|
12
|
+
EXISTING_FILE = "EXISTING_FILE"
|
|
12
13
|
# EXISTING_PATH_INLINE is a directive to the
|
|
13
14
|
# schema validation to inline the contents of
|
|
14
15
|
# the file.
|
ert/gui/main.py
CHANGED
|
@@ -29,7 +29,12 @@ from ert.gui.tools.event_viewer import (
|
|
|
29
29
|
from ert.namespace import Namespace
|
|
30
30
|
from ert.plugins import ErtRuntimePlugins, get_site_plugins
|
|
31
31
|
from ert.services import ErtServer
|
|
32
|
-
from ert.storage import
|
|
32
|
+
from ert.storage import (
|
|
33
|
+
ErtStorageException,
|
|
34
|
+
LocalStorage,
|
|
35
|
+
local_storage_set_ert_config,
|
|
36
|
+
open_storage,
|
|
37
|
+
)
|
|
33
38
|
from ert.trace import trace, tracer
|
|
34
39
|
|
|
35
40
|
from .ertwidgets import Suggestor
|
|
@@ -158,10 +163,7 @@ def _start_initial_gui_window(
|
|
|
158
163
|
storage_path = None
|
|
159
164
|
if ert_config is not None:
|
|
160
165
|
try:
|
|
161
|
-
|
|
162
|
-
should_migrate = read_storage.check_migration_needed()
|
|
163
|
-
|
|
164
|
-
if should_migrate:
|
|
166
|
+
if LocalStorage.check_migration_needed(Path(ert_config.ens_path)):
|
|
165
167
|
# Open in write mode to initialize the storage, so that
|
|
166
168
|
# dark storage can be mounted onto it
|
|
167
169
|
open_storage(ert_config.ens_path, mode="w").close()
|
ert/shared/version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '18.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (18, 0,
|
|
31
|
+
__version__ = version = '18.0.3'
|
|
32
|
+
__version_tuple__ = version_tuple = (18, 0, 3)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g211bdcd43'
|
ert/storage/local_storage.py
CHANGED
|
@@ -101,34 +101,35 @@ class LocalStorage(BaseMode):
|
|
|
101
101
|
raise ValueError(f"No index.json, but found: {errors}") from err
|
|
102
102
|
self.version = _LOCAL_STORAGE_VERSION
|
|
103
103
|
|
|
104
|
-
if self.check_migration_needed():
|
|
105
|
-
self.
|
|
104
|
+
if self.check_migration_needed(Path(self.path)):
|
|
105
|
+
if not self.can_write:
|
|
106
|
+
raise RuntimeError(
|
|
107
|
+
f"Cannot open storage '{self.path}' in read-only mode: "
|
|
108
|
+
f"Storage version {self.version} is too old. "
|
|
109
|
+
f"Run ert to initiate migration."
|
|
110
|
+
)
|
|
111
|
+
else:
|
|
112
|
+
self._migrate(self.version)
|
|
106
113
|
|
|
107
114
|
self.refresh()
|
|
108
115
|
if mode.can_write:
|
|
109
116
|
self._save_index()
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
@staticmethod
|
|
119
|
+
def check_migration_needed(storage_dir: Path) -> bool:
|
|
120
|
+
try:
|
|
121
|
+
version = _storage_version(storage_dir)
|
|
122
|
+
except FileNotFoundError:
|
|
123
|
+
version = _LOCAL_STORAGE_VERSION
|
|
124
|
+
|
|
125
|
+
if version > _LOCAL_STORAGE_VERSION:
|
|
113
126
|
raise RuntimeError(
|
|
114
|
-
f"Cannot open storage '{
|
|
115
|
-
f"is newer than the current version {_LOCAL_STORAGE_VERSION}
|
|
116
|
-
"upgrade ert to continue, or run with a different ENSPATH"
|
|
127
|
+
f"Cannot open storage '{storage_dir.absolute()}': Storage version "
|
|
128
|
+
f"{version} is newer than the current version {_LOCAL_STORAGE_VERSION}"
|
|
129
|
+
f", upgrade ert to continue, or run with a different ENSPATH"
|
|
117
130
|
)
|
|
118
131
|
|
|
119
|
-
return
|
|
120
|
-
|
|
121
|
-
def perform_migration(self) -> None:
|
|
122
|
-
if self.check_migration_needed():
|
|
123
|
-
if self.can_write:
|
|
124
|
-
self._migrate(self.version)
|
|
125
|
-
self._save_index()
|
|
126
|
-
else:
|
|
127
|
-
raise RuntimeError(
|
|
128
|
-
f"Cannot open storage '{self.path}' in read-only mode: "
|
|
129
|
-
f"Storage version {self.version} is too old. "
|
|
130
|
-
f"Run ert to initiate migration."
|
|
131
|
-
)
|
|
132
|
+
return version < _LOCAL_STORAGE_VERSION
|
|
132
133
|
|
|
133
134
|
def refresh(self) -> None:
|
|
134
135
|
"""
|
|
@@ -88,9 +88,9 @@ ert/config/parsing/_read_file.py,sha256=QKMQSNG5J05AdTzy_VQiK5AQ26g0bDHyxlSSPqIh
|
|
|
88
88
|
ert/config/parsing/config_dict.py,sha256=yyBb-NeaFnIjENrcziVA11Bq43uGguUiPECcKWLDg8w,52
|
|
89
89
|
ert/config/parsing/config_errors.py,sha256=p3lAcRPXTm4okupdVyLwRCVWJ_86a7rgCohkDaLRM10,4806
|
|
90
90
|
ert/config/parsing/config_keywords.py,sha256=J8kgzDVhuM8jvCwzO1kfOxvOH_DnDASOZPaJZujcIgQ,1860
|
|
91
|
-
ert/config/parsing/config_schema.py,sha256=
|
|
91
|
+
ert/config/parsing/config_schema.py,sha256=9ws2C3Oc-eT5uB_Xy2IEvPWON7b9rZnIc2FpID7hhWc,9614
|
|
92
92
|
ert/config/parsing/config_schema_deprecations.py,sha256=fmzyxUBxR9GtDNIkP0ozHWU2SH1TvyhBFFyFhG8vZjA,9125
|
|
93
|
-
ert/config/parsing/config_schema_item.py,sha256=
|
|
93
|
+
ert/config/parsing/config_schema_item.py,sha256=jjHT1KqobQvpLxh9gZ0rR8x_YylV29pvvP7oUASFwtA,14448
|
|
94
94
|
ert/config/parsing/context_values.py,sha256=S_j_BKuwqSm8RZNnw6Ki2ZQ4jz0VFXXmh0MZA2OstmQ,2288
|
|
95
95
|
ert/config/parsing/deprecation_info.py,sha256=E31LBTiG1qNeqACU8lTxp54bESIeuuVHgFim8j8uVjg,663
|
|
96
96
|
ert/config/parsing/error_info.py,sha256=AMOS0v-_ECHESj4aoy0m2fUPPlw9SE1DN_8MsaHeilY,2906
|
|
@@ -103,7 +103,7 @@ ert/config/parsing/lark_parser.py,sha256=SS0yXTI5w_qmpFvePMO-r0g9NPqOOrlCFF3amPe
|
|
|
103
103
|
ert/config/parsing/observations_parser.py,sha256=3hmDjQYjSgrumrb8592X2AbJFp-J72Sq_VLQpOwMaWw,6707
|
|
104
104
|
ert/config/parsing/queue_system.py,sha256=P4-oHftl7piNwCNjnelJAA3WePlBmgXGPhnbHhSb4Eo,570
|
|
105
105
|
ert/config/parsing/schema_dict.py,sha256=MWKhtLhdRvqfWm8oZatWFnAhiIU03DdQCOaX6A71068,4313
|
|
106
|
-
ert/config/parsing/schema_item_type.py,sha256=
|
|
106
|
+
ert/config/parsing/schema_item_type.py,sha256=LP6lXE7YihnAEVP3kCJ80kdpgH6Veu--xcPfgaqJhdc,653
|
|
107
107
|
ert/config/parsing/types.py,sha256=NXV5odfbVL_opQgPTaSlpgkilY4qaB3pal4TaV6pL80,315
|
|
108
108
|
ert/config/parsing/workflow_job_keywords.py,sha256=4SSy2dwLS3G2B1-HPw3b6dMEpIc5-2218ERL_PT_R1k,269
|
|
109
109
|
ert/config/parsing/workflow_job_schema.py,sha256=lkL7CAOFeNcWNRGfBuu1FdbcSqwPXM__8dCC8b3hkTg,2905
|
|
@@ -158,7 +158,7 @@ ert/gui/__init__.py,sha256=AULn_ohaSWhaM-7oZuGYbagLfZ8PGL03vyiPTtSR0vk,625
|
|
|
158
158
|
ert/gui/about_dialog.py,sha256=H0Jfso2v9s1eONTVgghH84UcaUlwVs0Cqqbv17Hvw4g,3127
|
|
159
159
|
ert/gui/ertnotifier.py,sha256=u3jWGjuS75Ml7hAOT6FjBIksB3NLrWNIoH0_WLT3gCE,3031
|
|
160
160
|
ert/gui/find_ert_info.py,sha256=hwqiCa5rDZEL_25QVsx920d9NOaVM2PyUor89_-70-Q,301
|
|
161
|
-
ert/gui/main.py,sha256=
|
|
161
|
+
ert/gui/main.py,sha256=h27FWct4C7R6uYRPa3b5stZbF1QuDr_2zXGCNjJEh4E,8980
|
|
162
162
|
ert/gui/main_window.py,sha256=ukP7OFIB23luoNIsKNTEts_yMaIlY0Qamcvn-Rfeu4E,14995
|
|
163
163
|
ert/gui/summarypanel.py,sha256=t12-A7Xx9ASoHa90VBZAISpSOVWvOYFb4GDTUpXkeSc,4235
|
|
164
164
|
ert/gui/ertwidgets/__init__.py,sha256=LtwHe4wpA0YpbealTrukMb7rDSSTxSyGkVaM8IvlI8A,1878
|
|
@@ -400,7 +400,7 @@ ert/services/ert_server.py,sha256=geh5mkdAKqNKgG56DcwSnEpvf0wcUc7vuw4feG1ykEI,10
|
|
|
400
400
|
ert/services/webviz_ert_service.py,sha256=J5vznqb_-DjlDMOze7tdvuBE4GWEPgJ5dIIXvRLKd0Y,650
|
|
401
401
|
ert/shared/__init__.py,sha256=OwgL-31MxA0fabETJ5Svw0tqJpHi569CZDRFHdHiqA0,644
|
|
402
402
|
ert/shared/net_utils.py,sha256=DDHIZLHdBnh7ZZ--1s-FUlsoNTSJJsfHmLQE44E2JqU,5324
|
|
403
|
-
ert/shared/version.py,sha256=
|
|
403
|
+
ert/shared/version.py,sha256=llZW1syJ0X_XI90_uTsjvEQ5V9UY3Fxv-4JUtLFBSRc,714
|
|
404
404
|
ert/shared/_doc_utils/__init__.py,sha256=zSl-NUpWLF167PVTvfjn0T50gExjvyWPw5OGq5Bt2Dc,983
|
|
405
405
|
ert/shared/_doc_utils/ert_jobs.py,sha256=uHP8ozhKwCHG6BkyhAgCGoy59JEFb102pHKot-5ZEys,8054
|
|
406
406
|
ert/shared/_doc_utils/everest_jobs.py,sha256=uBDN7tIwlBJIZVZ6ZFL1tkewEJJGDLoeVrFIIrJznvM,2081
|
|
@@ -419,7 +419,7 @@ ert/storage/__init__.py,sha256=W3sSffFeh60a3T3rGlylucgR1sYRQb2OEkAiqO0r1Y0,2053
|
|
|
419
419
|
ert/storage/load_status.py,sha256=7h_GdA2qYGgQ-M5AOIo7xG43ljwzEEgbRb7vg0xSYEE,304
|
|
420
420
|
ert/storage/local_ensemble.py,sha256=uJvqO1ywzv2VsjNnVvDaWHXlXp8Q9Jod2I4nl4iJyTk,50626
|
|
421
421
|
ert/storage/local_experiment.py,sha256=7I-SPoqrAv9esVjVRFH_xpS3smlf06pSo6jQRdRVoJE,16871
|
|
422
|
-
ert/storage/local_storage.py,sha256=
|
|
422
|
+
ert/storage/local_storage.py,sha256=WxGFYsVZOoal2Zjzz2bgBVCl5jtcnwNEJXbZxW8UVPw,23429
|
|
423
423
|
ert/storage/mode.py,sha256=GJBlRSqS0Q06qDvaAztdcG-oV2MLsVID2Mo3OgQKjUw,2470
|
|
424
424
|
ert/storage/realization_storage_state.py,sha256=JdiBr__Ce5e1MzmRsRdMuwgCtiuHZRjsQ-as8ivTX7Q,220
|
|
425
425
|
ert/storage/migration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -453,13 +453,13 @@ ert/validation/validation_status.py,sha256=f47_B7aS-9DEh6uaVzKxD97pXienkyTVVCqTy
|
|
|
453
453
|
ert/warnings/__init__.py,sha256=IBwQVkdD7Njaad9PAB-9K-kr15wnA4EBKboxyqgu9NA,214
|
|
454
454
|
ert/warnings/_warnings.py,sha256=7qhNZ0W4nnljzoOx6AXX7VlMv5pa34Ek5M5n1Ep0Kak,189
|
|
455
455
|
ert/warnings/specific_warning_handler.py,sha256=5dVXtOhzcMmtPBGx4AOddXNPfzTFOPA7RVtdH8hLv68,932
|
|
456
|
-
ert-18.0.
|
|
456
|
+
ert-18.0.3.dist-info/licenses/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
457
457
|
everest/__init__.py,sha256=8_f50f6H3-onqaiuNCwC0Eiotdl9JuTxhwyF_54MVvU,306
|
|
458
458
|
everest/config_file_loader.py,sha256=q_rmxk778uDrNxdQQW0tBs9R3hU4az6yGCJwuY_5xww,5698
|
|
459
459
|
everest/everest_storage.py,sha256=Xg2CuRdhZOqljm0i6H5o-pejcMeCwncSGw7Q6beZRgY,42173
|
|
460
460
|
everest/strings.py,sha256=KzWCBllsDmuphSsjbIN9kL_CTPvRcaTAxixDH3YA3ig,908
|
|
461
461
|
everest/api/__init__.py,sha256=_me3w2C92NQpPX2RrJ28IfQiXNif5-f2dN9Qg4HzbgY,86
|
|
462
|
-
everest/api/everest_data_api.py,sha256
|
|
462
|
+
everest/api/everest_data_api.py,sha256=-W_Qot75zJ6xl2M7S3SyL1SXGLcgpeopmMUSS8jSmHg,10333
|
|
463
463
|
everest/assets/everest_logo.svg,sha256=1GDy-tJYQSean8f_WWTlcKPhv1Wsb_xhFzXe3Gguke4,12048
|
|
464
464
|
everest/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
465
465
|
everest/bin/config_branch_script.py,sha256=-xMKskcDf5hxlzTtcyNG55yvnUKPQTtoUetlEGss6KM,5063
|
|
@@ -517,8 +517,8 @@ everest/templates/well_drill.tmpl,sha256=9iLexmBHMsMQNXyyRK4GlmVuVpVIxRcCHpy1av5
|
|
|
517
517
|
everest/templates/well_order.tmpl,sha256=XJ1eVRkeyTdLu5sLsltJSSK6BDLN7rFOAqLdM3ZZy3w,75
|
|
518
518
|
everest/util/__init__.py,sha256=xEYLz6pUtgkH8VHer1RfoCwKiO70dBnuhHonsOPaOx0,1359
|
|
519
519
|
everest/util/forward_models.py,sha256=JPxHhLI6TrmQJwW50wwGBmw57TfRd8SG2svYhXFHrc8,1617
|
|
520
|
-
ert-18.0.
|
|
521
|
-
ert-18.0.
|
|
522
|
-
ert-18.0.
|
|
523
|
-
ert-18.0.
|
|
524
|
-
ert-18.0.
|
|
520
|
+
ert-18.0.3.dist-info/METADATA,sha256=6VtOgk7bU0tXesTYDU64W3uB5doNHepwgh2Zsc31cMQ,10013
|
|
521
|
+
ert-18.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
522
|
+
ert-18.0.3.dist-info/entry_points.txt,sha256=ChZ7vn8Qy9v9rT8GM2JtAvWDN3NVoy4BIcvVRtU73CM,189
|
|
523
|
+
ert-18.0.3.dist-info/top_level.txt,sha256=LRh9GfdfyDWfAGmrQgp_XdoMHA4v6aotw8xgsy5YyHE,17
|
|
524
|
+
ert-18.0.3.dist-info/RECORD,,
|
everest/api/everest_data_api.py
CHANGED
|
@@ -224,6 +224,8 @@ class EverestDataAPI:
|
|
|
224
224
|
assert self._config.storage_dir
|
|
225
225
|
storage = open_storage(self._config.storage_dir, "r")
|
|
226
226
|
experiment = next(storage.experiments)
|
|
227
|
+
identical_columns_in_all_batches: bool = True
|
|
228
|
+
summary_columns: list[str] | None = None
|
|
227
229
|
for batch_id in batches:
|
|
228
230
|
try:
|
|
229
231
|
ensemble = experiment.get_ensemble_by_name(f"batch_{batch_id}")
|
|
@@ -238,6 +240,10 @@ class EverestDataAPI:
|
|
|
238
240
|
summary = summary.pivot(
|
|
239
241
|
on="response_key", index=["realization", "time"], sort_columns=True
|
|
240
242
|
)
|
|
243
|
+
if summary_columns is None:
|
|
244
|
+
summary_columns = summary.columns
|
|
245
|
+
identical_columns_in_all_batches &= summary_columns == summary.columns
|
|
246
|
+
|
|
241
247
|
# The 'Realization' column exported by ert are
|
|
242
248
|
# the 'simulations' of everest.
|
|
243
249
|
summary = summary.rename({"time": "date", "realization": "simulation"})
|
|
@@ -265,7 +271,14 @@ class EverestDataAPI:
|
|
|
265
271
|
|
|
266
272
|
data_frames.append(summary)
|
|
267
273
|
storage.close()
|
|
268
|
-
return
|
|
274
|
+
return (
|
|
275
|
+
pl.concat(
|
|
276
|
+
data_frames,
|
|
277
|
+
how="vertical" if identical_columns_in_all_batches else "diagonal",
|
|
278
|
+
)
|
|
279
|
+
if data_frames
|
|
280
|
+
else pl.DataFrame()
|
|
281
|
+
)
|
|
269
282
|
|
|
270
283
|
@property
|
|
271
284
|
def output_folder(self) -> str:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|