novelWriter 2.2b1__py3-none-any.whl → 2.2rc1__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.
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/METADATA +3 -3
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/RECORD +60 -48
- novelwriter/__init__.py +3 -3
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/icons/novelwriter.ico +0 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +8 -1
- novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_panel.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_eye.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +8 -1
- novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_panel.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_eye.svg +4 -0
- novelwriter/assets/icons/x-novelwriter-project.ico +0 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/release_notes.htm +4 -4
- novelwriter/common.py +22 -1
- novelwriter/config.py +12 -27
- novelwriter/constants.py +20 -3
- novelwriter/core/buildsettings.py +1 -1
- novelwriter/core/coretools.py +6 -1
- novelwriter/core/index.py +100 -34
- novelwriter/core/options.py +3 -0
- novelwriter/core/project.py +2 -2
- novelwriter/core/projectdata.py +1 -1
- novelwriter/core/tohtml.py +9 -3
- novelwriter/core/tokenizer.py +27 -20
- novelwriter/core/tomd.py +4 -0
- novelwriter/core/toodt.py +11 -4
- novelwriter/dialogs/preferences.py +80 -82
- novelwriter/dialogs/updates.py +25 -14
- novelwriter/enum.py +14 -4
- novelwriter/gui/doceditor.py +282 -177
- novelwriter/gui/dochighlight.py +7 -9
- novelwriter/gui/docviewer.py +142 -319
- novelwriter/gui/docviewerpanel.py +457 -0
- novelwriter/gui/editordocument.py +1 -1
- novelwriter/gui/mainmenu.py +16 -7
- novelwriter/gui/outline.py +10 -6
- novelwriter/gui/projtree.py +461 -376
- novelwriter/gui/sidebar.py +3 -3
- novelwriter/gui/statusbar.py +1 -1
- novelwriter/gui/theme.py +21 -2
- novelwriter/guimain.py +86 -32
- novelwriter/shared.py +23 -1
- novelwriter/tools/dictionaries.py +268 -0
- novelwriter/tools/manusbuild.py +17 -6
- novelwriter/tools/manuscript.py +1 -1
- novelwriter/tools/writingstats.py +1 -1
- novelwriter/assets/icons/typicons_dark/typ_at.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_at.svg +0 -4
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/WHEEL +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,268 @@
|
|
1
|
+
"""
|
2
|
+
novelWriter – GUI Dictionary Downloader
|
3
|
+
=======================================
|
4
|
+
|
5
|
+
File History:
|
6
|
+
Created: 2023-11-19 [2.2rc1]
|
7
|
+
|
8
|
+
This file is a part of novelWriter
|
9
|
+
Copyright 2018–2023, Veronica Berglyd Olsen
|
10
|
+
|
11
|
+
This program is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
This program is distributed in the hope that it will be useful, but
|
17
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
19
|
+
General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU General Public License
|
22
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
23
|
+
"""
|
24
|
+
from __future__ import annotations
|
25
|
+
|
26
|
+
import logging
|
27
|
+
|
28
|
+
from pathlib import Path
|
29
|
+
from zipfile import ZipFile
|
30
|
+
|
31
|
+
from PyQt5.QtGui import QCloseEvent, QTextCursor
|
32
|
+
from PyQt5.QtCore import pyqtSlot
|
33
|
+
from PyQt5.QtWidgets import (
|
34
|
+
QDialog, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout, QLabel,
|
35
|
+
QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget, qApp
|
36
|
+
)
|
37
|
+
|
38
|
+
from novelwriter import CONFIG, SHARED
|
39
|
+
from novelwriter.error import formatException
|
40
|
+
from novelwriter.common import openExternalPath, formatInt, getFileSize
|
41
|
+
|
42
|
+
logger = logging.getLogger(__name__)
|
43
|
+
|
44
|
+
|
45
|
+
class GuiDictionaries(QDialog):
|
46
|
+
|
47
|
+
def __init__(self, parent: QWidget) -> None:
|
48
|
+
super().__init__(parent=parent)
|
49
|
+
|
50
|
+
logger.debug("Create: GuiDictionaries")
|
51
|
+
self.setObjectName("GuiDictionaries")
|
52
|
+
self.setWindowTitle(self.tr("Add Dictionaries"))
|
53
|
+
|
54
|
+
self._installPath = None
|
55
|
+
self._currDicts = set()
|
56
|
+
|
57
|
+
iPx = CONFIG.pxInt(4)
|
58
|
+
mPx = CONFIG.pxInt(8)
|
59
|
+
sPx = CONFIG.pxInt(16)
|
60
|
+
|
61
|
+
self.setMinimumWidth(CONFIG.pxInt(500))
|
62
|
+
self.setMinimumHeight(CONFIG.pxInt(300))
|
63
|
+
|
64
|
+
# Hunspell Dictionaries
|
65
|
+
foUrl = "https://www.freeoffice.com/en/download/dictionaries"
|
66
|
+
loUrl = "https://extensions.libreoffice.org"
|
67
|
+
self.huInfo = QLabel("<br>".join([
|
68
|
+
self.tr("Download a dictionary from one of the links, and add it below."),
|
69
|
+
f" \u203a <a href='{foUrl}'>{foUrl}</a>",
|
70
|
+
f" \u203a <a href='{loUrl}'>{loUrl}</a>",
|
71
|
+
]))
|
72
|
+
self.huInfo.setOpenExternalLinks(True)
|
73
|
+
self.huInfo.setWordWrap(True)
|
74
|
+
self.huInput = QLineEdit(self)
|
75
|
+
self.huBrowse = QPushButton(self)
|
76
|
+
self.huBrowse.setIcon(SHARED.theme.getIcon("browse"))
|
77
|
+
self.huBrowse.clicked.connect(self._doBrowseHunspell)
|
78
|
+
self.huImport = QPushButton(self.tr("Add Dictionary"), self)
|
79
|
+
self.huImport.setIcon(SHARED.theme.getIcon("add"))
|
80
|
+
self.huImport.clicked.connect(self._doImportHunspell)
|
81
|
+
|
82
|
+
self.huPathBox = QHBoxLayout()
|
83
|
+
self.huPathBox.addWidget(self.huInput)
|
84
|
+
self.huPathBox.addWidget(self.huBrowse)
|
85
|
+
self.huPathBox.setSpacing(iPx)
|
86
|
+
self.huAddBox = QHBoxLayout()
|
87
|
+
self.huAddBox.addStretch(1)
|
88
|
+
self.huAddBox.addWidget(self.huImport)
|
89
|
+
|
90
|
+
# Install Path
|
91
|
+
self.inInfo = QLabel(self.tr("Dictionary install location"))
|
92
|
+
self.inPath = QLineEdit(self)
|
93
|
+
self.inPath.setReadOnly(True)
|
94
|
+
self.inBrowse = QPushButton(self)
|
95
|
+
self.inBrowse.setIcon(SHARED.theme.getIcon("browse"))
|
96
|
+
self.inBrowse.clicked.connect(self._doOpenInstallLocation)
|
97
|
+
|
98
|
+
self.inBox = QHBoxLayout()
|
99
|
+
self.inBox.addWidget(self.inPath)
|
100
|
+
self.inBox.addWidget(self.inBrowse)
|
101
|
+
self.inBox.setSpacing(iPx)
|
102
|
+
|
103
|
+
# Info Box
|
104
|
+
self.infoBox = QPlainTextEdit(self)
|
105
|
+
self.infoBox.setReadOnly(True)
|
106
|
+
self.infoBox.setFixedHeight(4*SHARED.theme.fontPixelSize)
|
107
|
+
self.infoBox.setFrameStyle(QFrame.Shape.NoFrame)
|
108
|
+
|
109
|
+
# Buttons
|
110
|
+
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
111
|
+
self.buttonBox.rejected.connect(self._doClose)
|
112
|
+
|
113
|
+
# Assemble
|
114
|
+
self.innerBox = QVBoxLayout()
|
115
|
+
self.innerBox.addWidget(self.huInfo)
|
116
|
+
self.innerBox.addLayout(self.huPathBox)
|
117
|
+
self.innerBox.addLayout(self.huAddBox)
|
118
|
+
self.innerBox.addSpacing(mPx)
|
119
|
+
self.innerBox.addWidget(self.inInfo)
|
120
|
+
self.innerBox.addLayout(self.inBox)
|
121
|
+
self.innerBox.addWidget(self.infoBox)
|
122
|
+
self.innerBox.setSpacing(iPx)
|
123
|
+
|
124
|
+
self.outerBox = QVBoxLayout()
|
125
|
+
self.outerBox.addLayout(self.innerBox, 0)
|
126
|
+
self.outerBox.addStretch(1)
|
127
|
+
self.outerBox.addWidget(self.buttonBox, 0)
|
128
|
+
self.outerBox.setSpacing(sPx)
|
129
|
+
|
130
|
+
self.setLayout(self.outerBox)
|
131
|
+
|
132
|
+
logger.debug("Ready: GuiDictionaries")
|
133
|
+
|
134
|
+
return
|
135
|
+
|
136
|
+
def __del__(self) -> None: # pragma: no cover
|
137
|
+
logger.debug("Delete: GuiDictionaries")
|
138
|
+
return
|
139
|
+
|
140
|
+
def initDialog(self) -> bool:
|
141
|
+
"""Prepare and check that we can proceed."""
|
142
|
+
try:
|
143
|
+
import enchant
|
144
|
+
path = Path(enchant.get_user_config_dir())
|
145
|
+
except Exception:
|
146
|
+
logger.error("Could not get enchant path")
|
147
|
+
return False
|
148
|
+
|
149
|
+
self._installPath = Path(path).resolve()
|
150
|
+
if path.is_dir():
|
151
|
+
self.inPath.setText(str(path))
|
152
|
+
hunspell = path / "hunspell"
|
153
|
+
if hunspell.is_dir():
|
154
|
+
self._currDicts = set(
|
155
|
+
i.stem for i in hunspell.iterdir() if i.is_file() and i.suffix == ".aff"
|
156
|
+
)
|
157
|
+
self._appendLog(self.tr(
|
158
|
+
"Additional dictionaries found: {0}"
|
159
|
+
).format(len(self._currDicts)))
|
160
|
+
|
161
|
+
qApp.processEvents()
|
162
|
+
self.adjustSize()
|
163
|
+
|
164
|
+
return True
|
165
|
+
|
166
|
+
##
|
167
|
+
# Events
|
168
|
+
##
|
169
|
+
|
170
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
171
|
+
"""Capture the user closing the window."""
|
172
|
+
event.accept()
|
173
|
+
self.deleteLater()
|
174
|
+
return
|
175
|
+
|
176
|
+
##
|
177
|
+
# Private Slots
|
178
|
+
##
|
179
|
+
|
180
|
+
@pyqtSlot()
|
181
|
+
def _doBrowseHunspell(self):
|
182
|
+
"""Browse for a Free/Libre Office dictionary."""
|
183
|
+
extFilter = [
|
184
|
+
self.tr("Free or Libre Office extension ({0})").format("*.sox *.oxt"),
|
185
|
+
self.tr("All files ({0})").format("*"),
|
186
|
+
]
|
187
|
+
soxFile, _ = QFileDialog.getOpenFileName(
|
188
|
+
self, self.tr("Browse Files"), "", filter=";;".join(extFilter)
|
189
|
+
)
|
190
|
+
if soxFile:
|
191
|
+
path = Path(soxFile).absolute()
|
192
|
+
self.huInput.setText(str(path))
|
193
|
+
return
|
194
|
+
|
195
|
+
@pyqtSlot()
|
196
|
+
def _doImportHunspell(self):
|
197
|
+
"""Import a hunspell dictionary from .sox or .oxt file."""
|
198
|
+
procErr = self.tr("Could not process dictionary file")
|
199
|
+
if self._installPath:
|
200
|
+
temp = self.huInput.text()
|
201
|
+
if temp and (path := Path(temp)).is_file():
|
202
|
+
hunspell = self._installPath / "hunspell"
|
203
|
+
hunspell.mkdir(exist_ok=True)
|
204
|
+
try:
|
205
|
+
nAff, nDic = self._extractDicts(path, hunspell)
|
206
|
+
if nAff == 0 or nDic == 0:
|
207
|
+
self._appendLog(procErr, err=True)
|
208
|
+
except Exception as exc:
|
209
|
+
self._appendLog(procErr, err=True)
|
210
|
+
self._appendLog(formatException(exc), err=True)
|
211
|
+
else:
|
212
|
+
self._appendLog(procErr, err=True)
|
213
|
+
return
|
214
|
+
|
215
|
+
@pyqtSlot()
|
216
|
+
def _doOpenInstallLocation(self) -> None:
|
217
|
+
"""Open the dictionary folder."""
|
218
|
+
if not openExternalPath(Path(self.inPath.text())):
|
219
|
+
SHARED.error("Path not found.")
|
220
|
+
return
|
221
|
+
|
222
|
+
@pyqtSlot()
|
223
|
+
def _doClose(self) -> None:
|
224
|
+
"""Close the dialog."""
|
225
|
+
self.close()
|
226
|
+
return
|
227
|
+
|
228
|
+
##
|
229
|
+
# Internal Functions
|
230
|
+
##
|
231
|
+
|
232
|
+
def _extractDicts(self, path: Path, output: Path) -> tuple[int, int]:
|
233
|
+
"""Extract a zip archive and return the number of .aff and .dic
|
234
|
+
files found in it.
|
235
|
+
"""
|
236
|
+
nAff = nDic = 0
|
237
|
+
with ZipFile(path, mode="r") as zipObj:
|
238
|
+
for item in zipObj.namelist():
|
239
|
+
zPath = Path(item)
|
240
|
+
if zPath.suffix not in (".aff", ".dic"):
|
241
|
+
continue
|
242
|
+
nAff += 1 if zPath.suffix == ".aff" else 0
|
243
|
+
nDic += 1 if zPath.suffix == ".dic" else 0
|
244
|
+
with zipObj.open(item) as zF:
|
245
|
+
oPath = output / zPath.name
|
246
|
+
oPath.write_bytes(zF.read())
|
247
|
+
size = getFileSize(oPath)
|
248
|
+
self._appendLog(self.tr(
|
249
|
+
"Added: {0} [{1}B]"
|
250
|
+
).format(zPath.name, formatInt(size)))
|
251
|
+
return nAff, nDic
|
252
|
+
|
253
|
+
def _appendLog(self, text: str, err: bool = False) -> None:
|
254
|
+
"""Append a line to the log output."""
|
255
|
+
cursor = self.infoBox.textCursor()
|
256
|
+
cursor.movePosition(QTextCursor.MoveOperation.End)
|
257
|
+
if cursor.position() > 0:
|
258
|
+
cursor.insertText("\n")
|
259
|
+
if err:
|
260
|
+
cursor.insertHtml(f"<font color='red'>{text}</font>")
|
261
|
+
else:
|
262
|
+
cursor.insertText(text)
|
263
|
+
cursor.movePosition(QTextCursor.MoveOperation.End)
|
264
|
+
cursor.deleteChar()
|
265
|
+
self.infoBox.setTextCursor(cursor)
|
266
|
+
return
|
267
|
+
|
268
|
+
# END Class GuiDictionaries
|
novelwriter/tools/manusbuild.py
CHANGED
@@ -27,6 +27,7 @@ import logging
|
|
27
27
|
|
28
28
|
from pathlib import Path
|
29
29
|
|
30
|
+
from PyQt5.QtGui import QCloseEvent
|
30
31
|
from PyQt5.QtCore import QSize, QTimer, Qt, pyqtSlot
|
31
32
|
from PyQt5.QtWidgets import (
|
32
33
|
QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog,
|
@@ -36,7 +37,7 @@ from PyQt5.QtWidgets import (
|
|
36
37
|
|
37
38
|
from novelwriter import CONFIG, SHARED
|
38
39
|
from novelwriter.enum import nwBuildFmt
|
39
|
-
from novelwriter.common import makeFileNameSafe
|
40
|
+
from novelwriter.common import makeFileNameSafe, openExternalPath
|
40
41
|
from novelwriter.constants import nwLabels
|
41
42
|
from novelwriter.core.item import NWItem
|
42
43
|
from novelwriter.core.docbuild import NWBuildDocument
|
@@ -175,9 +176,11 @@ class GuiManuscriptBuild(QDialog):
|
|
175
176
|
self.buildBox.setVerticalSpacing(sp4)
|
176
177
|
|
177
178
|
# Dialog Buttons
|
179
|
+
self.btnOpen = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Open Folder"))
|
178
180
|
self.btnBuild = QPushButton(SHARED.theme.getIcon("export"), self.tr("&Build"))
|
179
|
-
self.dlgButtons = QDialogButtonBox(QDialogButtonBox.Close)
|
180
|
-
self.dlgButtons.addButton(self.
|
181
|
+
self.dlgButtons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
|
182
|
+
self.dlgButtons.addButton(self.btnOpen, QDialogButtonBox.ButtonRole.ActionRole)
|
183
|
+
self.dlgButtons.addButton(self.btnBuild, QDialogButtonBox.ButtonRole.ActionRole)
|
181
184
|
|
182
185
|
# Assemble GUI
|
183
186
|
# ============
|
@@ -227,7 +230,7 @@ class GuiManuscriptBuild(QDialog):
|
|
227
230
|
|
228
231
|
return
|
229
232
|
|
230
|
-
def __del__(self): # pragma: no cover
|
233
|
+
def __del__(self) -> None: # pragma: no cover
|
231
234
|
logger.debug("Delete: GuiManuscriptBuild")
|
232
235
|
return
|
233
236
|
|
@@ -235,7 +238,7 @@ class GuiManuscriptBuild(QDialog):
|
|
235
238
|
# Events
|
236
239
|
##
|
237
240
|
|
238
|
-
def closeEvent(self, event):
|
241
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
239
242
|
"""Capture the user closing the window so we can save GUI
|
240
243
|
settings.
|
241
244
|
"""
|
@@ -253,7 +256,10 @@ class GuiManuscriptBuild(QDialog):
|
|
253
256
|
"""Handle button clicks from the dialog button box."""
|
254
257
|
role = self.dlgButtons.buttonRole(button)
|
255
258
|
if role == QDialogButtonBox.ActionRole:
|
256
|
-
self.
|
259
|
+
if button == self.btnBuild:
|
260
|
+
self._runBuild()
|
261
|
+
elif button == self.btnOpen:
|
262
|
+
self._openOutputFolder()
|
257
263
|
elif role == QDialogButtonBox.RejectRole:
|
258
264
|
self.close()
|
259
265
|
return
|
@@ -385,4 +391,9 @@ class GuiManuscriptBuild(QDialog):
|
|
385
391
|
|
386
392
|
return
|
387
393
|
|
394
|
+
def _openOutputFolder(self):
|
395
|
+
"""Open the build folder in the system's file explorer."""
|
396
|
+
openExternalPath(Path(self.buildPath.text()))
|
397
|
+
return
|
398
|
+
|
388
399
|
# END Class GuiManuscriptBuild
|
novelwriter/tools/manuscript.py
CHANGED
@@ -507,7 +507,7 @@ class _DetailsWidget(QWidget):
|
|
507
507
|
|
508
508
|
self._initExpanded = True
|
509
509
|
|
510
|
-
# Tree
|
510
|
+
# Tree Widget
|
511
511
|
self.listView = QTreeWidget(self)
|
512
512
|
self.listView.setHeaderLabels([self.tr("Setting"), self.tr("Value")])
|
513
513
|
self.listView.setIndentation(SHARED.theme.baseIconSize)
|
@@ -125,7 +125,7 @@ class GuiWritingStats(QDialog):
|
|
125
125
|
pOptions.getInt("GuiWritingStats", "sortOrder", Qt.DescendingOrder),
|
126
126
|
(Qt.AscendingOrder, Qt.DescendingOrder), Qt.DescendingOrder
|
127
127
|
)
|
128
|
-
self.listBox.sortByColumn(sortCol, sortOrder)
|
128
|
+
self.listBox.sortByColumn(sortCol, sortOrder) # type: ignore
|
129
129
|
self.listBox.setSortingEnabled(True)
|
130
130
|
|
131
131
|
# Word Bar
|
@@ -1,4 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
3
|
-
<path d="m12 2c-5.5138 0-10 4.4862-10 10s4.4862 10 10 10c2.02 0 3.965-0.59875 5.6238-1.73 0.57-0.39 0.7175-1.1675 0.32875-1.7375-0.38875-0.57125-1.165-0.715-1.7375-0.32875-1.2425 0.84875-2.7 1.2962-4.215 1.2962-4.1362 0-7.5-3.3638-7.5-7.5s3.3638-7.5 7.5-7.5 7.5 3.3638 7.5 7.5v0.625c0 0.69-0.56 1.25-1.25 1.25s-1.25-0.56-1.25-1.25v-3.75c0-0.69125-0.55875-1.25-1.25-1.25-0.55125 0-1.0062 0.3625-1.1725 0.86-0.725-0.53375-1.6112-0.86-2.5775-0.86-2.4125 0-4.375 1.9625-4.375 4.375s1.9625 4.375 4.375 4.375c1.3062 0 2.4688-0.5875 3.27-1.4988 0.685 0.90375 1.76 1.4988 2.98 1.4988 2.0675 0 3.75-1.6825 3.75-3.75v-0.625c0-5.5138-4.4862-10-10-10zm0 11.875c-1.0338 0-1.875-0.84125-1.875-1.875s0.84125-1.875 1.875-1.875 1.875 0.84125 1.875 1.875-0.84125 1.875-1.875 1.875z" fill="#69c" stroke-width="1.25"/>
|
4
|
-
</svg>
|
@@ -1,4 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<svg width="24" height="24" version="1.2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
3
|
-
<path d="m12 2c-5.5138 0-10 4.4862-10 10s4.4862 10 10 10c2.02 0 3.965-0.59875 5.6238-1.73 0.57-0.39 0.7175-1.1675 0.32875-1.7375-0.38875-0.57125-1.165-0.715-1.7375-0.32875-1.2425 0.84875-2.7 1.2962-4.215 1.2962-4.1362 0-7.5-3.3638-7.5-7.5s3.3638-7.5 7.5-7.5 7.5 3.3638 7.5 7.5v0.625c0 0.69-0.56 1.25-1.25 1.25s-1.25-0.56-1.25-1.25v-3.75c0-0.69125-0.55875-1.25-1.25-1.25-0.55125 0-1.0062 0.3625-1.1725 0.86-0.725-0.53375-1.6112-0.86-2.5775-0.86-2.4125 0-4.375 1.9625-4.375 4.375s1.9625 4.375 4.375 4.375c1.3062 0 2.4688-0.5875 3.27-1.4988 0.685 0.90375 1.76 1.4988 2.98 1.4988 2.0675 0 3.75-1.6825 3.75-3.75v-0.625c0-5.5138-4.4862-10-10-10zm0 11.875c-1.0338 0-1.875-0.84125-1.875-1.875s0.84125-1.875 1.875-1.875 1.875 0.84125 1.875 1.875-0.84125 1.875-1.875 1.875z" fill="#4271ae" stroke-width="1.25"/>
|
4
|
-
</svg>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|