interactive-pipe 0.8.4__tar.gz → 0.8.5__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.
- {interactive_pipe-0.8.4/src/interactive_pipe.egg-info → interactive_pipe-0.8.5}/PKG-INFO +2 -2
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/pyproject.toml +1 -1
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/readme.md +1 -1
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/__init__.py +1 -1
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/gradio_gui.py +4 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/mpl_window.py +5 -2
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/nb_control.py +18 -4
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/nb_gui.py +1 -1
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/qt_gui.py +6 -1
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/pipeline_decorator.py +8 -2
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5/src/interactive_pipe.egg-info}/PKG-INFO +2 -2
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/LICENSE +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/setup.cfg +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/__init__.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/cache.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/engine.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/filter.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/graph.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/pipeline.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/core/signature.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/__init__.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/audio.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/curves.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/data.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/image.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/parameters.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/__init__.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/gradio_control.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/gui.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/mpl_control.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/mpl_gui.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/qt_control.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/window.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/headless/__init__.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/headless/control.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/headless/keyboard.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/headless/pipeline.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/__init__.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/_private.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/choose_backend.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/control_abbreviation.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/filter_decorator.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/keyword_args_analyzer.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/thirdparty/images_openai_api.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/thirdparty/music_spotify.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/SOURCES.txt +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/dependency_links.txt +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/requires.txt +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/top_level.txt +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_cache.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_control_abbreviations.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_controller.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_core.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_curves.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_decorator.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_engine.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_filter.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_headless.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_image.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_parameters.py +0 -0
- {interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/test/test_recorder.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: interactive_pipe
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.5
|
|
4
4
|
Summary: Library to create flexible interactive image processing pipelines and automatically add a graphical user interface without knowing anything about GUI coding!
|
|
5
5
|
Author-email: Balthazar Neveu <balthazarneveu@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/balthazarneveu/interactive_pipe
|
|
@@ -106,7 +106,7 @@ pip install -e ".[full]"
|
|
|
106
106
|
|
|
107
107
|
## :scroll: Features
|
|
108
108
|
|
|
109
|
-
**Version 0.8.
|
|
109
|
+
**Version 0.8.5**
|
|
110
110
|
- Modular multi-image processing filters
|
|
111
111
|
- Declarative: Easily make graphical user interface without having to learn anything about pyQt or matplotlib
|
|
112
112
|
- Support in jupyter notebooks
|
|
@@ -62,7 +62,7 @@ pip install -e ".[full]"
|
|
|
62
62
|
|
|
63
63
|
## :scroll: Features
|
|
64
64
|
|
|
65
|
-
**Version 0.8.
|
|
65
|
+
**Version 0.8.5**
|
|
66
66
|
- Modular multi-image processing filters
|
|
67
67
|
- Declarative: Easily make graphical user interface without having to learn anything about pyQt or matplotlib
|
|
68
68
|
- Support in jupyter notebooks
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.8.
|
|
1
|
+
__version__ = "0.8.5"
|
|
2
2
|
from interactive_pipe.helper.pipeline_decorator import pipeline, interactive_pipeline
|
|
3
3
|
from interactive_pipe.headless.control import Control, CircularControl, TextPrompt
|
|
4
4
|
from interactive_pipe.data_objects.curves import Curve, SingleCurve
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/gradio_gui.py
RENAMED
|
@@ -82,6 +82,8 @@ class InteractivePipeGradio(InteractivePipeGUI):
|
|
|
82
82
|
out_list_gradio_containers.append(gr.Plot(label=title))
|
|
83
83
|
self.window.image_canvas[idx][idy]["type"] = "curve"
|
|
84
84
|
# @TODO: https://github.com/balthazarneveu/interactive_pipe/issues/50 support audio!
|
|
85
|
+
elif isinstance(out_list[idx][idy], str):
|
|
86
|
+
out_list_gradio_containers.append(gr.Textbox(label=title))
|
|
85
87
|
else:
|
|
86
88
|
raise NotImplementedError(
|
|
87
89
|
f"output type {type(out_list[idx][idy])} not supported")
|
|
@@ -135,6 +137,8 @@ class MainWindow(InteractivePipeWindow):
|
|
|
135
137
|
else:
|
|
136
138
|
logging.debug(f"CONVERTING IMAGE {idx} {idy}")
|
|
137
139
|
flat_out.append(self.convert_image(out[idx][idy]))
|
|
140
|
+
elif isinstance(out[idx][idy], str):
|
|
141
|
+
flat_out.append(out[idx][idy])
|
|
138
142
|
else:
|
|
139
143
|
raise NotImplementedError(
|
|
140
144
|
f"output type {type(out[idx][idy])} not suported")
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/mpl_window.py
RENAMED
|
@@ -6,7 +6,7 @@ from interactive_pipe.data_objects.curves import Curve
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class MatplotlibWindow(InteractivePipeWindow):
|
|
9
|
-
def __init__(self, controls=[], name="", pipeline=None, size=None, style: str = None, rc_params=None,
|
|
9
|
+
def __init__(self, controls=[], name="", pipeline=None, size=None, style: str = None, rc_params=None, **unused_kwargs):
|
|
10
10
|
"""
|
|
11
11
|
style: dark_background, seaborn-v0_8-dark
|
|
12
12
|
https://matplotlib.org/stable/gallery/style_sheets/style_sheets_reference.html
|
|
@@ -26,7 +26,6 @@ class MatplotlibWindow(InteractivePipeWindow):
|
|
|
26
26
|
if rc_params is not None:
|
|
27
27
|
for key, val in rc_params.items():
|
|
28
28
|
plt.rcParams[key] = val
|
|
29
|
-
self.markdown_description = markdown_description # won't be used!
|
|
30
29
|
|
|
31
30
|
def add_image_placeholder(self, row, col):
|
|
32
31
|
nrows, ncols = np.array(self.image_canvas).shape
|
|
@@ -63,6 +62,8 @@ class MatplotlibWindow(InteractivePipeWindow):
|
|
|
63
62
|
data.set_ydata(img)
|
|
64
63
|
elif isinstance(img, Curve):
|
|
65
64
|
img.update_plot(data, ax=ax_dict["ax"])
|
|
65
|
+
elif isinstance(img, str):
|
|
66
|
+
data.set_text(img)
|
|
66
67
|
else:
|
|
67
68
|
if isinstance(img, np.ndarray):
|
|
68
69
|
if len(img.shape) > 1:
|
|
@@ -71,6 +72,8 @@ class MatplotlibWindow(InteractivePipeWindow):
|
|
|
71
72
|
ax_dict["data"] = Curve([img]).create_plot(ax=ax_dict["ax"])
|
|
72
73
|
elif isinstance(img, Curve):
|
|
73
74
|
ax_dict["data"] = img.create_plot(ax=ax_dict["ax"])
|
|
75
|
+
elif isinstance(img, str):
|
|
76
|
+
ax_dict["data"] = ax_dict["ax"].text(0.5, 0.5, img, ha='center', va='center', fontsize=10)
|
|
74
77
|
if not (isinstance(img, Curve) and img.data["title"] is not None):
|
|
75
78
|
self.update_style(ax_dict["ax"], style=current_style)
|
|
76
79
|
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/nb_control.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from ipywidgets import Dropdown, FloatSlider, IntSlider, Checkbox, Layout
|
|
1
|
+
from ipywidgets import Dropdown, FloatSlider, IntSlider, Checkbox, Layout, Text
|
|
2
2
|
from interactive_pipe.headless.control import Control
|
|
3
3
|
import logging
|
|
4
4
|
|
|
@@ -55,9 +55,23 @@ class DialogNotebookControl(BaseControl):
|
|
|
55
55
|
|
|
56
56
|
def create(self):
|
|
57
57
|
options = self.ctrl.value_range
|
|
58
|
-
|
|
58
|
+
dropdown = Dropdown(
|
|
59
59
|
options=options, description=self.name, layout=self.layout)
|
|
60
|
-
return
|
|
60
|
+
return dropdown
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PromptNotebookControl(BaseControl):
|
|
64
|
+
def check_control_type(self):
|
|
65
|
+
assert self.ctrl._type == str
|
|
66
|
+
assert self.ctrl.value_range is None
|
|
67
|
+
|
|
68
|
+
def create(self):
|
|
69
|
+
text_box = Text(
|
|
70
|
+
value=self.ctrl.value,
|
|
71
|
+
description=self.name,
|
|
72
|
+
layout=self.layout
|
|
73
|
+
)
|
|
74
|
+
return text_box
|
|
61
75
|
|
|
62
76
|
|
|
63
77
|
class ControlFactory:
|
|
@@ -69,7 +83,7 @@ class ControlFactory:
|
|
|
69
83
|
bool: BoolCheckButtonNotebookControl,
|
|
70
84
|
int: IntSliderNotebookControl,
|
|
71
85
|
float: FloatSliderNotebookControl,
|
|
72
|
-
str: DialogNotebookControl,
|
|
86
|
+
str: PromptNotebookControl if control.value_range is None else DialogNotebookControl,
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
if control_type not in control_class_map:
|
|
@@ -24,7 +24,7 @@ class InteractivePipeJupyter(InteractivePipeGUI):
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class MainWindow(MatplotlibWindow):
|
|
27
|
-
def __init__(self, controls=[], name="", pipeline=None, size: Optional[Union[int, Tuple[int, int]]] = None, style: str = None, rc_params=None):
|
|
27
|
+
def __init__(self, controls=[], name="", pipeline=None, size: Optional[Union[int, Tuple[int, int]]] = None, style: str = None, rc_params=None, **unused_kwargs):
|
|
28
28
|
if size is not None and isinstance(size, int):
|
|
29
29
|
size = (size, size)
|
|
30
30
|
assert size is None or isinstance(size, tuple) or isinstance(
|
|
@@ -469,6 +469,9 @@ class MainWindow(QWidget, InteractivePipeWindow):
|
|
|
469
469
|
pixmap = QPixmap.fromImage(image)
|
|
470
470
|
image_label = self.image_canvas[row][col]["image"]
|
|
471
471
|
image_label.setPixmap(pixmap)
|
|
472
|
+
elif isinstance(image_array_original, str):
|
|
473
|
+
txt_label = self.image_canvas[row][col]["image"]
|
|
474
|
+
txt_label.setText(image_array_original)
|
|
472
475
|
if not isinstance(image_array_original, np.ndarray):
|
|
473
476
|
image_array = image_array_original
|
|
474
477
|
if MPL_SUPPORT and isinstance(image_array, Curve):
|
|
@@ -487,7 +490,9 @@ class MainWindow(QWidget, InteractivePipeWindow):
|
|
|
487
490
|
else:
|
|
488
491
|
image_array.update_plot(plt_obj, ax=ax)
|
|
489
492
|
ax.figure.canvas.draw()
|
|
490
|
-
|
|
493
|
+
elif isinstance(image_array, str):
|
|
494
|
+
txt_label = self.image_canvas[row][col]["image"]
|
|
495
|
+
txt_label.setText(image_array)
|
|
491
496
|
text_label = self.image_canvas[row][col]["title"]
|
|
492
497
|
text_label.setText(self.get_current_style(row, col).get("title", ""))
|
|
493
498
|
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/pipeline_decorator.py
RENAMED
|
@@ -20,7 +20,9 @@ def interactive_pipeline(
|
|
|
20
20
|
global_state: Optional[dict] = None, # alias for global_params
|
|
21
21
|
global_context: Optional[dict] = None, # alias for global_params
|
|
22
22
|
context: Optional[dict] = None, # alias for global_params
|
|
23
|
-
state: Optional[dict] = None, # alias for global_params
|
|
23
|
+
state: Optional[dict] = None, # alias for global_params,
|
|
24
|
+
markdown_description: Optional[str] = None,
|
|
25
|
+
name: Optional[str] = None,
|
|
24
26
|
**kwargs_gui,
|
|
25
27
|
) -> Union[HeadlessPipeline, InteractivePipeGUI]:
|
|
26
28
|
"""@interactive_pipeline
|
|
@@ -46,7 +48,11 @@ def interactive_pipeline(
|
|
|
46
48
|
else:
|
|
47
49
|
InteractivePipeGui = get_interactive_pipeline_class(gui)
|
|
48
50
|
gui_pipeline = InteractivePipeGui(
|
|
49
|
-
pipeline=headless_pipeline,
|
|
51
|
+
pipeline=headless_pipeline,
|
|
52
|
+
markdown_description=markdown_description,
|
|
53
|
+
name=name if name is not None else pipeline_function.__name__,
|
|
54
|
+
**kwargs_gui
|
|
55
|
+
)
|
|
50
56
|
|
|
51
57
|
@ functools.wraps(pipeline_function)
|
|
52
58
|
def inner(*args, **kwargs):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: interactive_pipe
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.5
|
|
4
4
|
Summary: Library to create flexible interactive image processing pipelines and automatically add a graphical user interface without knowing anything about GUI coding!
|
|
5
5
|
Author-email: Balthazar Neveu <balthazarneveu@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/balthazarneveu/interactive_pipe
|
|
@@ -106,7 +106,7 @@ pip install -e ".[full]"
|
|
|
106
106
|
|
|
107
107
|
## :scroll: Features
|
|
108
108
|
|
|
109
|
-
**Version 0.8.
|
|
109
|
+
**Version 0.8.5**
|
|
110
110
|
- Modular multi-image processing filters
|
|
111
111
|
- Declarative: Easily make graphical user interface without having to learn anything about pyQt or matplotlib
|
|
112
112
|
- Support in jupyter notebooks
|
|
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
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/__init__.py
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/audio.py
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/curves.py
RENAMED
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/image.py
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/data_objects/parameters.py
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/__init__.py
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/gradio_control.py
RENAMED
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/mpl_control.py
RENAMED
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/graphical/qt_control.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
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/choose_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/helper/filter_decorator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe/thirdparty/music_spotify.py
RENAMED
|
File without changes
|
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/requires.txt
RENAMED
|
File without changes
|
{interactive_pipe-0.8.4 → interactive_pipe-0.8.5}/src/interactive_pipe.egg-info/top_level.txt
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
|
|
File without changes
|
|
File without changes
|