python-negar 1.2.13__tar.gz → 1.3__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.
- {python_negar-1.2.13 → python_negar-1.3}/Changelog.txt +9 -0
- {python_negar-1.2.13 → python_negar-1.3}/PKG-INFO +2 -2
- {python_negar-1.2.13 → python_negar-1.3}/negar/constants.py +1 -1
- {python_negar-1.2.13 → python_negar-1.3}/negar/data/immutable.words +36 -6
- {python_negar-1.2.13 → python_negar-1.3}/negar/virastar.py +33 -29
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/PKG-INFO +2 -2
- {python_negar-1.2.13 → python_negar-1.3}/setup.py +1 -1
- {python_negar-1.2.13 → python_negar-1.3}/tests/test_unittest.py +10 -0
- {python_negar-1.2.13 → python_negar-1.3}/AUTHORS +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/LICENSE +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/MANIFEST.in +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/README.md +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/negar/__init__.py +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/negar/gui.py +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/SOURCES.txt +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/dependency_links.txt +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/entry_points.txt +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/requires.txt +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/python_negar.egg-info/top_level.txt +0 -0
- {python_negar-1.2.13 → python_negar-1.3}/setup.cfg +0 -0
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
1.3 - 2025-01-01
|
|
2
|
+
-- Enhanced the handling of immutable words to achieve greater accuracy in results.
|
|
3
|
+
|
|
4
|
+
1.2.15 - 2024-12-31
|
|
5
|
+
-- Fixed issue #24 and added several new immutable words.
|
|
6
|
+
|
|
7
|
+
1.2.14 - 2024-12-30
|
|
8
|
+
-- Fixed issue with prefix spacing in cases like "mi + space + ZWNJ + <word>".
|
|
9
|
+
|
|
1
10
|
1.2.13 - 2024-12-26
|
|
2
11
|
-- Fixed issue with quotes after a dot where no space was allowed in between.
|
|
3
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-negar
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Negar is a spell corrector and Persian text editor
|
|
5
5
|
Home-page: http://github.com/shahinism/python-negar
|
|
6
6
|
Author: Shahin Azad
|
|
@@ -13,7 +13,7 @@ Classifier: Environment :: Console
|
|
|
13
13
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
14
|
Classifier: Programming Language :: Python
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
License-File: AUTHORS
|
|
@@ -92,15 +92,18 @@
|
|
|
92
92
|
الشان
|
|
93
93
|
الکتر
|
|
94
94
|
الکترومتر
|
|
95
|
+
الکترومتری
|
|
95
96
|
الکتری
|
|
96
97
|
الماسنشان
|
|
97
98
|
المان
|
|
98
99
|
الها
|
|
99
100
|
امابیها
|
|
101
|
+
امابیها
|
|
100
102
|
امفیتآتر
|
|
101
103
|
امنیتتان
|
|
102
104
|
امها
|
|
103
105
|
انتها
|
|
106
|
+
انتهایی
|
|
104
107
|
انرژیدرمان
|
|
105
108
|
انساندوستان
|
|
106
109
|
انساندوستان
|
|
@@ -196,8 +199,11 @@
|
|
|
196
199
|
بنگستان
|
|
197
200
|
بنها
|
|
198
201
|
بها
|
|
202
|
+
بهائیت
|
|
199
203
|
بهارستان
|
|
200
204
|
بهارستان
|
|
205
|
+
بهایی
|
|
206
|
+
بهاییت
|
|
201
207
|
بهبها
|
|
202
208
|
بهتان
|
|
203
209
|
بهتان
|
|
@@ -205,6 +211,7 @@
|
|
|
205
211
|
بهتری
|
|
206
212
|
بهترین
|
|
207
213
|
بهترین
|
|
214
|
+
بهتنهایی
|
|
208
215
|
بهمان
|
|
209
216
|
بوتان
|
|
210
217
|
بودنتان
|
|
@@ -254,6 +261,7 @@
|
|
|
254
261
|
بیازمایید
|
|
255
262
|
بیاسایند
|
|
256
263
|
بیاشتها
|
|
264
|
+
بیاشتهایی
|
|
257
265
|
بیافتد
|
|
258
266
|
بیافرید
|
|
259
267
|
بیافریند
|
|
@@ -324,9 +332,11 @@
|
|
|
324
332
|
بیایی
|
|
325
333
|
بیایید
|
|
326
334
|
بیاییم
|
|
335
|
+
بیاییم
|
|
327
336
|
بیبسکو
|
|
328
337
|
بیبل
|
|
329
338
|
بیبها
|
|
339
|
+
بیبهایی
|
|
330
340
|
بیت
|
|
331
341
|
بیتالتکمهها
|
|
332
342
|
بیتالحکمه
|
|
@@ -379,6 +389,7 @@
|
|
|
379
389
|
بیدارتر
|
|
380
390
|
بیدارترین
|
|
381
391
|
بیداردل
|
|
392
|
+
بیداردل
|
|
382
393
|
بیدارشان
|
|
383
394
|
بیدارشدگی
|
|
384
395
|
بیدارگری
|
|
@@ -464,11 +475,14 @@
|
|
|
464
475
|
بیستمیلیونی
|
|
465
476
|
بیستمین
|
|
466
477
|
بیستوپنجم
|
|
478
|
+
بیستوپنجم
|
|
467
479
|
بیستوچهارساعته
|
|
480
|
+
بیستوچهارساعته
|
|
468
481
|
بیستودوم
|
|
469
482
|
بیستوسوم
|
|
470
483
|
بیستون
|
|
471
484
|
بیستوهفتم
|
|
485
|
+
بیستوهفتم
|
|
472
486
|
بیستویکم
|
|
473
487
|
بیسرنامه
|
|
474
488
|
بیسکای
|
|
@@ -540,6 +554,7 @@
|
|
|
540
554
|
بیکار
|
|
541
555
|
بیکاران
|
|
542
556
|
بیکارشده
|
|
557
|
+
بیکارشده
|
|
543
558
|
بیکارگی
|
|
544
559
|
بیکارند
|
|
545
560
|
بیکاره
|
|
@@ -659,6 +674,7 @@
|
|
|
659
674
|
بین
|
|
660
675
|
بینا
|
|
661
676
|
بینابینی
|
|
677
|
+
بینابینی
|
|
662
678
|
بینات
|
|
663
679
|
بیناتری
|
|
664
680
|
بینارداغ
|
|
@@ -852,7 +868,9 @@
|
|
|
852
868
|
تفتان
|
|
853
869
|
تکلیفتان
|
|
854
870
|
تکوتنها
|
|
871
|
+
تکوتنها
|
|
855
872
|
تکوتنهایی
|
|
873
|
+
تکوتنهایی
|
|
856
874
|
تلاشتان
|
|
857
875
|
تلویزیونتان
|
|
858
876
|
تماستان
|
|
@@ -864,6 +882,7 @@
|
|
|
864
882
|
تنها
|
|
865
883
|
تنهای
|
|
866
884
|
تنهایی
|
|
885
|
+
تنهایی
|
|
867
886
|
تنورهکشان
|
|
868
887
|
تهیدستان
|
|
869
888
|
توتستان
|
|
@@ -1039,6 +1058,7 @@
|
|
|
1039
1058
|
سینمادوستان
|
|
1040
1059
|
سینمادوستان
|
|
1041
1060
|
شاعرصفتان
|
|
1061
|
+
شاعرصفتان
|
|
1042
1062
|
شانگها
|
|
1043
1063
|
شبستان
|
|
1044
1064
|
شبستر
|
|
@@ -1055,6 +1075,7 @@
|
|
|
1055
1075
|
شورستان
|
|
1056
1076
|
شوشتر
|
|
1057
1077
|
شوشتری
|
|
1078
|
+
شیخبهایی
|
|
1058
1079
|
شیربها
|
|
1059
1080
|
صربستان
|
|
1060
1081
|
صفرکیلومتر
|
|
@@ -1150,10 +1171,12 @@
|
|
|
1150
1171
|
کودکستان
|
|
1151
1172
|
کوهستان
|
|
1152
1173
|
کیلومتر
|
|
1174
|
+
کیلومتری
|
|
1153
1175
|
کیها
|
|
1154
1176
|
گالوانومتر
|
|
1155
1177
|
گانگستر
|
|
1156
1178
|
گرانبها
|
|
1179
|
+
گرانبهایی
|
|
1157
1180
|
گرجستان
|
|
1158
1181
|
گردافشان
|
|
1159
1182
|
گردهافشان
|
|
@@ -1180,6 +1203,8 @@
|
|
|
1180
1203
|
لیموعمان
|
|
1181
1204
|
ماتریس
|
|
1182
1205
|
متان
|
|
1206
|
+
متر
|
|
1207
|
+
متری
|
|
1183
1208
|
متشابها
|
|
1184
1209
|
متکلمان
|
|
1185
1210
|
متها
|
|
@@ -1333,7 +1358,7 @@
|
|
|
1333
1358
|
میخی
|
|
1334
1359
|
مید
|
|
1335
1360
|
میداس
|
|
1336
|
-
|
|
1361
|
+
میداستار
|
|
1337
1362
|
میدان
|
|
1338
1363
|
میدانا
|
|
1339
1364
|
میدانچای
|
|
@@ -1383,7 +1408,7 @@
|
|
|
1383
1408
|
میرباقری
|
|
1384
1409
|
میرپنج
|
|
1385
1410
|
میرجاوه
|
|
1386
|
-
|
|
1411
|
+
میرجلیل
|
|
1387
1412
|
میرحاجی
|
|
1388
1413
|
میرحسین
|
|
1389
1414
|
میرحسینی
|
|
@@ -1397,14 +1422,15 @@
|
|
|
1397
1422
|
میرر
|
|
1398
1423
|
میرزا
|
|
1399
1424
|
میرزاآقابیک
|
|
1400
|
-
|
|
1425
|
+
میرزاابوطالبی
|
|
1401
1426
|
میرزابی
|
|
1402
1427
|
میرزابیگی
|
|
1403
|
-
|
|
1428
|
+
میرزاده
|
|
1404
1429
|
میرزاسالاریها
|
|
1430
|
+
میرزاسالاریها
|
|
1405
1431
|
میرزاغفور
|
|
1406
1432
|
میرزاغوثی
|
|
1407
|
-
|
|
1433
|
+
میرزانظری
|
|
1408
1434
|
میرزای
|
|
1409
1435
|
میرزایی
|
|
1410
1436
|
میرزمانی
|
|
@@ -1626,6 +1652,7 @@
|
|
|
1626
1652
|
میلیارددلاری
|
|
1627
1653
|
میلیاردر
|
|
1628
1654
|
میلیاردریالی
|
|
1655
|
+
میلیاردریالی
|
|
1629
1656
|
میلیاردم
|
|
1630
1657
|
میلیاردمین
|
|
1631
1658
|
میلیاردها
|
|
@@ -1757,6 +1784,7 @@
|
|
|
1757
1784
|
میهنه
|
|
1758
1785
|
میهنی
|
|
1759
1786
|
میهوی
|
|
1787
|
+
میهوی
|
|
1760
1788
|
میوت
|
|
1761
1789
|
میور
|
|
1762
1790
|
میوسن
|
|
@@ -1809,9 +1837,10 @@
|
|
|
1809
1837
|
نهاد
|
|
1810
1838
|
نهالستان
|
|
1811
1839
|
نهایت
|
|
1840
|
+
نهایی
|
|
1812
1841
|
نهتنها
|
|
1813
1842
|
نوبها
|
|
1814
|
-
|
|
1843
|
+
نودولتان
|
|
1815
1844
|
نورافشان
|
|
1816
1845
|
نوعدوستان
|
|
1817
1846
|
نونها
|
|
@@ -1822,6 +1851,7 @@
|
|
|
1822
1851
|
نیشتر
|
|
1823
1852
|
نیمبها
|
|
1824
1853
|
نیمهنها
|
|
1854
|
+
نیمهنهایی
|
|
1825
1855
|
هزاردستان
|
|
1826
1856
|
هستان
|
|
1827
1857
|
هشتر
|
|
@@ -57,7 +57,7 @@ class PersianEditor:
|
|
|
57
57
|
self.cleanup()
|
|
58
58
|
|
|
59
59
|
def cleanup(self):
|
|
60
|
-
self.
|
|
60
|
+
self.__handle_urls__(State.save)
|
|
61
61
|
# fix punctuation spaces at first
|
|
62
62
|
# : ; , ! ? and their Persian counterparts should have one space after and no space before
|
|
63
63
|
# An exception is triple dots, which should be handled first
|
|
@@ -77,10 +77,12 @@ class PersianEditor:
|
|
|
77
77
|
self.char_validator() if self._fix_misc_non_persian_chars else None
|
|
78
78
|
self.fix_arabic_numbers() if self._fix_arabic_numbers else None
|
|
79
79
|
self.fix_english_numbers() if self._fix_english_numbers else None
|
|
80
|
+
self.__handle_immutable_words__(State.save)
|
|
80
81
|
self.fix_prefix_spacing() if self._fix_prefix_spacing else None
|
|
81
82
|
self.fix_prefix_separate() if self._fix_prefix_separate else None
|
|
82
83
|
self.fix_suffix_spacing() if self._fix_suffix_spacing else None
|
|
83
84
|
self.fix_suffix_separate() if self._fix_suffix_separate else None
|
|
85
|
+
self.__handle_immutable_words__(State.restore)
|
|
84
86
|
self.fix_spacing_for_braces_and_quotes() \
|
|
85
87
|
if self._fix_spacing_for_braces_and_quotes else None
|
|
86
88
|
self.cleanup_redundant_zwnj()
|
|
@@ -92,7 +94,7 @@ class PersianEditor:
|
|
|
92
94
|
)
|
|
93
95
|
if self._trim_leading_trailing_whitespaces:
|
|
94
96
|
self.text = "\n".join([line.strip() for line in self.text.split("\n")])
|
|
95
|
-
self.
|
|
97
|
+
self.__handle_urls__(State.restore)
|
|
96
98
|
return self.text
|
|
97
99
|
|
|
98
100
|
def __repr__(self):
|
|
@@ -100,7 +102,7 @@ class PersianEditor:
|
|
|
100
102
|
|
|
101
103
|
__str__ = __repr__
|
|
102
104
|
|
|
103
|
-
def
|
|
105
|
+
def __handle_urls__(self, state):
|
|
104
106
|
"""Remove URLs and putting them back at the end of the process."""
|
|
105
107
|
if state == State.save:
|
|
106
108
|
self.urls = list(set(re.findall(URLREGX, self.text, re.M | re.I | re.X)))
|
|
@@ -111,6 +113,19 @@ class PersianEditor:
|
|
|
111
113
|
for i, url in enumerate(self.urls):
|
|
112
114
|
self.text = re.sub(f"__URL__#{i}__", url, self.text)
|
|
113
115
|
|
|
116
|
+
def __handle_immutable_words__(self, state):
|
|
117
|
+
"""Remove URLs and putting them back at the end of the process."""
|
|
118
|
+
if state == State.save:
|
|
119
|
+
self.immutable_words = {}
|
|
120
|
+
words = self.text.split()
|
|
121
|
+
for i, word in enumerate(words):
|
|
122
|
+
if (word:=word.strip()) in ImmutableWords.get():
|
|
123
|
+
self.immutable_words[i] = word
|
|
124
|
+
self.text = regex.sub(rf"\b{word}\b", rf"__IMM__#{i}__", self.text)
|
|
125
|
+
if state == State.restore:
|
|
126
|
+
for imm_key, imm_word in self.immutable_words.items():
|
|
127
|
+
self.text = re.sub(f"__IMM__#{imm_key}__", imm_word, self.text)
|
|
128
|
+
|
|
114
129
|
def fix_dashes(self):
|
|
115
130
|
"""Replace double and triple dashes with `ndash` and `mdash`, respectively."""
|
|
116
131
|
self.text = re.sub(r"-{3}", r"—", self.text)
|
|
@@ -178,9 +193,9 @@ class PersianEditor:
|
|
|
178
193
|
|
|
179
194
|
def fix_prefix_spacing(self):
|
|
180
195
|
"""Put ZWNJ between a word and its prefix (mi* nemi* bi* na*)."""
|
|
181
|
-
self.text = re.sub(r"\b(بی|نا)
|
|
196
|
+
self.text = re.sub(r"\b(بی|نا)([\s|]+)(?!(می)\b)", r"\1", self.text)
|
|
182
197
|
# the following case is for the mi(n.) and nemi(n.)
|
|
183
|
-
self.text = re.sub(rf"\b(ن?می)
|
|
198
|
+
self.text = re.sub(rf"\b(ن?می)([\s|]+)(?!(.|{self._prepositions})\b)", r"\1", self.text)
|
|
184
199
|
|
|
185
200
|
def fix_prefix_separate(self):
|
|
186
201
|
"""Put ZWNJ between a word and its prefix (mi* nemi* bi*)."""
|
|
@@ -193,22 +208,8 @@ class PersianEditor:
|
|
|
193
208
|
""",
|
|
194
209
|
re.VERBOSE,
|
|
195
210
|
) # \b for words like سهمیه
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
text = self.text.replace("\\", "PN__BACKSLASH__PN")
|
|
199
|
-
wlist = text.split(" ")
|
|
200
|
-
for word in wlist:
|
|
201
|
-
regx_iter = regx.finditer(word)
|
|
202
|
-
for p in regx_iter:
|
|
203
|
-
# Checks that the prefix (mi* nemi* bi*) is part a a word or not, like میلاد.
|
|
204
|
-
if p.group() not in ImmutableWords.get():
|
|
205
|
-
text = re.sub(
|
|
206
|
-
re.escape(p.group()),
|
|
207
|
-
p.group(1) + "\u200c" + p.group(2),
|
|
208
|
-
text,
|
|
209
|
-
)
|
|
210
|
-
# Restore the original backslashes
|
|
211
|
-
self.text = text.replace("PN__BACKSLASH__PN", "\\")
|
|
211
|
+
# Checks that the prefix (mi*, nemi*, and bi*) is part a a word or not, like میلاد.
|
|
212
|
+
self.__immutability_check__(regx)
|
|
212
213
|
|
|
213
214
|
def fix_suffix_spacing(self):
|
|
214
215
|
"""Put ZWNJ between a word and its suffix (*ha[ye] *tar[in])."""
|
|
@@ -256,19 +257,22 @@ class PersianEditor:
|
|
|
256
257
|
)\b""",
|
|
257
258
|
re.VERBOSE,
|
|
258
259
|
)
|
|
260
|
+
# Checks that the suffix (tar*, haye*) is part of a word or not, like بهتر.
|
|
261
|
+
self.__immutability_check__(regx)
|
|
262
|
+
|
|
263
|
+
def __immutability_check__(self, regx: re.Pattern):
|
|
259
264
|
# Replace backslashes with a temporary placeholder
|
|
260
265
|
text = self.text.replace("\\", "PN__BACKSLASH__PN")
|
|
261
|
-
wlist = text.split(
|
|
266
|
+
wlist = text.split()
|
|
262
267
|
for word in wlist:
|
|
263
268
|
regx_iter = regx.finditer(word)
|
|
264
269
|
for p in regx_iter:
|
|
265
|
-
#
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
)
|
|
270
|
+
# if p.group() not in ImmutableWords.get():
|
|
271
|
+
text = re.sub(
|
|
272
|
+
rf"\b{re.escape(p.group())}\b",
|
|
273
|
+
p.group(1) + "\u200c" + p.group(2),
|
|
274
|
+
text,
|
|
275
|
+
)
|
|
272
276
|
# Restore the original backslashes
|
|
273
277
|
self.text = text.replace("PN__BACKSLASH__PN", "\\")
|
|
274
278
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-negar
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Negar is a spell corrector and Persian text editor
|
|
5
5
|
Home-page: http://github.com/shahinism/python-negar
|
|
6
6
|
Author: Shahin Azad
|
|
@@ -13,7 +13,7 @@ Classifier: Environment :: Console
|
|
|
13
13
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
14
|
Classifier: Programming Language :: Python
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
License-File: AUTHORS
|
|
@@ -33,7 +33,7 @@ setup(
|
|
|
33
33
|
},
|
|
34
34
|
long_description_content_type="text/markdown",
|
|
35
35
|
long_description=open("README.md", encoding="utf8").read(),
|
|
36
|
-
python_requires=">=3.
|
|
36
|
+
python_requires=">=3.8",
|
|
37
37
|
classifiers=[
|
|
38
38
|
"Environment :: Console",
|
|
39
39
|
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
@@ -93,6 +93,16 @@ class Test(unittest.TestCase):
|
|
|
93
93
|
self.input_ = r"در پیشوند کلمات با نیمفاصله نظیر ' می شود '، ' میشود '، ' بی شک '، ' بیشک ' , ' خانه اش '، ' وظیفه شناس ' ، ' کمک تان ' و یا ' نمیرود '"
|
|
94
94
|
self.output_ = "در پیشوند کلمات با نیمفاصله نظیر «میشود»، «میشود»، «بیشک»، «بیشک»، «خانهاش»، «وظیفهشناس»، «کمکتان» و یا «نمیرود»"
|
|
95
95
|
|
|
96
|
+
@_assertEqual("Fix Prefix ZWNJ II")
|
|
97
|
+
def test_fix_prefix_ZWNJ_ii(self):
|
|
98
|
+
self.input_ = r"می شود"
|
|
99
|
+
self.output_ = "میشود"
|
|
100
|
+
|
|
101
|
+
@_assertEqual("Fix Prefix ZWNJ III")
|
|
102
|
+
def test_fix_prefix_ZWNJ_iii(self):
|
|
103
|
+
self.input_ = r"می شود"
|
|
104
|
+
self.output_ = "میشود"
|
|
105
|
+
|
|
96
106
|
@_assertEqual("Fix Suffix ZWNJ I")
|
|
97
107
|
def test_fix_suffix_ZWNJ_I(self):
|
|
98
108
|
self.input_ = r"در پسوند کلمات با نیمفاصله نظیر کتابها، خوشترین -- و البته امکان عدم تنظیم (در صورت انتخاب کاربر)"
|
|
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
|