LabelCraft 2.1.1__tar.gz → 2.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.
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/PKG-INFO +19 -6
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/SOURCES.txt +2 -0
- labelcraft-2.1.3/LabelCraft.egg-info/entry_points.txt +2 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/PKG-INFO +19 -6
- {labelcraft-2.1.1 → labelcraft-2.1.3}/README.md +18 -5
- {labelcraft-2.1.1 → labelcraft-2.1.3}/labelcraft_ui.py +22 -1
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/__init__.py +1 -1
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/annotation_importer.py +13 -3
- labelcraft-2.1.3/libs/cli.py +49 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/en.json +1 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/zh-CN.json +1 -0
- labelcraft-2.1.3/libs/theme_manager.py +267 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/setup.py +1 -1
- labelcraft-2.1.1/LabelCraft.egg-info/entry_points.txt +0 -2
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/dependency_links.txt +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/not-zip-safe +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/requires.txt +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/LabelCraft.egg-info/top_level.txt +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/MANIFEST.in +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/data/coco_classes.txt +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/data/predefined_classes.txt +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/annotation_converter.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/canvas.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/coco_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/colorDialog.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/combobox.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/constants.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/create_ml_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/csv_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/default_label_combobox.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/hashableQListWidgetItem.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/i18n_engine.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/json_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/labelDialog.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/labelFile.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/lightWidget.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/de-DE.json +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/fr-FR.json +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/ja-JP.json +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/locales/zh-TW.json +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/newProjectDialog.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/pascal_voc_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/project.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/resources.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/settings.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/shape.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/toolBar.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/ustr.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/utils.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/yolo_io.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/libs/zoomWidget.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/main.py +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/app.icns +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/app.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/app.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/app_screen.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/cancel.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/close.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/color.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/color_line.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/copy.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/delete.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/done.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/done.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/edit.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/expert1.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/expert2.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/eye.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/feBlend-icon.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/file.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/fit-width.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/fit-window.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/fit.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/format_createml.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/format_voc.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/format_yolo.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/help.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/labels.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/labels.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_brighten.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_darken.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_darken.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_lighten.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_reset.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/light_reset.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/new.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/next.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/objects.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/open.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/open.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/prev.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/quit.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/resetall.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/save-as.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/save-as.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/save.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/save.svg +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/undo-cross.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/undo.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/verify.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/zoom-in.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/zoom-out.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources/icons/zoom.png +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/resources.qrc +0 -0
- {labelcraft-2.1.1 → labelcraft-2.1.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: LabelCraft
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: LabelCraft - A modern graphical image annotation tool based on labelImg
|
|
5
5
|
Home-page: https://github.com/syd168/LabelCraft
|
|
6
6
|
Author: LabelCraft Contributors
|
|
@@ -37,13 +37,14 @@ Dynamic: summary
|
|
|
37
37
|
|
|
38
38
|
# LabelCraft - Intelligent Image Annotation Tool
|
|
39
39
|
|
|
40
|
-
> **Version 2.1.
|
|
40
|
+
> **Version 2.1.3** - A modern image annotation tool with project management and cross-platform support, developed based on [labelImg](https://github.com/tzutalin/labelImg)
|
|
41
41
|
|
|
42
42
|
[](LICENSE)
|
|
43
43
|
[](https://www.python.org/)
|
|
44
44
|
[](https://www.qt.io/)
|
|
45
|
-
[](https://github.com/syd168/LabelCraft/releases)
|
|
46
46
|
[](https://pepy.tech/project/labelcraft)
|
|
47
|
+
[](https://pypi.org/project/LabelCraft/)
|
|
47
48
|
|
|
48
49
|
**[中文文档](README-CN.md)** | **[English](README.md)**
|
|
49
50
|
|
|
@@ -99,6 +100,15 @@ Dynamic language switching without restart:
|
|
|
99
100
|
- Python API for integration
|
|
100
101
|
- Customizable shortcuts
|
|
101
102
|
- Brightness adjustment
|
|
103
|
+
- **Cross-Platform Dark Mode** (v2.1.2+)
|
|
104
|
+
- Windows 10/11: Automatic registry detection
|
|
105
|
+
- Linux (GNOME/KDE/Ubuntu): dconf/gsettings support
|
|
106
|
+
- macOS: System appearance detection
|
|
107
|
+
- Fusion style for consistent cross-platform rendering
|
|
108
|
+
- **Unified Build System** (v2.1.2+)
|
|
109
|
+
- PyInstaller-based builds for all platforms
|
|
110
|
+
- Consistent distribution packages
|
|
111
|
+
- GitHub Actions CI/CD automation
|
|
102
112
|
|
|
103
113
|
## 📸 Screenshot
|
|
104
114
|
|
|
@@ -401,15 +411,18 @@ See [TRANSLATION_GUIDE.md](doc/TRANSLATION_GUIDE.md) for details.
|
|
|
401
411
|
|
|
402
412
|
## ❓ FAQ
|
|
403
413
|
|
|
404
|
-
### Q: What's the difference between v1.x and v2.
|
|
414
|
+
### Q: What's the difference between v1.x and v2.1?
|
|
405
415
|
|
|
406
|
-
**A:** Version 2.
|
|
416
|
+
**A:** Version 2.1 introduces:
|
|
407
417
|
- ✅ Project-based workflow (vs. file-based in v1.x)
|
|
408
418
|
- ✅ Support for COCO and CSV formats
|
|
409
419
|
- ✅ Built-in format converter
|
|
410
|
-
- ✅ Dynamic language switching
|
|
420
|
+
- ✅ Dynamic language switching (6 languages)
|
|
411
421
|
- ✅ Enhanced UI with better organization
|
|
412
422
|
- ✅ Improved annotation management
|
|
423
|
+
- ✅ Cross-platform dark mode detection
|
|
424
|
+
- ✅ Unified PyInstaller build system
|
|
425
|
+
- ✅ PyPI package distribution
|
|
413
426
|
|
|
414
427
|
### Q: Can I still use it without creating a project?
|
|
415
428
|
|
|
@@ -18,6 +18,7 @@ libs/__init__.py
|
|
|
18
18
|
libs/annotation_converter.py
|
|
19
19
|
libs/annotation_importer.py
|
|
20
20
|
libs/canvas.py
|
|
21
|
+
libs/cli.py
|
|
21
22
|
libs/coco_io.py
|
|
22
23
|
libs/colorDialog.py
|
|
23
24
|
libs/combobox.py
|
|
@@ -37,6 +38,7 @@ libs/project.py
|
|
|
37
38
|
libs/resources.py
|
|
38
39
|
libs/settings.py
|
|
39
40
|
libs/shape.py
|
|
41
|
+
libs/theme_manager.py
|
|
40
42
|
libs/toolBar.py
|
|
41
43
|
libs/ustr.py
|
|
42
44
|
libs/utils.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: LabelCraft
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: LabelCraft - A modern graphical image annotation tool based on labelImg
|
|
5
5
|
Home-page: https://github.com/syd168/LabelCraft
|
|
6
6
|
Author: LabelCraft Contributors
|
|
@@ -37,13 +37,14 @@ Dynamic: summary
|
|
|
37
37
|
|
|
38
38
|
# LabelCraft - Intelligent Image Annotation Tool
|
|
39
39
|
|
|
40
|
-
> **Version 2.1.
|
|
40
|
+
> **Version 2.1.3** - A modern image annotation tool with project management and cross-platform support, developed based on [labelImg](https://github.com/tzutalin/labelImg)
|
|
41
41
|
|
|
42
42
|
[](LICENSE)
|
|
43
43
|
[](https://www.python.org/)
|
|
44
44
|
[](https://www.qt.io/)
|
|
45
|
-
[](https://github.com/syd168/LabelCraft/releases)
|
|
46
46
|
[](https://pepy.tech/project/labelcraft)
|
|
47
|
+
[](https://pypi.org/project/LabelCraft/)
|
|
47
48
|
|
|
48
49
|
**[中文文档](README-CN.md)** | **[English](README.md)**
|
|
49
50
|
|
|
@@ -99,6 +100,15 @@ Dynamic language switching without restart:
|
|
|
99
100
|
- Python API for integration
|
|
100
101
|
- Customizable shortcuts
|
|
101
102
|
- Brightness adjustment
|
|
103
|
+
- **Cross-Platform Dark Mode** (v2.1.2+)
|
|
104
|
+
- Windows 10/11: Automatic registry detection
|
|
105
|
+
- Linux (GNOME/KDE/Ubuntu): dconf/gsettings support
|
|
106
|
+
- macOS: System appearance detection
|
|
107
|
+
- Fusion style for consistent cross-platform rendering
|
|
108
|
+
- **Unified Build System** (v2.1.2+)
|
|
109
|
+
- PyInstaller-based builds for all platforms
|
|
110
|
+
- Consistent distribution packages
|
|
111
|
+
- GitHub Actions CI/CD automation
|
|
102
112
|
|
|
103
113
|
## 📸 Screenshot
|
|
104
114
|
|
|
@@ -401,15 +411,18 @@ See [TRANSLATION_GUIDE.md](doc/TRANSLATION_GUIDE.md) for details.
|
|
|
401
411
|
|
|
402
412
|
## ❓ FAQ
|
|
403
413
|
|
|
404
|
-
### Q: What's the difference between v1.x and v2.
|
|
414
|
+
### Q: What's the difference between v1.x and v2.1?
|
|
405
415
|
|
|
406
|
-
**A:** Version 2.
|
|
416
|
+
**A:** Version 2.1 introduces:
|
|
407
417
|
- ✅ Project-based workflow (vs. file-based in v1.x)
|
|
408
418
|
- ✅ Support for COCO and CSV formats
|
|
409
419
|
- ✅ Built-in format converter
|
|
410
|
-
- ✅ Dynamic language switching
|
|
420
|
+
- ✅ Dynamic language switching (6 languages)
|
|
411
421
|
- ✅ Enhanced UI with better organization
|
|
412
422
|
- ✅ Improved annotation management
|
|
423
|
+
- ✅ Cross-platform dark mode detection
|
|
424
|
+
- ✅ Unified PyInstaller build system
|
|
425
|
+
- ✅ PyPI package distribution
|
|
413
426
|
|
|
414
427
|
### Q: Can I still use it without creating a project?
|
|
415
428
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# LabelCraft - Intelligent Image Annotation Tool
|
|
2
2
|
|
|
3
|
-
> **Version 2.1.
|
|
3
|
+
> **Version 2.1.3** - A modern image annotation tool with project management and cross-platform support, developed based on [labelImg](https://github.com/tzutalin/labelImg)
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://www.qt.io/)
|
|
8
|
-
[](https://github.com/syd168/LabelCraft/releases)
|
|
9
9
|
[](https://pepy.tech/project/labelcraft)
|
|
10
|
+
[](https://pypi.org/project/LabelCraft/)
|
|
10
11
|
|
|
11
12
|
**[中文文档](README-CN.md)** | **[English](README.md)**
|
|
12
13
|
|
|
@@ -62,6 +63,15 @@ Dynamic language switching without restart:
|
|
|
62
63
|
- Python API for integration
|
|
63
64
|
- Customizable shortcuts
|
|
64
65
|
- Brightness adjustment
|
|
66
|
+
- **Cross-Platform Dark Mode** (v2.1.2+)
|
|
67
|
+
- Windows 10/11: Automatic registry detection
|
|
68
|
+
- Linux (GNOME/KDE/Ubuntu): dconf/gsettings support
|
|
69
|
+
- macOS: System appearance detection
|
|
70
|
+
- Fusion style for consistent cross-platform rendering
|
|
71
|
+
- **Unified Build System** (v2.1.2+)
|
|
72
|
+
- PyInstaller-based builds for all platforms
|
|
73
|
+
- Consistent distribution packages
|
|
74
|
+
- GitHub Actions CI/CD automation
|
|
65
75
|
|
|
66
76
|
## 📸 Screenshot
|
|
67
77
|
|
|
@@ -364,15 +374,18 @@ See [TRANSLATION_GUIDE.md](doc/TRANSLATION_GUIDE.md) for details.
|
|
|
364
374
|
|
|
365
375
|
## ❓ FAQ
|
|
366
376
|
|
|
367
|
-
### Q: What's the difference between v1.x and v2.
|
|
377
|
+
### Q: What's the difference between v1.x and v2.1?
|
|
368
378
|
|
|
369
|
-
**A:** Version 2.
|
|
379
|
+
**A:** Version 2.1 introduces:
|
|
370
380
|
- ✅ Project-based workflow (vs. file-based in v1.x)
|
|
371
381
|
- ✅ Support for COCO and CSV formats
|
|
372
382
|
- ✅ Built-in format converter
|
|
373
|
-
- ✅ Dynamic language switching
|
|
383
|
+
- ✅ Dynamic language switching (6 languages)
|
|
374
384
|
- ✅ Enhanced UI with better organization
|
|
375
385
|
- ✅ Improved annotation management
|
|
386
|
+
- ✅ Cross-platform dark mode detection
|
|
387
|
+
- ✅ Unified PyInstaller build system
|
|
388
|
+
- ✅ PyPI package distribution
|
|
376
389
|
|
|
377
390
|
### Q: Can I still use it without creating a project?
|
|
378
391
|
|
|
@@ -40,6 +40,7 @@ from libs.ustr import ustr
|
|
|
40
40
|
from libs.hashableQListWidgetItem import HashableQListWidgetItem
|
|
41
41
|
from libs.project import Project, RecentProjectsManager
|
|
42
42
|
from libs.newProjectDialog import NewProjectDialog
|
|
43
|
+
from libs.theme_manager import apply_system_theme
|
|
43
44
|
from libs import __version__
|
|
44
45
|
|
|
45
46
|
__appname__ = 'LabelCraft'
|
|
@@ -4896,7 +4897,23 @@ class MainWindow(QMainWindow, WindowMixin):
|
|
|
4896
4897
|
print(f"Using {len(classes_list)} classes from label history")
|
|
4897
4898
|
else:
|
|
4898
4899
|
classes_list = []
|
|
4899
|
-
print("Warning: No classes list available.
|
|
4900
|
+
print("Warning: No classes list available.")
|
|
4901
|
+
|
|
4902
|
+
# For YOLO and COCO formats, show warning and ask user to continue
|
|
4903
|
+
if selected_format[0] in [LabelFileFormat.YOLO, LabelFileFormat.COCO]:
|
|
4904
|
+
reply = QMessageBox.warning(
|
|
4905
|
+
self,
|
|
4906
|
+
self.get_str('warningTitle'),
|
|
4907
|
+
f'{self.get_str("exportNoLabelsWarning")}\n\n'
|
|
4908
|
+
f'Project has no defined labels. Export to {selected_format[0].name} format requires labels.\n\n'
|
|
4909
|
+
f'Options:\n'
|
|
4910
|
+
f'1. Add labels to project first (recommended)\n'
|
|
4911
|
+
f'2. Continue with empty labels (annotations will use numeric IDs)',
|
|
4912
|
+
QMessageBox.StandardButton.Cancel | QMessageBox.StandardButton.Ok,
|
|
4913
|
+
QMessageBox.StandardButton.Cancel
|
|
4914
|
+
)
|
|
4915
|
+
if reply == QMessageBox.StandardButton.Cancel:
|
|
4916
|
+
return
|
|
4900
4917
|
|
|
4901
4918
|
try:
|
|
4902
4919
|
# Iterate through all annotation files
|
|
@@ -5293,6 +5310,10 @@ def get_main_app(argv=None):
|
|
|
5293
5310
|
app.setApplicationName(__appname__)
|
|
5294
5311
|
app.setWindowIcon(new_icon("app"))
|
|
5295
5312
|
|
|
5313
|
+
# Apply system theme (light/dark mode)
|
|
5314
|
+
# This will automatically follow the system's theme preference
|
|
5315
|
+
apply_system_theme(app)
|
|
5316
|
+
|
|
5296
5317
|
# Tzutalin 201705+: Accept extra arguments to change predefined class file
|
|
5297
5318
|
argparser = argparse.ArgumentParser(
|
|
5298
5319
|
prog='labelcraft',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version_info__ = ('2', '1', '
|
|
1
|
+
__version_info__ = ('2', '1', '3')
|
|
2
2
|
__version__ = '.'.join(__version_info__)
|
|
@@ -817,6 +817,8 @@ class AnnotationImporter:
|
|
|
817
817
|
|
|
818
818
|
# Get classes list - prioritize project labels over source labels
|
|
819
819
|
# This ensures imported annotations match the project's label definitions
|
|
820
|
+
labels_added_to_project = False
|
|
821
|
+
|
|
820
822
|
if self.current_project.labels:
|
|
821
823
|
# Project has defined labels, use them (most important)
|
|
822
824
|
classes_list = self.current_project.labels
|
|
@@ -828,10 +830,18 @@ class AnnotationImporter:
|
|
|
828
830
|
print(f"Imported annotations will be mapped to project labels by class ID.")
|
|
829
831
|
print(f"This may cause incorrect labels if the class order differs!")
|
|
830
832
|
elif yolo_labels:
|
|
831
|
-
# No project labels, use YOLO labels from data.yaml
|
|
833
|
+
# No project labels, use YOLO labels from data.yaml AND add them to project
|
|
832
834
|
classes_list = yolo_labels
|
|
833
|
-
print(f"Using {len(classes_list)} classes from YOLO data.yaml: {classes_list[:5]}...")
|
|
834
|
-
|
|
835
|
+
print(f"Project has no labels. Using {len(classes_list)} classes from YOLO data.yaml: {classes_list[:5]}...")
|
|
836
|
+
|
|
837
|
+
# Automatically add these labels to the project
|
|
838
|
+
try:
|
|
839
|
+
self.current_project.labels = classes_list.copy()
|
|
840
|
+
self.current_project.save() # Save project to persist labels
|
|
841
|
+
labels_added_to_project = True
|
|
842
|
+
print(f"✓ Added {len(classes_list)} labels to project automatically")
|
|
843
|
+
except Exception as e:
|
|
844
|
+
print(f"Warning: Failed to add labels to project: {e}")
|
|
835
845
|
else:
|
|
836
846
|
# No labels available at all
|
|
837
847
|
classes_list = []
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
LabelCraft CLI Entry Point
|
|
5
|
+
This module serves as the proper entry point for the labelcraft command,
|
|
6
|
+
ensuring it works correctly regardless of the installation location.
|
|
7
|
+
"""
|
|
8
|
+
import sys
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
"""
|
|
13
|
+
Main entry point for LabelCraft command-line interface.
|
|
14
|
+
This ensures proper module resolution and data file loading
|
|
15
|
+
from any installation location.
|
|
16
|
+
"""
|
|
17
|
+
# Get the directory where this module is located
|
|
18
|
+
module_dir = os.path.dirname(os.path.abspath(__file__))
|
|
19
|
+
# Get the parent directory (project root)
|
|
20
|
+
project_root = os.path.dirname(module_dir)
|
|
21
|
+
|
|
22
|
+
# Add project root and module directory to Python path for proper imports
|
|
23
|
+
if project_root not in sys.path:
|
|
24
|
+
sys.path.insert(0, project_root)
|
|
25
|
+
if module_dir not in sys.path:
|
|
26
|
+
sys.path.insert(0, module_dir)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
from PySide6.QtWidgets import QApplication
|
|
30
|
+
from labelcraft_ui import get_main_app
|
|
31
|
+
|
|
32
|
+
# Create and run the application
|
|
33
|
+
app, _win = get_main_app(sys.argv)
|
|
34
|
+
sys.exit(app.exec())
|
|
35
|
+
|
|
36
|
+
except ImportError as e:
|
|
37
|
+
print(f"Error: Failed to import required modules: {e}")
|
|
38
|
+
print("Please ensure PySide6 and lxml are installed:")
|
|
39
|
+
print(" pip install pyside6>=6.5.0 lxml>=4.9.0")
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
print(f"Error: Failed to start LabelCraft: {e}")
|
|
43
|
+
import traceback
|
|
44
|
+
traceback.print_exc()
|
|
45
|
+
sys.exit(1)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == '__main__':
|
|
49
|
+
main()
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"setVerifiedDetail": "Mark selected annotations as verified",
|
|
519
519
|
"setUnverifiedDetail": "Mark selected annotations as unverified",
|
|
520
520
|
"showVerificationStatusDetail": "Toggle showing verification status color in completed annotations list",
|
|
521
|
+
"exportNoLabelsWarning": "⚠️ No Labels Defined\n\nProject has no defined labels. Export to this format requires labels for proper conversion.",
|
|
521
522
|
"tutorialContent": "<div style='font-size: 14px; line-height: 1.8;'>\n<h2 style='text-align: center; margin-bottom: 20px;'>Welcome to LabelCraft!</h2>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>Basic Annotation Steps:</h3>\n<p><b>1. Create/Open Project:</b> File → New Project or Open Project<br>\n<b>2. Add Images:</b> Click \"+ Add Images\" or \"+ Add Folder\" in the bottom panel<br>\n<b>3. Annotate:</b> Double-click an image, then press 'W' to draw bounding boxes<br>\n<b>4. Save:</b> Press Ctrl+S to save annotations (auto-saves when moving to next image)<br>\n<b>5. Export:</b> Output → Export to convert annotations to desired format</p>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>Helpful Tips:</h3>\n<p><b>• Shortcuts:</b> Help → Keyboard shortcuts to view all shortcuts<br>\n<b>• Labels:</b> Use the right panel to filter and manage labels<br>\n<b>• Navigation:</b> Mouse wheel to zoom, drag to pan<br>\n<b>• Brightness:</b> Adjust image brightness with slider in toolbar</p>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>For more detailed documentation:</h3>\n<p>• <a href='https://github.com/syd168/LabelCraft'>Visit our GitHub repository for complete tutorials and examples</a><br>\n• <a href='https://github.com/syd168/LabelCraft/blob/master/README.md'>Documentation & Tutorials</a><br>\n• <a href='https://github.com/syd168/LabelCraft/issues'>Report Issues</a></p>\n</div>"
|
|
522
523
|
}
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"setVerifiedDetail": "将选中的标注标记为已验证",
|
|
519
519
|
"setUnverifiedDetail": "将选中的标注标记为未验证",
|
|
520
520
|
"showVerificationStatusDetail": "切换在已完成标注列表中显示验证状态颜色",
|
|
521
|
+
"exportNoLabelsWarning": "⚠️ 未定义标签\n\n项目没有定义标签。导出到此格式需要标签才能正确转换。",
|
|
521
522
|
"tutorialContent": "<div style='font-size: 14px; line-height: 1.8;'>\n<h2 style='text-align: center; margin-bottom: 20px;'>欢迎使用 LabelCraft!</h2>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>基本标注步骤:</h3>\n<p><b>1. 创建/打开项目:</b> 文件 → 新建项目 或 打开项目<br>\n<b>2. 添加图像:</b> 点击底部面板的 \"+ 添加图像\" 或 \"+ 添加文件夹\"<br>\n<b>3. 标注:</b> 双击图像,然后按 'W' 键绘制边界框<br>\n<b>4. 保存:</b> 按 Ctrl+S 保存标注(切换到下一张图像时自动保存)<br>\n<b>5. 导出:</b> 输出 → 导出 将标注转换为所需格式</p>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>实用技巧:</h3>\n<p><b>• 快捷键:</b> 帮助 → 键盘快捷键 查看所有快捷键<br>\n<b>• 标签管理:</b> 使用右侧面板过滤和管理标签<br>\n<b>• 导航:</b> 鼠标滚轮缩放,拖拽平移<br>\n<b>• 亮度:</b> 使用工具栏中的滑块调整图像亮度</p>\n\n<h3 style='margin-top: 20px; font-weight: bold;'>更多详细文档:</h3>\n<p>• <a href='https://github.com/syd168/LabelCraft'>访问我们的 GitHub 仓库获取完整教程和示例</a><br>\n• <a href='https://github.com/syd168/LabelCraft/blob/master/README.md'>文档与教程</a><br>\n• <a href='https://github.com/syd168/LabelCraft/issues'>报告问题</a></p>\n</div>"
|
|
522
523
|
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
LabelCraft Theme Manager
|
|
5
|
+
Provides automatic system theme detection and application.
|
|
6
|
+
Supports light/dark mode following system settings on:
|
|
7
|
+
- Linux (GNOME, KDE, Ubuntu)
|
|
8
|
+
- Windows (Windows 10, Windows 11)
|
|
9
|
+
- macOS
|
|
10
|
+
"""
|
|
11
|
+
from PySide6.QtGui import QPalette, QColor
|
|
12
|
+
from PySide6.QtWidgets import QApplication
|
|
13
|
+
from PySide6.QtCore import Qt
|
|
14
|
+
import platform
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _create_dark_palette():
|
|
19
|
+
"""
|
|
20
|
+
Create a comprehensive dark theme palette.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
QPalette: Configured dark palette
|
|
24
|
+
"""
|
|
25
|
+
dark_palette = QPalette()
|
|
26
|
+
|
|
27
|
+
# Base colors for dark theme
|
|
28
|
+
dark_bg = QColor(53, 53, 53)
|
|
29
|
+
darker_bg = QColor(25, 25, 25)
|
|
30
|
+
light_text = QColor(255, 255, 255)
|
|
31
|
+
link_color = QColor(42, 130, 218)
|
|
32
|
+
|
|
33
|
+
# Window and base colors
|
|
34
|
+
dark_palette.setColor(QPalette.ColorRole.Window, dark_bg)
|
|
35
|
+
dark_palette.setColor(QPalette.ColorRole.Base, darker_bg)
|
|
36
|
+
dark_palette.setColor(QPalette.ColorRole.AlternateBase, dark_bg)
|
|
37
|
+
|
|
38
|
+
# Text colors
|
|
39
|
+
dark_palette.setColor(QPalette.ColorRole.WindowText, light_text)
|
|
40
|
+
dark_palette.setColor(QPalette.ColorRole.Text, light_text)
|
|
41
|
+
dark_palette.setColor(QPalette.ColorRole.ButtonText, light_text)
|
|
42
|
+
|
|
43
|
+
# Button and control colors
|
|
44
|
+
dark_palette.setColor(QPalette.ColorRole.Button, dark_bg)
|
|
45
|
+
dark_palette.setColor(QPalette.ColorRole.Shadow, QColor(20, 20, 20))
|
|
46
|
+
dark_palette.setColor(QPalette.ColorRole.Highlight, link_color)
|
|
47
|
+
dark_palette.setColor(QPalette.ColorRole.HighlightedText, QColor(255, 255, 255))
|
|
48
|
+
|
|
49
|
+
# Link colors
|
|
50
|
+
dark_palette.setColor(QPalette.ColorRole.Link, link_color)
|
|
51
|
+
|
|
52
|
+
# Tooltips
|
|
53
|
+
dark_palette.setColor(QPalette.ColorRole.ToolTipBase, light_text)
|
|
54
|
+
dark_palette.setColor(QPalette.ColorRole.ToolTipText, dark_bg)
|
|
55
|
+
|
|
56
|
+
# Disabled state
|
|
57
|
+
dark_palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.WindowText, QColor(128, 128, 128))
|
|
58
|
+
dark_palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, QColor(128, 128, 128))
|
|
59
|
+
dark_palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, QColor(128, 128, 128))
|
|
60
|
+
|
|
61
|
+
return dark_palette
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _create_light_palette():
|
|
65
|
+
"""
|
|
66
|
+
Create a comprehensive light theme palette.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
QPalette: Configured light palette
|
|
70
|
+
"""
|
|
71
|
+
light_palette = QPalette()
|
|
72
|
+
|
|
73
|
+
# Use system default light colors
|
|
74
|
+
# Light palette is typically the default, so we return a new instance
|
|
75
|
+
return light_palette
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _detect_windows_dark_mode():
|
|
79
|
+
"""
|
|
80
|
+
Detect if Windows 11/10 is using dark mode.
|
|
81
|
+
|
|
82
|
+
Checks the Windows Registry:
|
|
83
|
+
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
|
|
84
|
+
AppsUseLightTheme = 0 means dark mode
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
bool: True if dark mode detected, False otherwise
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
import winreg
|
|
91
|
+
try:
|
|
92
|
+
# Try to open the registry key
|
|
93
|
+
key = winreg.OpenKey(
|
|
94
|
+
winreg.HKEY_CURRENT_USER,
|
|
95
|
+
r'Software\Microsoft\Windows\CurrentVersion\Themes\Personalize'
|
|
96
|
+
)
|
|
97
|
+
# Read AppsUseLightTheme value
|
|
98
|
+
# 0 = dark mode, 1 = light mode
|
|
99
|
+
value, regtype = winreg.QueryValueEx(key, 'AppsUseLightTheme')
|
|
100
|
+
winreg.CloseKey(key)
|
|
101
|
+
return value == 0
|
|
102
|
+
except Exception:
|
|
103
|
+
# Key or value not found - assume light mode
|
|
104
|
+
return False
|
|
105
|
+
except ImportError:
|
|
106
|
+
# winreg not available (not on Windows)
|
|
107
|
+
return False
|
|
108
|
+
except Exception:
|
|
109
|
+
# Any other error - assume light mode
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _detect_linux_dark_mode():
|
|
114
|
+
"""
|
|
115
|
+
Detect if Linux desktop environment is using dark mode.
|
|
116
|
+
|
|
117
|
+
Supports:
|
|
118
|
+
- GNOME/Ubuntu (via dconf)
|
|
119
|
+
- KDE Plasma (via kdeglobals)
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
bool: True if dark mode detected, False otherwise
|
|
123
|
+
"""
|
|
124
|
+
# Method 1: Check GNOME/Ubuntu GTK theme via dconf
|
|
125
|
+
try:
|
|
126
|
+
import subprocess
|
|
127
|
+
result = subprocess.run(
|
|
128
|
+
['dconf', 'read', '/org/gnome/desktop/interface/gtk-theme'],
|
|
129
|
+
capture_output=True,
|
|
130
|
+
text=True,
|
|
131
|
+
timeout=2
|
|
132
|
+
)
|
|
133
|
+
if result.returncode == 0:
|
|
134
|
+
theme_name = result.stdout.strip().strip("'\"")
|
|
135
|
+
if 'dark' in theme_name.lower():
|
|
136
|
+
return True
|
|
137
|
+
except (FileNotFoundError, subprocess.TimeoutExpired, Exception):
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
# Method 2: Check GNOME settings (alternative method)
|
|
141
|
+
try:
|
|
142
|
+
import subprocess
|
|
143
|
+
result = subprocess.run(
|
|
144
|
+
['gsettings', 'get', 'org.gnome.desktop.interface', 'gtk-application-prefer-dark-theme'],
|
|
145
|
+
capture_output=True,
|
|
146
|
+
text=True,
|
|
147
|
+
timeout=2
|
|
148
|
+
)
|
|
149
|
+
if result.returncode == 0:
|
|
150
|
+
return 'true' in result.stdout.lower()
|
|
151
|
+
except (FileNotFoundError, subprocess.TimeoutExpired, Exception):
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
# Method 3: Check environment variables
|
|
155
|
+
if os.environ.get('GTK_THEME', '').lower().endswith('-dark') or 'dark' in os.environ.get('GTK_THEME', '').lower():
|
|
156
|
+
return True
|
|
157
|
+
|
|
158
|
+
if 'dark' in os.environ.get('QT_STYLE_OVERRIDE', '').lower():
|
|
159
|
+
return True
|
|
160
|
+
|
|
161
|
+
# Method 4: Check Plasma/KDE settings
|
|
162
|
+
try:
|
|
163
|
+
config_path = os.path.expanduser('~/.config/kdeglobals')
|
|
164
|
+
if os.path.exists(config_path):
|
|
165
|
+
with open(config_path, 'r') as f:
|
|
166
|
+
content = f.read()
|
|
167
|
+
if '[General]' in content and 'ColorScheme=' in content:
|
|
168
|
+
for line in content.split('\n'):
|
|
169
|
+
if 'ColorScheme=' in line and 'dark' in line.lower():
|
|
170
|
+
return True
|
|
171
|
+
except Exception:
|
|
172
|
+
pass
|
|
173
|
+
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _detect_macos_dark_mode():
|
|
178
|
+
"""
|
|
179
|
+
Detect if macOS is using dark mode.
|
|
180
|
+
|
|
181
|
+
Uses `defaults read` to check the system appearance setting.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
bool: True if dark mode detected, False otherwise
|
|
185
|
+
"""
|
|
186
|
+
try:
|
|
187
|
+
import subprocess
|
|
188
|
+
result = subprocess.run(
|
|
189
|
+
['defaults', 'read', '-g', 'AppleInterfaceStyle'],
|
|
190
|
+
capture_output=True,
|
|
191
|
+
text=True,
|
|
192
|
+
timeout=2
|
|
193
|
+
)
|
|
194
|
+
# If the command returns 'Dark', dark mode is enabled
|
|
195
|
+
return 'Dark' in result.stdout or result.returncode == 0
|
|
196
|
+
except (FileNotFoundError, subprocess.TimeoutExpired, Exception):
|
|
197
|
+
# If the command fails, assume light mode (default on macOS)
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _detect_system_dark_mode():
|
|
202
|
+
"""
|
|
203
|
+
Detect if the system is using dark mode.
|
|
204
|
+
|
|
205
|
+
Tries multiple methods based on the operating system:
|
|
206
|
+
- Windows: Registry check (AppsUseLightTheme)
|
|
207
|
+
- Linux: dconf, gsettings, or environment variables
|
|
208
|
+
- macOS: defaults read
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
bool: True if dark mode detected, False otherwise
|
|
212
|
+
"""
|
|
213
|
+
system = platform.system()
|
|
214
|
+
|
|
215
|
+
if system == 'Windows':
|
|
216
|
+
return _detect_windows_dark_mode()
|
|
217
|
+
elif system == 'Linux':
|
|
218
|
+
return _detect_linux_dark_mode()
|
|
219
|
+
elif system == 'Darwin': # macOS
|
|
220
|
+
return _detect_macos_dark_mode()
|
|
221
|
+
else:
|
|
222
|
+
# Unknown system - assume light mode
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def apply_system_theme(app):
|
|
227
|
+
"""
|
|
228
|
+
Apply system theme (light/dark mode) to the application.
|
|
229
|
+
|
|
230
|
+
This function detects the system's current theme preference
|
|
231
|
+
and applies it to the QApplication. The application will
|
|
232
|
+
automatically use the correct colors and styles based on
|
|
233
|
+
the system's light/dark mode setting.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
app (QApplication): The Qt application instance
|
|
237
|
+
"""
|
|
238
|
+
# Use Fusion style for better cross-platform theme support
|
|
239
|
+
app.setStyle('Fusion')
|
|
240
|
+
|
|
241
|
+
# Detect if system is in dark mode
|
|
242
|
+
is_dark = _detect_system_dark_mode()
|
|
243
|
+
|
|
244
|
+
# Apply the appropriate palette
|
|
245
|
+
if is_dark:
|
|
246
|
+
dark_palette = _create_dark_palette()
|
|
247
|
+
app.setPalette(dark_palette)
|
|
248
|
+
else:
|
|
249
|
+
# Light mode uses default palette
|
|
250
|
+
light_palette = _create_light_palette()
|
|
251
|
+
app.setPalette(light_palette)
|
|
252
|
+
|
|
253
|
+
# Return theme info
|
|
254
|
+
return {
|
|
255
|
+
'is_dark_mode': is_dark,
|
|
256
|
+
'palette': app.palette()
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def is_system_dark_mode():
|
|
261
|
+
"""
|
|
262
|
+
Detect if the system is using dark mode.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
bool: True if dark mode is detected, False for light mode
|
|
266
|
+
"""
|
|
267
|
+
return _detect_system_dark_mode()
|
|
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
|
|
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
|
|
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
|