pms-nvidia-processor 2.5.0__tar.gz → 2.6.0__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.
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/PKG-INFO +1 -1
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/__init__.py +5 -3
- pms_nvidia_processor-2.6.0/pms_nvidia_processor/processor/cdru_f2/config.py +27 -0
- pms_nvidia_processor-2.6.0/pms_nvidia_processor/processor/cdru_f2/context.py +42 -0
- pms_nvidia_processor-2.6.0/pms_nvidia_processor/processor/cdru_f2/processor.py +160 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/col_en/processor.py +1 -1
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/_patcher_w.py +2 -1
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pyproject.toml +1 -1
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/README.md +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/base/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/base/dependency.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/base/logger.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/base/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/col_en/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/col_en/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/color_resnet/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/color_resnet/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/color_resnet/processor_post.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/color_resnet/processor_pre.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dpir/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dpir/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dpir/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_asm_sr_f3/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_asm_sr_f3/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_asm_sr_f3/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_f3_gloss/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_f3_gloss/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_f3_gloss/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_pc_f2/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_pc_f2/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_deinter_pc_f2/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f3/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f3/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f3/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f5/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f5/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/dru_rbpn_sr_f5/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/fisf/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/fisf/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/fisf/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/gg/config.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/gg/context.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/processor/gg/processor.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/batch.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/caster.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/normalizer/__init__.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/normalizer/_factory.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/normalizer/_multi_normalizer.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/normalizer/_normalization_param.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/normalizer/_single_normalizer.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/__init__.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/_patch_collection.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/_patch_position.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/_patcher.py +0 -0
- {pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/patcher/_patcher_v2.py +0 -0
|
@@ -10,7 +10,8 @@ from .processor.fisf.processor import FISFProcessor
|
|
|
10
10
|
from .processor.color_resnet.processor_pre import COLORRESNETPREProcessor
|
|
11
11
|
from .processor.color_resnet.processor_post import COLORRESNETPOSTProcessor
|
|
12
12
|
from .processor.gg.processor import GGProcessor
|
|
13
|
-
from .processor.col_en.processor import
|
|
13
|
+
from .processor.col_en.processor import COLENProcessor
|
|
14
|
+
from .processor.cdru_f2.processor import CDRUF2Processor
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
__all__: list[str] = [
|
|
@@ -24,7 +25,8 @@ __all__: list[str] = [
|
|
|
24
25
|
"COLORRESNETPREProcessor",
|
|
25
26
|
"COLORRESNETPOSTProcessor",
|
|
26
27
|
"GGProcessor",
|
|
27
|
-
"
|
|
28
|
+
"COLENProcessor",
|
|
29
|
+
"CDRUF2Processor",
|
|
28
30
|
]
|
|
29
31
|
|
|
30
|
-
__version__ = "2.
|
|
32
|
+
__version__ = "2.6.0"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from ..base.config import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CDRUF2Config:
|
|
5
|
+
NUMBER_OF_FRAMES = 2
|
|
6
|
+
NUMBER_OF_INPUT_CHANNELS: int = 3 * NUMBER_OF_FRAMES
|
|
7
|
+
NUMBER_OF_OUTPUT_CHANNELS: int = 3
|
|
8
|
+
UPSCALE_RATIO: int = 2
|
|
9
|
+
PATCH_SIZE = 512
|
|
10
|
+
MAX_BATCH_SIZE = 8
|
|
11
|
+
MIN_BATCH_SIZE = 1
|
|
12
|
+
OPT_BATCH_SIZE = MAX_BATCH_SIZE // 2
|
|
13
|
+
INPUT_OVERLAB_LENGTH = 16
|
|
14
|
+
|
|
15
|
+
PATCHER_CONFIG = PatcherIOConfig(
|
|
16
|
+
patch_size=PATCH_SIZE,
|
|
17
|
+
upscale_ratio=UPSCALE_RATIO,
|
|
18
|
+
number_of_input_channels=NUMBER_OF_INPUT_CHANNELS,
|
|
19
|
+
number_of_output_channels=NUMBER_OF_OUTPUT_CHANNELS,
|
|
20
|
+
input_overlab_length=INPUT_OVERLAB_LENGTH,
|
|
21
|
+
)
|
|
22
|
+
TRT_CONFIG = TRTIOConfig(
|
|
23
|
+
patch_size=PATCH_SIZE,
|
|
24
|
+
upscale_ratio=UPSCALE_RATIO,
|
|
25
|
+
number_of_input_channels=NUMBER_OF_INPUT_CHANNELS,
|
|
26
|
+
number_of_output_channels=NUMBER_OF_OUTPUT_CHANNELS,
|
|
27
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from .config import *
|
|
2
|
+
from ..base.dependency import *
|
|
3
|
+
from ..base.processor import *
|
|
4
|
+
from ...utility import patcher, normalizer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CDRUF2Context:
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
input_vector: np.ndarray,
|
|
12
|
+
input_patcher: patcher.Patcher,
|
|
13
|
+
) -> None:
|
|
14
|
+
config = CDRUF2Config
|
|
15
|
+
|
|
16
|
+
self.input_vector = input_vector
|
|
17
|
+
self.input_pathcer = input_patcher
|
|
18
|
+
self.padded_input_image = patcher.pad_vector(
|
|
19
|
+
vector=self.input_vector,
|
|
20
|
+
overlap_length=config.PATCHER_CONFIG.input_overlab_length,
|
|
21
|
+
mode="edge",
|
|
22
|
+
)
|
|
23
|
+
self.input_patches: list[np.ndarray] = self.input_pathcer.slice(
|
|
24
|
+
self.padded_input_image
|
|
25
|
+
)
|
|
26
|
+
self.output_patches: np.ndarray = np.zeros(
|
|
27
|
+
(
|
|
28
|
+
len(self.input_patches),
|
|
29
|
+
config.PATCH_SIZE * config.UPSCALE_RATIO,
|
|
30
|
+
config.PATCH_SIZE * config.UPSCALE_RATIO,
|
|
31
|
+
3,
|
|
32
|
+
),
|
|
33
|
+
np.float32,
|
|
34
|
+
)
|
|
35
|
+
self.output_vector: np.ndarray = np.zeros(
|
|
36
|
+
(
|
|
37
|
+
input_vector.shape[0] * config.UPSCALE_RATIO,
|
|
38
|
+
input_vector.shape[1] * config.UPSCALE_RATIO,
|
|
39
|
+
config.NUMBER_OF_OUTPUT_CHANNELS,
|
|
40
|
+
),
|
|
41
|
+
np.float32,
|
|
42
|
+
)
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from .config import *
|
|
2
|
+
from .context import *
|
|
3
|
+
from ..base.dependency import *
|
|
4
|
+
from ..base.processor import *
|
|
5
|
+
from ...utility import patcher, normalizer, batch, caster
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _pre_processing(
|
|
9
|
+
batch_input_images: list[np.ndarray],
|
|
10
|
+
input_buffer: np.ndarray,
|
|
11
|
+
) -> None:
|
|
12
|
+
b = len(batch_input_images)
|
|
13
|
+
for batch_idx in range(b):
|
|
14
|
+
image = batch_input_images[batch_idx]
|
|
15
|
+
h, w, c = image.shape
|
|
16
|
+
input_buffer[batch_idx, 0:c, :h, :w] = image.transpose(2, 0, 1)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _post_processing(
|
|
20
|
+
output_buffer: np.ndarray, # BxCxHxW
|
|
21
|
+
output_image: np.ndarray, # BxHxWxC
|
|
22
|
+
) -> None:
|
|
23
|
+
b, h, w, c = output_image.shape
|
|
24
|
+
x = output_buffer[:b, :, :h, :w]
|
|
25
|
+
for i in range(3):
|
|
26
|
+
np.copyto(
|
|
27
|
+
src=x[:b, i, :h, :w],
|
|
28
|
+
dst=output_image[:, :, :, i],
|
|
29
|
+
casting="safe",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@register
|
|
34
|
+
class CDRUF2Processor(NVIDIAProcessorBase[EngineIOData, EngineIOData]):
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
concurrency: int,
|
|
39
|
+
index: int,
|
|
40
|
+
model_path: str,
|
|
41
|
+
device: Literal["auto"] | int = "auto",
|
|
42
|
+
normalization: str = "color-basic",
|
|
43
|
+
):
|
|
44
|
+
# super
|
|
45
|
+
super().__init__(
|
|
46
|
+
concurrency=concurrency,
|
|
47
|
+
index=index,
|
|
48
|
+
model_path=model_path,
|
|
49
|
+
device=device,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
self.config = CDRUF2Config
|
|
53
|
+
self.normalizer = normalizer.NormalizerFactory.create_multi(normalization)
|
|
54
|
+
|
|
55
|
+
async def inference(
|
|
56
|
+
self,
|
|
57
|
+
batch_input_data: list[np.ndarray],
|
|
58
|
+
batch_output_data: np.ndarray,
|
|
59
|
+
):
|
|
60
|
+
session = self.session
|
|
61
|
+
_pre_processing(
|
|
62
|
+
batch_input_images=batch_input_data,
|
|
63
|
+
input_buffer=self.input_buffer,
|
|
64
|
+
)
|
|
65
|
+
session.run()
|
|
66
|
+
_post_processing(
|
|
67
|
+
output_buffer=self.output_buffer,
|
|
68
|
+
output_image=batch_output_data,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
async def _run(self, input_data: EngineIOData) -> EngineIOData:
|
|
72
|
+
max_batch_size = self.io_shapes["input"][0][0]
|
|
73
|
+
input_vector = self.caster.cast(input_data.frame)
|
|
74
|
+
[
|
|
75
|
+
self.normalizer.normalize(input_vector[:, :, i * 3 : (i + 1) * 3], 2)
|
|
76
|
+
for i in range(self.config.NUMBER_OF_FRAMES)
|
|
77
|
+
]
|
|
78
|
+
context = CDRUF2Context(input_vector, self.patcher)
|
|
79
|
+
# batch inference
|
|
80
|
+
for batch_input_patches, batch_output_patches in zip(
|
|
81
|
+
batch.BatchTool.batch_list(context.input_patches, max_batch_size),
|
|
82
|
+
batch.BatchTool.batch_vector(context.output_patches, max_batch_size),
|
|
83
|
+
):
|
|
84
|
+
await self.inference(
|
|
85
|
+
batch_input_data=batch_input_patches,
|
|
86
|
+
batch_output_data=batch_output_patches,
|
|
87
|
+
)
|
|
88
|
+
self.patcher.merge(
|
|
89
|
+
output_vector=context.output_vector,
|
|
90
|
+
patches=context.output_patches,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
self.normalizer.denormalize(context.output_vector, 2)
|
|
94
|
+
return EngineIOData(
|
|
95
|
+
frame_id=input_data.frame_id,
|
|
96
|
+
frame=self.caster.uncast(context.output_vector),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def _ready_processor(self) -> bool:
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
def _bind_io(self, input_data: EngineIOData):
|
|
103
|
+
self.caster = caster.Caster(input_data.frame)
|
|
104
|
+
patcher_config = self.config.PATCHER_CONFIG
|
|
105
|
+
trt_config = self.config.TRT_CONFIG
|
|
106
|
+
|
|
107
|
+
input_image: np.ndarray = input_data.frame # type: ignore
|
|
108
|
+
padded_input_image = patcher.pad_vector(
|
|
109
|
+
input_image,
|
|
110
|
+
overlap_length=patcher_config.input_overlab_length,
|
|
111
|
+
)
|
|
112
|
+
output_image: np.ndarray = np.zeros(
|
|
113
|
+
(
|
|
114
|
+
input_image.shape[0] * self.config.UPSCALE_RATIO,
|
|
115
|
+
input_image.shape[1] * self.config.UPSCALE_RATIO,
|
|
116
|
+
self.config.NUMBER_OF_OUTPUT_CHANNELS,
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
self.patcher = patcher.Patcher(
|
|
120
|
+
**patcher_config.build_patcher_params(
|
|
121
|
+
input_vector=padded_input_image,
|
|
122
|
+
output_vector=output_image,
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
n_patches = len(self.patcher.slice(input_vector=padded_input_image))
|
|
126
|
+
|
|
127
|
+
# set io shape
|
|
128
|
+
self.batch_size = min(n_patches, self.config.MAX_BATCH_SIZE)
|
|
129
|
+
self.io_shapes = {
|
|
130
|
+
"input": (
|
|
131
|
+
[self.batch_size, *trt_config.input_shape],
|
|
132
|
+
np.float32,
|
|
133
|
+
),
|
|
134
|
+
"output": (
|
|
135
|
+
[self.batch_size, *trt_config.output_shape],
|
|
136
|
+
np.float32,
|
|
137
|
+
),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# init trt engine
|
|
141
|
+
self.initialize_trt_session(
|
|
142
|
+
required_batch_size=self.batch_size,
|
|
143
|
+
io_shape=self.io_shapes,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# set io buffer
|
|
147
|
+
self.input_buffer = self.session._input_bindings[0].host_buffer.reshape(
|
|
148
|
+
self.io_shapes["input"][0]
|
|
149
|
+
)
|
|
150
|
+
self.output_buffer = self.session._output_bindings[0].host_buffer.reshape(
|
|
151
|
+
*self.io_shapes["output"][0]
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
return True
|
|
155
|
+
|
|
156
|
+
def _get_live(self) -> bool:
|
|
157
|
+
return True
|
|
158
|
+
|
|
159
|
+
def _get_concurrency(self) -> int:
|
|
160
|
+
return self._concurrency
|
|
@@ -94,7 +94,8 @@ class PatcherW:
|
|
|
94
94
|
output_vector: np.ndarray,
|
|
95
95
|
scale: int = 1,
|
|
96
96
|
):
|
|
97
|
-
w_vector = np.ones((*output_vector.shape[:-1], 1), np.float32) * (1e-8)
|
|
97
|
+
# w_vector = np.ones((*output_vector.shape[:-1], 1), np.float32) * (1e-8)
|
|
98
|
+
w_vector = np.zeros((*output_vector.shape[:-1], 1), np.float32)
|
|
98
99
|
for (ys, xs), patch in zip(self._patch_pos_list, patches, strict=True):
|
|
99
100
|
ys_out = slice(ys.start * scale, ys.stop * scale)
|
|
100
101
|
xs_out = slice(xs.start * scale, xs.stop * scale)
|
|
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
|
{pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/batch.py
RENAMED
|
File without changes
|
{pms_nvidia_processor-2.5.0 → pms_nvidia_processor-2.6.0}/pms_nvidia_processor/utility/caster.py
RENAMED
|
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
|