hestia-earth-models 0.73.7__py3-none-any.whl → 0.74.0__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.
Potentially problematic release.
This version of hestia-earth-models might be problematic. Click here for more details.
- hestia_earth/models/aware/scarcityWeightedWaterUse.py +7 -6
- hestia_earth/models/aware2_0/__init__.py +14 -0
- hestia_earth/models/aware2_0/scarcityWeightedWaterUse.py +115 -0
- hestia_earth/models/config/Cycle.json +121 -29
- hestia_earth/models/config/ImpactAssessment.json +240 -200
- hestia_earth/models/config/__init__.py +26 -2
- hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +2 -2
- hestia_earth/models/cycle/animal/input/properties.py +6 -5
- hestia_earth/models/cycle/animal/milkYield.py +8 -3
- hestia_earth/models/cycle/utils.py +6 -6
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +11 -9
- hestia_earth/models/data/ecoinventV3/__init__.py +8 -26
- hestia_earth/models/ecoalimV9/cycle.py +51 -45
- hestia_earth/models/ecoalimV9/impact_assessment.py +63 -45
- hestia_earth/models/ecoalimV9/utils.py +21 -15
- hestia_earth/models/ecoinventV3/__init__.py +8 -140
- hestia_earth/models/ecoinventV3/cycle.py +140 -0
- hestia_earth/models/ecoinventV3/utils.py +28 -1
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -137
- hestia_earth/models/ecoinventV3AndEmberClimate/cycle.py +144 -0
- hestia_earth/models/emepEea2019/n2OToAirFuelCombustionDirect.py +2 -2
- hestia_earth/models/emepEea2019/utils.py +2 -3
- hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +5 -7
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +41 -43
- hestia_earth/models/geospatialDatabase/awareWaterBasinId.py +2 -2
- hestia_earth/models/geospatialDatabase/awareWaterBasinId_v1.py +45 -0
- hestia_earth/models/hestia/default_emissions.py +7 -7
- hestia_earth/models/hestia/default_resourceUse.py +7 -6
- hestia_earth/models/hestia/landCover.py +110 -12
- hestia_earth/models/hestia/seed_emissions.py +7 -3
- hestia_earth/models/hestia/utils.py +1 -0
- hestia_earth/models/hestia/waterSalinity.py +2 -3
- hestia_earth/models/impact_assessment/emissions.py +3 -5
- hestia_earth/models/ipcc2019/biocharOrganicCarbonPerHa.py +9 -3
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +1 -5
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +1 -5
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -33
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +1 -5
- hestia_earth/models/ipcc2019/n2OToAirAquacultureSystemsIndirect.py +44 -0
- hestia_earth/models/ipcc2019/n2OToAirCropResidueBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirExcretaIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirFuelCombustionIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirNaturalVegetationBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAir_indirect_emissions_utils.py +112 -0
- hestia_earth/models/ipcc2019/utils.py +0 -25
- hestia_earth/models/jarvisAndPain1994/n2ToAirExcreta.py +11 -9
- hestia_earth/models/linkedImpactAssessment/emissions.py +25 -16
- hestia_earth/models/linkedImpactAssessment/utils.py +5 -1
- hestia_earth/models/log.py +8 -3
- hestia_earth/models/mocking/search-results.json +1670 -1666
- hestia_earth/models/utils/__init__.py +3 -0
- hestia_earth/models/utils/background_emissions.py +121 -14
- hestia_earth/models/utils/blank_node.py +1 -11
- hestia_earth/models/utils/emission.py +18 -8
- hestia_earth/models/utils/feedipedia.py +2 -2
- hestia_earth/models/utils/impact_assessment.py +4 -6
- hestia_earth/models/utils/indicator.py +8 -1
- hestia_earth/models/utils/lookup.py +30 -18
- hestia_earth/models/utils/productivity.py +1 -1
- hestia_earth/models/version.py +1 -1
- hestia_earth/orchestrator/log.py +8 -3
- hestia_earth/orchestrator/strategies/merge/merge_list.py +41 -54
- {hestia_earth_models-0.73.7.dist-info → hestia_earth_models-0.74.0.dist-info}/METADATA +3 -3
- {hestia_earth_models-0.73.7.dist-info → hestia_earth_models-0.74.0.dist-info}/RECORD +99 -75
- tests/models/aware2_0/__init__.py +0 -0
- tests/models/aware2_0/test_scarcityWeightedWaterUse.py +58 -0
- tests/models/dammgen2009/test_noxToAirExcreta.py +2 -2
- tests/models/ecoalimV9/test_cycle.py +1 -1
- tests/models/ecoalimV9/test_impact_assessment.py +1 -1
- tests/models/ecoinventV3/__init__.py +0 -0
- tests/models/{test_ecoinventV3.py → ecoinventV3/test_cycle.py} +5 -5
- tests/models/ecoinventV3AndEmberClimate/__init__.py +0 -0
- tests/models/{test_ecoinventV3AndEmberClimate.py → ecoinventV3AndEmberClimate/test_cycle.py} +6 -4
- tests/models/environmentalFootprintV3_1/test_environmentalFootprintSingleOverallScore.py +2 -2
- tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +18 -27
- tests/models/hestia/test_landCover.py +16 -6
- tests/models/ipcc2019/test_biocharOrganicCarbonPerHa.py +2 -1
- tests/models/ipcc2019/test_n2OToAirAquacultureSystemsIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirCropResidueBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirCropResidueDecompositionIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirExcretaIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirFuelCombustionIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirInorganicFertiliserIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirNaturalVegetationBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirOrganicFertiliserIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirOrganicSoilBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirOrganicSoilCultivationIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAir_indirect_emissions_utils.py +19 -0
- tests/models/site/pre_checks/test_cache_geospatialDatabase.py +4 -4
- tests/models/test_config.py +53 -7
- tests/models/utils/test_background_emissions.py +13 -0
- {hestia_earth_models-0.73.7.dist-info → hestia_earth_models-0.74.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.73.7.dist-info → hestia_earth_models-0.74.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.73.7.dist-info → hestia_earth_models-0.74.0.dist-info}/top_level.txt +0 -0
|
@@ -2,40 +2,14 @@ from unittest.mock import patch
|
|
|
2
2
|
import json
|
|
3
3
|
from tests.utils import fixtures_path, fake_new_emission
|
|
4
4
|
|
|
5
|
-
from hestia_earth.models.ipcc2019
|
|
6
|
-
|
|
7
|
-
)
|
|
5
|
+
from hestia_earth.models.ipcc2019 import MODEL
|
|
6
|
+
from hestia_earth.models.ipcc2019.n2OToAirOrganicFertiliserIndirect import TERM_ID, run
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
utils_path = f"hestia_earth.models.{MODEL}.n2OToAir_indirect_emissions_utils"
|
|
10
9
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
# no emissions => no run
|
|
15
|
-
cycle = {'completeness': {'fertiliser': True}, 'emissions': []}
|
|
16
|
-
should_run, *args = _should_run(cycle)
|
|
17
|
-
assert not should_run
|
|
18
|
-
|
|
19
|
-
# with no3 emission => run
|
|
20
|
-
cycle['emissions'] = [
|
|
21
|
-
{
|
|
22
|
-
'term': {'@id': NO3_TERM_ID},
|
|
23
|
-
'value': [100]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
'term': {'@id': NH3_TERM_ID},
|
|
27
|
-
'value': [100]
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
'term': {'@id': NOX_TERM_ID},
|
|
31
|
-
'value': [100]
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
should_run, *args = _should_run(cycle)
|
|
35
|
-
assert should_run is True
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
|
12
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
39
13
|
def test_run(*args):
|
|
40
14
|
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
41
15
|
cycle = json.load(f)
|
|
@@ -47,7 +21,7 @@ def test_run(*args):
|
|
|
47
21
|
assert value == expected
|
|
48
22
|
|
|
49
23
|
|
|
50
|
-
@patch(f"{
|
|
24
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
51
25
|
def test_run_wet(*args):
|
|
52
26
|
with open(f"{fixtures_folder}/ecoClimateZone-wet/cycle.jsonld", encoding='utf-8') as f:
|
|
53
27
|
cycle = json.load(f)
|
|
@@ -59,7 +33,7 @@ def test_run_wet(*args):
|
|
|
59
33
|
assert value == expected
|
|
60
34
|
|
|
61
35
|
|
|
62
|
-
@patch(f"{
|
|
36
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
63
37
|
def test_run_dry(*args):
|
|
64
38
|
with open(f"{fixtures_folder}/ecoClimateZone-dry/cycle.jsonld", encoding='utf-8') as f:
|
|
65
39
|
cycle = json.load(f)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from unittest.mock import patch
|
|
2
|
+
import json
|
|
3
|
+
from tests.utils import fixtures_path, fake_new_emission
|
|
4
|
+
|
|
5
|
+
from hestia_earth.models.ipcc2019 import MODEL
|
|
6
|
+
from hestia_earth.models.ipcc2019.n2OToAirOrganicSoilBurningIndirect import TERM_ID, run
|
|
7
|
+
|
|
8
|
+
utils_path = f"hestia_earth.models.{MODEL}.n2OToAir_indirect_emissions_utils"
|
|
9
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
13
|
+
def test_run(*args):
|
|
14
|
+
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
15
|
+
cycle = json.load(f)
|
|
16
|
+
|
|
17
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
|
18
|
+
expected = json.load(f)
|
|
19
|
+
|
|
20
|
+
value = run(cycle)
|
|
21
|
+
assert value == expected
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
25
|
+
def test_run_wet(*args):
|
|
26
|
+
with open(f"{fixtures_folder}/ecoClimateZone-wet/cycle.jsonld", encoding='utf-8') as f:
|
|
27
|
+
cycle = json.load(f)
|
|
28
|
+
|
|
29
|
+
with open(f"{fixtures_folder}/ecoClimateZone-wet/result.jsonld", encoding='utf-8') as f:
|
|
30
|
+
expected = json.load(f)
|
|
31
|
+
|
|
32
|
+
value = run(cycle)
|
|
33
|
+
assert value == expected
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
37
|
+
def test_run_dry(*args):
|
|
38
|
+
with open(f"{fixtures_folder}/ecoClimateZone-dry/cycle.jsonld", encoding='utf-8') as f:
|
|
39
|
+
cycle = json.load(f)
|
|
40
|
+
|
|
41
|
+
with open(f"{fixtures_folder}/ecoClimateZone-dry/result.jsonld", encoding='utf-8') as f:
|
|
42
|
+
expected = json.load(f)
|
|
43
|
+
|
|
44
|
+
value = run(cycle)
|
|
45
|
+
assert value == expected
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from unittest.mock import patch
|
|
2
|
+
import json
|
|
3
|
+
from tests.utils import fixtures_path, fake_new_emission
|
|
4
|
+
|
|
5
|
+
from hestia_earth.models.ipcc2019 import MODEL
|
|
6
|
+
from hestia_earth.models.ipcc2019.n2OToAirOrganicSoilCultivationIndirect import TERM_ID, run
|
|
7
|
+
|
|
8
|
+
utils_path = f"hestia_earth.models.{MODEL}.n2OToAir_indirect_emissions_utils"
|
|
9
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
13
|
+
def test_run(*args):
|
|
14
|
+
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
15
|
+
cycle = json.load(f)
|
|
16
|
+
|
|
17
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
|
18
|
+
expected = json.load(f)
|
|
19
|
+
|
|
20
|
+
value = run(cycle)
|
|
21
|
+
assert value == expected
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
25
|
+
def test_run_wet(*args):
|
|
26
|
+
with open(f"{fixtures_folder}/ecoClimateZone-wet/cycle.jsonld", encoding='utf-8') as f:
|
|
27
|
+
cycle = json.load(f)
|
|
28
|
+
|
|
29
|
+
with open(f"{fixtures_folder}/ecoClimateZone-wet/result.jsonld", encoding='utf-8') as f:
|
|
30
|
+
expected = json.load(f)
|
|
31
|
+
|
|
32
|
+
value = run(cycle)
|
|
33
|
+
assert value == expected
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@patch(f"{utils_path}._new_emission", side_effect=fake_new_emission)
|
|
37
|
+
def test_run_dry(*args):
|
|
38
|
+
with open(f"{fixtures_folder}/ecoClimateZone-dry/cycle.jsonld", encoding='utf-8') as f:
|
|
39
|
+
cycle = json.load(f)
|
|
40
|
+
|
|
41
|
+
with open(f"{fixtures_folder}/ecoClimateZone-dry/result.jsonld", encoding='utf-8') as f:
|
|
42
|
+
expected = json.load(f)
|
|
43
|
+
|
|
44
|
+
value = run(cycle)
|
|
45
|
+
assert value == expected
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from hestia_earth.models.ipcc2019.n2OToAir_indirect_emissions_utils import _should_run
|
|
2
|
+
from hestia_earth.models.ipcc2019.n2OToAirCropResidueDecompositionIndirect import _EMISSION_IDS
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_should_run():
|
|
6
|
+
# no emissions => no run
|
|
7
|
+
cycle = {'completeness': {'cropResidue': True}, 'emissions': []}
|
|
8
|
+
should_run, *args = _should_run('', _EMISSION_IDS, cycle)
|
|
9
|
+
assert not should_run
|
|
10
|
+
|
|
11
|
+
# with no3 emission => run
|
|
12
|
+
cycle['emissions'] = [
|
|
13
|
+
{
|
|
14
|
+
'term': {'@id': id},
|
|
15
|
+
'value': [100]
|
|
16
|
+
} for id in _EMISSION_IDS
|
|
17
|
+
]
|
|
18
|
+
should_run, *args = _should_run('', _EMISSION_IDS, cycle)
|
|
19
|
+
assert should_run is True
|
|
@@ -11,10 +11,10 @@ def test_list_rasters():
|
|
|
11
11
|
@pytest.mark.parametrize(
|
|
12
12
|
'name,site,expected_len',
|
|
13
13
|
[
|
|
14
|
-
('without values', {},
|
|
15
|
-
('with region', {'region': 'region'},
|
|
16
|
-
('with ecoregion', {'ecoregion': 'ecoregion'},
|
|
17
|
-
('with awareWaterBasinId', {'awareWaterBasinId': 'awareWaterBasinId'},
|
|
14
|
+
('without values', {}, 4),
|
|
15
|
+
('with region', {'region': 'region'}, 3),
|
|
16
|
+
('with ecoregion', {'ecoregion': 'ecoregion'}, 3),
|
|
17
|
+
('with awareWaterBasinId', {'awareWaterBasinId': 'awareWaterBasinId'}, 3),
|
|
18
18
|
]
|
|
19
19
|
)
|
|
20
20
|
def test_list_vectors(name: str, site: dict, expected_len: int):
|
tests/models/test_config.py
CHANGED
|
@@ -4,8 +4,15 @@ import pytest
|
|
|
4
4
|
from hestia_earth.utils.tools import flatten
|
|
5
5
|
|
|
6
6
|
from hestia_earth.models.config import (
|
|
7
|
-
load_config,
|
|
8
|
-
|
|
7
|
+
load_config,
|
|
8
|
+
config_max_stage,
|
|
9
|
+
_is_aggregated_model,
|
|
10
|
+
_remove_aggregated,
|
|
11
|
+
_use_aware_1,
|
|
12
|
+
load_run_config,
|
|
13
|
+
load_trigger_config,
|
|
14
|
+
get_max_stage,
|
|
15
|
+
AWARE_VERSION
|
|
9
16
|
)
|
|
10
17
|
|
|
11
18
|
_aggregated_model = {
|
|
@@ -29,6 +36,27 @@ def test_load_config_error():
|
|
|
29
36
|
load_config(node_type)
|
|
30
37
|
|
|
31
38
|
|
|
39
|
+
def test_load_config_skip_aggregated_models():
|
|
40
|
+
node_type = 'Cycle'
|
|
41
|
+
all_models = load_config(node_type, skip_aggregated_models=False).get('models')
|
|
42
|
+
models_no_aggregated = load_config(node_type, skip_aggregated_models=True).get('models')
|
|
43
|
+
assert all_models != models_no_aggregated
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_load_config_use_aware_v1_site():
|
|
47
|
+
node_type = 'Site'
|
|
48
|
+
v1_models = load_config(node_type, use_aware_version=AWARE_VERSION.V1).get('models')
|
|
49
|
+
v2_models = load_config(node_type, use_aware_version=AWARE_VERSION.V2).get('models')
|
|
50
|
+
assert v1_models != v2_models
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_load_config_use_aware_v1_impact_assessment():
|
|
54
|
+
node_type = 'ImpactAssessment'
|
|
55
|
+
v1_models = load_config(node_type, use_aware_version=AWARE_VERSION.V1).get('models')
|
|
56
|
+
v2_models = load_config(node_type, use_aware_version=AWARE_VERSION.V2).get('models')
|
|
57
|
+
assert v1_models != v2_models
|
|
58
|
+
|
|
59
|
+
|
|
32
60
|
def test_config_max_stage():
|
|
33
61
|
node_type = 'Cycle'
|
|
34
62
|
config = load_config(node_type)
|
|
@@ -48,11 +76,29 @@ def test_remove_aggregated():
|
|
|
48
76
|
assert _remove_aggregated(models) == [[_other_model], _other_model]
|
|
49
77
|
|
|
50
78
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
def test_use_aware_1():
|
|
80
|
+
scarcity_model = {
|
|
81
|
+
"model": "aware2-0",
|
|
82
|
+
"value": "scarcityWeightedWaterUse"
|
|
83
|
+
}
|
|
84
|
+
basinid_model = {
|
|
85
|
+
"model": "geospatialDatabase",
|
|
86
|
+
"value": "awareWaterBasinId"
|
|
87
|
+
}
|
|
88
|
+
models = [
|
|
89
|
+
[scarcity_model],
|
|
90
|
+
basinid_model
|
|
91
|
+
]
|
|
92
|
+
assert _use_aware_1(models) == [
|
|
93
|
+
[{
|
|
94
|
+
"model": "aware",
|
|
95
|
+
"value": "scarcityWeightedWaterUse"
|
|
96
|
+
}],
|
|
97
|
+
{
|
|
98
|
+
"model": "geospatialDatabase",
|
|
99
|
+
"value": "awareWaterBasinId_v1"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
56
102
|
|
|
57
103
|
|
|
58
104
|
def test_load_run_config():
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from hestia_earth.models.utils.background_emissions import _values_from_column
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_values_from_column():
|
|
5
|
+
column = 'landTransformation+landCover[pond]+previousLandCover[permanentCropland]+country[GADM-BRA]'
|
|
6
|
+
assert _values_from_column('', column, '10') == {
|
|
7
|
+
'landTransformation': {
|
|
8
|
+
'value': 10,
|
|
9
|
+
'landCover': 'pond',
|
|
10
|
+
'previousLandCover': 'permanentCropland',
|
|
11
|
+
'country': 'GADM-BRA'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|