Compare commits
99 commits
master
...
release-5.
Author | SHA1 | Date | |
---|---|---|---|
|
94136262a8 | ||
|
f52947e27e | ||
|
315e88aee9 | ||
|
9104351c89 | ||
|
e58b0a65d2 | ||
|
878d829904 | ||
|
063f77bc6c | ||
|
2a4077414f | ||
|
2a44253802 | ||
|
4712eba0dc | ||
|
983b7814aa | ||
|
e082a21751 | ||
|
7dd1d1bac8 | ||
|
49f57b1049 | ||
|
fbf68a0649 | ||
|
39229dc06a | ||
|
bb314e1555 | ||
|
a3a8b15828 | ||
|
b579afe1aa | ||
|
93096dba56 | ||
|
6379c33964 | ||
|
84372de675 | ||
|
403b7c7c35 | ||
|
b2fab43865 | ||
|
387821267f | ||
|
dd7ef8e934 | ||
|
cce295faeb | ||
|
db5479ea01 | ||
|
e1216c4c9a | ||
|
f4a0868426 | ||
|
59a5fcf7d0 | ||
|
f9a2b02a8d | ||
|
04f6a565f3 | ||
|
3e96048ee4 | ||
|
d4ccf3001c | ||
|
64506f16bd | ||
|
24a7a835af | ||
|
93b9bf9552 | ||
|
f4125601de | ||
|
2d67729617 | ||
|
878ebbed41 | ||
|
c61c3d7cd8 | ||
|
978fbbdc0d | ||
|
63689cf763 | ||
|
cebc72d3cf | ||
|
a67bd271c6 | ||
|
a8cffbb205 | ||
|
7dfb0110d4 | ||
|
3ad8fcbdd2 | ||
|
195eae5f3d | ||
|
920ae26f7b | ||
|
09ed0d6b66 | ||
|
4f0cc8aa11 | ||
|
4d490c84e7 | ||
|
96607ce874 | ||
|
418edc7471 | ||
|
bd01b7c4df | ||
|
b0ac763048 | ||
|
127d2d6f0b | ||
|
4149609e78 | ||
|
78c549f83e | ||
|
a3a53e2e0e | ||
|
5aaa43e01d | ||
|
86745d7b07 | ||
|
210650a5ee | ||
|
fe93b6d0d8 | ||
|
e8b585acd8 | ||
|
cea20141a9 | ||
|
0f5a27ed50 | ||
|
c2cf898ccd | ||
|
5e5aa8a563 | ||
|
12a4c3fda2 | ||
|
5f50b701d2 | ||
|
9f20d9c3aa | ||
|
05e3130baa | ||
|
683492648f | ||
|
2f2e158877 | ||
|
e60e96cb0e | ||
|
5f31208bf1 | ||
|
fa58e58e70 | ||
|
671943a9a6 | ||
|
8bad80bcdd | ||
|
c44e300507 | ||
|
318a677e8f | ||
|
0246df790a | ||
|
782fbc1425 | ||
|
7deccd5592 | ||
|
4a36fe7278 | ||
|
1c5af96ad8 | ||
|
3bb47a5410 | ||
|
d7abeb4bf0 | ||
|
a19d623ead | ||
|
1ef21bc2b7 | ||
|
4687b4e8e4 | ||
|
d2e5163861 | ||
|
8a15ea8026 | ||
|
2b99554813 | ||
|
e6638f9c19 | ||
|
ec6eac2ba1 |
7
.github/workflows/ci_macos.yaml
vendored
|
@ -23,7 +23,6 @@ jobs:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
boost_path: "${{ github.workspace }}/../boost"
|
boost_path: "${{ github.workspace }}/../boost"
|
||||||
openssl_root: "$(brew --prefix openssl@3)"
|
|
||||||
libtorrent_path: "${{ github.workspace }}/../libtorrent"
|
libtorrent_path: "${{ github.workspace }}/../libtorrent"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -70,7 +69,7 @@ jobs:
|
||||||
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v3
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.qt_version }}
|
version: ${{ matrix.qt_version }}
|
||||||
archives: qtbase qtdeclarative qtsvg qttools
|
archives: qtbase qtdeclarative qtsvg qttools
|
||||||
|
@ -94,8 +93,7 @@ jobs:
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||||
-DBOOST_ROOT="${{ env.boost_path }}" \
|
-DBOOST_ROOT="${{ env.boost_path }}" \
|
||||||
-Ddeprecated-functions=OFF \
|
-Ddeprecated-functions=OFF
|
||||||
-DOPENSSL_ROOT_DIR="${{ env.openssl_root }}"
|
|
||||||
cmake --build build
|
cmake --build build
|
||||||
sudo cmake --install build
|
sudo cmake --install build
|
||||||
|
|
||||||
|
@ -109,7 +107,6 @@ jobs:
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||||
-DBOOST_ROOT="${{ env.boost_path }}" \
|
-DBOOST_ROOT="${{ env.boost_path }}" \
|
||||||
-DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \
|
|
||||||
-DTESTING=ON \
|
-DTESTING=ON \
|
||||||
-DVERBOSE_CONFIGURE=ON \
|
-DVERBOSE_CONFIGURE=ON \
|
||||||
-D${{ matrix.qbt_gui }}
|
-D${{ matrix.qbt_gui }}
|
||||||
|
|
12
.github/workflows/ci_python.yaml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
||||||
python-version: '3.7'
|
python-version: '3.7'
|
||||||
|
|
||||||
- name: Install tools (search engine)
|
- name: Install tools (search engine)
|
||||||
run: pip install bandit pycodestyle pyflakes
|
run: pip install bandit mypy pycodestyle pyflakes pyright
|
||||||
|
|
||||||
- name: Gather files (search engine)
|
- name: Gather files (search engine)
|
||||||
run: |
|
run: |
|
||||||
|
@ -61,6 +61,16 @@ jobs:
|
||||||
echo $PY_FILES
|
echo $PY_FILES
|
||||||
echo "PY_FILES=$PY_FILES" >> "$GITHUB_ENV"
|
echo "PY_FILES=$PY_FILES" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Check typings (search engine)
|
||||||
|
run: |
|
||||||
|
MYPYPATH="src/searchengine/nova3" \
|
||||||
|
mypy \
|
||||||
|
--follow-imports skip \
|
||||||
|
--strict \
|
||||||
|
$PY_FILES
|
||||||
|
pyright \
|
||||||
|
$PY_FILES
|
||||||
|
|
||||||
- name: Lint code (search engine)
|
- name: Lint code (search engine)
|
||||||
run: |
|
run: |
|
||||||
pyflakes $PY_FILES
|
pyflakes $PY_FILES
|
||||||
|
|
14
.github/workflows/ci_ubuntu.yaml
vendored
|
@ -64,7 +64,7 @@ jobs:
|
||||||
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v3
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.qt_version }}
|
version: ${{ matrix.qt_version }}
|
||||||
archives: icu qtbase qtdeclarative qtsvg qttools
|
archives: icu qtbase qtdeclarative qtsvg qttools
|
||||||
|
@ -138,12 +138,12 @@ jobs:
|
||||||
curl \
|
curl \
|
||||||
-L \
|
-L \
|
||||||
-Z \
|
-Z \
|
||||||
-O https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage \
|
-O https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-static-x86_64.AppImage \
|
||||||
-O https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage \
|
-O https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-static-x86_64.AppImage \
|
||||||
-O https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage
|
-O https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage
|
||||||
chmod +x \
|
chmod +x \
|
||||||
linuxdeploy-x86_64.AppImage \
|
linuxdeploy-static-x86_64.AppImage \
|
||||||
linuxdeploy-plugin-qt-x86_64.AppImage \
|
linuxdeploy-plugin-qt-static-x86_64.AppImage \
|
||||||
linuxdeploy-plugin-appimage-x86_64.AppImage
|
linuxdeploy-plugin-appimage-x86_64.AppImage
|
||||||
|
|
||||||
- name: Prepare files for AppImage
|
- name: Prepare files for AppImage
|
||||||
|
@ -156,12 +156,12 @@ jobs:
|
||||||
|
|
||||||
- name: Package AppImage
|
- name: Package AppImage
|
||||||
run: |
|
run: |
|
||||||
./linuxdeploy-x86_64.AppImage --appdir qbittorrent --plugin qt
|
./linuxdeploy-static-x86_64.AppImage --appdir qbittorrent --plugin qt
|
||||||
rm qbittorrent/apprun-hooks/*
|
rm qbittorrent/apprun-hooks/*
|
||||||
cp .github/workflows/helper/appimage/export_vars.sh qbittorrent/apprun-hooks/export_vars.sh
|
cp .github/workflows/helper/appimage/export_vars.sh qbittorrent/apprun-hooks/export_vars.sh
|
||||||
NO_APPSTREAM=1 \
|
NO_APPSTREAM=1 \
|
||||||
OUTPUT=upload/qbittorrent-CI_Ubuntu_x86_64.AppImage \
|
OUTPUT=upload/qbittorrent-CI_Ubuntu_x86_64.AppImage \
|
||||||
./linuxdeploy-x86_64.AppImage --appdir qbittorrent --output appimage
|
./linuxdeploy-static-x86_64.AppImage --appdir qbittorrent --output appimage
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|
32
.github/workflows/ci_windows.yaml
vendored
|
@ -93,9 +93,9 @@ jobs:
|
||||||
move "${{ github.workspace }}/../boost_*" "${{ env.boost_path }}"
|
move "${{ github.workspace }}/../boost_*" "${{ env.boost_path }}"
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v3
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: "6.7.0"
|
version: "6.7.3"
|
||||||
archives: qtbase qtsvg qttools
|
archives: qtbase qtsvg qttools
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
|
@ -153,26 +153,26 @@ jobs:
|
||||||
copy build/qbittorrent.pdb upload/qBittorrent
|
copy build/qbittorrent.pdb upload/qBittorrent
|
||||||
copy dist/windows/qt.conf upload/qBittorrent
|
copy dist/windows/qt.conf upload/qBittorrent
|
||||||
# runtimes
|
# runtimes
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Core.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Core.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Network.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Network.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent
|
||||||
copy "${{ env.Qt6_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent
|
copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent
|
||||||
mkdir upload/qBittorrent/plugins/iconengines
|
mkdir upload/qBittorrent/plugins/iconengines
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines
|
||||||
mkdir upload/qBittorrent/plugins/imageformats
|
mkdir upload/qBittorrent/plugins/imageformats
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats
|
||||||
mkdir upload/qBittorrent/plugins/platforms
|
mkdir upload/qBittorrent/plugins/platforms
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms
|
||||||
mkdir upload/qBittorrent/plugins/sqldrivers
|
mkdir upload/qBittorrent/plugins/sqldrivers
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers
|
||||||
mkdir upload/qBittorrent/plugins/styles
|
mkdir upload/qBittorrent/plugins/styles
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles
|
||||||
mkdir upload/qBittorrent/plugins/tls
|
mkdir upload/qBittorrent/plugins/tls
|
||||||
copy "${{ env.Qt6_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls
|
copy "${{ env.Qt_ROOT_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls
|
||||||
# cmake additionals
|
# cmake additionals
|
||||||
mkdir upload/cmake
|
mkdir upload/cmake
|
||||||
copy build/compile_commands.json upload/cmake
|
copy build/compile_commands.json upload/cmake
|
||||||
|
|
2
.github/workflows/coverity-scan.yaml
vendored
|
@ -52,7 +52,7 @@ jobs:
|
||||||
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v3
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.qt_version }}
|
version: ${{ matrix.qt_version }}
|
||||||
archives: icu qtbase qtdeclarative qtsvg qttools
|
archives: icu qtbase qtdeclarative qtsvg qttools
|
||||||
|
|
|
@ -78,11 +78,7 @@ repos:
|
||||||
m4/.* |
|
m4/.* |
|
||||||
src/base/3rdparty/.* |
|
src/base/3rdparty/.* |
|
||||||
src/searchengine/nova3/socks.py |
|
src/searchengine/nova3/socks.py |
|
||||||
src/webui/www/private/lang/.* |
|
src/webui/www/private/scripts/lib/.*
|
||||||
src/webui/www/private/scripts/lib/.* |
|
|
||||||
src/webui/www/public/lang/.* |
|
|
||||||
src/webui/www/public/scripts/lib/.* |
|
|
||||||
src/webui/www/transifex/.*
|
|
||||||
)$
|
)$
|
||||||
exclude_types:
|
exclude_types:
|
||||||
- ts
|
- ts
|
||||||
|
@ -106,11 +102,7 @@ repos:
|
||||||
m4/.* |
|
m4/.* |
|
||||||
src/base/3rdparty/.* |
|
src/base/3rdparty/.* |
|
||||||
src/searchengine/nova3/socks.py |
|
src/searchengine/nova3/socks.py |
|
||||||
src/webui/www/private/lang/.* |
|
src/webui/www/private/scripts/lib/.*
|
||||||
src/webui/www/private/scripts/lib/.* |
|
|
||||||
src/webui/www/public/lang/.* |
|
|
||||||
src/webui/www/public/scripts/lib/.* |
|
|
||||||
src/webui/www/transifex/.*
|
|
||||||
)$
|
)$
|
||||||
exclude_types:
|
exclude_types:
|
||||||
- svg
|
- svg
|
||||||
|
|
12
.tx/config
|
@ -1,7 +1,7 @@
|
||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
|
|
||||||
[o:sledgehammer999:p:qbittorrent:r:qbittorrent_master]
|
[o:sledgehammer999:p:qbittorrent:r:qbittorrent_v50x]
|
||||||
file_filter = src/lang/qbittorrent_<lang>.ts
|
file_filter = src/lang/qbittorrent_<lang>.ts
|
||||||
source_file = src/lang/qbittorrent_en.ts
|
source_file = src/lang/qbittorrent_en.ts
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
@ -9,7 +9,7 @@ type = QT
|
||||||
minimum_perc = 23
|
minimum_perc = 23
|
||||||
lang_map = pt: pt_PT, zh: zh_CN
|
lang_map = pt: pt_PT, zh: zh_CN
|
||||||
|
|
||||||
[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui]
|
[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_v50x]
|
||||||
file_filter = src/webui/www/translations/webui_<lang>.ts
|
file_filter = src/webui/www/translations/webui_<lang>.ts
|
||||||
source_file = src/webui/www/translations/webui_en.ts
|
source_file = src/webui/www/translations/webui_en.ts
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
@ -17,14 +17,6 @@ type = QT
|
||||||
minimum_perc = 23
|
minimum_perc = 23
|
||||||
lang_map = pt: pt_PT, zh: zh_CN
|
lang_map = pt: pt_PT, zh: zh_CN
|
||||||
|
|
||||||
[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_json]
|
|
||||||
file_filter = src/webui/www/transifex/<lang>.json
|
|
||||||
source_file = src/webui/www/transifex/en.json
|
|
||||||
source_lang = en
|
|
||||||
type = KEYVALUEJSON
|
|
||||||
minimum_perc = 23
|
|
||||||
lang_map = pt: pt_PT, zh: zh_CN
|
|
||||||
|
|
||||||
[o:sledgehammer999:p:qbittorrent:r:qbittorrentdesktop_master]
|
[o:sledgehammer999:p:qbittorrent:r:qbittorrentdesktop_master]
|
||||||
source_file = dist/unix/org.qbittorrent.qBittorrent.desktop
|
source_file = dist/unix/org.qbittorrent.qBittorrent.desktop
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
|
63
Changelog
|
@ -1,4 +1,24 @@
|
||||||
Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0
|
Mon Oct 28th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.1
|
||||||
|
- FEATURE: Add "Simple pread/pwrite" disk IO type (Hanabishi)
|
||||||
|
- BUGFIX: Don't ignore SSL errors (sledgehammer999)
|
||||||
|
- BUGFIX: Don't try to apply Mark-of-the-Web to nonexistent files (glassez)
|
||||||
|
- BUGFIX: Disable "Move to trash" option by default (glassez)
|
||||||
|
- BUGFIX: Disable the ability to create torrents with a piece size of 256MiB (stalkerok)
|
||||||
|
- BUGFIX: Allow to choose Qt style (glassez)
|
||||||
|
- BUGFIX: Always notify user about duplicate torrent (glassez)
|
||||||
|
- BUGFIX: Correctly handle "torrent finished after move" event (glassez)
|
||||||
|
- BUGFIX: Correctly apply filename filter when `!qB` extension is enabled (glassez)
|
||||||
|
- BUGFIX: Improve color scheme change detection (glassez)
|
||||||
|
- BUGFIX: Fix button state for SSL certificate check (Chocobo1)
|
||||||
|
- WEBUI: Fix CSS that results in hidden torrent list in some browsers (skomerko)
|
||||||
|
- WEBUI: Use proper text color to highlight items in all filter lists (skomerko)
|
||||||
|
- WEBUI: Fix 'rename files' dialog cannot be opened more than once (Chocobo1)
|
||||||
|
- WEBUI: Fix UI of Advanced Settings to show all settings (glassez)
|
||||||
|
- WEBUI: Free resources allocated by web session once it is destructed (dyseg)
|
||||||
|
- SEARCH: Import correct libraries (Chocobo1)
|
||||||
|
- OTHER: Sync flag icons with upstream (xavier2k6)
|
||||||
|
|
||||||
|
Sun Sep 29th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0
|
||||||
- FEATURE: Support creating .torrent with larger piece size (Chocobo1)
|
- FEATURE: Support creating .torrent with larger piece size (Chocobo1)
|
||||||
- FEATURE: Improve tracker entries handling (glassez)
|
- FEATURE: Improve tracker entries handling (glassez)
|
||||||
- FEATURE: Add separate filter item for tracker errors (glassez)
|
- FEATURE: Add separate filter item for tracker errors (glassez)
|
||||||
|
@ -12,14 +32,30 @@ Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0
|
||||||
- FEATURE: Enable Ctrl+F hotkey for more inputs (thalieht)
|
- FEATURE: Enable Ctrl+F hotkey for more inputs (thalieht)
|
||||||
- FEATURE: Add seeding limits to RSS and Watched folders options UI (glassez)
|
- FEATURE: Add seeding limits to RSS and Watched folders options UI (glassez)
|
||||||
- FEATURE: Subcategories implicitly follow the parent category options (glassez)
|
- FEATURE: Subcategories implicitly follow the parent category options (glassez)
|
||||||
- FEATURE: Add support for SSL torrents (Chocobo1, Radu Carpa)
|
|
||||||
- FEATURE: Add option to name each qbittorrent instance (Chocobo1)
|
- FEATURE: Add option to name each qbittorrent instance (Chocobo1)
|
||||||
- FEATURE: Add button for sending test email (Thomas Piccirello)
|
- FEATURE: Add button for sending test email (Thomas Piccirello)
|
||||||
- FEATURE: Allow torrents to override default share limit action (glassez)
|
- FEATURE: Allow torrents to override default share limit action (glassez)
|
||||||
|
- FEATURE: Use Start/Stop instead of Resume/Pause (thalieht)
|
||||||
|
- FEATURE: Add the Popularity metric (Aliaksei Urbanski)
|
||||||
|
- FEATURE: Focus on Download button if torrent link retrieved from the clipboard (glassez)
|
||||||
|
- FEATURE: Add ability to pause/resume entire BitTorrent session (glassez)
|
||||||
|
- FEATURE: Add an option to set BitTorrent session shutdown timeout (glassez)
|
||||||
|
- FEATURE: Apply "Excluded file names" to folder names as well (glassez)
|
||||||
|
- FEATURE: Allow to use regular expression to filter torrent content (glassez)
|
||||||
|
- FEATURE: Allow to move content files to Trash instead of deleting them (glassez)
|
||||||
|
- FEATURE: Add ability to display torrent "privateness" in UI (ManiMatter)
|
||||||
|
- FEATURE: Add a flag in `Peers` tab denoting a connection using NAT hole punching (stalkerok)
|
||||||
- BUGFIX: Display error message when unrecoverable error occurred (glassez)
|
- BUGFIX: Display error message when unrecoverable error occurred (glassez)
|
||||||
- BUGFIX: Update size of selected files when selection is changed (glassez)
|
- BUGFIX: Update size of selected files when selection is changed (glassez)
|
||||||
- BUGFIX: Normalize tags by trimming leading/trailing whitespace (glassez)
|
- BUGFIX: Normalize tags by trimming leading/trailing whitespace (glassez)
|
||||||
- BUGFIX: Correctly handle share limits in torrent options dialog (glassez)
|
- BUGFIX: Correctly handle share limits in torrent options dialog (glassez)
|
||||||
|
- BUGFIX: Adjust tracker tier when adding additional trackers (Chocobo1)
|
||||||
|
- BUGFIX: Fix inconsistent naming between `Done/Progress` column (luzpaz)
|
||||||
|
- BUGFIX: Sanitize peer client names (Hanabishi)
|
||||||
|
- BUGFIX: Apply share limits immediately when torrent downloading is finished (glassez)
|
||||||
|
- BUGFIX: Show download progress for folders with zero byte size as 100 instead of 0 (vikas_c)
|
||||||
|
- BUGFIX: Fix highlighted piece color (Prince Gupta)
|
||||||
|
- BUGFIX: Apply "merge trackers" logic regardless of way the torrent is added (glassez)
|
||||||
- WEBUI: Improve WebUI responsiveness (Chocobo1)
|
- WEBUI: Improve WebUI responsiveness (Chocobo1)
|
||||||
- WEBUI: Do not exit the app when WebUI has failed to start (Hanabishi)
|
- WEBUI: Do not exit the app when WebUI has failed to start (Hanabishi)
|
||||||
- WEBUI: Add `Moving` filter to side panel (xavier2k6)
|
- WEBUI: Add `Moving` filter to side panel (xavier2k6)
|
||||||
|
@ -28,14 +64,37 @@ Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0
|
||||||
- WEBUI: Leave the fields empty when value is invalid (Chocobo1)
|
- WEBUI: Leave the fields empty when value is invalid (Chocobo1)
|
||||||
- WEBUI: Use natural sorting (Chocobo1)
|
- WEBUI: Use natural sorting (Chocobo1)
|
||||||
- WEBUI: Improve WebUI login behavior (JayRet)
|
- WEBUI: Improve WebUI login behavior (JayRet)
|
||||||
|
- WEBUI: Conditionally show filters sidebar (Thomas Piccirello)
|
||||||
|
- WEBUI: Add support for running concurrent searches (Thomas Piccirello)
|
||||||
|
- WEBUI: Improve accuracy of trackers list (Thomas Piccirello)
|
||||||
|
- WEBUI: Fix error when category doesn't exist (Thomas Piccirello)
|
||||||
|
- WEBUI: Improve table scrolling and selection on mobile (Thomas Piccirello)
|
||||||
|
- WEBUI: Restore search tabs on load (Thomas Piccirello)
|
||||||
|
- WEBUI: Restore previously used tab on load (Thomas Piccirello)
|
||||||
|
- WEBUI: Increase default height of `Share ratio limit` dialog (thalieht)
|
||||||
|
- WEBUI: Use enabled search plugins by default (Thomas Piccirello)
|
||||||
|
- WEBUI: Add columns `Incomplete Save Path`, `Info Hash v1`, `Info Hash v2` (thalieht)
|
||||||
|
- WEBUI: Always create generic filter items (skomerko)
|
||||||
|
- WEBUI: Provide `Use Category paths in Manual Mode` option (skomerko)
|
||||||
|
- WEBUI: Provide `Merge trackers to existing torrent` option (skomerko)
|
||||||
- WEBAPI: Fix wrong timestamp values (Chocobo1)
|
- WEBAPI: Fix wrong timestamp values (Chocobo1)
|
||||||
- WEBAPI: Send binary data with filename and mime type specified (glassez)
|
- WEBAPI: Send binary data with filename and mime type specified (glassez)
|
||||||
- WEBAPI: Expose API for the torrent creator (glassez, Radu Carpa)
|
- WEBAPI: Expose API for the torrent creator (glassez, Radu Carpa)
|
||||||
|
- WEBAPI: Add support for SSL torrents (Chocobo1, Radu Carpa)
|
||||||
|
- WEBAPI: Provide endpoint for listing directory content (Paweł Kotiuk)
|
||||||
|
- WEBAPI: Provide "private" flag via "torrents/info" endpoint (ManiMatter)
|
||||||
|
- WEBAPI: Add a way to download .torrent file using search plugin (glassez)
|
||||||
|
- WEBAPI: Add "private" filter for "torrents/info" endpoint (ManiMatter)
|
||||||
|
- WEBAPI: Add root_path to "torrents/info" result (David Newhall)
|
||||||
- RSS: Show RSS feed title in HTML browser (Jay)
|
- RSS: Show RSS feed title in HTML browser (Jay)
|
||||||
- RSS: Allow to set delay between requests to the same host (jNullj)
|
- RSS: Allow to set delay between requests to the same host (jNullj)
|
||||||
- SEARCH: Allow users to specify Python executable path (Chocobo1)
|
- SEARCH: Allow users to specify Python executable path (Chocobo1)
|
||||||
|
- SEARCH: Lazy load search plugins (milahu)
|
||||||
|
- SEARCH: Add date column to the built-in search engine (ducalex)
|
||||||
|
- SEARCH: Allow to rearrange search tabs (glassez)
|
||||||
- WINDOWS: Use Fusion style on Windows 10+. It has better compatibility with dark mode (glassez)
|
- WINDOWS: Use Fusion style on Windows 10+. It has better compatibility with dark mode (glassez)
|
||||||
- WINDOWS: Allow to set qBittorrent as default program (glassez)
|
- WINDOWS: Allow to set qBittorrent as default program (glassez)
|
||||||
|
- WINDOWS: Don't access "Favorites" folder unexpectedly (glassez)
|
||||||
- LINUX: Add support for systemd power management (Chocobo1)
|
- LINUX: Add support for systemd power management (Chocobo1)
|
||||||
- LINUX: Add support for localized man pages (Victor Chernyakin)
|
- LINUX: Add support for localized man pages (Victor Chernyakin)
|
||||||
- LINUX: Specify a locale if none is set (Chocobo1)
|
- LINUX: Specify a locale if none is set (Chocobo1)
|
||||||
|
|
2
dist/mac/Info.plist
vendored
|
@ -55,7 +55,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>5.0.0</string>
|
<string>5.0.1</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>${EXECUTABLE_NAME}</string>
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
|
146
dist/unix/org.qbittorrent.qBittorrent.desktop
vendored
|
@ -14,216 +14,220 @@ Keywords=bittorrent;torrent;magnet;download;p2p;
|
||||||
SingleMainWindow=true
|
SingleMainWindow=true
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Comment[af]=Aflaai en deel lêers oor BitTorrent
|
|
||||||
GenericName[af]=BitTorrent kliënt
|
GenericName[af]=BitTorrent kliënt
|
||||||
|
Comment[af]=Aflaai en deel lêers oor BitTorrent
|
||||||
Name[af]=qBittorrent
|
Name[af]=qBittorrent
|
||||||
Comment[ar]=نزّل وشارك الملفات عبر كيوبتتورنت
|
|
||||||
GenericName[ar]=عميل بتتورنت
|
GenericName[ar]=عميل بتتورنت
|
||||||
|
Comment[ar]=نزّل وشارك الملفات عبر كيوبتتورنت
|
||||||
Name[ar]=qBittorrent
|
Name[ar]=qBittorrent
|
||||||
Comment[be]=Спампоўванне і раздача файлаў праз пратакол BitTorrent
|
|
||||||
GenericName[be]=Кліент BitTorrent
|
GenericName[be]=Кліент BitTorrent
|
||||||
|
Comment[be]=Спампоўванне і раздача файлаў праз пратакол BitTorrent
|
||||||
Name[be]=qBittorrent
|
Name[be]=qBittorrent
|
||||||
Comment[bg]=Сваляне и споделяне на файлове чрез BitTorrent
|
|
||||||
GenericName[bg]=BitTorrent клиент
|
GenericName[bg]=BitTorrent клиент
|
||||||
|
Comment[bg]=Сваляне и споделяне на файлове чрез BitTorrent
|
||||||
Name[bg]=qBittorrent
|
Name[bg]=qBittorrent
|
||||||
Comment[bn]=বিটটরেন্টে ফাইল ডাউনলোড এবং শেয়ার করুন
|
|
||||||
GenericName[bn]=বিটটরেন্ট ক্লায়েন্ট
|
GenericName[bn]=বিটটরেন্ট ক্লায়েন্ট
|
||||||
|
Comment[bn]=বিটটরেন্টে ফাইল ডাউনলোড এবং শেয়ার করুন
|
||||||
Name[bn]=qBittorrent
|
Name[bn]=qBittorrent
|
||||||
Comment[zh]=通过 BitTorrent 下载和分享文件
|
|
||||||
GenericName[zh]=BitTorrent 客户端
|
GenericName[zh]=BitTorrent 客户端
|
||||||
|
Comment[zh]=通过 BitTorrent 下载和分享文件
|
||||||
Name[zh]=qBittorrent
|
Name[zh]=qBittorrent
|
||||||
Comment[bs]=Preuzmi i dijeli datoteke preko BitTorrent-a
|
|
||||||
GenericName[bs]=BitTorrent klijent
|
GenericName[bs]=BitTorrent klijent
|
||||||
|
Comment[bs]=Preuzmi i dijeli datoteke preko BitTorrent-a
|
||||||
Name[bs]=qBittorrent
|
Name[bs]=qBittorrent
|
||||||
Comment[ca]=Baixeu i compartiu fitxers amb el BitTorrent
|
|
||||||
GenericName[ca]=Client de BitTorrent
|
GenericName[ca]=Client de BitTorrent
|
||||||
|
Comment[ca]=Baixeu i compartiu fitxers amb el BitTorrent
|
||||||
Name[ca]=qBittorrent
|
Name[ca]=qBittorrent
|
||||||
Comment[cs]=Stahování a sdílení souborů přes síť BitTorrent
|
|
||||||
GenericName[cs]=BitTorrent klient
|
GenericName[cs]=BitTorrent klient
|
||||||
|
Comment[cs]=Stahování a sdílení souborů přes síť BitTorrent
|
||||||
Name[cs]=qBittorrent
|
Name[cs]=qBittorrent
|
||||||
Comment[da]=Download og del filer over BitTorrent
|
|
||||||
GenericName[da]=BitTorrent-klient
|
GenericName[da]=BitTorrent-klient
|
||||||
|
Comment[da]=Download og del filer over BitTorrent
|
||||||
Name[da]=qBittorrent
|
Name[da]=qBittorrent
|
||||||
Comment[de]=Über BitTorrent Dateien herunterladen und teilen
|
|
||||||
GenericName[de]=BitTorrent Client
|
GenericName[de]=BitTorrent Client
|
||||||
|
Comment[de]=Über BitTorrent Dateien herunterladen und teilen
|
||||||
Name[de]=qBittorrent
|
Name[de]=qBittorrent
|
||||||
Comment[el]=Κάντε λήψη και μοιραστείτε αρχεία μέσω BitTorrent
|
|
||||||
GenericName[el]=BitTorrent client
|
GenericName[el]=BitTorrent client
|
||||||
|
Comment[el]=Κάντε λήψη και μοιραστείτε αρχεία μέσω BitTorrent
|
||||||
Name[el]=qBittorrent
|
Name[el]=qBittorrent
|
||||||
Comment[en_GB]=Download and share files over BitTorrent
|
|
||||||
GenericName[en_GB]=BitTorrent client
|
GenericName[en_GB]=BitTorrent client
|
||||||
|
Comment[en_GB]=Download and share files over BitTorrent
|
||||||
Name[en_GB]=qBittorrent
|
Name[en_GB]=qBittorrent
|
||||||
Comment[es]=Descargue y comparta archivos por BitTorrent
|
|
||||||
GenericName[es]=Cliente BitTorrent
|
GenericName[es]=Cliente BitTorrent
|
||||||
|
Comment[es]=Descargue y comparta archivos por BitTorrent
|
||||||
Name[es]=qBittorrent
|
Name[es]=qBittorrent
|
||||||
Comment[et]=Lae alla ja jaga faile üle BitTorrenti
|
|
||||||
GenericName[et]=BitTorrent klient
|
GenericName[et]=BitTorrent klient
|
||||||
|
Comment[et]=Lae alla ja jaga faile üle BitTorrenti
|
||||||
Name[et]=qBittorrent
|
Name[et]=qBittorrent
|
||||||
Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
|
|
||||||
GenericName[eu]=BitTorrent bezeroa
|
GenericName[eu]=BitTorrent bezeroa
|
||||||
|
Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
|
||||||
Name[eu]=qBittorrent
|
Name[eu]=qBittorrent
|
||||||
Comment[fa]=دانلود و به اشتراک گذاری فایل های بوسیله بیت تورنت
|
|
||||||
GenericName[fa]=بیت تورنت نسخه کلاینت
|
GenericName[fa]=بیت تورنت نسخه کلاینت
|
||||||
|
Comment[fa]=دانلود و به اشتراک گذاری فایل های بوسیله بیت تورنت
|
||||||
Name[fa]=qBittorrent
|
Name[fa]=qBittorrent
|
||||||
Comment[fi]=Lataa ja jaa tiedostoja BitTorrentia käyttäen
|
|
||||||
GenericName[fi]=BitTorrent-asiakasohjelma
|
GenericName[fi]=BitTorrent-asiakasohjelma
|
||||||
|
Comment[fi]=Lataa ja jaa tiedostoja BitTorrentia käyttäen
|
||||||
Name[fi]=qBittorrent
|
Name[fi]=qBittorrent
|
||||||
Comment[fr]=Télécharger et partager des fichiers sur BitTorrent
|
|
||||||
GenericName[fr]=Client BitTorrent
|
GenericName[fr]=Client BitTorrent
|
||||||
|
Comment[fr]=Télécharger et partager des fichiers sur BitTorrent
|
||||||
Name[fr]=qBittorrent
|
Name[fr]=qBittorrent
|
||||||
Comment[gl]=Descargar e compartir ficheiros co protocolo BitTorrent
|
|
||||||
GenericName[gl]=Cliente BitTorrent
|
GenericName[gl]=Cliente BitTorrent
|
||||||
|
Comment[gl]=Descargar e compartir ficheiros co protocolo BitTorrent
|
||||||
Name[gl]=qBittorrent
|
Name[gl]=qBittorrent
|
||||||
Comment[gu]=બિટ્ટોરેંટ પર ફાઈલો ડાઉનલોડ અને શેર કરો
|
|
||||||
GenericName[gu]=બિટ્ટોરેંટ ક્લાયન્ટ
|
GenericName[gu]=બિટ્ટોરેંટ ક્લાયન્ટ
|
||||||
|
Comment[gu]=બિટ્ટોરેંટ પર ફાઈલો ડાઉનલોડ અને શેર કરો
|
||||||
Name[gu]=qBittorrent
|
Name[gu]=qBittorrent
|
||||||
Comment[he]=הורד ושתף קבצים על גבי ביטורנט
|
|
||||||
GenericName[he]=לקוח ביטורנט
|
GenericName[he]=לקוח ביטורנט
|
||||||
|
Comment[he]=הורד ושתף קבצים על גבי ביטורנט
|
||||||
Name[he]=qBittorrent
|
Name[he]=qBittorrent
|
||||||
Comment[hr]=Preuzmite i dijelite datoteke putem BitTorrenta
|
|
||||||
GenericName[hr]=BitTorrent klijent
|
GenericName[hr]=BitTorrent klijent
|
||||||
|
Comment[hr]=Preuzmite i dijelite datoteke putem BitTorrenta
|
||||||
Name[hr]=qBittorrent
|
Name[hr]=qBittorrent
|
||||||
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
|
||||||
GenericName[hu]=BitTorrent kliens
|
GenericName[hu]=BitTorrent kliens
|
||||||
|
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
||||||
Name[hu]=qBittorrent
|
Name[hu]=qBittorrent
|
||||||
Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
|
|
||||||
GenericName[hy]=BitTorrent սպասառու
|
GenericName[hy]=BitTorrent սպասառու
|
||||||
|
Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
|
||||||
Name[hy]=qBittorrent
|
Name[hy]=qBittorrent
|
||||||
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
|
||||||
GenericName[id]=Klien BitTorrent
|
GenericName[id]=Klien BitTorrent
|
||||||
|
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
||||||
Name[id]=qBittorrent
|
Name[id]=qBittorrent
|
||||||
Comment[is]=Sækja og deila skrám yfir BitTorrent
|
|
||||||
GenericName[is]=BitTorrent biðlarar
|
GenericName[is]=BitTorrent biðlarar
|
||||||
|
Comment[is]=Sækja og deila skrám yfir BitTorrent
|
||||||
Name[is]=qBittorrent
|
Name[is]=qBittorrent
|
||||||
Comment[it]=Scarica e condividi file tramite BitTorrent
|
|
||||||
GenericName[it]=Client BitTorrent
|
GenericName[it]=Client BitTorrent
|
||||||
|
Comment[it]=Scarica e condividi file tramite BitTorrent
|
||||||
Name[it]=qBittorrent
|
Name[it]=qBittorrent
|
||||||
Comment[ja]=BitTorrentでファイルのダウンロードと共有
|
|
||||||
GenericName[ja]=BitTorrentクライアント
|
GenericName[ja]=BitTorrentクライアント
|
||||||
|
Comment[ja]=BitTorrentでファイルのダウンロードと共有
|
||||||
Name[ja]=qBittorrent
|
Name[ja]=qBittorrent
|
||||||
Comment[ka]=გადმოტვირთეთ და გააზიარეთ ფაილები BitTorrent-ის საშუალებით
|
|
||||||
GenericName[ka]=BitTorrent კლიენტი
|
GenericName[ka]=BitTorrent კლიენტი
|
||||||
|
Comment[ka]=გადმოტვირთეთ და გააზიარეთ ფაილები BitTorrent-ის საშუალებით
|
||||||
Name[ka]=qBittorrent
|
Name[ka]=qBittorrent
|
||||||
Comment[ko]=BitTorrent를 통한 파일 내려받기 및 공유
|
|
||||||
GenericName[ko]=BitTorrent 클라이언트
|
GenericName[ko]=BitTorrent 클라이언트
|
||||||
|
Comment[ko]=BitTorrent를 통한 파일 다운로드 및 공유
|
||||||
Name[ko]=qBittorrent
|
Name[ko]=qBittorrent
|
||||||
Comment[lt]=Atsisiųskite bei dalinkitės failais BitTorrent tinkle
|
|
||||||
GenericName[lt]=BitTorrent klientas
|
GenericName[lt]=BitTorrent klientas
|
||||||
|
Comment[lt]=Atsisiųskite bei dalinkitės failais BitTorrent tinkle
|
||||||
Name[lt]=qBittorrent
|
Name[lt]=qBittorrent
|
||||||
Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
|
|
||||||
GenericName[mk]=BitTorrent клиент
|
GenericName[mk]=BitTorrent клиент
|
||||||
|
Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
|
||||||
Name[mk]=qBittorrent
|
Name[mk]=qBittorrent
|
||||||
Comment[my]=တောရန့်ဖြင့်ဖိုင်များဒေါင်းလုဒ်ဆွဲရန်နှင့်မျှဝေရန်
|
|
||||||
GenericName[my]=တောရန့်စီမံခန့်ခွဲသည့်အရာ
|
GenericName[my]=တောရန့်စီမံခန့်ခွဲသည့်အရာ
|
||||||
|
Comment[my]=တောရန့်ဖြင့်ဖိုင်များဒေါင်းလုဒ်ဆွဲရန်နှင့်မျှဝေရန်
|
||||||
Name[my]=qBittorrent
|
Name[my]=qBittorrent
|
||||||
Comment[nb]=Last ned og del filer over BitTorrent
|
|
||||||
GenericName[nb]=BitTorrent-klient
|
GenericName[nb]=BitTorrent-klient
|
||||||
|
Comment[nb]=Last ned og del filer over BitTorrent
|
||||||
Name[nb]=qBittorrent
|
Name[nb]=qBittorrent
|
||||||
Comment[nl]=Bestanden downloaden en delen via BitTorrent
|
|
||||||
GenericName[nl]=BitTorrent-client
|
GenericName[nl]=BitTorrent-client
|
||||||
|
Comment[nl]=Bestanden downloaden en delen via BitTorrent
|
||||||
Name[nl]=qBittorrent
|
Name[nl]=qBittorrent
|
||||||
Comment[pl]=Pobieraj i dziel się plikami przez BitTorrent
|
|
||||||
GenericName[pl]=Klient BitTorrent
|
GenericName[pl]=Klient BitTorrent
|
||||||
|
Comment[pl]=Pobieraj i dziel się plikami przez BitTorrent
|
||||||
Name[pl]=qBittorrent
|
Name[pl]=qBittorrent
|
||||||
Comment[pt]=Transferir e partilhar ficheiros por BitTorrent
|
|
||||||
GenericName[pt]=Cliente BitTorrent
|
GenericName[pt]=Cliente BitTorrent
|
||||||
|
Comment[pt]=Transferir e partilhar ficheiros por BitTorrent
|
||||||
Name[pt]=qBittorrent
|
Name[pt]=qBittorrent
|
||||||
Comment[pt_BR]=Baixe e compartilhe arquivos pelo BitTorrent
|
|
||||||
GenericName[pt_BR]=Cliente BitTorrent
|
GenericName[pt_BR]=Cliente BitTorrent
|
||||||
|
Comment[pt_BR]=Baixe e compartilhe arquivos pelo BitTorrent
|
||||||
Name[pt_BR]=qBittorrent
|
Name[pt_BR]=qBittorrent
|
||||||
Comment[ro]=Descărcați și partajați fișiere prin BitTorrent
|
|
||||||
GenericName[ro]=Client BitTorrent
|
GenericName[ro]=Client BitTorrent
|
||||||
|
Comment[ro]=Descărcați și partajați fișiere prin BitTorrent
|
||||||
Name[ro]=qBittorrent
|
Name[ro]=qBittorrent
|
||||||
Comment[ru]=Обмен файлами по сети БитТоррент
|
|
||||||
GenericName[ru]=Клиент сети БитТоррент
|
GenericName[ru]=Клиент сети БитТоррент
|
||||||
|
Comment[ru]=Обмен файлами по сети БитТоррент
|
||||||
Name[ru]=qBittorrent
|
Name[ru]=qBittorrent
|
||||||
Comment[sk]=Sťahovanie a zdieľanie súborov prostredníctvom siete BitTorrent
|
|
||||||
GenericName[sk]=Klient siete BitTorrent
|
GenericName[sk]=Klient siete BitTorrent
|
||||||
|
Comment[sk]=Sťahovanie a zdieľanie súborov prostredníctvom siete BitTorrent
|
||||||
Name[sk]=qBittorrent
|
Name[sk]=qBittorrent
|
||||||
Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
|
|
||||||
GenericName[sl]=BitTorrent odjemalec
|
GenericName[sl]=BitTorrent odjemalec
|
||||||
|
Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
|
||||||
Name[sl]=qBittorrent
|
Name[sl]=qBittorrent
|
||||||
|
GenericName[sq]=Klienti BitTorrent
|
||||||
|
Comment[sq]=Shkarko dhe shpërndaj skedarë në BitTorrent
|
||||||
Name[sq]=qBittorrent
|
Name[sq]=qBittorrent
|
||||||
Comment[sr]=Преузимајте и делите фајлове преко BitTorrent протокола
|
GenericName[sr]=BitTorrent клијент
|
||||||
GenericName[sr]=BitTorrent-клијент
|
Comment[sr]=Преузимајте и делите фајлове преко BitTorrent-а
|
||||||
Name[sr]=qBittorrent
|
Name[sr]=qBittorrent
|
||||||
Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
|
|
||||||
GenericName[sr@latin]=BitTorrent klijent
|
GenericName[sr@latin]=BitTorrent klijent
|
||||||
|
Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
|
||||||
Name[sr@latin]=qBittorrent
|
Name[sr@latin]=qBittorrent
|
||||||
Comment[sv]=Hämta och dela filer över BitTorrent
|
|
||||||
GenericName[sv]=BitTorrent-klient
|
GenericName[sv]=BitTorrent-klient
|
||||||
|
Comment[sv]=Hämta och dela filer över BitTorrent
|
||||||
Name[sv]=qBittorrent
|
Name[sv]=qBittorrent
|
||||||
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
|
||||||
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
||||||
|
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
||||||
Name[ta]=qBittorrent
|
Name[ta]=qBittorrent
|
||||||
Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
|
|
||||||
GenericName[te]=క్యు బిట్ టొరెంట్ క్లయింట్
|
GenericName[te]=క్యు బిట్ టొరెంట్ క్లయింట్
|
||||||
|
Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
|
||||||
Name[te]=qBittorrent
|
Name[te]=qBittorrent
|
||||||
Comment[th]=ดาวน์โหลดและแชร์ไฟล์ผ่าน BitTorrent
|
GenericName[th]=โปรแกรมบิตทอร์เรนต์
|
||||||
GenericName[th]=โปรแกรมบิททอเร้นท์
|
Comment[th]=ดาวน์โหลดและแชร์ไฟล์ผ่านบิตทอร์เรนต์
|
||||||
Name[th]=qBittorrent
|
Name[th]=qBittorrent
|
||||||
Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
|
|
||||||
GenericName[tr]=BitTorrent istemcisi
|
GenericName[tr]=BitTorrent istemcisi
|
||||||
|
Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
|
||||||
Name[tr]=qBittorrent
|
Name[tr]=qBittorrent
|
||||||
Comment[ur]=BitTorrent پر فائلوں کو ڈاؤن لوڈ کریں اور اشتراک کریں
|
|
||||||
GenericName[ur]=قیو بٹ ٹورنٹ کلائنٹ
|
GenericName[ur]=قیو بٹ ٹورنٹ کلائنٹ
|
||||||
|
Comment[ur]=BitTorrent پر فائلوں کو ڈاؤن لوڈ کریں اور اشتراک کریں
|
||||||
Name[ur]=qBittorrent
|
Name[ur]=qBittorrent
|
||||||
Comment[uk]=Завантажуйте та поширюйте файли через BitTorrent
|
|
||||||
GenericName[uk]=BitTorrent-клієнт
|
GenericName[uk]=BitTorrent-клієнт
|
||||||
|
Comment[uk]=Завантажуйте та поширюйте файли через BitTorrent
|
||||||
Name[uk]=qBittorrent
|
Name[uk]=qBittorrent
|
||||||
Comment[vi]=Tải xuống và chia sẻ tệp qua BitTorrent
|
|
||||||
GenericName[vi]=Máy khách BitTorrent
|
GenericName[vi]=Máy khách BitTorrent
|
||||||
|
Comment[vi]=Tải xuống và chia sẻ tệp qua BitTorrent
|
||||||
Name[vi]=qBittorrent
|
Name[vi]=qBittorrent
|
||||||
Comment[zh_HK]=經由BitTorrent下載並分享檔案
|
|
||||||
GenericName[zh_HK]=BitTorrent用戶端
|
GenericName[zh_HK]=BitTorrent用戶端
|
||||||
|
Comment[zh_HK]=經由BitTorrent下載並分享檔案
|
||||||
Name[zh_HK]=qBittorrent
|
Name[zh_HK]=qBittorrent
|
||||||
Comment[zh_TW]=經由 BitTorrent 下載並分享檔案
|
|
||||||
GenericName[zh_TW]=BitTorrent 用戶端
|
GenericName[zh_TW]=BitTorrent 用戶端
|
||||||
|
Comment[zh_TW]=使用 BitTorrent 下載並分享檔案
|
||||||
Name[zh_TW]=qBittorrent
|
Name[zh_TW]=qBittorrent
|
||||||
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
|
||||||
GenericName[eo]=BitTorrent-kliento
|
GenericName[eo]=BitTorrent-kliento
|
||||||
|
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
||||||
Name[eo]=qBittorrent
|
Name[eo]=qBittorrent
|
||||||
Comment[kk]=BitTorrent арқылы файл жүктеу және бөлісу
|
|
||||||
GenericName[kk]=BitTorrent клиенті
|
GenericName[kk]=BitTorrent клиенті
|
||||||
|
Comment[kk]=BitTorrent арқылы файл жүктеу және бөлісу
|
||||||
Name[kk]=qBittorrent
|
Name[kk]=qBittorrent
|
||||||
Comment[en_AU]=Download and share files over BitTorrent
|
|
||||||
GenericName[en_AU]=BitTorrent client
|
GenericName[en_AU]=BitTorrent client
|
||||||
|
Comment[en_AU]=Download and share files over BitTorrent
|
||||||
Name[en_AU]=qBittorrent
|
Name[en_AU]=qBittorrent
|
||||||
Name[rm]=qBittorrent
|
Name[rm]=qBittorrent
|
||||||
Name[jv]=qBittorrent
|
Name[jv]=qBittorrent
|
||||||
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
|
||||||
GenericName[oc]=Client BitTorrent
|
GenericName[oc]=Client BitTorrent
|
||||||
|
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
||||||
Name[oc]=qBittorrent
|
Name[oc]=qBittorrent
|
||||||
Name[ug]=qBittorrent
|
Name[ug]=qBittorrent
|
||||||
Name[yi]=qBittorrent
|
Name[yi]=qBittorrent
|
||||||
Comment[nqo]=ߞߐߕߐ߯ߘߐ ߟߎ߬ ߟߊߖߌ߰ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ߟߎ߬ ߘߐߕߟߊ߫ ߓߌߙߏߙߍ߲ߕ ߞߊ߲߬
|
|
||||||
GenericName[nqo]=ߓߌߙߏߙߍ߲ߕ ߕߣߐ߬ߓߐ߬ߟߊ
|
GenericName[nqo]=ߓߌߙߏߙߍ߲ߕ ߕߣߐ߬ߓߐ߬ߟߊ
|
||||||
|
Comment[nqo]=ߞߐߕߐ߯ߘߐ ߟߎ߬ ߟߊߖߌ߰ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ߟߎ߬ ߘߐߕߟߊ߫ ߓߌߙߏߙߍ߲ߕ ߞߊ߲߬
|
||||||
Name[nqo]=qBittorrent
|
Name[nqo]=qBittorrent
|
||||||
Comment[uz@Latn]=BitTorrent orqali fayllarni yuklab olish va baham ko‘rish
|
|
||||||
GenericName[uz@Latn]=BitTorrent mijozi
|
GenericName[uz@Latn]=BitTorrent mijozi
|
||||||
|
Comment[uz@Latn]=BitTorrent orqali fayllarni yuklab olish va baham ko‘rish
|
||||||
Name[uz@Latn]=qBittorrent
|
Name[uz@Latn]=qBittorrent
|
||||||
Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
|
|
||||||
GenericName[ltg]=BitTorrent klients
|
GenericName[ltg]=BitTorrent klients
|
||||||
|
Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
|
||||||
Name[ltg]=qBittorrent
|
Name[ltg]=qBittorrent
|
||||||
Comment[hi_IN]=BitTorrent द्वारा फाइल डाउनलोड व सहभाजन
|
|
||||||
GenericName[hi_IN]=Bittorrent साधन
|
GenericName[hi_IN]=Bittorrent साधन
|
||||||
|
Comment[hi_IN]=BitTorrent द्वारा फाइल डाउनलोड व सहभाजन
|
||||||
Name[hi_IN]=qBittorrent
|
Name[hi_IN]=qBittorrent
|
||||||
Comment[az@latin]=Faylları BitTorrent vasitəsilə endirin və paylaşın
|
|
||||||
GenericName[az@latin]=BitTorrent client
|
GenericName[az@latin]=BitTorrent client
|
||||||
|
Comment[az@latin]=Faylları BitTorrent vasitəsilə endirin və paylaşın
|
||||||
Name[az@latin]=qBittorrent
|
Name[az@latin]=qBittorrent
|
||||||
Comment[lv_LV]=Lejupielādēt un koplietot failus ar BitTorrent
|
|
||||||
GenericName[lv_LV]=BitTorrent klients
|
GenericName[lv_LV]=BitTorrent klients
|
||||||
|
Comment[lv_LV]=Lejupielādēt un koplietot failus ar BitTorrent
|
||||||
Name[lv_LV]=qBittorrent
|
Name[lv_LV]=qBittorrent
|
||||||
Comment[ms_MY]=Muat turun dan kongsi fail melalui BitTorrent
|
|
||||||
GenericName[ms_MY]=Klien BitTorrent
|
GenericName[ms_MY]=Klien BitTorrent
|
||||||
|
Comment[ms_MY]=Muat turun dan kongsi fail melalui BitTorrent
|
||||||
Name[ms_MY]=qBittorrent
|
Name[ms_MY]=qBittorrent
|
||||||
Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
|
|
||||||
GenericName[mn_MN]=BitTorrent татагч
|
GenericName[mn_MN]=BitTorrent татагч
|
||||||
|
Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
|
||||||
Name[mn_MN]=qBittorrent
|
Name[mn_MN]=qBittorrent
|
||||||
Comment[ne_NP]=फाइलहरू डाउनलोड गर्नुहोस् र BitTorrent मा साझा गर्नुहोस्
|
|
||||||
GenericName[ne_NP]=BitTorrent क्लाइन्ट
|
GenericName[ne_NP]=BitTorrent क्लाइन्ट
|
||||||
|
Comment[ne_NP]=फाइलहरू डाउनलोड गर्नुहोस् र BitTorrent मा साझा गर्नुहोस्
|
||||||
Name[ne_NP]=qBittorrent
|
Name[ne_NP]=qBittorrent
|
||||||
Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
|
|
||||||
GenericName[pt_PT]=Cliente BitTorrent
|
GenericName[pt_PT]=Cliente BitTorrent
|
||||||
|
Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
|
||||||
Name[pt_PT]=qBittorrent
|
Name[pt_PT]=qBittorrent
|
||||||
|
GenericName[si_LK]=BitTorrent සේවාදායකයා
|
||||||
|
Comment[si_LK]=BitTorrent හරහා ගොනු බාගත කර බෙදාගන්න.
|
||||||
Name[si_LK]=qBittorrent
|
Name[si_LK]=qBittorrent
|
||||||
|
|
|
@ -62,6 +62,6 @@
|
||||||
<url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url>
|
<url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url>
|
||||||
<content_rating type="oars-1.1"/>
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="5.0.0~beta1" date="2024-03-19"/>
|
<release version="5.0.1" date="2024-10-28"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|
2
dist/windows/config.nsh
vendored
|
@ -14,7 +14,7 @@
|
||||||
; 4.5.1.3 -> good
|
; 4.5.1.3 -> good
|
||||||
; 4.5.1.3.2 -> bad
|
; 4.5.1.3.2 -> bad
|
||||||
; 4.5.0beta -> bad
|
; 4.5.0beta -> bad
|
||||||
!define /ifndef QBT_VERSION "5.0.0"
|
!define /ifndef QBT_VERSION "5.0.1"
|
||||||
|
|
||||||
; Option that controls the installer's window name
|
; Option that controls the installer's window name
|
||||||
; If set, its value will be used like this:
|
; If set, its value will be used like this:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2014-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2014-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -58,10 +58,6 @@
|
||||||
#include <QSplashScreen>
|
#include <QSplashScreen>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#include <QOperatingSystemVersion>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef QBT_STATIC_QT
|
#ifdef QBT_STATIC_QT
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
Q_IMPORT_PLUGIN(QICOPlugin)
|
Q_IMPORT_PLUGIN(QICOPlugin)
|
||||||
|
@ -189,11 +185,6 @@ int main(int argc, char *argv[])
|
||||||
// We must save it here because QApplication constructor may change it
|
// We must save it here because QApplication constructor may change it
|
||||||
const bool isOneArg = (argc == 2);
|
const bool isOneArg = (argc == 2);
|
||||||
|
|
||||||
#if !defined(DISABLE_GUI) && defined(Q_OS_WIN)
|
|
||||||
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
|
|
||||||
QApplication::setStyle(u"Fusion"_s);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// `app` must be declared out of try block to allow display message box in case of exception
|
// `app` must be declared out of try block to allow display message box in case of exception
|
||||||
std::unique_ptr<Application> app;
|
std::unique_ptr<Application> app;
|
||||||
try
|
try
|
||||||
|
|
|
@ -38,6 +38,8 @@ add_library(qbt_base STATIC
|
||||||
bittorrent/torrent.h
|
bittorrent/torrent.h
|
||||||
bittorrent/torrentcontenthandler.h
|
bittorrent/torrentcontenthandler.h
|
||||||
bittorrent/torrentcontentlayout.h
|
bittorrent/torrentcontentlayout.h
|
||||||
|
bittorrent/torrentcontentremoveoption.h
|
||||||
|
bittorrent/torrentcontentremover.h
|
||||||
bittorrent/torrentcreationmanager.h
|
bittorrent/torrentcreationmanager.h
|
||||||
bittorrent/torrentcreationtask.h
|
bittorrent/torrentcreationtask.h
|
||||||
bittorrent/torrentcreator.h
|
bittorrent/torrentcreator.h
|
||||||
|
@ -145,6 +147,7 @@ add_library(qbt_base STATIC
|
||||||
bittorrent/sslparameters.cpp
|
bittorrent/sslparameters.cpp
|
||||||
bittorrent/torrent.cpp
|
bittorrent/torrent.cpp
|
||||||
bittorrent/torrentcontenthandler.cpp
|
bittorrent/torrentcontenthandler.cpp
|
||||||
|
bittorrent/torrentcontentremover.cpp
|
||||||
bittorrent/torrentcreationmanager.cpp
|
bittorrent/torrentcreationmanager.cpp
|
||||||
bittorrent/torrentcreationtask.cpp
|
bittorrent/torrentcreationtask.cpp
|
||||||
bittorrent/torrentcreator.cpp
|
bittorrent/torrentcreator.cpp
|
||||||
|
|
|
@ -157,10 +157,36 @@ void AddTorrentManager::handleAddTorrentFailed(const QString &source, const QStr
|
||||||
emit addTorrentFailed(source, reason);
|
emit addTorrentFailed(source, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTorrentManager::handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message)
|
void AddTorrentManager::handleDuplicateTorrent(const QString &source
|
||||||
|
, const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent)
|
||||||
{
|
{
|
||||||
|
const bool hasMetadata = torrentDescr.info().has_value();
|
||||||
|
if (hasMetadata)
|
||||||
|
{
|
||||||
|
// Trying to set metadata to existing torrent in case if it has none
|
||||||
|
existingTorrent->setMetadata(*torrentDescr.info());
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool isPrivate = existingTorrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
|
||||||
|
QString message;
|
||||||
|
if (!btSession()->isMergeTrackersEnabled())
|
||||||
|
{
|
||||||
|
message = tr("Merging of trackers is disabled");
|
||||||
|
}
|
||||||
|
else if (isPrivate)
|
||||||
|
{
|
||||||
|
message = tr("Trackers cannot be merged because it is a private torrent");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// merge trackers and web seeds
|
||||||
|
existingTorrent->addTrackers(torrentDescr.trackers());
|
||||||
|
existingTorrent->addUrlSeeds(torrentDescr.urlSeeds());
|
||||||
|
message = tr("Trackers are merged from new source");
|
||||||
|
}
|
||||||
|
|
||||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3")
|
LogMsg(tr("Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3")
|
||||||
.arg(source, torrent->name(), message));
|
.arg(source, existingTorrent->name(), message));
|
||||||
emit addTorrentFailed(source, message);
|
emit addTorrentFailed(source, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,32 +210,7 @@ bool AddTorrentManager::processTorrent(const QString &source, const BitTorrent::
|
||||||
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
|
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
|
||||||
{
|
{
|
||||||
// a duplicate torrent is being added
|
// a duplicate torrent is being added
|
||||||
|
handleDuplicateTorrent(source, torrentDescr, torrent);
|
||||||
const bool hasMetadata = torrentDescr.info().has_value();
|
|
||||||
if (hasMetadata)
|
|
||||||
{
|
|
||||||
// Trying to set metadata to existing torrent in case if it has none
|
|
||||||
torrent->setMetadata(*torrentDescr.info());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!btSession()->isMergeTrackersEnabled())
|
|
||||||
{
|
|
||||||
handleDuplicateTorrent(source, torrent, tr("Merging of trackers is disabled"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool isPrivate = torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
|
|
||||||
if (isPrivate)
|
|
||||||
{
|
|
||||||
handleDuplicateTorrent(source, torrent, tr("Trackers cannot be merged because it is a private torrent"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge trackers and web seeds
|
|
||||||
torrent->addTrackers(torrentDescr.trackers());
|
|
||||||
torrent->addUrlSeeds(torrentDescr.urlSeeds());
|
|
||||||
|
|
||||||
handleDuplicateTorrent(source, torrent, tr("Trackers are merged from new source"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ protected:
|
||||||
bool addTorrentToSession(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr
|
bool addTorrentToSession(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr
|
||||||
, const BitTorrent::AddTorrentParams &addTorrentParams);
|
, const BitTorrent::AddTorrentParams &addTorrentParams);
|
||||||
void handleAddTorrentFailed(const QString &source, const QString &reason);
|
void handleAddTorrentFailed(const QString &source, const QString &reason);
|
||||||
void handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message);
|
void handleDuplicateTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent);
|
||||||
void setTorrentFileGuard(const QString &source, std::shared_ptr<TorrentFileGuard> torrentFileGuard);
|
void setTorrentFileGuard(const QString &source, std::shared_ptr<TorrentFileGuard> torrentFileGuard);
|
||||||
void releaseTorrentFileGuard(const QString &source);
|
void releaseTorrentFileGuard(const QString &source);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "base/algorithm.h"
|
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
|
|
|
@ -240,11 +240,11 @@ void CustomDiskIOThread::handleCompleteFiles(lt::storage_index_t storage, const
|
||||||
|
|
||||||
lt::storage_interface *customStorageConstructor(const lt::storage_params ¶ms, lt::file_pool &pool)
|
lt::storage_interface *customStorageConstructor(const lt::storage_params ¶ms, lt::file_pool &pool)
|
||||||
{
|
{
|
||||||
return new CustomStorage {params, pool};
|
return new CustomStorage(params, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomStorage::CustomStorage(const lt::storage_params ¶ms, lt::file_pool &filePool)
|
CustomStorage::CustomStorage(const lt::storage_params ¶ms, lt::file_pool &filePool)
|
||||||
: lt::default_storage {params, filePool}
|
: lt::default_storage(params, filePool)
|
||||||
, m_savePath {params.path}
|
, m_savePath {params.path}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,6 +367,10 @@ void PeerInfo::determineFlags()
|
||||||
if (useUTPSocket())
|
if (useUTPSocket())
|
||||||
updateFlags(u'P', C_UTP);
|
updateFlags(u'P', C_UTP);
|
||||||
|
|
||||||
|
// h = Peer is using NAT hole punching
|
||||||
|
if (isHolepunched())
|
||||||
|
updateFlags(u'h', tr("Peer is using NAT hole punching"));
|
||||||
|
|
||||||
m_flags.chop(1);
|
m_flags.chop(1);
|
||||||
m_flagsDescription.chop(1);
|
m_flagsDescription.chop(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,17 +37,12 @@
|
||||||
#include "addtorrentparams.h"
|
#include "addtorrentparams.h"
|
||||||
#include "categoryoptions.h"
|
#include "categoryoptions.h"
|
||||||
#include "sharelimitaction.h"
|
#include "sharelimitaction.h"
|
||||||
|
#include "torrentcontentremoveoption.h"
|
||||||
#include "trackerentry.h"
|
#include "trackerentry.h"
|
||||||
#include "trackerentrystatus.h"
|
#include "trackerentrystatus.h"
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
enum DeleteOption
|
|
||||||
{
|
|
||||||
DeleteTorrent,
|
|
||||||
DeleteTorrentAndFiles
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
|
@ -58,6 +53,12 @@ namespace BitTorrent
|
||||||
struct CacheStatus;
|
struct CacheStatus;
|
||||||
struct SessionStatus;
|
struct SessionStatus;
|
||||||
|
|
||||||
|
enum class TorrentRemoveOption
|
||||||
|
{
|
||||||
|
KeepContent,
|
||||||
|
RemoveContent
|
||||||
|
};
|
||||||
|
|
||||||
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
|
@ -91,7 +92,8 @@ namespace BitTorrent
|
||||||
{
|
{
|
||||||
Default = 0,
|
Default = 0,
|
||||||
MMap = 1,
|
MMap = 1,
|
||||||
Posix = 2
|
Posix = 2,
|
||||||
|
SimplePreadPwrite = 3
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(DiskIOType)
|
Q_ENUM_NS(DiskIOType)
|
||||||
|
|
||||||
|
@ -425,7 +427,7 @@ namespace BitTorrent
|
||||||
virtual void setExcludedFileNamesEnabled(bool enabled) = 0;
|
virtual void setExcludedFileNamesEnabled(bool enabled) = 0;
|
||||||
virtual QStringList excludedFileNames() const = 0;
|
virtual QStringList excludedFileNames() const = 0;
|
||||||
virtual void setExcludedFileNames(const QStringList &newList) = 0;
|
virtual void setExcludedFileNames(const QStringList &newList) = 0;
|
||||||
virtual bool isFilenameExcluded(const QString &fileName) const = 0;
|
virtual void applyFilenameFilter(const PathList &files, QList<BitTorrent::DownloadPriority> &priorities) = 0;
|
||||||
virtual QStringList bannedIPs() const = 0;
|
virtual QStringList bannedIPs() const = 0;
|
||||||
virtual void setBannedIPs(const QStringList &newList) = 0;
|
virtual void setBannedIPs(const QStringList &newList) = 0;
|
||||||
virtual ResumeDataStorageType resumeDataStorageType() const = 0;
|
virtual ResumeDataStorageType resumeDataStorageType() const = 0;
|
||||||
|
@ -434,6 +436,8 @@ namespace BitTorrent
|
||||||
virtual void setMergeTrackersEnabled(bool enabled) = 0;
|
virtual void setMergeTrackersEnabled(bool enabled) = 0;
|
||||||
virtual bool isStartPaused() const = 0;
|
virtual bool isStartPaused() const = 0;
|
||||||
virtual void setStartPaused(bool value) = 0;
|
virtual void setStartPaused(bool value) = 0;
|
||||||
|
virtual TorrentContentRemoveOption torrentContentRemoveOption() const = 0;
|
||||||
|
virtual void setTorrentContentRemoveOption(TorrentContentRemoveOption option) = 0;
|
||||||
|
|
||||||
virtual bool isRestored() const = 0;
|
virtual bool isRestored() const = 0;
|
||||||
|
|
||||||
|
@ -453,7 +457,7 @@ namespace BitTorrent
|
||||||
|
|
||||||
virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0;
|
virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0;
|
||||||
virtual bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) = 0;
|
virtual bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) = 0;
|
||||||
virtual bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteOption::DeleteTorrent) = 0;
|
virtual bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) = 0;
|
||||||
virtual bool downloadMetadata(const TorrentDescriptor &torrentDescr) = 0;
|
virtual bool downloadMetadata(const TorrentDescriptor &torrentDescr) = 0;
|
||||||
virtual bool cancelDownloadMetadata(const TorrentID &id) = 0;
|
virtual bool cancelDownloadMetadata(const TorrentID &id) = 0;
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
#include "nativesessionextension.h"
|
#include "nativesessionextension.h"
|
||||||
#include "portforwarderimpl.h"
|
#include "portforwarderimpl.h"
|
||||||
#include "resumedatastorage.h"
|
#include "resumedatastorage.h"
|
||||||
|
#include "torrentcontentremover.h"
|
||||||
#include "torrentdescriptor.h"
|
#include "torrentdescriptor.h"
|
||||||
#include "torrentimpl.h"
|
#include "torrentimpl.h"
|
||||||
#include "tracker.h"
|
#include "tracker.h"
|
||||||
|
@ -525,6 +526,7 @@ SessionImpl::SessionImpl(QObject *parent)
|
||||||
, m_I2POutboundQuantity {BITTORRENT_SESSION_KEY(u"I2P/OutboundQuantity"_s), 3}
|
, m_I2POutboundQuantity {BITTORRENT_SESSION_KEY(u"I2P/OutboundQuantity"_s), 3}
|
||||||
, m_I2PInboundLength {BITTORRENT_SESSION_KEY(u"I2P/InboundLength"_s), 3}
|
, m_I2PInboundLength {BITTORRENT_SESSION_KEY(u"I2P/InboundLength"_s), 3}
|
||||||
, m_I2POutboundLength {BITTORRENT_SESSION_KEY(u"I2P/OutboundLength"_s), 3}
|
, m_I2POutboundLength {BITTORRENT_SESSION_KEY(u"I2P/OutboundLength"_s), 3}
|
||||||
|
, m_torrentContentRemoveOption {BITTORRENT_SESSION_KEY(u"TorrentContentRemoveOption"_s), TorrentContentRemoveOption::Delete}
|
||||||
, m_startPaused {BITTORRENT_SESSION_KEY(u"StartPaused"_s)}
|
, m_startPaused {BITTORRENT_SESSION_KEY(u"StartPaused"_s)}
|
||||||
, m_seedingLimitTimer {new QTimer(this)}
|
, m_seedingLimitTimer {new QTimer(this)}
|
||||||
, m_resumeDataTimer {new QTimer(this)}
|
, m_resumeDataTimer {new QTimer(this)}
|
||||||
|
@ -550,7 +552,14 @@ SessionImpl::SessionImpl(QObject *parent)
|
||||||
, this, [this]() { m_recentErroredTorrents.clear(); });
|
, this, [this]() { m_recentErroredTorrents.clear(); });
|
||||||
|
|
||||||
m_seedingLimitTimer->setInterval(10s);
|
m_seedingLimitTimer->setInterval(10s);
|
||||||
connect(m_seedingLimitTimer, &QTimer::timeout, this, &SessionImpl::processShareLimits);
|
connect(m_seedingLimitTimer, &QTimer::timeout, this, [this]
|
||||||
|
{
|
||||||
|
// We shouldn't iterate over `m_torrents` in the loop below
|
||||||
|
// since `deleteTorrent()` modifies it indirectly
|
||||||
|
const QHash<TorrentID, TorrentImpl *> torrents {m_torrents};
|
||||||
|
for (TorrentImpl *torrent : torrents)
|
||||||
|
processTorrentShareLimits(torrent);
|
||||||
|
});
|
||||||
|
|
||||||
initializeNativeSession();
|
initializeNativeSession();
|
||||||
configureComponents();
|
configureComponents();
|
||||||
|
@ -586,6 +595,11 @@ SessionImpl::SessionImpl(QObject *parent)
|
||||||
connect(m_ioThread.get(), &QThread::finished, m_fileSearcher, &QObject::deleteLater);
|
connect(m_ioThread.get(), &QThread::finished, m_fileSearcher, &QObject::deleteLater);
|
||||||
connect(m_fileSearcher, &FileSearcher::searchFinished, this, &SessionImpl::fileSearchFinished);
|
connect(m_fileSearcher, &FileSearcher::searchFinished, this, &SessionImpl::fileSearchFinished);
|
||||||
|
|
||||||
|
m_torrentContentRemover = new TorrentContentRemover;
|
||||||
|
m_torrentContentRemover->moveToThread(m_ioThread.get());
|
||||||
|
connect(m_ioThread.get(), &QThread::finished, m_torrentContentRemover, &QObject::deleteLater);
|
||||||
|
connect(m_torrentContentRemover, &TorrentContentRemover::jobFinished, this, &SessionImpl::torrentContentRemovingFinished);
|
||||||
|
|
||||||
m_ioThread->start();
|
m_ioThread->start();
|
||||||
|
|
||||||
initMetrics();
|
initMetrics();
|
||||||
|
@ -604,7 +618,7 @@ SessionImpl::~SessionImpl()
|
||||||
{
|
{
|
||||||
m_nativeSession->pause();
|
m_nativeSession->pause();
|
||||||
|
|
||||||
const qint64 timeout = (m_shutdownTimeout >= 0) ? (m_shutdownTimeout * 1000) : -1;
|
const auto timeout = (m_shutdownTimeout >= 0) ? (static_cast<qint64>(m_shutdownTimeout) * 1000) : -1;
|
||||||
const QDeadlineTimer shutdownDeadlineTimer {timeout};
|
const QDeadlineTimer shutdownDeadlineTimer {timeout};
|
||||||
|
|
||||||
if (m_torrentsQueueChanged)
|
if (m_torrentsQueueChanged)
|
||||||
|
@ -1624,6 +1638,13 @@ void SessionImpl::initializeNativeSession()
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
// preserve the same behavior as in earlier libtorrent versions
|
// preserve the same behavior as in earlier libtorrent versions
|
||||||
pack.set_bool(lt::settings_pack::enable_set_file_valid_data, true);
|
pack.set_bool(lt::settings_pack::enable_set_file_valid_data, true);
|
||||||
|
|
||||||
|
// This is a special case. We use MMap disk IO but tweak it to always fallback to pread/pwrite.
|
||||||
|
if (diskIOType() == DiskIOType::SimplePreadPwrite)
|
||||||
|
{
|
||||||
|
pack.set_int(lt::settings_pack::mmap_file_size_cutoff, std::numeric_limits<int>::max());
|
||||||
|
pack.set_int(lt::settings_pack::disk_write_mode, lt::settings_pack::mmap_write_mode_t::always_pwrite);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lt::session_params sessionParams {std::move(pack), {}};
|
lt::session_params sessionParams {std::move(pack), {}};
|
||||||
|
@ -1634,6 +1655,7 @@ void SessionImpl::initializeNativeSession()
|
||||||
sessionParams.disk_io_constructor = customPosixDiskIOConstructor;
|
sessionParams.disk_io_constructor = customPosixDiskIOConstructor;
|
||||||
break;
|
break;
|
||||||
case DiskIOType::MMap:
|
case DiskIOType::MMap:
|
||||||
|
case DiskIOType::SimplePreadPwrite:
|
||||||
sessionParams.disk_io_constructor = customMMapDiskIOConstructor;
|
sessionParams.disk_io_constructor = customMMapDiskIOConstructor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2236,21 +2258,16 @@ void SessionImpl::populateAdditionalTrackers()
|
||||||
m_additionalTrackerEntries = parseTrackerEntries(additionalTrackers());
|
m_additionalTrackerEntries = parseTrackerEntries(additionalTrackers());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::processShareLimits()
|
void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
|
if (!torrent->isFinished() || torrent->isForced())
|
||||||
|
return;
|
||||||
|
|
||||||
const auto effectiveLimit = []<typename T>(const T limit, const T useGlobalLimit, const T globalLimit) -> T
|
const auto effectiveLimit = []<typename T>(const T limit, const T useGlobalLimit, const T globalLimit) -> T
|
||||||
{
|
{
|
||||||
return (limit == useGlobalLimit) ? globalLimit : limit;
|
return (limit == useGlobalLimit) ? globalLimit : limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We shouldn't iterate over `m_torrents` in the loop below
|
|
||||||
// since `deleteTorrent()` modifies it indirectly
|
|
||||||
const QHash<TorrentID, TorrentImpl *> torrents {m_torrents};
|
|
||||||
for (const auto &[torrentID, torrent] : torrents.asKeyValueRange())
|
|
||||||
{
|
|
||||||
if (!torrent->isFinished() || torrent->isForced())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
|
const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
|
||||||
const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
|
const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
|
||||||
const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
|
const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
|
||||||
|
@ -2285,12 +2302,12 @@ void SessionImpl::processShareLimits()
|
||||||
if (shareLimitAction == ShareLimitAction::Remove)
|
if (shareLimitAction == ShareLimitAction::Remove)
|
||||||
{
|
{
|
||||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent."), torrentName));
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent."), torrentName));
|
||||||
deleteTorrent(torrentID);
|
removeTorrent(torrent->id(), TorrentRemoveOption::KeepContent);
|
||||||
}
|
}
|
||||||
else if (shareLimitAction == ShareLimitAction::RemoveWithContent)
|
else if (shareLimitAction == ShareLimitAction::RemoveWithContent)
|
||||||
{
|
{
|
||||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent and deleting its content."), torrentName));
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent and deleting its content."), torrentName));
|
||||||
deleteTorrent(torrentID, DeleteTorrentAndFiles);
|
removeTorrent(torrent->id(), TorrentRemoveOption::RemoveContent);
|
||||||
}
|
}
|
||||||
else if ((shareLimitAction == ShareLimitAction::Stop) && !torrent->isStopped())
|
else if ((shareLimitAction == ShareLimitAction::Stop) && !torrent->isStopped())
|
||||||
{
|
{
|
||||||
|
@ -2304,7 +2321,6 @@ void SessionImpl::processShareLimits()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames)
|
void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames)
|
||||||
{
|
{
|
||||||
|
@ -2331,6 +2347,19 @@ void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionImpl::torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage)
|
||||||
|
{
|
||||||
|
if (errorMessage.isEmpty())
|
||||||
|
{
|
||||||
|
LogMsg(tr("Torrent content removed. Torrent: \"%1\"").arg(torrentName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogMsg(tr("Failed to remove torrent content. Torrent: \"%1\". Error: \"%2\"")
|
||||||
|
.arg(torrentName, errorMessage), Log::WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Torrent *SessionImpl::getTorrent(const TorrentID &id) const
|
Torrent *SessionImpl::getTorrent(const TorrentID &id) const
|
||||||
{
|
{
|
||||||
return m_torrents.value(id);
|
return m_torrents.value(id);
|
||||||
|
@ -2377,22 +2406,25 @@ void SessionImpl::banIP(const QString &ip)
|
||||||
|
|
||||||
// Delete a torrent from the session, given its hash
|
// Delete a torrent from the session, given its hash
|
||||||
// and from the disk, if the corresponding deleteOption is chosen
|
// and from the disk, if the corresponding deleteOption is chosen
|
||||||
bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption)
|
bool SessionImpl::removeTorrent(const TorrentID &id, const TorrentRemoveOption deleteOption)
|
||||||
{
|
{
|
||||||
TorrentImpl *const torrent = m_torrents.take(id);
|
TorrentImpl *const torrent = m_torrents.take(id);
|
||||||
if (!torrent)
|
if (!torrent)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrent->id().toString()));
|
const TorrentID torrentID = torrent->id();
|
||||||
|
const QString torrentName = torrent->name();
|
||||||
|
|
||||||
|
qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrentID.toString()));
|
||||||
emit torrentAboutToBeRemoved(torrent);
|
emit torrentAboutToBeRemoved(torrent);
|
||||||
|
|
||||||
if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid())
|
if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid())
|
||||||
m_hybridTorrentsByAltID.remove(TorrentID::fromSHA1Hash(infoHash.v1()));
|
m_hybridTorrentsByAltID.remove(TorrentID::fromSHA1Hash(infoHash.v1()));
|
||||||
|
|
||||||
// Remove it from session
|
// Remove it from session
|
||||||
if (deleteOption == DeleteTorrent)
|
if (deleteOption == TorrentRemoveOption::KeepContent)
|
||||||
{
|
{
|
||||||
m_removingTorrents[torrent->id()] = {torrent->name(), {}, deleteOption};
|
m_removingTorrents[torrentID] = {torrentName, torrent->actualStorageLocation(), {}, deleteOption};
|
||||||
|
|
||||||
const lt::torrent_handle nativeHandle {torrent->nativeHandle()};
|
const lt::torrent_handle nativeHandle {torrent->nativeHandle()};
|
||||||
const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end()
|
const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end()
|
||||||
|
@ -2414,7 +2446,7 @@ bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOp
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_removingTorrents[torrent->id()] = {torrent->name(), torrent->rootPath(), deleteOption};
|
m_removingTorrents[torrentID] = {torrentName, torrent->actualStorageLocation(), torrent->actualFilePaths(), deleteOption};
|
||||||
|
|
||||||
if (m_moveStorageQueue.size() > 1)
|
if (m_moveStorageQueue.size() > 1)
|
||||||
{
|
{
|
||||||
|
@ -2429,12 +2461,13 @@ bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOp
|
||||||
m_moveStorageQueue.erase(iter);
|
m_moveStorageQueue.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nativeSession->remove_torrent(torrent->nativeHandle(), lt::session::delete_files);
|
m_nativeSession->remove_torrent(torrent->nativeHandle(), lt::session::delete_partfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove it from torrent resume directory
|
// Remove it from torrent resume directory
|
||||||
m_resumeDataStorage->remove(torrent->id());
|
m_resumeDataStorage->remove(torrentID);
|
||||||
|
|
||||||
|
LogMsg(tr("Torrent removed. Torrent: \"%1\"").arg(torrentName));
|
||||||
delete torrent;
|
delete torrent;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2462,7 +2495,7 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_files);
|
m_nativeSession->remove_torrent(nativeHandle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2686,8 +2719,39 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
||||||
if (m_loadingTorrents.contains(id) || (infoHash.isHybrid() && m_loadingTorrents.contains(altID)))
|
if (m_loadingTorrents.contains(id) || (infoHash.isHybrid() && m_loadingTorrents.contains(altID)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (findTorrent(infoHash))
|
if (Torrent *torrent = findTorrent(infoHash))
|
||||||
|
{
|
||||||
|
// a duplicate torrent is being added
|
||||||
|
|
||||||
|
if (hasMetadata)
|
||||||
|
{
|
||||||
|
// Trying to set metadata to existing torrent in case if it has none
|
||||||
|
torrent->setMetadata(*source.info());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMergeTrackersEnabled())
|
||||||
|
{
|
||||||
|
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||||
|
.arg(torrent->name(), tr("Merging of trackers is disabled")));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool isPrivate = torrent->isPrivate() || (hasMetadata && source.info()->isPrivate());
|
||||||
|
if (isPrivate)
|
||||||
|
{
|
||||||
|
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||||
|
.arg(torrent->name(), tr("Trackers cannot be merged because it is a private torrent")));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge trackers and web seeds
|
||||||
|
torrent->addTrackers(source.trackers());
|
||||||
|
torrent->addUrlSeeds(source.urlSeeds());
|
||||||
|
|
||||||
|
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||||
|
.arg(torrent->name(), tr("Trackers are merged from new source")));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// It looks illogical that we don't just use an existing handle,
|
// It looks illogical that we don't just use an existing handle,
|
||||||
// but as previous experience has shown, it actually creates unnecessary
|
// but as previous experience has shown, it actually creates unnecessary
|
||||||
|
@ -2751,6 +2815,19 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
||||||
loadTorrentParams.name = contentName;
|
loadTorrentParams.name = contentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto nativeIndexes = torrentInfo.nativeIndexes();
|
||||||
|
|
||||||
|
Q_ASSERT(p.file_priorities.empty());
|
||||||
|
Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
|
||||||
|
QList<DownloadPriority> filePriorities = addTorrentParams.filePriorities;
|
||||||
|
|
||||||
|
// Filename filter should be applied before `findIncompleteFiles()` is called.
|
||||||
|
if (filePriorities.isEmpty() && isExcludedFileNamesEnabled())
|
||||||
|
{
|
||||||
|
// Check file name blacklist when priorities are not explicitly set
|
||||||
|
applyFilenameFilter(filePaths, filePriorities);
|
||||||
|
}
|
||||||
|
|
||||||
if (!loadTorrentParams.hasFinishedStatus)
|
if (!loadTorrentParams.hasFinishedStatus)
|
||||||
{
|
{
|
||||||
const Path actualDownloadPath = useAutoTMM
|
const Path actualDownloadPath = useAutoTMM
|
||||||
|
@ -2759,36 +2836,20 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
||||||
isFindingIncompleteFiles = true;
|
isFindingIncompleteFiles = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto nativeIndexes = torrentInfo.nativeIndexes();
|
|
||||||
if (!isFindingIncompleteFiles)
|
if (!isFindingIncompleteFiles)
|
||||||
{
|
{
|
||||||
for (int index = 0; index < filePaths.size(); ++index)
|
for (int index = 0; index < filePaths.size(); ++index)
|
||||||
p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString();
|
p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(p.file_priorities.empty());
|
|
||||||
Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
|
|
||||||
|
|
||||||
const int internalFilesCount = torrentInfo.nativeInfo()->files().num_files(); // including .pad files
|
const int internalFilesCount = torrentInfo.nativeInfo()->files().num_files(); // including .pad files
|
||||||
// Use qBittorrent default priority rather than libtorrent's (4)
|
// Use qBittorrent default priority rather than libtorrent's (4)
|
||||||
p.file_priorities = std::vector(internalFilesCount, LT::toNative(DownloadPriority::Normal));
|
p.file_priorities = std::vector(internalFilesCount, LT::toNative(DownloadPriority::Normal));
|
||||||
|
|
||||||
if (addTorrentParams.filePriorities.isEmpty())
|
if (!filePriorities.isEmpty())
|
||||||
{
|
{
|
||||||
if (isExcludedFileNamesEnabled())
|
for (int i = 0; i < filePriorities.size(); ++i)
|
||||||
{
|
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(filePriorities[i]);
|
||||||
// Check file name blacklist when priorities are not explicitly set
|
|
||||||
for (int i = 0; i < filePaths.size(); ++i)
|
|
||||||
{
|
|
||||||
if (isFilenameExcluded(filePaths.at(i).filename()))
|
|
||||||
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = lt::dont_download;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i)
|
|
||||||
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(p.ti);
|
Q_ASSERT(p.ti);
|
||||||
|
@ -3874,21 +3935,41 @@ void SessionImpl::populateExcludedFileNamesRegExpList()
|
||||||
|
|
||||||
for (const QString &str : excludedNames)
|
for (const QString &str : excludedNames)
|
||||||
{
|
{
|
||||||
const QString pattern = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(str));
|
const QString pattern = QRegularExpression::wildcardToRegularExpression(str);
|
||||||
const QRegularExpression re {pattern, QRegularExpression::CaseInsensitiveOption};
|
const QRegularExpression re {pattern, QRegularExpression::CaseInsensitiveOption};
|
||||||
m_excludedFileNamesRegExpList.append(re);
|
m_excludedFileNamesRegExpList.append(re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionImpl::isFilenameExcluded(const QString &fileName) const
|
void SessionImpl::applyFilenameFilter(const PathList &files, QList<DownloadPriority> &priorities)
|
||||||
{
|
{
|
||||||
if (!isExcludedFileNamesEnabled())
|
if (!isExcludedFileNamesEnabled())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
return std::any_of(m_excludedFileNamesRegExpList.begin(), m_excludedFileNamesRegExpList.end(), [&fileName](const QRegularExpression &re)
|
const auto isFilenameExcluded = [patterns = m_excludedFileNamesRegExpList](const Path &fileName)
|
||||||
{
|
{
|
||||||
return re.match(fileName).hasMatch();
|
return std::any_of(patterns.begin(), patterns.end(), [&fileName](const QRegularExpression &re)
|
||||||
|
{
|
||||||
|
Path path = fileName;
|
||||||
|
while (!re.match(path.filename()).hasMatch())
|
||||||
|
{
|
||||||
|
path = path.parentPath();
|
||||||
|
if (path.isEmpty())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
priorities.resize(files.count(), DownloadPriority::Normal);
|
||||||
|
for (int i = 0; i < priorities.size(); ++i)
|
||||||
|
{
|
||||||
|
if (priorities[i] == BitTorrent::DownloadPriority::Ignored)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isFilenameExcluded(files.at(i)))
|
||||||
|
priorities[i] = BitTorrent::DownloadPriority::Ignored;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::setBannedIPs(const QStringList &newList)
|
void SessionImpl::setBannedIPs(const QStringList &newList)
|
||||||
|
@ -3957,6 +4038,16 @@ void SessionImpl::setStartPaused(const bool value)
|
||||||
m_startPaused = value;
|
m_startPaused = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TorrentContentRemoveOption SessionImpl::torrentContentRemoveOption() const
|
||||||
|
{
|
||||||
|
return m_torrentContentRemoveOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionImpl::setTorrentContentRemoveOption(const TorrentContentRemoveOption option)
|
||||||
|
{
|
||||||
|
m_torrentContentRemoveOption = option;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList SessionImpl::bannedIPs() const
|
QStringList SessionImpl::bannedIPs() const
|
||||||
{
|
{
|
||||||
return m_bannedIPs;
|
return m_bannedIPs;
|
||||||
|
@ -5002,18 +5093,7 @@ void SessionImpl::handleTorrentChecked(TorrentImpl *const torrent)
|
||||||
|
|
||||||
void SessionImpl::handleTorrentFinished(TorrentImpl *const torrent)
|
void SessionImpl::handleTorrentFinished(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name()));
|
m_pendingFinishedTorrents.append(torrent);
|
||||||
emit torrentFinished(torrent);
|
|
||||||
|
|
||||||
if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty())
|
|
||||||
exportTorrentFile(torrent, exportPath);
|
|
||||||
|
|
||||||
const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
|
||||||
{
|
|
||||||
return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored());
|
|
||||||
});
|
|
||||||
if (!hasUnfinishedTorrents)
|
|
||||||
emit allTorrentsFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleTorrentResumeDataReady(TorrentImpl *const torrent, const LoadTorrentParams &data)
|
void SessionImpl::handleTorrentResumeDataReady(TorrentImpl *const torrent, const LoadTorrentParams &data)
|
||||||
|
@ -5135,17 +5215,46 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath)
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
torrent->handleMoveStorageJobFinished(newPath, finishedJob.context, torrentHasOutstandingJob);
|
torrent->handleMoveStorageJobFinished(newPath, finishedJob.context, torrentHasOutstandingJob);
|
||||||
|
// The torrent may become "finished" at the end of the move if it was moved
|
||||||
|
// from the "incomplete" location after downloading finished.
|
||||||
|
processPendingFinishedTorrents();
|
||||||
}
|
}
|
||||||
else if (!torrentHasOutstandingJob)
|
else if (!torrentHasOutstandingJob)
|
||||||
{
|
{
|
||||||
// Last job is completed for torrent that being removing, so actually remove it
|
// Last job is completed for torrent that being removing, so actually remove it
|
||||||
const lt::torrent_handle nativeHandle {finishedJob.torrentHandle};
|
const lt::torrent_handle nativeHandle {finishedJob.torrentHandle};
|
||||||
const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()];
|
const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()];
|
||||||
if (removingTorrentData.deleteOption == DeleteTorrent)
|
if (removingTorrentData.removeOption == TorrentRemoveOption::KeepContent)
|
||||||
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile);
|
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionImpl::processPendingFinishedTorrents()
|
||||||
|
{
|
||||||
|
if (m_pendingFinishedTorrents.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (TorrentImpl *torrent : asConst(m_pendingFinishedTorrents))
|
||||||
|
{
|
||||||
|
LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name()));
|
||||||
|
emit torrentFinished(torrent);
|
||||||
|
|
||||||
|
if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty())
|
||||||
|
exportTorrentFile(torrent, exportPath);
|
||||||
|
|
||||||
|
processTorrentShareLimits(torrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pendingFinishedTorrents.clear();
|
||||||
|
|
||||||
|
const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
||||||
|
{
|
||||||
|
return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored());
|
||||||
|
});
|
||||||
|
if (!hasUnfinishedTorrents)
|
||||||
|
emit allTorrentsFinished();
|
||||||
|
}
|
||||||
|
|
||||||
void SessionImpl::storeCategories() const
|
void SessionImpl::storeCategories() const
|
||||||
{
|
{
|
||||||
QJsonObject jsonObj;
|
QJsonObject jsonObj;
|
||||||
|
@ -5660,74 +5769,32 @@ TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle,
|
||||||
return torrent;
|
return torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert *alert)
|
void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*alert*/)
|
||||||
{
|
{
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
// We cannot consider `torrent_removed_alert` as a starting point for removing content,
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hashes);
|
// because it has an inconsistent posting time between different versions of libtorrent,
|
||||||
#else
|
// so files may still be in use in some cases.
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hash);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const auto removingTorrentDataIter = m_removingTorrents.find(id);
|
|
||||||
if (removingTorrentDataIter != m_removingTorrents.end())
|
|
||||||
{
|
|
||||||
if (removingTorrentDataIter->deleteOption == DeleteTorrent)
|
|
||||||
{
|
|
||||||
LogMsg(tr("Removed torrent. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
|
|
||||||
m_removingTorrents.erase(removingTorrentDataIter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *alert)
|
void SessionImpl::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *alert)
|
||||||
{
|
{
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hashes);
|
const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes);
|
||||||
#else
|
#else
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hash);
|
const auto torrentID = TorrentID::fromInfoHash(alert->info_hash);
|
||||||
#endif
|
#endif
|
||||||
|
handleRemovedTorrent(torrentID);
|
||||||
const auto removingTorrentDataIter = m_removingTorrents.find(id);
|
|
||||||
if (removingTorrentDataIter == m_removingTorrents.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// torrent_deleted_alert can also be posted due to deletion of partfile. Ignore it in such a case.
|
|
||||||
if (removingTorrentDataIter->deleteOption == DeleteTorrent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove);
|
|
||||||
LogMsg(tr("Removed torrent and deleted its content. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
|
|
||||||
m_removingTorrents.erase(removingTorrentDataIter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *alert)
|
void SessionImpl::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *alert)
|
||||||
{
|
{
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hashes);
|
const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes);
|
||||||
#else
|
#else
|
||||||
const auto id = TorrentID::fromInfoHash(alert->info_hash);
|
const auto torrentID = TorrentID::fromInfoHash(alert->info_hash);
|
||||||
#endif
|
#endif
|
||||||
|
const auto errorMessage = alert->error ? QString::fromLocal8Bit(alert->error.message().c_str()) : QString();
|
||||||
const auto removingTorrentDataIter = m_removingTorrents.find(id);
|
handleRemovedTorrent(torrentID, errorMessage);
|
||||||
if (removingTorrentDataIter == m_removingTorrents.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (alert->error)
|
|
||||||
{
|
|
||||||
// libtorrent won't delete the directory if it contains files not listed in the torrent,
|
|
||||||
// so we remove the directory ourselves
|
|
||||||
Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove);
|
|
||||||
|
|
||||||
LogMsg(tr("Removed torrent but failed to delete its content and/or partfile. Torrent: \"%1\". Error: \"%2\"")
|
|
||||||
.arg(removingTorrentDataIter->name, QString::fromLocal8Bit(alert->error.message().c_str()))
|
|
||||||
, Log::WARNING);
|
|
||||||
}
|
|
||||||
else // torrent without metadata, hence no files on disk
|
|
||||||
{
|
|
||||||
LogMsg(tr("Removed torrent. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_removingTorrents.erase(removingTorrentDataIter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleTorrentNeedCertAlert(const lt::torrent_need_cert_alert *alert)
|
void SessionImpl::handleTorrentNeedCertAlert(const lt::torrent_need_cert_alert *alert)
|
||||||
|
@ -6079,6 +6146,8 @@ void SessionImpl::handleStateUpdateAlert(const lt::state_update_alert *alert)
|
||||||
if (!updatedTorrents.isEmpty())
|
if (!updatedTorrents.isEmpty())
|
||||||
emit torrentsUpdated(updatedTorrents);
|
emit torrentsUpdated(updatedTorrents);
|
||||||
|
|
||||||
|
processPendingFinishedTorrents();
|
||||||
|
|
||||||
if (m_needSaveTorrentsQueue)
|
if (m_needSaveTorrentsQueue)
|
||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
|
|
||||||
|
@ -6140,7 +6209,7 @@ void SessionImpl::handleTorrentConflictAlert(const lt::torrent_conflict_alert *a
|
||||||
if (torrent2)
|
if (torrent2)
|
||||||
{
|
{
|
||||||
if (torrent1)
|
if (torrent1)
|
||||||
deleteTorrent(torrentIDv1);
|
removeTorrent(torrentIDv1);
|
||||||
else
|
else
|
||||||
cancelDownloadMetadata(torrentIDv1);
|
cancelDownloadMetadata(torrentIDv1);
|
||||||
|
|
||||||
|
@ -6249,3 +6318,29 @@ void SessionImpl::updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, Q
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionImpl::handleRemovedTorrent(const TorrentID &torrentID, const QString &partfileRemoveError)
|
||||||
|
{
|
||||||
|
const auto removingTorrentDataIter = m_removingTorrents.find(torrentID);
|
||||||
|
if (removingTorrentDataIter == m_removingTorrents.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!partfileRemoveError.isEmpty())
|
||||||
|
{
|
||||||
|
LogMsg(tr("Failed to remove partfile. Torrent: \"%1\". Reason: \"%2\".")
|
||||||
|
.arg(removingTorrentDataIter->name, partfileRemoveError)
|
||||||
|
, Log::WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((removingTorrentDataIter->removeOption == TorrentRemoveOption::RemoveContent)
|
||||||
|
&& !removingTorrentDataIter->contentStoragePath.isEmpty())
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(m_torrentContentRemover, [this, jobData = *removingTorrentDataIter]
|
||||||
|
{
|
||||||
|
m_torrentContentRemover->performJob(jobData.name, jobData.contentStoragePath
|
||||||
|
, jobData.fileNames, m_torrentContentRemoveOption);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
m_removingTorrents.erase(removingTorrentDataIter);
|
||||||
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace BitTorrent
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
class ResumeDataStorage;
|
class ResumeDataStorage;
|
||||||
class Torrent;
|
class Torrent;
|
||||||
|
class TorrentContentRemover;
|
||||||
class TorrentDescriptor;
|
class TorrentDescriptor;
|
||||||
class TorrentImpl;
|
class TorrentImpl;
|
||||||
class Tracker;
|
class Tracker;
|
||||||
|
@ -402,7 +403,7 @@ namespace BitTorrent
|
||||||
void setExcludedFileNamesEnabled(bool enabled) override;
|
void setExcludedFileNamesEnabled(bool enabled) override;
|
||||||
QStringList excludedFileNames() const override;
|
QStringList excludedFileNames() const override;
|
||||||
void setExcludedFileNames(const QStringList &excludedFileNames) override;
|
void setExcludedFileNames(const QStringList &excludedFileNames) override;
|
||||||
bool isFilenameExcluded(const QString &fileName) const override;
|
void applyFilenameFilter(const PathList &files, QList<BitTorrent::DownloadPriority> &priorities) override;
|
||||||
QStringList bannedIPs() const override;
|
QStringList bannedIPs() const override;
|
||||||
void setBannedIPs(const QStringList &newList) override;
|
void setBannedIPs(const QStringList &newList) override;
|
||||||
ResumeDataStorageType resumeDataStorageType() const override;
|
ResumeDataStorageType resumeDataStorageType() const override;
|
||||||
|
@ -411,6 +412,8 @@ namespace BitTorrent
|
||||||
void setMergeTrackersEnabled(bool enabled) override;
|
void setMergeTrackersEnabled(bool enabled) override;
|
||||||
bool isStartPaused() const override;
|
bool isStartPaused() const override;
|
||||||
void setStartPaused(bool value) override;
|
void setStartPaused(bool value) override;
|
||||||
|
TorrentContentRemoveOption torrentContentRemoveOption() const override;
|
||||||
|
void setTorrentContentRemoveOption(TorrentContentRemoveOption option) override;
|
||||||
|
|
||||||
bool isRestored() const override;
|
bool isRestored() const override;
|
||||||
|
|
||||||
|
@ -430,7 +433,7 @@ namespace BitTorrent
|
||||||
|
|
||||||
bool isKnownTorrent(const InfoHash &infoHash) const override;
|
bool isKnownTorrent(const InfoHash &infoHash) const override;
|
||||||
bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) override;
|
bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) override;
|
||||||
bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent) override;
|
bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) override;
|
||||||
bool downloadMetadata(const TorrentDescriptor &torrentDescr) override;
|
bool downloadMetadata(const TorrentDescriptor &torrentDescr) override;
|
||||||
bool cancelDownloadMetadata(const TorrentID &id) override;
|
bool cancelDownloadMetadata(const TorrentID &id) override;
|
||||||
|
|
||||||
|
@ -487,11 +490,11 @@ namespace BitTorrent
|
||||||
void configureDeferred();
|
void configureDeferred();
|
||||||
void readAlerts();
|
void readAlerts();
|
||||||
void enqueueRefresh();
|
void enqueueRefresh();
|
||||||
void processShareLimits();
|
|
||||||
void generateResumeData();
|
void generateResumeData();
|
||||||
void handleIPFilterParsed(int ruleCount);
|
void handleIPFilterParsed(int ruleCount);
|
||||||
void handleIPFilterError();
|
void handleIPFilterError();
|
||||||
void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames);
|
void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames);
|
||||||
|
void torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ResumeSessionContext;
|
struct ResumeSessionContext;
|
||||||
|
@ -507,8 +510,9 @@ namespace BitTorrent
|
||||||
struct RemovingTorrentData
|
struct RemovingTorrentData
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
Path pathToRemove;
|
Path contentStoragePath;
|
||||||
DeleteOption deleteOption {};
|
PathList fileNames;
|
||||||
|
TorrentRemoveOption removeOption {};
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit SessionImpl(QObject *parent = nullptr);
|
explicit SessionImpl(QObject *parent = nullptr);
|
||||||
|
@ -536,6 +540,7 @@ namespace BitTorrent
|
||||||
void enableIPFilter();
|
void enableIPFilter();
|
||||||
void disableIPFilter();
|
void disableIPFilter();
|
||||||
void processTrackerStatuses();
|
void processTrackerStatuses();
|
||||||
|
void processTorrentShareLimits(TorrentImpl *torrent);
|
||||||
void populateExcludedFileNamesRegExpList();
|
void populateExcludedFileNamesRegExpList();
|
||||||
void prepareStartup();
|
void prepareStartup();
|
||||||
void handleLoadedResumeData(ResumeSessionContext *context);
|
void handleLoadedResumeData(ResumeSessionContext *context);
|
||||||
|
@ -588,6 +593,7 @@ namespace BitTorrent
|
||||||
|
|
||||||
void moveTorrentStorage(const MoveStorageJob &job) const;
|
void moveTorrentStorage(const MoveStorageJob &job) const;
|
||||||
void handleMoveTorrentStorageJobFinished(const Path &newPath);
|
void handleMoveTorrentStorageJobFinished(const Path &newPath);
|
||||||
|
void processPendingFinishedTorrents();
|
||||||
|
|
||||||
void loadCategories();
|
void loadCategories();
|
||||||
void storeCategories() const;
|
void storeCategories() const;
|
||||||
|
@ -599,13 +605,7 @@ namespace BitTorrent
|
||||||
|
|
||||||
void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers);
|
void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers);
|
||||||
|
|
||||||
// BitTorrent
|
void handleRemovedTorrent(const TorrentID &torrentID, const QString &partfileRemoveError = {});
|
||||||
lt::session *m_nativeSession = nullptr;
|
|
||||||
NativeSessionExtension *m_nativeSessionExtension = nullptr;
|
|
||||||
|
|
||||||
bool m_deferredConfigureScheduled = false;
|
|
||||||
bool m_IPFilteringConfigured = false;
|
|
||||||
mutable bool m_listenInterfaceConfigured = false;
|
|
||||||
|
|
||||||
CachedSettingValue<QString> m_DHTBootstrapNodes;
|
CachedSettingValue<QString> m_DHTBootstrapNodes;
|
||||||
CachedSettingValue<bool> m_isDHTEnabled;
|
CachedSettingValue<bool> m_isDHTEnabled;
|
||||||
|
@ -731,8 +731,16 @@ namespace BitTorrent
|
||||||
CachedSettingValue<int> m_I2POutboundQuantity;
|
CachedSettingValue<int> m_I2POutboundQuantity;
|
||||||
CachedSettingValue<int> m_I2PInboundLength;
|
CachedSettingValue<int> m_I2PInboundLength;
|
||||||
CachedSettingValue<int> m_I2POutboundLength;
|
CachedSettingValue<int> m_I2POutboundLength;
|
||||||
|
CachedSettingValue<TorrentContentRemoveOption> m_torrentContentRemoveOption;
|
||||||
SettingValue<bool> m_startPaused;
|
SettingValue<bool> m_startPaused;
|
||||||
|
|
||||||
|
lt::session *m_nativeSession = nullptr;
|
||||||
|
NativeSessionExtension *m_nativeSessionExtension = nullptr;
|
||||||
|
|
||||||
|
bool m_deferredConfigureScheduled = false;
|
||||||
|
bool m_IPFilteringConfigured = false;
|
||||||
|
mutable bool m_listenInterfaceConfigured = false;
|
||||||
|
|
||||||
bool m_isRestored = false;
|
bool m_isRestored = false;
|
||||||
bool m_isPaused = isStartPaused();
|
bool m_isPaused = isStartPaused();
|
||||||
|
|
||||||
|
@ -766,6 +774,7 @@ namespace BitTorrent
|
||||||
QThreadPool *m_asyncWorker = nullptr;
|
QThreadPool *m_asyncWorker = nullptr;
|
||||||
ResumeDataStorage *m_resumeDataStorage = nullptr;
|
ResumeDataStorage *m_resumeDataStorage = nullptr;
|
||||||
FileSearcher *m_fileSearcher = nullptr;
|
FileSearcher *m_fileSearcher = nullptr;
|
||||||
|
TorrentContentRemover *m_torrentContentRemover = nullptr;
|
||||||
|
|
||||||
QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata;
|
QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata;
|
||||||
|
|
||||||
|
@ -809,6 +818,8 @@ namespace BitTorrent
|
||||||
QTimer *m_wakeupCheckTimer = nullptr;
|
QTimer *m_wakeupCheckTimer = nullptr;
|
||||||
QDateTime m_wakeupCheckTimestamp;
|
QDateTime m_wakeupCheckTimestamp;
|
||||||
|
|
||||||
|
QList<TorrentImpl *> m_pendingFinishedTorrents;
|
||||||
|
|
||||||
friend void Session::initInstance();
|
friend void Session::initInstance();
|
||||||
friend void Session::freeInstance();
|
friend void Session::freeInstance();
|
||||||
friend Session *Session::instance();
|
friend Session *Session::instance();
|
||||||
|
|
|
@ -228,6 +228,7 @@ namespace BitTorrent
|
||||||
virtual void setShareLimitAction(ShareLimitAction action) = 0;
|
virtual void setShareLimitAction(ShareLimitAction action) = 0;
|
||||||
|
|
||||||
virtual PathList filePaths() const = 0;
|
virtual PathList filePaths() const = 0;
|
||||||
|
virtual PathList actualFilePaths() const = 0;
|
||||||
|
|
||||||
virtual TorrentInfo info() const = 0;
|
virtual TorrentInfo info() const = 0;
|
||||||
virtual bool isFinished() const = 0;
|
virtual bool isFinished() const = 0;
|
||||||
|
|
50
src/base/bittorrent/torrentcontentremoveoption.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
|
inline namespace TorrentContentRemoveOptionNS
|
||||||
|
{
|
||||||
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class TorrentContentRemoveOption
|
||||||
|
{
|
||||||
|
Delete,
|
||||||
|
MoveToTrash
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM_NS(TorrentContentRemoveOption)
|
||||||
|
}
|
||||||
|
}
|
61
src/base/bittorrent/torrentcontentremover.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "torrentcontentremover.h"
|
||||||
|
|
||||||
|
#include "base/utils/fs.h"
|
||||||
|
|
||||||
|
void BitTorrent::TorrentContentRemover::performJob(const QString &torrentName, const Path &basePath
|
||||||
|
, const PathList &fileNames, const TorrentContentRemoveOption option)
|
||||||
|
{
|
||||||
|
QString errorMessage;
|
||||||
|
|
||||||
|
if (!fileNames.isEmpty())
|
||||||
|
{
|
||||||
|
const auto removeFileFn = [&option](const Path &filePath)
|
||||||
|
{
|
||||||
|
return ((option == TorrentContentRemoveOption::MoveToTrash)
|
||||||
|
? Utils::Fs::moveFileToTrash : Utils::Fs::removeFile)(filePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const Path &fileName : fileNames)
|
||||||
|
{
|
||||||
|
if (const auto result = removeFileFn(basePath / fileName)
|
||||||
|
; !result && errorMessage.isEmpty())
|
||||||
|
{
|
||||||
|
errorMessage = result.error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Path rootPath = Path::findRootFolder(fileNames);
|
||||||
|
if (!rootPath.isEmpty())
|
||||||
|
Utils::Fs::smartRemoveEmptyFolderTree(basePath / rootPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit jobFinished(torrentName, errorMessage);
|
||||||
|
}
|
53
src/base/bittorrent/torrentcontentremover.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "base/path.h"
|
||||||
|
#include "torrentcontentremoveoption.h"
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
class TorrentContentRemover final : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(TorrentContentRemover)
|
||||||
|
|
||||||
|
public:
|
||||||
|
using QObject::QObject;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void performJob(const QString &torrentName, const Path &basePath
|
||||||
|
, const PathList &fileNames, TorrentContentRemoveOption option);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void jobFinished(const QString &torrentName, const QString &errorMessage);
|
||||||
|
};
|
||||||
|
}
|
|
@ -77,6 +77,10 @@
|
||||||
#include "base/utils/os.h"
|
#include "base/utils/os.h"
|
||||||
#endif // Q_OS_MACOS || Q_OS_WIN
|
#endif // Q_OS_MACOS || Q_OS_WIN
|
||||||
|
|
||||||
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
|
#include "customstorage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -456,6 +460,8 @@ Path TorrentImpl::savePath() const
|
||||||
void TorrentImpl::setSavePath(const Path &path)
|
void TorrentImpl::setSavePath(const Path &path)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!isAutoTMMEnabled());
|
Q_ASSERT(!isAutoTMMEnabled());
|
||||||
|
if (isAutoTMMEnabled()) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
const Path basePath = m_session->useCategoryPathsInManualMode()
|
const Path basePath = m_session->useCategoryPathsInManualMode()
|
||||||
? m_session->categorySavePath(category()) : m_session->savePath();
|
? m_session->categorySavePath(category()) : m_session->savePath();
|
||||||
|
@ -483,6 +489,8 @@ Path TorrentImpl::downloadPath() const
|
||||||
void TorrentImpl::setDownloadPath(const Path &path)
|
void TorrentImpl::setDownloadPath(const Path &path)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!isAutoTMMEnabled());
|
Q_ASSERT(!isAutoTMMEnabled());
|
||||||
|
if (isAutoTMMEnabled()) [[unlikely]]
|
||||||
|
return;
|
||||||
|
|
||||||
const Path basePath = m_session->useCategoryPathsInManualMode()
|
const Path basePath = m_session->useCategoryPathsInManualMode()
|
||||||
? m_session->categoryDownloadPath(category()) : m_session->downloadPath();
|
? m_session->categoryDownloadPath(category()) : m_session->downloadPath();
|
||||||
|
@ -982,6 +990,21 @@ PathList TorrentImpl::filePaths() const
|
||||||
return m_filePaths;
|
return m_filePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PathList TorrentImpl::actualFilePaths() const
|
||||||
|
{
|
||||||
|
if (!hasMetadata())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
PathList paths;
|
||||||
|
paths.reserve(filesCount());
|
||||||
|
|
||||||
|
const lt::file_storage files = nativeTorrentInfo()->files();
|
||||||
|
for (const lt::file_index_t &nativeIndex : asConst(m_torrentInfo.nativeIndexes()))
|
||||||
|
paths.emplaceBack(files.file_path(nativeIndex));
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<DownloadPriority> TorrentImpl::filePriorities() const
|
QVector<DownloadPriority> TorrentImpl::filePriorities() const
|
||||||
{
|
{
|
||||||
return m_filePriorities;
|
return m_filePriorities;
|
||||||
|
@ -1447,11 +1470,13 @@ QBitArray TorrentImpl::pieces() const
|
||||||
|
|
||||||
QBitArray TorrentImpl::downloadingPieces() const
|
QBitArray TorrentImpl::downloadingPieces() const
|
||||||
{
|
{
|
||||||
QBitArray result(piecesCount());
|
if (!hasMetadata())
|
||||||
|
return {};
|
||||||
|
|
||||||
std::vector<lt::partial_piece_info> queue;
|
std::vector<lt::partial_piece_info> queue;
|
||||||
m_nativeHandle.get_download_queue(queue);
|
m_nativeHandle.get_download_queue(queue);
|
||||||
|
|
||||||
|
QBitArray result {piecesCount()};
|
||||||
for (const lt::partial_piece_info &info : queue)
|
for (const lt::partial_piece_info &info : queue)
|
||||||
result.setBit(LT::toUnderlyingType(info.piece_index));
|
result.setBit(LT::toUnderlyingType(info.piece_index));
|
||||||
|
|
||||||
|
@ -1791,12 +1816,13 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
|
||||||
const Path filePath = actualFilePath.removedExtension(QB_EXT);
|
const Path filePath = actualFilePath.removedExtension(QB_EXT);
|
||||||
m_filePaths.append(filePath);
|
m_filePaths.append(filePath);
|
||||||
|
|
||||||
lt::download_priority_t &nativePriority = p.file_priorities[LT::toUnderlyingType(nativeIndex)];
|
m_filePriorities.append(LT::fromNative(p.file_priorities[LT::toUnderlyingType(nativeIndex)]));
|
||||||
if ((nativePriority != lt::dont_download) && m_session->isFilenameExcluded(filePath.filename()))
|
|
||||||
nativePriority = lt::dont_download;
|
|
||||||
const auto priority = LT::fromNative(nativePriority);
|
|
||||||
m_filePriorities.append(priority);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_session->applyFilenameFilter(m_filePaths, m_filePriorities);
|
||||||
|
for (int i = 0; i < m_filePriorities.size(); ++i)
|
||||||
|
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(m_filePriorities[i]);
|
||||||
|
|
||||||
p.save_path = savePath.toString().toStdString();
|
p.save_path = savePath.toString().toStdString();
|
||||||
p.ti = metadata;
|
p.ti = metadata;
|
||||||
|
|
||||||
|
@ -1859,6 +1885,9 @@ void TorrentImpl::reload()
|
||||||
|
|
||||||
auto *const extensionData = new ExtensionData;
|
auto *const extensionData = new ExtensionData;
|
||||||
p.userdata = LTClientData(extensionData);
|
p.userdata = LTClientData(extensionData);
|
||||||
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
|
p.storage = customStorageConstructor;
|
||||||
|
#endif
|
||||||
m_nativeHandle = m_nativeSession->add_torrent(p);
|
m_nativeHandle = m_nativeSession->add_torrent(p);
|
||||||
|
|
||||||
m_nativeStatus = extensionData->status;
|
m_nativeStatus = extensionData->status;
|
||||||
|
@ -1932,9 +1961,18 @@ void TorrentImpl::start(const TorrentOperatingMode mode)
|
||||||
void TorrentImpl::moveStorage(const Path &newPath, const MoveStorageContext context)
|
void TorrentImpl::moveStorage(const Path &newPath, const MoveStorageContext context)
|
||||||
{
|
{
|
||||||
if (!hasMetadata())
|
if (!hasMetadata())
|
||||||
|
{
|
||||||
|
if (context == MoveStorageContext::ChangeSavePath)
|
||||||
{
|
{
|
||||||
m_savePath = newPath;
|
m_savePath = newPath;
|
||||||
m_session->handleTorrentSavePathChanged(this);
|
m_session->handleTorrentSavePathChanged(this);
|
||||||
|
}
|
||||||
|
else if (context == MoveStorageContext::ChangeDownloadPath)
|
||||||
|
{
|
||||||
|
m_downloadPath = newPath;
|
||||||
|
m_session->handleTorrentSavePathChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ namespace BitTorrent
|
||||||
Path actualFilePath(int index) const override;
|
Path actualFilePath(int index) const override;
|
||||||
qlonglong fileSize(int index) const override;
|
qlonglong fileSize(int index) const override;
|
||||||
PathList filePaths() const override;
|
PathList filePaths() const override;
|
||||||
|
PathList actualFilePaths() const override;
|
||||||
QVector<DownloadPriority> filePriorities() const override;
|
QVector<DownloadPriority> filePriorities() const override;
|
||||||
|
|
||||||
TorrentInfo info() const override;
|
TorrentInfo info() const override;
|
||||||
|
|
|
@ -44,6 +44,7 @@ Connection::Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObj
|
||||||
, m_requestHandler(requestHandler)
|
, m_requestHandler(requestHandler)
|
||||||
{
|
{
|
||||||
m_socket->setParent(this);
|
m_socket->setParent(this);
|
||||||
|
connect(m_socket, &QAbstractSocket::disconnected, this, &Connection::closed);
|
||||||
|
|
||||||
// reserve common size for requests, don't use the max allowed size which is too big for
|
// reserve common size for requests, don't use the max allowed size which is too big for
|
||||||
// memory constrained platforms
|
// memory constrained platforms
|
||||||
|
@ -62,11 +63,6 @@ Connection::Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObj
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection::~Connection()
|
|
||||||
{
|
|
||||||
m_socket->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Connection::read()
|
void Connection::read()
|
||||||
{
|
{
|
||||||
// reuse existing buffer and avoid unnecessary memory allocation/relocation
|
// reuse existing buffer and avoid unnecessary memory allocation/relocation
|
||||||
|
@ -182,11 +178,6 @@ bool Connection::hasExpired(const qint64 timeout) const
|
||||||
&& m_idleTimer.hasExpired(timeout);
|
&& m_idleTimer.hasExpired(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Connection::isClosed() const
|
|
||||||
{
|
|
||||||
return (m_socket->state() == QAbstractSocket::UnconnectedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Connection::acceptsGzipEncoding(QString codings)
|
bool Connection::acceptsGzipEncoding(QString codings)
|
||||||
{
|
{
|
||||||
// [rfc7231] 5.3.4. Accept-Encoding
|
// [rfc7231] 5.3.4. Accept-Encoding
|
||||||
|
|
|
@ -47,10 +47,11 @@ namespace Http
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObject *parent = nullptr);
|
Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObject *parent = nullptr);
|
||||||
~Connection();
|
|
||||||
|
|
||||||
bool hasExpired(qint64 timeout) const;
|
bool hasExpired(qint64 timeout) const;
|
||||||
bool isClosed() const;
|
|
||||||
|
signals:
|
||||||
|
void closed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool acceptsGzipEncoding(QString codings);
|
static bool acceptsGzipEncoding(QString codings);
|
||||||
|
|
|
@ -32,7 +32,10 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <QtLogging>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
#include <QSslCipher>
|
#include <QSslCipher>
|
||||||
#include <QSslConfiguration>
|
#include <QSslConfiguration>
|
||||||
|
@ -40,7 +43,6 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "base/algorithm.h"
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/utils/net.h"
|
#include "base/utils/net.h"
|
||||||
#include "base/utils/sslkey.h"
|
#include "base/utils/sslkey.h"
|
||||||
|
@ -113,32 +115,38 @@ Server::Server(IRequestHandler *requestHandler, QObject *parent)
|
||||||
|
|
||||||
void Server::incomingConnection(const qintptr socketDescriptor)
|
void Server::incomingConnection(const qintptr socketDescriptor)
|
||||||
{
|
{
|
||||||
if (m_connections.size() >= CONNECTIONS_LIMIT) return;
|
std::unique_ptr<QTcpSocket> serverSocket = m_https ? std::make_unique<QSslSocket>(this) : std::make_unique<QTcpSocket>(this);
|
||||||
|
|
||||||
QTcpSocket *serverSocket = nullptr;
|
|
||||||
if (m_https)
|
|
||||||
serverSocket = new QSslSocket(this);
|
|
||||||
else
|
|
||||||
serverSocket = new QTcpSocket(this);
|
|
||||||
|
|
||||||
if (!serverSocket->setSocketDescriptor(socketDescriptor))
|
if (!serverSocket->setSocketDescriptor(socketDescriptor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_connections.size() >= CONNECTIONS_LIMIT)
|
||||||
{
|
{
|
||||||
delete serverSocket;
|
qWarning("Too many connections. Exceeded CONNECTIONS_LIMIT (%d). Connection closed.", CONNECTIONS_LIMIT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (m_https)
|
if (m_https)
|
||||||
{
|
{
|
||||||
static_cast<QSslSocket *>(serverSocket)->setProtocol(QSsl::SecureProtocols);
|
auto *sslSocket = static_cast<QSslSocket *>(serverSocket.get());
|
||||||
static_cast<QSslSocket *>(serverSocket)->setPrivateKey(m_key);
|
sslSocket->setProtocol(QSsl::SecureProtocols);
|
||||||
static_cast<QSslSocket *>(serverSocket)->setLocalCertificateChain(m_certificates);
|
sslSocket->setPrivateKey(m_key);
|
||||||
static_cast<QSslSocket *>(serverSocket)->setPeerVerifyMode(QSslSocket::VerifyNone);
|
sslSocket->setLocalCertificateChain(m_certificates);
|
||||||
static_cast<QSslSocket *>(serverSocket)->startServerEncryption();
|
sslSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||||
|
sslSocket->startServerEncryption();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *c = new Connection(serverSocket, m_requestHandler, this);
|
auto *connection = new Connection(serverSocket.release(), m_requestHandler, this);
|
||||||
m_connections.insert(c);
|
m_connections.insert(connection);
|
||||||
connect(serverSocket, &QAbstractSocket::disconnected, this, [c, this]() { removeConnection(c); });
|
connect(connection, &Connection::closed, this, [this, connection] { removeConnection(connection); });
|
||||||
|
}
|
||||||
|
catch (const std::bad_alloc &exception)
|
||||||
|
{
|
||||||
|
// drop the connection instead of throwing exception and crash
|
||||||
|
qWarning("Failed to allocate memory for HTTP connection. Connection closed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removeConnection(Connection *connection)
|
void Server::removeConnection(Connection *connection)
|
||||||
|
|
|
@ -148,10 +148,20 @@ Net::DownloadManager::DownloadManager(QObject *parent)
|
||||||
QStringList errorList;
|
QStringList errorList;
|
||||||
for (const QSslError &error : errors)
|
for (const QSslError &error : errors)
|
||||||
errorList += error.errorString();
|
errorList += error.errorString();
|
||||||
LogMsg(tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"").arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
|
|
||||||
|
|
||||||
|
QString errorMsg;
|
||||||
|
if (!Preferences::instance()->isIgnoreSSLErrors())
|
||||||
|
{
|
||||||
|
errorMsg = tr("SSL error, URL: \"%1\", errors: \"%2\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorMsg = tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"");
|
||||||
// Ignore all SSL errors
|
// Ignore all SSL errors
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMsg(errorMsg.arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
|
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
|
||||||
|
|
|
@ -43,7 +43,6 @@ class QSslSocket;
|
||||||
#else
|
#else
|
||||||
class QTcpSocket;
|
class QTcpSocket;
|
||||||
#endif
|
#endif
|
||||||
class QTextCodec;
|
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,17 +134,17 @@ void Preferences::setCustomUIThemePath(const Path &path)
|
||||||
setValue(u"Preferences/General/CustomUIThemePath"_s, path);
|
setValue(u"Preferences/General/CustomUIThemePath"_s, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Preferences::deleteTorrentFilesAsDefault() const
|
bool Preferences::removeTorrentContent() const
|
||||||
{
|
{
|
||||||
return value(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, false);
|
return value(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::setDeleteTorrentFilesAsDefault(const bool del)
|
void Preferences::setRemoveTorrentContent(const bool remove)
|
||||||
{
|
{
|
||||||
if (del == deleteTorrentFilesAsDefault())
|
if (remove == removeTorrentContent())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setValue(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, del);
|
setValue(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Preferences::confirmOnExit() const
|
bool Preferences::confirmOnExit() const
|
||||||
|
@ -429,6 +429,19 @@ void Preferences::setWinStartup(const bool b)
|
||||||
settings.remove(profileID);
|
settings.remove(profileID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Preferences::getStyle() const
|
||||||
|
{
|
||||||
|
return value<QString>(u"Appearance/Style"_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::setStyle(const QString &styleName)
|
||||||
|
{
|
||||||
|
if (styleName == getStyle())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setValue(u"Appearance/Style"_s, styleName);
|
||||||
|
}
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
// Downloads
|
// Downloads
|
||||||
|
@ -1330,6 +1343,19 @@ void Preferences::setMarkOfTheWebEnabled(const bool enabled)
|
||||||
setValue(u"Preferences/Advanced/markOfTheWeb"_s, enabled);
|
setValue(u"Preferences/Advanced/markOfTheWeb"_s, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Preferences::isIgnoreSSLErrors() const
|
||||||
|
{
|
||||||
|
return value(u"Preferences/Advanced/IgnoreSSLErrors"_s, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::setIgnoreSSLErrors(const bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled == isIgnoreSSLErrors())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setValue(u"Preferences/Advanced/IgnoreSSLErrors"_s, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
Path Preferences::getPythonExecutablePath() const
|
Path Preferences::getPythonExecutablePath() const
|
||||||
{
|
{
|
||||||
return value(u"Preferences/Search/pythonExecutablePath"_s, Path());
|
return value(u"Preferences/Search/pythonExecutablePath"_s, Path());
|
||||||
|
|
|
@ -105,8 +105,8 @@ public:
|
||||||
void setUseCustomUITheme(bool use);
|
void setUseCustomUITheme(bool use);
|
||||||
Path customUIThemePath() const;
|
Path customUIThemePath() const;
|
||||||
void setCustomUIThemePath(const Path &path);
|
void setCustomUIThemePath(const Path &path);
|
||||||
bool deleteTorrentFilesAsDefault() const;
|
bool removeTorrentContent() const;
|
||||||
void setDeleteTorrentFilesAsDefault(bool del);
|
void setRemoveTorrentContent(bool remove);
|
||||||
bool confirmOnExit() const;
|
bool confirmOnExit() const;
|
||||||
void setConfirmOnExit(bool confirm);
|
void setConfirmOnExit(bool confirm);
|
||||||
bool speedInTitleBar() const;
|
bool speedInTitleBar() const;
|
||||||
|
@ -130,6 +130,8 @@ public:
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
bool WinStartup() const;
|
bool WinStartup() const;
|
||||||
void setWinStartup(bool b);
|
void setWinStartup(bool b);
|
||||||
|
QString getStyle() const;
|
||||||
|
void setStyle(const QString &styleName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Downloads
|
// Downloads
|
||||||
|
@ -293,6 +295,8 @@ public:
|
||||||
void setTrackerPortForwardingEnabled(bool enabled);
|
void setTrackerPortForwardingEnabled(bool enabled);
|
||||||
bool isMarkOfTheWebEnabled() const;
|
bool isMarkOfTheWebEnabled() const;
|
||||||
void setMarkOfTheWebEnabled(bool enabled);
|
void setMarkOfTheWebEnabled(bool enabled);
|
||||||
|
bool isIgnoreSSLErrors() const;
|
||||||
|
void setIgnoreSSLErrors(bool enabled);
|
||||||
Path getPythonExecutablePath() const;
|
Path getPythonExecutablePath() const;
|
||||||
void setPythonExecutablePath(const Path &path);
|
void setPythonExecutablePath(const Path &path);
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
||||||
|
|
|
@ -52,19 +52,21 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
|
||||||
using BitTorrent::Torrent;
|
using BitTorrent::Torrent;
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter(const Type type, const std::optional<TorrentIDSet> &idSet
|
TorrentFilter::TorrentFilter(const Type type, const std::optional<TorrentIDSet> &idSet
|
||||||
, const std::optional<QString> &category, const std::optional<Tag> &tag)
|
, const std::optional<QString> &category, const std::optional<Tag> &tag, const std::optional<bool> isPrivate)
|
||||||
: m_type {type}
|
: m_type {type}
|
||||||
, m_category {category}
|
, m_category {category}
|
||||||
, m_tag {tag}
|
, m_tag {tag}
|
||||||
, m_idSet {idSet}
|
, m_idSet {idSet}
|
||||||
|
, m_private {isPrivate}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet
|
TorrentFilter::TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet
|
||||||
, const std::optional<QString> &category, const std::optional<Tag> &tag)
|
, const std::optional<QString> &category, const std::optional<Tag> &tag, const std::optional<bool> isPrivate)
|
||||||
: m_category {category}
|
: m_category {category}
|
||||||
, m_tag {tag}
|
, m_tag {tag}
|
||||||
, m_idSet {idSet}
|
, m_idSet {idSet}
|
||||||
|
, m_private {isPrivate}
|
||||||
{
|
{
|
||||||
setTypeByName(filter);
|
setTypeByName(filter);
|
||||||
}
|
}
|
||||||
|
@ -147,11 +149,22 @@ bool TorrentFilter::setTag(const std::optional<Tag> &tag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TorrentFilter::setPrivate(const std::optional<bool> isPrivate)
|
||||||
|
{
|
||||||
|
if (m_private != isPrivate)
|
||||||
|
{
|
||||||
|
m_private = isPrivate;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TorrentFilter::match(const Torrent *const torrent) const
|
bool TorrentFilter::match(const Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (!torrent) return false;
|
if (!torrent) return false;
|
||||||
|
|
||||||
return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent));
|
return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent) && matchPrivate(torrent));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
|
bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
|
||||||
|
@ -224,3 +237,11 @@ bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const
|
||||||
|
|
||||||
return torrent->hasTag(*m_tag);
|
return torrent->hasTag(*m_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TorrentFilter::matchPrivate(const BitTorrent::Torrent *const torrent) const
|
||||||
|
{
|
||||||
|
if (!m_private)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return m_private == torrent->isPrivate();
|
||||||
|
}
|
||||||
|
|
|
@ -87,16 +87,24 @@ public:
|
||||||
|
|
||||||
TorrentFilter() = default;
|
TorrentFilter() = default;
|
||||||
// category & tags: pass empty string for uncategorized / untagged torrents.
|
// category & tags: pass empty string for uncategorized / untagged torrents.
|
||||||
TorrentFilter(Type type, const std::optional<TorrentIDSet> &idSet = AnyID
|
TorrentFilter(Type type
|
||||||
, const std::optional<QString> &category = AnyCategory, const std::optional<Tag> &tag = AnyTag);
|
, const std::optional<TorrentIDSet> &idSet = AnyID
|
||||||
TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet = AnyID
|
, const std::optional<QString> &category = AnyCategory
|
||||||
, const std::optional<QString> &category = AnyCategory, const std::optional<Tag> &tags = AnyTag);
|
, const std::optional<Tag> &tag = AnyTag
|
||||||
|
, std::optional<bool> isPrivate = {});
|
||||||
|
TorrentFilter(const QString &filter
|
||||||
|
, const std::optional<TorrentIDSet> &idSet = AnyID
|
||||||
|
, const std::optional<QString> &category = AnyCategory
|
||||||
|
, const std::optional<Tag> &tags = AnyTag
|
||||||
|
, std::optional<bool> isPrivate = {});
|
||||||
|
|
||||||
|
|
||||||
bool setType(Type type);
|
bool setType(Type type);
|
||||||
bool setTypeByName(const QString &filter);
|
bool setTypeByName(const QString &filter);
|
||||||
bool setTorrentIDSet(const std::optional<TorrentIDSet> &idSet);
|
bool setTorrentIDSet(const std::optional<TorrentIDSet> &idSet);
|
||||||
bool setCategory(const std::optional<QString> &category);
|
bool setCategory(const std::optional<QString> &category);
|
||||||
bool setTag(const std::optional<Tag> &tag);
|
bool setTag(const std::optional<Tag> &tag);
|
||||||
|
bool setPrivate(std::optional<bool> isPrivate);
|
||||||
|
|
||||||
bool match(const BitTorrent::Torrent *torrent) const;
|
bool match(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
|
@ -105,9 +113,11 @@ private:
|
||||||
bool matchHash(const BitTorrent::Torrent *torrent) const;
|
bool matchHash(const BitTorrent::Torrent *torrent) const;
|
||||||
bool matchCategory(const BitTorrent::Torrent *torrent) const;
|
bool matchCategory(const BitTorrent::Torrent *torrent) const;
|
||||||
bool matchTag(const BitTorrent::Torrent *torrent) const;
|
bool matchTag(const BitTorrent::Torrent *torrent) const;
|
||||||
|
bool matchPrivate(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
Type m_type {All};
|
Type m_type {All};
|
||||||
std::optional<QString> m_category;
|
std::optional<QString> m_category;
|
||||||
std::optional<Tag> m_tag;
|
std::optional<Tag> m_tag;
|
||||||
std::optional<TorrentIDSet> m_idSet;
|
std::optional<TorrentIDSet> m_idSet;
|
||||||
|
std::optional<bool> m_private;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -29,8 +29,6 @@
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
@ -52,6 +50,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -311,20 +310,42 @@ bool Utils::Fs::renameFile(const Path &from, const Path &to)
|
||||||
*
|
*
|
||||||
* This function will try to fix the file permissions before removing it.
|
* This function will try to fix the file permissions before removing it.
|
||||||
*/
|
*/
|
||||||
bool Utils::Fs::removeFile(const Path &path)
|
nonstd::expected<void, QString> Utils::Fs::removeFile(const Path &path)
|
||||||
{
|
{
|
||||||
if (QFile::remove(path.data()))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
QFile file {path.data()};
|
QFile file {path.data()};
|
||||||
|
if (file.remove())
|
||||||
|
return {};
|
||||||
|
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
return true;
|
return {};
|
||||||
|
|
||||||
// Make sure we have read/write permissions
|
// Make sure we have read/write permissions
|
||||||
file.setPermissions(file.permissions() | QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser);
|
file.setPermissions(file.permissions() | QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser);
|
||||||
return file.remove();
|
if (file.remove())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return nonstd::make_unexpected(file.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nonstd::expected<void, QString> Utils::Fs::moveFileToTrash(const Path &path)
|
||||||
|
{
|
||||||
|
QFile file {path.data()};
|
||||||
|
if (file.moveToTrash())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (!file.exists())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Make sure we have read/write permissions
|
||||||
|
file.setPermissions(file.permissions() | QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser);
|
||||||
|
if (file.moveToTrash())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const QString errorMessage = file.errorString();
|
||||||
|
return nonstd::make_unexpected(!errorMessage.isEmpty() ? errorMessage : QCoreApplication::translate("fs", "Unknown error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Utils::Fs::isReadable(const Path &path)
|
bool Utils::Fs::isReadable(const Path &path)
|
||||||
{
|
{
|
||||||
return QFileInfo(path.data()).isReadable();
|
return QFileInfo(path.data()).isReadable();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "base/3rdparty/expected.hpp"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/pathfwd.h"
|
#include "base/pathfwd.h"
|
||||||
|
|
||||||
|
@ -60,7 +61,8 @@ namespace Utils::Fs
|
||||||
|
|
||||||
bool copyFile(const Path &from, const Path &to);
|
bool copyFile(const Path &from, const Path &to);
|
||||||
bool renameFile(const Path &from, const Path &to);
|
bool renameFile(const Path &from, const Path &to);
|
||||||
bool removeFile(const Path &path);
|
nonstd::expected<void, QString> removeFile(const Path &path);
|
||||||
|
nonstd::expected<void, QString> moveFileToTrash(const Path &path);
|
||||||
bool mkdir(const Path &dirPath);
|
bool mkdir(const Path &dirPath);
|
||||||
bool mkpath(const Path &dirPath);
|
bool mkpath(const Path &dirPath);
|
||||||
bool rmdir(const Path &dirPath);
|
bool rmdir(const Path &dirPath);
|
||||||
|
|
|
@ -271,6 +271,11 @@ Path Utils::OS::windowsSystemPath()
|
||||||
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
||||||
bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
|
bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
|
||||||
{
|
{
|
||||||
|
// Trying to apply this to a non-existent file is unacceptable,
|
||||||
|
// as it may unexpectedly create such a file.
|
||||||
|
if (!file.exists())
|
||||||
|
return false;
|
||||||
|
|
||||||
Q_ASSERT(url.isEmpty() || url.startsWith(u"http:") || url.startsWith(u"https:"));
|
Q_ASSERT(url.isEmpty() || url.startsWith(u"http:") || url.startsWith(u"https:"));
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
|
|
||||||
#define QBT_VERSION_MAJOR 5
|
#define QBT_VERSION_MAJOR 5
|
||||||
#define QBT_VERSION_MINOR 0
|
#define QBT_VERSION_MINOR 0
|
||||||
#define QBT_VERSION_BUGFIX 0
|
#define QBT_VERSION_BUGFIX 1
|
||||||
#define QBT_VERSION_BUILD 0
|
#define QBT_VERSION_BUILD 0
|
||||||
#define QBT_VERSION_STATUS "beta1" // Should be empty for stable releases!
|
#define QBT_VERSION_STATUS "" // Should be empty for stable releases!
|
||||||
|
|
||||||
#define QBT__STRINGIFY(x) #x
|
#define QBT__STRINGIFY(x) #x
|
||||||
#define QBT_STRINGIFY(x) QBT__STRINGIFY(x)
|
#define QBT_STRINGIFY(x) QBT__STRINGIFY(x)
|
||||||
|
|
|
@ -52,6 +52,8 @@ add_library(qbt_gui STATIC
|
||||||
desktopintegration.h
|
desktopintegration.h
|
||||||
downloadfromurldialog.h
|
downloadfromurldialog.h
|
||||||
executionlogwidget.h
|
executionlogwidget.h
|
||||||
|
filterpatternformat.h
|
||||||
|
filterpatternformatmenu.h
|
||||||
flowlayout.h
|
flowlayout.h
|
||||||
fspathedit.h
|
fspathedit.h
|
||||||
fspathedit_p.h
|
fspathedit_p.h
|
||||||
|
@ -151,6 +153,7 @@ add_library(qbt_gui STATIC
|
||||||
desktopintegration.cpp
|
desktopintegration.cpp
|
||||||
downloadfromurldialog.cpp
|
downloadfromurldialog.cpp
|
||||||
executionlogwidget.cpp
|
executionlogwidget.cpp
|
||||||
|
filterpatternformatmenu.cpp
|
||||||
flowlayout.cpp
|
flowlayout.cpp
|
||||||
fspathedit.cpp
|
fspathedit.cpp
|
||||||
fspathedit_p.cpp
|
fspathedit_p.cpp
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -64,6 +64,7 @@
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
|
#include "filterpatternformatmenu.h"
|
||||||
#include "lineedit.h"
|
#include "lineedit.h"
|
||||||
#include "torrenttagsdialog.h"
|
#include "torrenttagsdialog.h"
|
||||||
|
|
||||||
|
@ -181,6 +182,11 @@ public:
|
||||||
return (m_filePaths.isEmpty() ? m_torrentInfo.filePath(index) : m_filePaths.at(index));
|
return (m_filePaths.isEmpty() ? m_torrentInfo.filePath(index) : m_filePaths.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PathList filePaths() const
|
||||||
|
{
|
||||||
|
return (m_filePaths.isEmpty() ? m_torrentInfo.filePaths() : m_filePaths);
|
||||||
|
}
|
||||||
|
|
||||||
void renameFile(const int index, const Path &newFilePath) override
|
void renameFile(const int index, const Path &newFilePath) override
|
||||||
{
|
{
|
||||||
Q_ASSERT((index >= 0) && (index < filesCount()));
|
Q_ASSERT((index >= 0) && (index < filesCount()));
|
||||||
|
@ -290,6 +296,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
|
||||||
, m_storeRememberLastSavePath {SETTINGS_KEY(u"RememberLastSavePath"_s)}
|
, m_storeRememberLastSavePath {SETTINGS_KEY(u"RememberLastSavePath"_s)}
|
||||||
, m_storeTreeHeaderState {u"GUI/Qt6/" SETTINGS_KEY(u"TreeHeaderState"_s)}
|
, m_storeTreeHeaderState {u"GUI/Qt6/" SETTINGS_KEY(u"TreeHeaderState"_s)}
|
||||||
, m_storeSplitterState {u"GUI/Qt6/" SETTINGS_KEY(u"SplitterState"_s)}
|
, m_storeSplitterState {u"GUI/Qt6/" SETTINGS_KEY(u"SplitterState"_s)}
|
||||||
|
, m_storeFilterPatternFormat {u"GUI/" SETTINGS_KEY(u"FilterPatternFormat"_s)}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
@ -316,6 +323,8 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
|
||||||
// Torrent content filtering
|
// Torrent content filtering
|
||||||
m_filterLine->setPlaceholderText(tr("Filter files..."));
|
m_filterLine->setPlaceholderText(tr("Filter files..."));
|
||||||
m_filterLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
m_filterLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
m_filterLine->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_filterLine, &QWidget::customContextMenuRequested, this, &AddNewTorrentDialog::showContentFilterContextMenu);
|
||||||
m_ui->contentFilterLayout->insertWidget(3, m_filterLine);
|
m_ui->contentFilterLayout->insertWidget(3, m_filterLine);
|
||||||
const auto *focusSearchHotkey = new QShortcut(QKeySequence::Find, this);
|
const auto *focusSearchHotkey = new QShortcut(QKeySequence::Find, this);
|
||||||
connect(focusSearchHotkey, &QShortcut::activated, this, [this]()
|
connect(focusSearchHotkey, &QShortcut::activated, this, [this]()
|
||||||
|
@ -360,7 +369,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
|
||||||
});
|
});
|
||||||
dlg->open();
|
dlg->open();
|
||||||
});
|
});
|
||||||
connect(m_filterLine, &LineEdit::textChanged, m_ui->contentTreeView, &TorrentContentWidget::setFilterPattern);
|
connect(m_filterLine, &LineEdit::textChanged, this, &AddNewTorrentDialog::setContentFilterPattern);
|
||||||
connect(m_ui->buttonSelectAll, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkAll);
|
connect(m_ui->buttonSelectAll, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkAll);
|
||||||
connect(m_ui->buttonSelectNone, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkNone);
|
connect(m_ui->buttonSelectNone, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkNone);
|
||||||
connect(Preferences::instance(), &Preferences::changed, []
|
connect(Preferences::instance(), &Preferences::changed, []
|
||||||
|
@ -691,6 +700,28 @@ void AddNewTorrentDialog::saveTorrentFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddNewTorrentDialog::showContentFilterContextMenu()
|
||||||
|
{
|
||||||
|
QMenu *menu = m_filterLine->createStandardContextMenu();
|
||||||
|
|
||||||
|
auto *formatMenu = new FilterPatternFormatMenu(m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards), menu);
|
||||||
|
connect(formatMenu, &FilterPatternFormatMenu::patternFormatChanged, this, [this](const FilterPatternFormat format)
|
||||||
|
{
|
||||||
|
m_storeFilterPatternFormat = format;
|
||||||
|
setContentFilterPattern();
|
||||||
|
});
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addMenu(formatMenu);
|
||||||
|
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
menu->popup(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddNewTorrentDialog::setContentFilterPattern()
|
||||||
|
{
|
||||||
|
m_ui->contentTreeView->setFilterPattern(m_filterLine->text(), m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards));
|
||||||
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::populateSavePaths()
|
void AddNewTorrentDialog::populateSavePaths()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_currentContext);
|
Q_ASSERT(m_currentContext);
|
||||||
|
@ -886,15 +917,7 @@ void AddNewTorrentDialog::setupTreeview()
|
||||||
{
|
{
|
||||||
// Check file name blacklist for torrents that are manually added
|
// Check file name blacklist for torrents that are manually added
|
||||||
QVector<BitTorrent::DownloadPriority> priorities = m_contentAdaptor->filePriorities();
|
QVector<BitTorrent::DownloadPriority> priorities = m_contentAdaptor->filePriorities();
|
||||||
for (int i = 0; i < priorities.size(); ++i)
|
BitTorrent::Session::instance()->applyFilenameFilter(m_contentAdaptor->filePaths(), priorities);
|
||||||
{
|
|
||||||
if (priorities[i] == BitTorrent::DownloadPriority::Ignored)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (BitTorrent::Session::instance()->isFilenameExcluded(torrentInfo.filePath(i).filename()))
|
|
||||||
priorities[i] = BitTorrent::DownloadPriority::Ignored;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_contentAdaptor->prioritizeFiles(priorities);
|
m_contentAdaptor->prioritizeFiles(priorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "base/settingvalue.h"
|
#include "base/settingvalue.h"
|
||||||
|
#include "filterpatternformat.h"
|
||||||
|
|
||||||
class LineEdit;
|
class LineEdit;
|
||||||
|
|
||||||
|
@ -92,6 +93,8 @@ private:
|
||||||
void setMetadataProgressIndicator(bool visibleIndicator, const QString &labelText = {});
|
void setMetadataProgressIndicator(bool visibleIndicator, const QString &labelText = {});
|
||||||
void setupTreeview();
|
void setupTreeview();
|
||||||
void saveTorrentFile();
|
void saveTorrentFile();
|
||||||
|
void showContentFilterContextMenu();
|
||||||
|
void setContentFilterPattern();
|
||||||
|
|
||||||
Ui::AddNewTorrentDialog *m_ui = nullptr;
|
Ui::AddNewTorrentDialog *m_ui = nullptr;
|
||||||
std::unique_ptr<TorrentContentAdaptor> m_contentAdaptor;
|
std::unique_ptr<TorrentContentAdaptor> m_contentAdaptor;
|
||||||
|
@ -107,4 +110,5 @@ private:
|
||||||
SettingValue<bool> m_storeRememberLastSavePath;
|
SettingValue<bool> m_storeRememberLastSavePath;
|
||||||
SettingValue<QByteArray> m_storeTreeHeaderState;
|
SettingValue<QByteArray> m_storeTreeHeaderState;
|
||||||
SettingValue<QByteArray> m_storeSplitterState;
|
SettingValue<QByteArray> m_storeSplitterState;
|
||||||
|
SettingValue<FilterPatternFormat> m_storeFilterPatternFormat;
|
||||||
};
|
};
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace
|
||||||
// qBittorrent section
|
// qBittorrent section
|
||||||
QBITTORRENT_HEADER,
|
QBITTORRENT_HEADER,
|
||||||
RESUME_DATA_STORAGE,
|
RESUME_DATA_STORAGE,
|
||||||
|
TORRENT_CONTENT_REMOVE_OPTION,
|
||||||
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
|
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
|
||||||
MEMORY_WORKING_SET_LIMIT,
|
MEMORY_WORKING_SET_LIMIT,
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,6 +105,7 @@ namespace
|
||||||
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
||||||
ENABLE_MARK_OF_THE_WEB,
|
ENABLE_MARK_OF_THE_WEB,
|
||||||
#endif // Q_OS_MACOS || Q_OS_WIN
|
#endif // Q_OS_MACOS || Q_OS_WIN
|
||||||
|
IGNORE_SSL_ERRORS,
|
||||||
PYTHON_EXECUTABLE_PATH,
|
PYTHON_EXECUTABLE_PATH,
|
||||||
START_SESSION_PAUSED,
|
START_SESSION_PAUSED,
|
||||||
SESSION_SHUTDOWN_TIMEOUT,
|
SESSION_SHUTDOWN_TIMEOUT,
|
||||||
|
@ -331,6 +333,8 @@ void AdvancedSettings::saveAdvancedSettings() const
|
||||||
// Mark-of-the-Web
|
// Mark-of-the-Web
|
||||||
pref->setMarkOfTheWebEnabled(m_checkBoxMarkOfTheWeb.isChecked());
|
pref->setMarkOfTheWebEnabled(m_checkBoxMarkOfTheWeb.isChecked());
|
||||||
#endif // Q_OS_MACOS || Q_OS_WIN
|
#endif // Q_OS_MACOS || Q_OS_WIN
|
||||||
|
// Ignore SSL errors
|
||||||
|
pref->setIgnoreSSLErrors(m_checkBoxIgnoreSSLErrors.isChecked());
|
||||||
// Python executable path
|
// Python executable path
|
||||||
pref->setPythonExecutablePath(Path(m_pythonExecutablePath.text().trimmed()));
|
pref->setPythonExecutablePath(Path(m_pythonExecutablePath.text().trimmed()));
|
||||||
// Start session paused
|
// Start session paused
|
||||||
|
@ -364,6 +368,8 @@ void AdvancedSettings::saveAdvancedSettings() const
|
||||||
session->setI2PInboundLength(m_spinBoxI2PInboundLength.value());
|
session->setI2PInboundLength(m_spinBoxI2PInboundLength.value());
|
||||||
session->setI2POutboundLength(m_spinBoxI2POutboundLength.value());
|
session->setI2POutboundLength(m_spinBoxI2POutboundLength.value());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
session->setTorrentContentRemoveOption(m_comboBoxTorrentContentRemoveOption.currentData().value<BitTorrent::TorrentContentRemoveOption>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QBT_USES_LIBTORRENT2
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
|
@ -472,6 +478,11 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||||
m_comboBoxResumeDataStorage.setCurrentIndex(m_comboBoxResumeDataStorage.findData(QVariant::fromValue(session->resumeDataStorageType())));
|
m_comboBoxResumeDataStorage.setCurrentIndex(m_comboBoxResumeDataStorage.findData(QVariant::fromValue(session->resumeDataStorageType())));
|
||||||
addRow(RESUME_DATA_STORAGE, tr("Resume data storage type (requires restart)"), &m_comboBoxResumeDataStorage);
|
addRow(RESUME_DATA_STORAGE, tr("Resume data storage type (requires restart)"), &m_comboBoxResumeDataStorage);
|
||||||
|
|
||||||
|
m_comboBoxTorrentContentRemoveOption.addItem(tr("Delete files permanently"), QVariant::fromValue(BitTorrent::TorrentContentRemoveOption::Delete));
|
||||||
|
m_comboBoxTorrentContentRemoveOption.addItem(tr("Move files to trash (if possible)"), QVariant::fromValue(BitTorrent::TorrentContentRemoveOption::MoveToTrash));
|
||||||
|
m_comboBoxTorrentContentRemoveOption.setCurrentIndex(m_comboBoxTorrentContentRemoveOption.findData(QVariant::fromValue(session->torrentContentRemoveOption())));
|
||||||
|
addRow(TORRENT_CONTENT_REMOVE_OPTION, tr("Torrent content removing mode"), &m_comboBoxTorrentContentRemoveOption);
|
||||||
|
|
||||||
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
|
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
|
||||||
// Physical memory (RAM) usage limit
|
// Physical memory (RAM) usage limit
|
||||||
m_spinBoxMemoryWorkingSetLimit.setMinimum(1);
|
m_spinBoxMemoryWorkingSetLimit.setMinimum(1);
|
||||||
|
@ -577,6 +588,7 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||||
m_comboBoxDiskIOType.addItem(tr("Default"), QVariant::fromValue(BitTorrent::DiskIOType::Default));
|
m_comboBoxDiskIOType.addItem(tr("Default"), QVariant::fromValue(BitTorrent::DiskIOType::Default));
|
||||||
m_comboBoxDiskIOType.addItem(tr("Memory mapped files"), QVariant::fromValue(BitTorrent::DiskIOType::MMap));
|
m_comboBoxDiskIOType.addItem(tr("Memory mapped files"), QVariant::fromValue(BitTorrent::DiskIOType::MMap));
|
||||||
m_comboBoxDiskIOType.addItem(tr("POSIX-compliant"), QVariant::fromValue(BitTorrent::DiskIOType::Posix));
|
m_comboBoxDiskIOType.addItem(tr("POSIX-compliant"), QVariant::fromValue(BitTorrent::DiskIOType::Posix));
|
||||||
|
m_comboBoxDiskIOType.addItem(tr("Simple pread/pwrite"), QVariant::fromValue(BitTorrent::DiskIOType::SimplePreadPwrite));
|
||||||
m_comboBoxDiskIOType.setCurrentIndex(m_comboBoxDiskIOType.findData(QVariant::fromValue(session->diskIOType())));
|
m_comboBoxDiskIOType.setCurrentIndex(m_comboBoxDiskIOType.findData(QVariant::fromValue(session->diskIOType())));
|
||||||
addRow(DISK_IO_TYPE, tr("Disk IO type (requires restart)") + u' ' + makeLink(u"https://www.libtorrent.org/single-page-ref.html#default-disk-io-constructor", u"(?)")
|
addRow(DISK_IO_TYPE, tr("Disk IO type (requires restart)") + u' ' + makeLink(u"https://www.libtorrent.org/single-page-ref.html#default-disk-io-constructor", u"(?)")
|
||||||
, &m_comboBoxDiskIOType);
|
, &m_comboBoxDiskIOType);
|
||||||
|
@ -845,6 +857,10 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||||
m_checkBoxMarkOfTheWeb.setChecked(pref->isMarkOfTheWebEnabled());
|
m_checkBoxMarkOfTheWeb.setChecked(pref->isMarkOfTheWebEnabled());
|
||||||
addRow(ENABLE_MARK_OF_THE_WEB, motwLabel, &m_checkBoxMarkOfTheWeb);
|
addRow(ENABLE_MARK_OF_THE_WEB, motwLabel, &m_checkBoxMarkOfTheWeb);
|
||||||
#endif // Q_OS_MACOS || Q_OS_WIN
|
#endif // Q_OS_MACOS || Q_OS_WIN
|
||||||
|
// Ignore SSL errors
|
||||||
|
m_checkBoxIgnoreSSLErrors.setChecked(pref->isIgnoreSSLErrors());
|
||||||
|
m_checkBoxIgnoreSSLErrors.setToolTip(tr("Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)"));
|
||||||
|
addRow(IGNORE_SSL_ERRORS, tr("Ignore SSL errors"), &m_checkBoxIgnoreSSLErrors);
|
||||||
// Python executable path
|
// Python executable path
|
||||||
m_pythonExecutablePath.setPlaceholderText(tr("(Auto detect if empty)"));
|
m_pythonExecutablePath.setPlaceholderText(tr("(Auto detect if empty)"));
|
||||||
m_pythonExecutablePath.setText(pref->getPythonExecutablePath().toString());
|
m_pythonExecutablePath.setText(pref->getPythonExecutablePath().toString());
|
||||||
|
|
|
@ -77,11 +77,12 @@ private:
|
||||||
m_spinBoxSavePathHistoryLength, m_spinBoxPeerTurnover, m_spinBoxPeerTurnoverCutoff, m_spinBoxPeerTurnoverInterval, m_spinBoxRequestQueueSize;
|
m_spinBoxSavePathHistoryLength, m_spinBoxPeerTurnover, m_spinBoxPeerTurnoverCutoff, m_spinBoxPeerTurnoverInterval, m_spinBoxRequestQueueSize;
|
||||||
QCheckBox m_checkBoxOsCache, m_checkBoxRecheckCompleted, m_checkBoxResolveCountries, m_checkBoxResolveHosts,
|
QCheckBox m_checkBoxOsCache, m_checkBoxRecheckCompleted, m_checkBoxResolveCountries, m_checkBoxResolveHosts,
|
||||||
m_checkBoxProgramNotifications, m_checkBoxTorrentAddedNotifications, m_checkBoxReannounceWhenAddressChanged, m_checkBoxTrackerFavicon, m_checkBoxTrackerStatus,
|
m_checkBoxProgramNotifications, m_checkBoxTorrentAddedNotifications, m_checkBoxReannounceWhenAddressChanged, m_checkBoxTrackerFavicon, m_checkBoxTrackerStatus,
|
||||||
m_checkBoxTrackerPortForwarding, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers, m_checkBoxAnnounceAllTiers,
|
m_checkBoxTrackerPortForwarding, m_checkBoxIgnoreSSLErrors, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers,
|
||||||
m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts, m_checkBoxPieceExtentAffinity,
|
m_checkBoxAnnounceAllTiers, m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts,
|
||||||
m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport, m_checkBoxConfirmRemoveTrackerFromAllTorrents, m_checkBoxStartSessionPaused;
|
m_checkBoxPieceExtentAffinity, m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport, m_checkBoxConfirmRemoveTrackerFromAllTorrents,
|
||||||
|
m_checkBoxStartSessionPaused;
|
||||||
QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm,
|
QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm,
|
||||||
m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage;
|
m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage, m_comboBoxTorrentContentRemoveOption;
|
||||||
QLineEdit m_lineEditAppInstanceName, m_pythonExecutablePath, m_lineEditAnnounceIP, m_lineEditDHTBootstrapNodes;
|
QLineEdit m_lineEditAppInstanceName, m_pythonExecutablePath, m_lineEditAnnounceIP, m_lineEditDHTBootstrapNodes;
|
||||||
|
|
||||||
#ifndef QBT_USES_LIBTORRENT2
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "uithememanager.h"
|
#include "uithememanager.h"
|
||||||
|
@ -53,8 +55,8 @@ DeletionConfirmationDialog::DeletionConfirmationDialog(QWidget *parent, const in
|
||||||
m_ui->rememberBtn->setIcon(UIThemeManager::instance()->getIcon(u"object-locked"_s));
|
m_ui->rememberBtn->setIcon(UIThemeManager::instance()->getIcon(u"object-locked"_s));
|
||||||
m_ui->rememberBtn->setIconSize(Utils::Gui::mediumIconSize());
|
m_ui->rememberBtn->setIconSize(Utils::Gui::mediumIconSize());
|
||||||
|
|
||||||
m_ui->checkPermDelete->setChecked(defaultDeleteFiles || Preferences::instance()->deleteTorrentFilesAsDefault());
|
m_ui->checkRemoveContent->setChecked(defaultDeleteFiles || Preferences::instance()->removeTorrentContent());
|
||||||
connect(m_ui->checkPermDelete, &QCheckBox::clicked, this, &DeletionConfirmationDialog::updateRememberButtonState);
|
connect(m_ui->checkRemoveContent, &QCheckBox::clicked, this, &DeletionConfirmationDialog::updateRememberButtonState);
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Remove"));
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Remove"));
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
|
||||||
|
|
||||||
|
@ -67,18 +69,18 @@ DeletionConfirmationDialog::~DeletionConfirmationDialog()
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeletionConfirmationDialog::isDeleteFileSelected() const
|
bool DeletionConfirmationDialog::isRemoveContentSelected() const
|
||||||
{
|
{
|
||||||
return m_ui->checkPermDelete->isChecked();
|
return m_ui->checkRemoveContent->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeletionConfirmationDialog::updateRememberButtonState()
|
void DeletionConfirmationDialog::updateRememberButtonState()
|
||||||
{
|
{
|
||||||
m_ui->rememberBtn->setEnabled(m_ui->checkPermDelete->isChecked() != Preferences::instance()->deleteTorrentFilesAsDefault());
|
m_ui->rememberBtn->setEnabled(m_ui->checkRemoveContent->isChecked() != Preferences::instance()->removeTorrentContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeletionConfirmationDialog::on_rememberBtn_clicked()
|
void DeletionConfirmationDialog::on_rememberBtn_clicked()
|
||||||
{
|
{
|
||||||
Preferences::instance()->setDeleteTorrentFilesAsDefault(m_ui->checkPermDelete->isChecked());
|
Preferences::instance()->setRemoveTorrentContent(m_ui->checkRemoveContent->isChecked());
|
||||||
m_ui->rememberBtn->setEnabled(false);
|
m_ui->rememberBtn->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -37,16 +38,16 @@ namespace Ui
|
||||||
class DeletionConfirmationDialog;
|
class DeletionConfirmationDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeletionConfirmationDialog : public QDialog
|
class DeletionConfirmationDialog final : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY_MOVE(DeletionConfirmationDialog)
|
Q_DISABLE_COPY_MOVE(DeletionConfirmationDialog)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeletionConfirmationDialog(QWidget *parent, int size, const QString &name, bool defaultDeleteFiles);
|
DeletionConfirmationDialog(QWidget *parent, int size, const QString &name, bool defaultDeleteFiles);
|
||||||
~DeletionConfirmationDialog();
|
~DeletionConfirmationDialog() override;
|
||||||
|
|
||||||
bool isDeleteFileSelected() const;
|
bool isRemoveContentSelected() const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateRememberButtonState();
|
void updateRememberButtonState();
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="checkPermDelete">
|
<widget class="QCheckBox" name="checkRemoveContent">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Also permanently delete the files</string>
|
<string>Also remove the content files</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
48
src/gui/filterpatternformat.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
|
inline namespace FilterPatternFormatNS
|
||||||
|
{
|
||||||
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class FilterPatternFormat
|
||||||
|
{
|
||||||
|
PlainText,
|
||||||
|
Wildcards,
|
||||||
|
Regex
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM_NS(FilterPatternFormat)
|
||||||
|
}
|
82
src/gui/filterpatternformatmenu.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filterpatternformatmenu.h"
|
||||||
|
|
||||||
|
#include <QActionGroup>
|
||||||
|
|
||||||
|
FilterPatternFormatMenu::FilterPatternFormatMenu(const FilterPatternFormat format, QWidget *parent)
|
||||||
|
: QMenu(parent)
|
||||||
|
{
|
||||||
|
setTitle(tr("Pattern Format"));
|
||||||
|
|
||||||
|
auto *patternFormatGroup = new QActionGroup(this);
|
||||||
|
patternFormatGroup->setExclusive(true);
|
||||||
|
|
||||||
|
QAction *plainTextAction = addAction(tr("Plain text"));
|
||||||
|
plainTextAction->setCheckable(true);
|
||||||
|
patternFormatGroup->addAction(plainTextAction);
|
||||||
|
|
||||||
|
QAction *wildcardsAction = addAction(tr("Wildcards"));
|
||||||
|
wildcardsAction->setCheckable(true);
|
||||||
|
patternFormatGroup->addAction(wildcardsAction);
|
||||||
|
|
||||||
|
QAction *regexAction = addAction(tr("Regular expression"));
|
||||||
|
regexAction->setCheckable(true);
|
||||||
|
patternFormatGroup->addAction(regexAction);
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case FilterPatternFormat::Wildcards:
|
||||||
|
default:
|
||||||
|
wildcardsAction->setChecked(true);
|
||||||
|
break;
|
||||||
|
case FilterPatternFormat::PlainText:
|
||||||
|
plainTextAction->setChecked(true);
|
||||||
|
break;
|
||||||
|
case FilterPatternFormat::Regex:
|
||||||
|
regexAction->setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(plainTextAction, &QAction::toggled, this, [this](const bool checked)
|
||||||
|
{
|
||||||
|
if (checked)
|
||||||
|
emit patternFormatChanged(FilterPatternFormat::PlainText);
|
||||||
|
});
|
||||||
|
connect(wildcardsAction, &QAction::toggled, this, [this](const bool checked)
|
||||||
|
{
|
||||||
|
if (checked)
|
||||||
|
emit patternFormatChanged(FilterPatternFormat::Wildcards);
|
||||||
|
});
|
||||||
|
connect(regexAction, &QAction::toggled, this, [this](const bool checked)
|
||||||
|
{
|
||||||
|
if (checked)
|
||||||
|
emit patternFormatChanged(FilterPatternFormat::Regex);
|
||||||
|
});
|
||||||
|
}
|
45
src/gui/filterpatternformatmenu.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "filterpatternformat.h"
|
||||||
|
|
||||||
|
class FilterPatternFormatMenu final : public QMenu
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(FilterPatternFormatMenu)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FilterPatternFormatMenu(FilterPatternFormat format, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void patternFormatChanged(FilterPatternFormat format);
|
||||||
|
};
|
|
@ -175,13 +175,16 @@ void GUIAddTorrentManager::onMetadataDownloaded(const BitTorrent::TorrentInfo &m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUIAddTorrentManager::processTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams ¶ms)
|
bool GUIAddTorrentManager::processTorrent(const QString &source
|
||||||
|
, const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams ¶ms)
|
||||||
{
|
{
|
||||||
const bool hasMetadata = torrentDescr.info().has_value();
|
const bool hasMetadata = torrentDescr.info().has_value();
|
||||||
const BitTorrent::InfoHash infoHash = torrentDescr.infoHash();
|
const BitTorrent::InfoHash infoHash = torrentDescr.infoHash();
|
||||||
|
|
||||||
// Prevent showing the dialog if download is already present
|
// Prevent showing the dialog if download is already present
|
||||||
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
|
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
|
||||||
|
{
|
||||||
|
if (Preferences::instance()->confirmMergeTrackers())
|
||||||
{
|
{
|
||||||
if (hasMetadata)
|
if (hasMetadata)
|
||||||
{
|
{
|
||||||
|
@ -189,27 +192,32 @@ bool GUIAddTorrentManager::processTorrent(const QString &source, const BitTorren
|
||||||
torrent->setMetadata(*torrentDescr.info());
|
torrent->setMetadata(*torrentDescr.info());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate()))
|
const bool isPrivate = torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
|
||||||
|
const QString dialogCaption = tr("Torrent is already present");
|
||||||
|
if (isPrivate)
|
||||||
{
|
{
|
||||||
handleDuplicateTorrent(source, torrent, tr("Trackers cannot be merged because it is a private torrent"));
|
// We cannot merge trackers for private torrent but we still notify user
|
||||||
|
// about duplicate torrent if confirmation dialog is enabled.
|
||||||
|
RaisedMessageBox::warning(app()->mainWindow(), dialogCaption
|
||||||
|
, tr("Trackers cannot be merged because it is a private torrent."));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool mergeTrackers = btSession()->isMergeTrackersEnabled();
|
const bool mergeTrackers = btSession()->isMergeTrackersEnabled();
|
||||||
if (Preferences::instance()->confirmMergeTrackers())
|
const QMessageBox::StandardButton btn = RaisedMessageBox::question(app()->mainWindow(), dialogCaption
|
||||||
{
|
|
||||||
const QMessageBox::StandardButton btn = RaisedMessageBox::question(app()->mainWindow(), tr("Torrent is already present")
|
|
||||||
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
|
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
|
||||||
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
|
, (QMessageBox::Yes | QMessageBox::No), (mergeTrackers ? QMessageBox::Yes : QMessageBox::No));
|
||||||
mergeTrackers = (btn == QMessageBox::Yes);
|
if (btn == QMessageBox::Yes)
|
||||||
}
|
|
||||||
|
|
||||||
if (mergeTrackers)
|
|
||||||
{
|
{
|
||||||
torrent->addTrackers(torrentDescr.trackers());
|
torrent->addTrackers(torrentDescr.trackers());
|
||||||
torrent->addUrlSeeds(torrentDescr.urlSeeds());
|
torrent->addUrlSeeds(torrentDescr.urlSeeds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handleDuplicateTorrent(source, torrentDescr, torrent);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "optionsdialog.h"
|
#include "optionsdialog.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -44,6 +45,10 @@
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <QStyleFactory>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/sharelimitaction.h"
|
#include "base/bittorrent/sharelimitaction.h"
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
|
@ -56,6 +61,7 @@
|
||||||
#include "base/rss/rss_session.h"
|
#include "base/rss/rss_session.h"
|
||||||
#include "base/torrentfileguard.h"
|
#include "base/torrentfileguard.h"
|
||||||
#include "base/torrentfileswatcher.h"
|
#include "base/torrentfileswatcher.h"
|
||||||
|
#include "base/utils/compare.h"
|
||||||
#include "base/utils/io.h"
|
#include "base/utils/io.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/net.h"
|
#include "base/utils/net.h"
|
||||||
|
@ -236,6 +242,8 @@ void OptionsDialog::loadBehaviorTabOptions()
|
||||||
initializeLanguageCombo();
|
initializeLanguageCombo();
|
||||||
setLocale(pref->getLocale());
|
setLocale(pref->getLocale());
|
||||||
|
|
||||||
|
initializeStyleCombo();
|
||||||
|
|
||||||
m_ui->checkUseCustomTheme->setChecked(Preferences::instance()->useCustomUITheme());
|
m_ui->checkUseCustomTheme->setChecked(Preferences::instance()->useCustomUITheme());
|
||||||
m_ui->customThemeFilePath->setSelectedPath(Preferences::instance()->customUIThemePath());
|
m_ui->customThemeFilePath->setSelectedPath(Preferences::instance()->customUIThemePath());
|
||||||
m_ui->customThemeFilePath->setMode(FileSystemPathEdit::Mode::FileOpen);
|
m_ui->customThemeFilePath->setMode(FileSystemPathEdit::Mode::FileOpen);
|
||||||
|
@ -345,7 +353,11 @@ void OptionsDialog::loadBehaviorTabOptions()
|
||||||
|
|
||||||
m_ui->checkBoxPerformanceWarning->setChecked(session->isPerformanceWarningEnabled());
|
m_ui->checkBoxPerformanceWarning->setChecked(session->isPerformanceWarningEnabled());
|
||||||
|
|
||||||
connect(m_ui->comboI18n, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
connect(m_ui->comboLanguage, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
connect(m_ui->comboStyle, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
||||||
connect(m_ui->checkUseSystemIcon, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkUseSystemIcon, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||||
|
@ -443,6 +455,13 @@ void OptionsDialog::saveBehaviorTabOptions() const
|
||||||
}
|
}
|
||||||
pref->setLocale(locale);
|
pref->setLocale(locale);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (const QVariant systemStyle = m_ui->comboStyle->currentData(); systemStyle.isValid())
|
||||||
|
pref->setStyle(systemStyle.toString());
|
||||||
|
else
|
||||||
|
pref->setStyle(m_ui->comboStyle->currentText());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
||||||
pref->useSystemIcons(m_ui->checkUseSystemIcon->isChecked());
|
pref->useSystemIcons(m_ui->checkUseSystemIcon->isChecked());
|
||||||
#endif
|
#endif
|
||||||
|
@ -1387,7 +1406,7 @@ void OptionsDialog::initializeLanguageCombo()
|
||||||
for (const QString &langFile : langFiles)
|
for (const QString &langFile : langFiles)
|
||||||
{
|
{
|
||||||
const QString langCode = QStringView(langFile).sliced(12).chopped(3).toString(); // remove "qbittorrent_" and ".qm"
|
const QString langCode = QStringView(langFile).sliced(12).chopped(3).toString(); // remove "qbittorrent_" and ".qm"
|
||||||
m_ui->comboI18n->addItem(Utils::Misc::languageToLocalizedString(langCode), langCode);
|
m_ui->comboLanguage->addItem(Utils::Misc::languageToLocalizedString(langCode), langCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1672,6 +1691,33 @@ bool OptionsDialog::isSplashScreenDisabled() const
|
||||||
return !m_ui->checkShowSplash->isChecked();
|
return !m_ui->checkShowSplash->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OptionsDialog::initializeStyleCombo()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
m_ui->labelStyleHint->setText(tr("%1 is recommended for best compatibility with Windows dark mode"
|
||||||
|
, "Fusion is recommended for best compatibility with Windows dark mode").arg(u"Fusion"_s));
|
||||||
|
m_ui->comboStyle->addItem(tr("System", "System default Qt style"), u"system"_s);
|
||||||
|
m_ui->comboStyle->setItemData(0, tr("Let Qt decide the style for this system"), Qt::ToolTipRole);
|
||||||
|
m_ui->comboStyle->insertSeparator(1);
|
||||||
|
|
||||||
|
QStringList styleNames = QStyleFactory::keys();
|
||||||
|
std::sort(styleNames.begin(), styleNames.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||||
|
m_ui->comboStyle->addItems(styleNames);
|
||||||
|
const QString prefStyleName = Preferences::instance()->getStyle();
|
||||||
|
const QString selectedStyleName = prefStyleName.isEmpty() ? QApplication::style()->name() : prefStyleName;
|
||||||
|
|
||||||
|
if (selectedStyleName.compare(u"system"_s, Qt::CaseInsensitive) != 0)
|
||||||
|
m_ui->comboStyle->setCurrentText(selectedStyleName);
|
||||||
|
#else
|
||||||
|
m_ui->labelStyle->hide();
|
||||||
|
m_ui->comboStyle->hide();
|
||||||
|
m_ui->labelStyleHint->hide();
|
||||||
|
m_ui->UISettingsBoxLayout->removeWidget(m_ui->labelStyle);
|
||||||
|
m_ui->UISettingsBoxLayout->removeWidget(m_ui->comboStyle);
|
||||||
|
m_ui->UISettingsBoxLayout->removeWidget(m_ui->labelStyleHint);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
bool OptionsDialog::WinStartup() const
|
bool OptionsDialog::WinStartup() const
|
||||||
{
|
{
|
||||||
|
@ -1721,7 +1767,7 @@ QString OptionsDialog::getProxyPassword() const
|
||||||
// Locale Settings
|
// Locale Settings
|
||||||
QString OptionsDialog::getLocale() const
|
QString OptionsDialog::getLocale() const
|
||||||
{
|
{
|
||||||
return m_ui->comboI18n->itemData(m_ui->comboI18n->currentIndex(), Qt::UserRole).toString();
|
return m_ui->comboLanguage->itemData(m_ui->comboLanguage->currentIndex(), Qt::UserRole).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::setLocale(const QString &localeStr)
|
void OptionsDialog::setLocale(const QString &localeStr)
|
||||||
|
@ -1746,7 +1792,7 @@ void OptionsDialog::setLocale(const QString &localeStr)
|
||||||
name = locale.name();
|
name = locale.name();
|
||||||
}
|
}
|
||||||
// Attempt to find exact match
|
// Attempt to find exact match
|
||||||
int index = m_ui->comboI18n->findData(name, Qt::UserRole);
|
int index = m_ui->comboLanguage->findData(name, Qt::UserRole);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
//Attempt to find a language match without a country
|
//Attempt to find a language match without a country
|
||||||
|
@ -1754,16 +1800,16 @@ void OptionsDialog::setLocale(const QString &localeStr)
|
||||||
if (pos > -1)
|
if (pos > -1)
|
||||||
{
|
{
|
||||||
QString lang = name.left(pos);
|
QString lang = name.left(pos);
|
||||||
index = m_ui->comboI18n->findData(lang, Qt::UserRole);
|
index = m_ui->comboLanguage->findData(lang, Qt::UserRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
// Unrecognized, use US English
|
// Unrecognized, use US English
|
||||||
index = m_ui->comboI18n->findData(u"en"_s, Qt::UserRole);
|
index = m_ui->comboLanguage->findData(u"en"_s, Qt::UserRole);
|
||||||
Q_ASSERT(index >= 0);
|
Q_ASSERT(index >= 0);
|
||||||
}
|
}
|
||||||
m_ui->comboI18n->setCurrentIndex(index);
|
m_ui->comboLanguage->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path OptionsDialog::getTorrentExportDir() const
|
Path OptionsDialog::getTorrentExportDir() const
|
||||||
|
@ -1869,7 +1915,7 @@ Path OptionsDialog::getFilter() const
|
||||||
void OptionsDialog::webUIHttpsCertChanged(const Path &path)
|
void OptionsDialog::webUIHttpsCertChanged(const Path &path)
|
||||||
{
|
{
|
||||||
const auto readResult = Utils::IO::readFile(path, Utils::Net::MAX_SSL_FILE_SIZE);
|
const auto readResult = Utils::IO::readFile(path, Utils::Net::MAX_SSL_FILE_SIZE);
|
||||||
const bool isCertValid = !Utils::SSLKey::load(readResult.value_or(QByteArray())).isNull();
|
const bool isCertValid = Utils::Net::isSSLCertificatesValid(readResult.value_or(QByteArray()));
|
||||||
|
|
||||||
m_ui->textWebUIHttpsCert->setSelectedPath(path);
|
m_ui->textWebUIHttpsCert->setSelectedPath(path);
|
||||||
m_ui->lblSslCertStatus->setPixmap(UIThemeManager::instance()->getScaledPixmap(
|
m_ui->lblSslCertStatus->setPixmap(UIThemeManager::instance()->getScaledPixmap(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -143,6 +143,7 @@ private:
|
||||||
|
|
||||||
// General options
|
// General options
|
||||||
void initializeLanguageCombo();
|
void initializeLanguageCombo();
|
||||||
|
void initializeStyleCombo();
|
||||||
QString getLocale() const;
|
QString getLocale() const;
|
||||||
bool isSplashScreenDisabled() const;
|
bool isSplashScreenDisabled() const;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
|
@ -132,9 +132,9 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Interface</string>
|
<string>Interface</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_81">
|
<layout class="QGridLayout" name="UISettingsBoxLayout">
|
||||||
<item row="0" column="0" colspan="3">
|
<item row="0" column="0" colspan="3">
|
||||||
<widget class="QLabel" name="label_15">
|
<widget class="QLabel" name="labelRestartRequired">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<italic>true</italic>
|
<italic>true</italic>
|
||||||
|
@ -146,17 +146,17 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<widget class="QLabel" name="labelLanguage">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Language:</string>
|
<string>Language:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="comboI18n"/>
|
<widget class="QComboBox" name="comboLanguage"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<spacer name="horizontalSpacer_111">
|
<spacer name="spacerLanguage">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -168,7 +168,26 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="3">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="labelStyle">
|
||||||
|
<property name="text">
|
||||||
|
<string>Style:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="comboStyle"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="labelStyleHint">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="3">
|
||||||
<widget class="QGroupBox" name="checkUseCustomTheme">
|
<widget class="QGroupBox" name="checkUseCustomTheme">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Use custom UI Theme</string>
|
<string>Use custom UI Theme</string>
|
||||||
|
@ -190,14 +209,14 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="2">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="checkUseSystemIcon">
|
<widget class="QCheckBox" name="checkUseSystemIcon">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use icons from system theme</string>
|
<string>Use icons from system theme</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0" colspan="2">
|
<item row="5" column="0" colspan="2">
|
||||||
<widget class="QPushButton" name="buttonCustomizeUITheme">
|
<widget class="QPushButton" name="buttonCustomizeUITheme">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Customize UI Theme...</string>
|
<string>Customize UI Theme...</string>
|
||||||
|
@ -3881,7 +3900,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>tabOption</tabstop>
|
<tabstop>tabOption</tabstop>
|
||||||
<tabstop>comboI18n</tabstop>
|
<tabstop>comboLanguage</tabstop>
|
||||||
<tabstop>checkUseCustomTheme</tabstop>
|
<tabstop>checkUseCustomTheme</tabstop>
|
||||||
<tabstop>customThemeFilePath</tabstop>
|
<tabstop>customThemeFilePath</tabstop>
|
||||||
<tabstop>checkAddStopped</tabstop>
|
<tabstop>checkAddStopped</tabstop>
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
#include "programupdater.h"
|
#include "programupdater.h"
|
||||||
|
|
||||||
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
|
#include <QtCore/qconfig.h>
|
||||||
#include <QtSystemDetection>
|
#include <QtSystemDetection>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
@ -61,6 +64,20 @@ namespace
|
||||||
}
|
}
|
||||||
return (newVersion > currentVersion);
|
return (newVersion > currentVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString buildVariant()
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_MACOS)
|
||||||
|
const auto BASE_OS = u"Mac OS X"_s;
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
const auto BASE_OS = u"Windows x64"_s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if constexpr ((QT_VERSION_MAJOR == 6) && (LIBTORRENT_VERSION_MAJOR == 1))
|
||||||
|
return BASE_OS;
|
||||||
|
|
||||||
|
return u"%1 (qt%2 lt%3%4)"_s.arg(BASE_OS, QString::number(QT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MINOR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramUpdater::checkForUpdates() const
|
void ProgramUpdater::checkForUpdates() const
|
||||||
|
@ -97,12 +114,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
|
||||||
: QString {};
|
: QString {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
const QString variant = buildVariant();
|
||||||
const QString OS_TYPE = u"Mac OS X"_s;
|
|
||||||
#elif defined(Q_OS_WIN)
|
|
||||||
const QString OS_TYPE = u"Windows x64"_s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool inItem = false;
|
bool inItem = false;
|
||||||
QString version;
|
QString version;
|
||||||
QString updateLink;
|
QString updateLink;
|
||||||
|
@ -128,7 +140,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
|
||||||
{
|
{
|
||||||
if (inItem && (xml.name() == u"item"))
|
if (inItem && (xml.name() == u"item"))
|
||||||
{
|
{
|
||||||
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0)
|
if (type.compare(variant, Qt::CaseInsensitive) == 0)
|
||||||
{
|
{
|
||||||
qDebug("The last update available is %s", qUtf8Printable(version));
|
qDebug("The last update available is %s", qUtf8Printable(version));
|
||||||
if (!version.isEmpty())
|
if (!version.isEmpty())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -46,9 +47,9 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent)
|
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent)
|
||||||
: base {parent}
|
: base(parent)
|
||||||
, m_dlPieceColor {dlPieceColor(pieceColor())}
|
|
||||||
{
|
{
|
||||||
|
updateColorsImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin, int reqSize)
|
QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin, int reqSize)
|
||||||
|
@ -128,25 +129,24 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DownloadedPiecesBar::updateImage(QImage &image)
|
QImage DownloadedPiecesBar::renderImage()
|
||||||
{
|
{
|
||||||
// qDebug() << "updateImage";
|
// qDebug() << "updateImage";
|
||||||
QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
|
QImage image {width() - 2 * borderWidth, 1, QImage::Format_RGB888};
|
||||||
if (image2.isNull())
|
if (image.isNull())
|
||||||
{
|
{
|
||||||
qDebug() << "QImage image2() allocation failed, width():" << width();
|
qDebug() << "QImage allocation failed, width():" << width();
|
||||||
return false;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pieces.isEmpty())
|
if (m_pieces.isEmpty())
|
||||||
{
|
{
|
||||||
image2.fill(backgroundColor());
|
image.fill(backgroundColor());
|
||||||
image = image2;
|
return image;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<float> scaledPieces = bitfieldToFloatVector(m_pieces, image2.width());
|
QVector<float> scaledPieces = bitfieldToFloatVector(m_pieces, image.width());
|
||||||
QVector<float> scaledPiecesDl = bitfieldToFloatVector(m_downloadedPieces, image2.width());
|
QVector<float> scaledPiecesDl = bitfieldToFloatVector(m_downloadedPieces, image.width());
|
||||||
|
|
||||||
// filling image
|
// filling image
|
||||||
for (int x = 0; x < scaledPieces.size(); ++x)
|
for (int x = 0; x < scaledPieces.size(); ++x)
|
||||||
|
@ -161,15 +161,15 @@ bool DownloadedPiecesBar::updateImage(QImage &image)
|
||||||
QRgb mixedColor = mixTwoColors(pieceColor().rgb(), m_dlPieceColor.rgb(), ratio);
|
QRgb mixedColor = mixTwoColors(pieceColor().rgb(), m_dlPieceColor.rgb(), ratio);
|
||||||
mixedColor = mixTwoColors(backgroundColor().rgb(), mixedColor, fillRatio);
|
mixedColor = mixTwoColors(backgroundColor().rgb(), mixedColor, fillRatio);
|
||||||
|
|
||||||
image2.setPixel(x, 0, mixedColor);
|
image.setPixel(x, 0, mixedColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
|
image.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image = image2;
|
|
||||||
return true;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &downloadedPieces)
|
void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &downloadedPieces)
|
||||||
|
@ -177,7 +177,7 @@ void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &
|
||||||
m_pieces = pieces;
|
m_pieces = pieces;
|
||||||
m_downloadedPieces = downloadedPieces;
|
m_downloadedPieces = downloadedPieces;
|
||||||
|
|
||||||
requestImageUpdate();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadedPiecesBar::clear()
|
void DownloadedPiecesBar::clear()
|
||||||
|
@ -198,3 +198,14 @@ QString DownloadedPiecesBar::simpleToolTipText() const
|
||||||
+ u"</table>";
|
+ u"</table>";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DownloadedPiecesBar::updateColors()
|
||||||
|
{
|
||||||
|
PiecesBar::updateColors();
|
||||||
|
updateColorsImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadedPiecesBar::updateColorsImpl()
|
||||||
|
{
|
||||||
|
m_dlPieceColor = dlPieceColor(pieceColor());
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -52,11 +53,13 @@ public:
|
||||||
private:
|
private:
|
||||||
// scale bitfield vector to float vector
|
// scale bitfield vector to float vector
|
||||||
QVector<float> bitfieldToFloatVector(const QBitArray &vecin, int reqSize);
|
QVector<float> bitfieldToFloatVector(const QBitArray &vecin, int reqSize);
|
||||||
bool updateImage(QImage &image) override;
|
QImage renderImage() override;
|
||||||
QString simpleToolTipText() const override;
|
QString simpleToolTipText() const override;
|
||||||
|
void updateColors() override;
|
||||||
|
void updateColorsImpl();
|
||||||
|
|
||||||
// incomplete piece color
|
// incomplete piece color
|
||||||
const QColor m_dlPieceColor;
|
QColor m_dlPieceColor;
|
||||||
// last used bitfields, uses to better resize redraw
|
// last used bitfields, uses to better resize redraw
|
||||||
// TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster
|
// TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster
|
||||||
QBitArray m_pieces;
|
QBitArray m_pieces;
|
||||||
|
|
|
@ -411,7 +411,7 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove I2P peers since they will be completely reloaded.
|
// Remove I2P peers since they will be completely reloaded.
|
||||||
for (QStandardItem *item : asConst(m_I2PPeerItems))
|
for (const QStandardItem *item : asConst(m_I2PPeerItems))
|
||||||
m_listModel->removeRow(item->row());
|
m_listModel->removeRow(item->row());
|
||||||
m_I2PPeerItems.clear();
|
m_I2PPeerItems.clear();
|
||||||
|
|
||||||
|
@ -466,10 +466,14 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
|
||||||
{
|
{
|
||||||
QStandardItem *item = m_peerItems.take(peerEndpoint);
|
QStandardItem *item = m_peerItems.take(peerEndpoint);
|
||||||
|
|
||||||
QSet<QStandardItem *> &items = m_itemsByIP[peerEndpoint.address.ip];
|
const auto items = m_itemsByIP.find(peerEndpoint.address.ip);
|
||||||
items.remove(item);
|
Q_ASSERT(items != m_itemsByIP.end());
|
||||||
if (items.isEmpty())
|
if (items == m_itemsByIP.end()) [[unlikely]]
|
||||||
m_itemsByIP.remove(peerEndpoint.address.ip);
|
continue;
|
||||||
|
|
||||||
|
items->remove(item);
|
||||||
|
if (items->isEmpty())
|
||||||
|
m_itemsByIP.erase(items);
|
||||||
|
|
||||||
m_listModel->removeRow(item->row());
|
m_listModel->removeRow(item->row());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -126,39 +127,38 @@ QVector<float> PieceAvailabilityBar::intToFloatVector(const QVector<int> &vecin,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PieceAvailabilityBar::updateImage(QImage &image)
|
QImage PieceAvailabilityBar::renderImage()
|
||||||
{
|
{
|
||||||
QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
|
QImage image {width() - 2 * borderWidth, 1, QImage::Format_RGB888};
|
||||||
if (image2.isNull())
|
if (image.isNull())
|
||||||
{
|
{
|
||||||
qDebug() << "QImage image2() allocation failed, width():" << width();
|
qDebug() << "QImage allocation failed, width():" << width();
|
||||||
return false;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pieces.empty())
|
if (m_pieces.empty())
|
||||||
{
|
{
|
||||||
image2.fill(backgroundColor());
|
image.fill(backgroundColor());
|
||||||
image = image2;
|
return image;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<float> scaledPieces = intToFloatVector(m_pieces, image2.width());
|
QVector<float> scaledPieces = intToFloatVector(m_pieces, image.width());
|
||||||
|
|
||||||
// filling image
|
// filling image
|
||||||
for (int x = 0; x < scaledPieces.size(); ++x)
|
for (int x = 0; x < scaledPieces.size(); ++x)
|
||||||
{
|
{
|
||||||
float piecesToValue = scaledPieces.at(x);
|
float piecesToValue = scaledPieces.at(x);
|
||||||
image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
|
image.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
|
||||||
}
|
}
|
||||||
image = image2;
|
|
||||||
return true;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PieceAvailabilityBar::setAvailability(const QVector<int> &avail)
|
void PieceAvailabilityBar::setAvailability(const QVector<int> &avail)
|
||||||
{
|
{
|
||||||
m_pieces = avail;
|
m_pieces = avail;
|
||||||
|
|
||||||
requestImageUpdate();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PieceAvailabilityBar::clear()
|
void PieceAvailabilityBar::clear()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -46,7 +47,7 @@ public:
|
||||||
void clear() override;
|
void clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool updateImage(QImage &image) override;
|
QImage renderImage() override;
|
||||||
QString simpleToolTipText() const override;
|
QString simpleToolTipText() const override;
|
||||||
|
|
||||||
// last used int vector, uses to better resize redraw
|
// last used int vector, uses to better resize redraw
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2016 Eugene Shalygin
|
* Copyright (C) 2016 Eugene Shalygin
|
||||||
* Copyright (C) 2006 Christophe Dumez
|
* Copyright (C) 2006 Christophe Dumez
|
||||||
*
|
*
|
||||||
|
@ -114,10 +115,10 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
PiecesBar::PiecesBar(QWidget *parent)
|
PiecesBar::PiecesBar(QWidget *parent)
|
||||||
: QWidget {parent}
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
updatePieceColors();
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
updateColorsImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PiecesBar::setTorrent(const BitTorrent::Torrent *torrent)
|
void PiecesBar::setTorrent(const BitTorrent::Torrent *torrent)
|
||||||
|
@ -135,12 +136,19 @@ void PiecesBar::clear()
|
||||||
|
|
||||||
bool PiecesBar::event(QEvent *e)
|
bool PiecesBar::event(QEvent *e)
|
||||||
{
|
{
|
||||||
if (e->type() == QEvent::ToolTip)
|
const QEvent::Type eventType = e->type();
|
||||||
|
if (eventType == QEvent::ToolTip)
|
||||||
{
|
{
|
||||||
showToolTip(static_cast<QHelpEvent *>(e));
|
showToolTip(static_cast<QHelpEvent *>(e));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eventType == QEvent::PaletteChange)
|
||||||
|
{
|
||||||
|
updateColors();
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
return base::event(e);
|
return base::event(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +162,7 @@ void PiecesBar::leaveEvent(QEvent *e)
|
||||||
{
|
{
|
||||||
m_hovered = false;
|
m_hovered = false;
|
||||||
m_highlightedRegion = {};
|
m_highlightedRegion = {};
|
||||||
requestImageUpdate();
|
redraw();
|
||||||
base::leaveEvent(e);
|
base::leaveEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,16 +186,17 @@ void PiecesBar::paintEvent(QPaintEvent *)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_image.width() != imageRect.width())
|
if (m_image.width() != imageRect.width())
|
||||||
updateImage(m_image);
|
{
|
||||||
|
if (const QImage image = renderImage(); !image.isNull())
|
||||||
|
m_image = image;
|
||||||
|
}
|
||||||
painter.drawImage(imageRect, m_image);
|
painter.drawImage(imageRect, m_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_highlightedRegion.isNull())
|
if (!m_highlightedRegion.isNull())
|
||||||
{
|
{
|
||||||
QColor highlightColor {this->palette().color(QPalette::Active, QPalette::Highlight)};
|
|
||||||
highlightColor.setAlphaF(0.35f);
|
|
||||||
QRect targetHighlightRect {m_highlightedRegion.adjusted(borderWidth, borderWidth, borderWidth, height() - 2 * borderWidth)};
|
QRect targetHighlightRect {m_highlightedRegion.adjusted(borderWidth, borderWidth, borderWidth, height() - 2 * borderWidth)};
|
||||||
painter.fillRect(targetHighlightRect, highlightColor);
|
painter.fillRect(targetHighlightRect, highlightedPieceColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainterPath border;
|
QPainterPath border;
|
||||||
|
@ -196,30 +205,40 @@ void PiecesBar::paintEvent(QPaintEvent *)
|
||||||
painter.drawPath(border);
|
painter.drawPath(border);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PiecesBar::requestImageUpdate()
|
void PiecesBar::redraw()
|
||||||
{
|
{
|
||||||
if (updateImage(m_image))
|
if (const QImage image = renderImage(); !image.isNull())
|
||||||
|
{
|
||||||
|
m_image = image;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QColor PiecesBar::backgroundColor() const
|
QColor PiecesBar::backgroundColor() const
|
||||||
{
|
{
|
||||||
return palette().color(QPalette::Base);
|
return palette().color(QPalette::Active, QPalette::Base);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor PiecesBar::borderColor() const
|
QColor PiecesBar::borderColor() const
|
||||||
{
|
{
|
||||||
return palette().color(QPalette::Dark);
|
return palette().color(QPalette::Active, QPalette::Dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor PiecesBar::pieceColor() const
|
QColor PiecesBar::pieceColor() const
|
||||||
{
|
{
|
||||||
return palette().color(QPalette::Highlight);
|
return palette().color(QPalette::Active, QPalette::Highlight);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor PiecesBar::highlightedPieceColor() const
|
||||||
|
{
|
||||||
|
QColor col = palette().color(QPalette::Highlight).darker();
|
||||||
|
col.setAlphaF(0.35);
|
||||||
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor PiecesBar::colorBoxBorderColor() const
|
QColor PiecesBar::colorBoxBorderColor() const
|
||||||
{
|
{
|
||||||
return palette().color(QPalette::ToolTipText);
|
return palette().color(QPalette::Active, QPalette::ToolTipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<QRgb> &PiecesBar::pieceColors() const
|
const QVector<QRgb> &PiecesBar::pieceColors() const
|
||||||
|
@ -325,12 +344,17 @@ void PiecesBar::highlightFile(int imagePos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PiecesBar::updatePieceColors()
|
void PiecesBar::updateColors()
|
||||||
|
{
|
||||||
|
updateColorsImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PiecesBar::updateColorsImpl()
|
||||||
{
|
{
|
||||||
m_pieceColors = QVector<QRgb>(256);
|
m_pieceColors = QVector<QRgb>(256);
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
{
|
{
|
||||||
float ratio = (i / 255.0);
|
const float ratio = (i / 255.0);
|
||||||
m_pieceColors[i] = mixTwoColors(backgroundColor().rgb(), pieceColor().rgb(), ratio);
|
m_pieceColors[i] = mixTwoColors(backgroundColor().rgb(), pieceColor().rgb(), ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2016 Eugene Shalygin
|
* Copyright (C) 2016 Eugene Shalygin
|
||||||
* Copyright (C) 2006 Christophe Dumez
|
* Copyright (C) 2006 Christophe Dumez
|
||||||
*
|
*
|
||||||
|
@ -54,22 +55,22 @@ public:
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
// QObject interface
|
|
||||||
bool event(QEvent *e) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// QWidget interface
|
bool event(QEvent *e) override;
|
||||||
void enterEvent(QEnterEvent *e) override;
|
void enterEvent(QEnterEvent *e) override;
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void requestImageUpdate();
|
|
||||||
|
virtual void updateColors();
|
||||||
|
void redraw();
|
||||||
|
|
||||||
QColor backgroundColor() const;
|
QColor backgroundColor() const;
|
||||||
QColor borderColor() const;
|
QColor borderColor() const;
|
||||||
QColor pieceColor() const;
|
QColor pieceColor() const;
|
||||||
|
QColor highlightedPieceColor() const;
|
||||||
QColor colorBoxBorderColor() const;
|
QColor colorBoxBorderColor() const;
|
||||||
|
|
||||||
const QVector<QRgb> &pieceColors() const;
|
const QVector<QRgb> &pieceColors() const;
|
||||||
|
|
||||||
// mix two colors by light model, ratio <0, 1>
|
// mix two colors by light model, ratio <0, 1>
|
||||||
|
@ -82,11 +83,9 @@ private:
|
||||||
void highlightFile(int imagePos);
|
void highlightFile(int imagePos);
|
||||||
|
|
||||||
virtual QString simpleToolTipText() const = 0;
|
virtual QString simpleToolTipText() const = 0;
|
||||||
|
virtual QImage renderImage() = 0;
|
||||||
|
|
||||||
// draw new image to replace the actual image
|
void updateColorsImpl();
|
||||||
// returns true if image was successfully updated
|
|
||||||
virtual bool updateImage(QImage &image) = 0;
|
|
||||||
void updatePieceColors();
|
|
||||||
|
|
||||||
const BitTorrent::Torrent *m_torrent = nullptr;
|
const BitTorrent::Torrent *m_torrent = nullptr;
|
||||||
QImage m_image;
|
QImage m_image;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -52,6 +52,7 @@
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
#include "gui/autoexpandabledialog.h"
|
#include "gui/autoexpandabledialog.h"
|
||||||
|
#include "gui/filterpatternformatmenu.h"
|
||||||
#include "gui/lineedit.h"
|
#include "gui/lineedit.h"
|
||||||
#include "gui/trackerlist/trackerlistwidget.h"
|
#include "gui/trackerlist/trackerlistwidget.h"
|
||||||
#include "gui/uithememanager.h"
|
#include "gui/uithememanager.h"
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
PropertiesWidget::PropertiesWidget(QWidget *parent)
|
PropertiesWidget::PropertiesWidget(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_ui {new Ui::PropertiesWidget}
|
, m_ui {new Ui::PropertiesWidget}
|
||||||
|
, m_storeFilterPatternFormat {u"GUI/PropertiesWidget/FilterPatternFormat"_s}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
#ifndef Q_OS_MACOS
|
#ifndef Q_OS_MACOS
|
||||||
|
@ -78,7 +80,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent)
|
||||||
m_contentFilterLine = new LineEdit(this);
|
m_contentFilterLine = new LineEdit(this);
|
||||||
m_contentFilterLine->setPlaceholderText(tr("Filter files..."));
|
m_contentFilterLine->setPlaceholderText(tr("Filter files..."));
|
||||||
m_contentFilterLine->setFixedWidth(300);
|
m_contentFilterLine->setFixedWidth(300);
|
||||||
connect(m_contentFilterLine, &LineEdit::textChanged, m_ui->filesList, &TorrentContentWidget::setFilterPattern);
|
m_contentFilterLine->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_contentFilterLine, &QWidget::customContextMenuRequested, this, &PropertiesWidget::showContentFilterContextMenu);
|
||||||
|
connect(m_contentFilterLine, &LineEdit::textChanged, this, &PropertiesWidget::setContentFilterPattern);
|
||||||
m_ui->contentFilterLayout->insertWidget(3, m_contentFilterLine);
|
m_ui->contentFilterLayout->insertWidget(3, m_contentFilterLine);
|
||||||
|
|
||||||
m_ui->filesList->setDoubleClickAction(TorrentContentWidget::DoubleClickAction::Open);
|
m_ui->filesList->setDoubleClickAction(TorrentContentWidget::DoubleClickAction::Open);
|
||||||
|
@ -206,6 +210,7 @@ void PropertiesWidget::clear()
|
||||||
m_ui->labelSavePathVal->clear();
|
m_ui->labelSavePathVal->clear();
|
||||||
m_ui->labelCreatedOnVal->clear();
|
m_ui->labelCreatedOnVal->clear();
|
||||||
m_ui->labelTotalPiecesVal->clear();
|
m_ui->labelTotalPiecesVal->clear();
|
||||||
|
m_ui->labelPrivateVal->clear();
|
||||||
m_ui->labelInfohash1Val->clear();
|
m_ui->labelInfohash1Val->clear();
|
||||||
m_ui->labelInfohash2Val->clear();
|
m_ui->labelInfohash2Val->clear();
|
||||||
m_ui->labelCommentVal->clear();
|
m_ui->labelCommentVal->clear();
|
||||||
|
@ -274,6 +279,28 @@ void PropertiesWidget::updateSavePath(BitTorrent::Torrent *const torrent)
|
||||||
m_ui->labelSavePathVal->setText(m_torrent->savePath().toString());
|
m_ui->labelSavePathVal->setText(m_torrent->savePath().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropertiesWidget::showContentFilterContextMenu()
|
||||||
|
{
|
||||||
|
QMenu *menu = m_contentFilterLine->createStandardContextMenu();
|
||||||
|
|
||||||
|
auto *formatMenu = new FilterPatternFormatMenu(m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards), menu);
|
||||||
|
connect(formatMenu, &FilterPatternFormatMenu::patternFormatChanged, this, [this](const FilterPatternFormat format)
|
||||||
|
{
|
||||||
|
m_storeFilterPatternFormat = format;
|
||||||
|
setContentFilterPattern();
|
||||||
|
});
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addMenu(formatMenu);
|
||||||
|
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
menu->popup(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesWidget::setContentFilterPattern()
|
||||||
|
{
|
||||||
|
m_ui->filesList->setFilterPattern(m_contentFilterLine->text(), m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards));
|
||||||
|
}
|
||||||
|
|
||||||
void PropertiesWidget::updateTorrentInfos(BitTorrent::Torrent *const torrent)
|
void PropertiesWidget::updateTorrentInfos(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
if (torrent == m_torrent)
|
if (torrent == m_torrent)
|
||||||
|
@ -309,7 +336,14 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::Torrent *const torrent)
|
||||||
m_ui->labelCommentVal->setText(Utils::Misc::parseHtmlLinks(m_torrent->comment().toHtmlEscaped()));
|
m_ui->labelCommentVal->setText(Utils::Misc::parseHtmlLinks(m_torrent->comment().toHtmlEscaped()));
|
||||||
|
|
||||||
m_ui->labelCreatedByVal->setText(m_torrent->creator());
|
m_ui->labelCreatedByVal->setText(m_torrent->creator());
|
||||||
|
|
||||||
|
m_ui->labelPrivateVal->setText(m_torrent->isPrivate() ? tr("Yes") : tr("No"));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->labelPrivateVal->setText(tr("N/A"));
|
||||||
|
}
|
||||||
|
|
||||||
// Load dynamic data
|
// Load dynamic data
|
||||||
loadDynamicData();
|
loadDynamicData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -32,7 +32,8 @@
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "base/pathfwd.h"
|
#include "base/settingvalue.h"
|
||||||
|
#include "gui/filterpatternformat.h"
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QTreeView;
|
class QTreeView;
|
||||||
|
@ -102,6 +103,8 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPushButton *getButtonFromIndex(int index);
|
QPushButton *getButtonFromIndex(int index);
|
||||||
|
void showContentFilterContextMenu();
|
||||||
|
void setContentFilterPattern();
|
||||||
|
|
||||||
Ui::PropertiesWidget *m_ui = nullptr;
|
Ui::PropertiesWidget *m_ui = nullptr;
|
||||||
BitTorrent::Torrent *m_torrent = nullptr;
|
BitTorrent::Torrent *m_torrent = nullptr;
|
||||||
|
@ -115,4 +118,6 @@ private:
|
||||||
PropTabBar *m_tabBar = nullptr;
|
PropTabBar *m_tabBar = nullptr;
|
||||||
LineEdit *m_contentFilterLine = nullptr;
|
LineEdit *m_contentFilterLine = nullptr;
|
||||||
int m_handleWidth = -1;
|
int m_handleWidth = -1;
|
||||||
|
|
||||||
|
SettingValue<FilterPatternFormat> m_storeFilterPatternFormat;
|
||||||
};
|
};
|
||||||
|
|
|
@ -823,6 +823,38 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="labelPrivate">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Private:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1" colspan="5">
|
||||||
|
<widget class="QLabel" name="labelPrivateVal">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::PlainText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="labelInfohash1">
|
<widget class="QLabel" name="labelInfohash1">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
@ -838,71 +870,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="labelInfohash2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Info Hash v2:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1" colspan="5">
|
<item row="3" column="1" colspan="5">
|
||||||
<widget class="QLabel" name="labelInfohash2Val">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::PlainText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="labelSavePath">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Save Path:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="labelComment">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Comment:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1" colspan="5">
|
|
||||||
<widget class="QLabel" name="labelInfohash1Val">
|
<widget class="QLabel" name="labelInfohash1Val">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
@ -918,7 +886,55 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="labelInfohash2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Info Hash v2:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="4" column="1" colspan="5">
|
<item row="4" column="1" colspan="5">
|
||||||
|
<widget class="QLabel" name="labelInfohash2Val">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::PlainText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="labelSavePath">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save Path:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1" colspan="5">
|
||||||
<widget class="QLabel" name="labelSavePathVal">
|
<widget class="QLabel" name="labelSavePathVal">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
@ -937,7 +953,23 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1" colspan="5">
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="labelComment">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Comment:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1" colspan="5">
|
||||||
<widget class="QLabel" name="labelCommentVal">
|
<widget class="QLabel" name="labelCommentVal">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
|
|
@ -126,6 +126,8 @@ RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
|
||||||
, this, &RSSWidget::handleSessionProcessingStateChanged);
|
, this, &RSSWidget::handleSessionProcessingStateChanged);
|
||||||
connect(RSS::Session::instance()->rootFolder(), &RSS::Folder::unreadCountChanged
|
connect(RSS::Session::instance()->rootFolder(), &RSS::Folder::unreadCountChanged
|
||||||
, this, &RSSWidget::handleUnreadCountChanged);
|
, this, &RSSWidget::handleUnreadCountChanged);
|
||||||
|
|
||||||
|
m_ui->textBrowser->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
RSSWidget::~RSSWidget()
|
RSSWidget::~RSSWidget()
|
||||||
|
@ -494,14 +496,76 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
|
||||||
article->markAsRead();
|
article->markAsRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentItem) return;
|
if (!currentItem)
|
||||||
|
return;
|
||||||
|
|
||||||
auto *article = m_articleListWidget->getRSSArticle(currentItem);
|
auto *article = m_articleListWidget->getRSSArticle(currentItem);
|
||||||
|
renderArticle(article);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::saveSlidersPosition()
|
||||||
|
{
|
||||||
|
// Remember sliders positions
|
||||||
|
Preferences *const pref = Preferences::instance();
|
||||||
|
pref->setRssSideSplitterState(m_ui->splitterSide->saveState());
|
||||||
|
pref->setRssMainSplitterState(m_ui->splitterMain->saveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::restoreSlidersPosition()
|
||||||
|
{
|
||||||
|
const Preferences *const pref = Preferences::instance();
|
||||||
|
const QByteArray stateSide = pref->getRssSideSplitterState();
|
||||||
|
if (!stateSide.isEmpty())
|
||||||
|
m_ui->splitterSide->restoreState(stateSide);
|
||||||
|
const QByteArray stateMain = pref->getRssMainSplitterState();
|
||||||
|
if (!stateMain.isEmpty())
|
||||||
|
m_ui->splitterMain->restoreState(stateMain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::updateRefreshInterval(int val) const
|
||||||
|
{
|
||||||
|
RSS::Session::instance()->setRefreshInterval(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::on_rssDownloaderBtn_clicked()
|
||||||
|
{
|
||||||
|
auto *downloader = new AutomatedRssDownloader(this);
|
||||||
|
downloader->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
downloader->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::handleSessionProcessingStateChanged(bool enabled)
|
||||||
|
{
|
||||||
|
m_ui->labelWarn->setVisible(!enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::handleUnreadCountChanged()
|
||||||
|
{
|
||||||
|
emit unreadCountUpdated(RSS::Session::instance()->rootFolder()->unreadCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSSWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if ((obj == m_ui->textBrowser) && (event->type() == QEvent::PaletteChange))
|
||||||
|
{
|
||||||
|
QListWidgetItem *currentItem = m_articleListWidget->currentItem();
|
||||||
|
if (currentItem)
|
||||||
|
{
|
||||||
|
const RSS::Article *article = m_articleListWidget->getRSSArticle(currentItem);
|
||||||
|
renderArticle(article);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSSWidget::renderArticle(const RSS::Article *article) const
|
||||||
|
{
|
||||||
Q_ASSERT(article);
|
Q_ASSERT(article);
|
||||||
|
|
||||||
const QString highlightedBaseColor = m_ui->textBrowser->palette().color(QPalette::Highlight).name();
|
const QString highlightedBaseColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::Highlight).name();
|
||||||
const QString highlightedBaseTextColor = m_ui->textBrowser->palette().color(QPalette::HighlightedText).name();
|
const QString highlightedBaseTextColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::HighlightedText).name();
|
||||||
const QString alternateBaseColor = m_ui->textBrowser->palette().color(QPalette::AlternateBase).name();
|
const QString alternateBaseColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::AlternateBase).name();
|
||||||
|
|
||||||
QString html =
|
QString html =
|
||||||
u"<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>" +
|
u"<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>" +
|
||||||
|
@ -549,44 +613,3 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
|
||||||
html += u"</div>";
|
html += u"</div>";
|
||||||
m_ui->textBrowser->setHtml(html);
|
m_ui->textBrowser->setHtml(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSSWidget::saveSlidersPosition()
|
|
||||||
{
|
|
||||||
// Remember sliders positions
|
|
||||||
Preferences *const pref = Preferences::instance();
|
|
||||||
pref->setRssSideSplitterState(m_ui->splitterSide->saveState());
|
|
||||||
pref->setRssMainSplitterState(m_ui->splitterMain->saveState());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSSWidget::restoreSlidersPosition()
|
|
||||||
{
|
|
||||||
const Preferences *const pref = Preferences::instance();
|
|
||||||
const QByteArray stateSide = pref->getRssSideSplitterState();
|
|
||||||
if (!stateSide.isEmpty())
|
|
||||||
m_ui->splitterSide->restoreState(stateSide);
|
|
||||||
const QByteArray stateMain = pref->getRssMainSplitterState();
|
|
||||||
if (!stateMain.isEmpty())
|
|
||||||
m_ui->splitterMain->restoreState(stateMain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSSWidget::updateRefreshInterval(int val) const
|
|
||||||
{
|
|
||||||
RSS::Session::instance()->setRefreshInterval(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSSWidget::on_rssDownloaderBtn_clicked()
|
|
||||||
{
|
|
||||||
auto *downloader = new AutomatedRssDownloader(this);
|
|
||||||
downloader->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
downloader->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSSWidget::handleSessionProcessingStateChanged(bool enabled)
|
|
||||||
{
|
|
||||||
m_ui->labelWarn->setVisible(!enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSSWidget::handleUnreadCountChanged()
|
|
||||||
{
|
|
||||||
emit unreadCountUpdated(RSS::Session::instance()->rootFolder()->unreadCount());
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,6 +40,11 @@ class QTreeWidgetItem;
|
||||||
class ArticleListWidget;
|
class ArticleListWidget;
|
||||||
class FeedListWidget;
|
class FeedListWidget;
|
||||||
|
|
||||||
|
namespace RSS
|
||||||
|
{
|
||||||
|
class Article;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class RSSWidget;
|
class RSSWidget;
|
||||||
|
@ -85,6 +90,9 @@ private slots:
|
||||||
void handleUnreadCountChanged();
|
void handleUnreadCountChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
void renderArticle(const RSS::Article *article) const;
|
||||||
|
|
||||||
Ui::RSSWidget *m_ui = nullptr;
|
Ui::RSSWidget *m_ui = nullptr;
|
||||||
ArticleListWidget *m_articleListWidget = nullptr;
|
ArticleListWidget *m_articleListWidget = nullptr;
|
||||||
FeedListWidget *m_feedListWidget = nullptr;
|
FeedListWidget *m_feedListWidget = nullptr;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -50,6 +50,19 @@
|
||||||
#include "searchsortmodel.h"
|
#include "searchsortmodel.h"
|
||||||
#include "ui_searchjobwidget.h"
|
#include "ui_searchjobwidget.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum DataRole
|
||||||
|
{
|
||||||
|
LinkVisitedRole = Qt::UserRole + 100
|
||||||
|
};
|
||||||
|
|
||||||
|
QColor visitedRowColor()
|
||||||
|
{
|
||||||
|
return QApplication::palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *app, QWidget *parent)
|
SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *app, QWidget *parent)
|
||||||
: GUIApplicationComponent(app, parent)
|
: GUIApplicationComponent(app, parent)
|
||||||
, m_ui {new Ui::SearchJobWidget}
|
, m_ui {new Ui::SearchJobWidget}
|
||||||
|
@ -158,6 +171,8 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *
|
||||||
connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
|
connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
|
||||||
|
|
||||||
setStatusTip(statusText(m_status));
|
setStatusTip(statusText(m_status));
|
||||||
|
|
||||||
|
connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, &SearchJobWidget::onUIThemeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchJobWidget::~SearchJobWidget()
|
SearchJobWidget::~SearchJobWidget()
|
||||||
|
@ -179,9 +194,31 @@ QHeaderView *SearchJobWidget::header() const
|
||||||
// Set the color of a row in data model
|
// Set the color of a row in data model
|
||||||
void SearchJobWidget::setRowColor(int row, const QColor &color)
|
void SearchJobWidget::setRowColor(int row, const QColor &color)
|
||||||
{
|
{
|
||||||
m_proxyModel->setDynamicSortFilter(false);
|
|
||||||
for (int i = 0; i < m_proxyModel->columnCount(); ++i)
|
for (int i = 0; i < m_proxyModel->columnCount(); ++i)
|
||||||
m_proxyModel->setData(m_proxyModel->index(row, i), color, Qt::ForegroundRole);
|
m_proxyModel->setData(m_proxyModel->index(row, i), color, Qt::ForegroundRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchJobWidget::setRowVisited(const int row)
|
||||||
|
{
|
||||||
|
m_proxyModel->setDynamicSortFilter(false);
|
||||||
|
|
||||||
|
m_proxyModel->setData(m_proxyModel->index(row, 0), true, LinkVisitedRole);
|
||||||
|
setRowColor(row, visitedRowColor());
|
||||||
|
|
||||||
|
m_proxyModel->setDynamicSortFilter(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchJobWidget::onUIThemeChanged()
|
||||||
|
{
|
||||||
|
m_proxyModel->setDynamicSortFilter(false);
|
||||||
|
|
||||||
|
for (int row = 0; row < m_proxyModel->rowCount(); ++row)
|
||||||
|
{
|
||||||
|
const QVariant userData = m_proxyModel->data(m_proxyModel->index(row, 0), LinkVisitedRole);
|
||||||
|
const bool isVisited = userData.toBool();
|
||||||
|
if (isVisited)
|
||||||
|
setRowColor(row, visitedRowColor());
|
||||||
|
}
|
||||||
|
|
||||||
m_proxyModel->setDynamicSortFilter(true);
|
m_proxyModel->setDynamicSortFilter(true);
|
||||||
}
|
}
|
||||||
|
@ -284,7 +321,8 @@ void SearchJobWidget::downloadTorrent(const QModelIndex &rowIndex, const AddTorr
|
||||||
, this, [this, option](const QString &source) { addTorrentToSession(source, option); });
|
, this, [this, option](const QString &source) { addTorrentToSession(source, option); });
|
||||||
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
|
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
|
||||||
}
|
}
|
||||||
setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
|
|
||||||
|
setRowVisited(rowIndex.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchJobWidget::addTorrentToSession(const QString &source, const AddTorrentOption option)
|
void SearchJobWidget::addTorrentToSession(const QString &source, const AddTorrentOption option)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -113,8 +113,10 @@ private:
|
||||||
void fillFilterComboBoxes();
|
void fillFilterComboBoxes();
|
||||||
NameFilteringMode filteringMode() const;
|
NameFilteringMode filteringMode() const;
|
||||||
QHeaderView *header() const;
|
QHeaderView *header() const;
|
||||||
void setRowColor(int row, const QColor &color);
|
|
||||||
int visibleColumnsCount() const;
|
int visibleColumnsCount() const;
|
||||||
|
void setRowColor(int row, const QColor &color);
|
||||||
|
void setRowVisited(int row);
|
||||||
|
void onUIThemeChanged();
|
||||||
|
|
||||||
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
|
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
|
||||||
void openTorrentPages() const;
|
void openTorrentPages() const;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006-2012 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006-2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -37,17 +37,12 @@
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QScopeGuard>
|
#include <QScopeGuard>
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_MACOS)
|
||||||
#include <windows.h>
|
|
||||||
#include <shellapi.h>
|
|
||||||
#else
|
|
||||||
#include <QMimeDatabase>
|
|
||||||
#include <QMimeType>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined Q_OS_WIN || defined Q_OS_MACOS
|
|
||||||
#define QBT_PIXMAP_CACHE_FOR_FILE_ICONS
|
#define QBT_PIXMAP_CACHE_FOR_FILE_ICONS
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
|
#elif !defined(Q_OS_WIN)
|
||||||
|
#include <QMimeDatabase>
|
||||||
|
#include <QMimeType>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/bittorrent/downloadpriority.h"
|
#include "base/bittorrent/downloadpriority.h"
|
||||||
|
@ -116,27 +111,8 @@ namespace
|
||||||
};
|
};
|
||||||
#endif // QBT_PIXMAP_CACHE_FOR_FILE_ICONS
|
#endif // QBT_PIXMAP_CACHE_FOR_FILE_ICONS
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_MACOS)
|
||||||
// See QTBUG-25319 for explanation why this is required
|
// There is a bug on macOS, to be reported to Qt
|
||||||
class WinShellFileIconProvider final : public CachingFileIconProvider
|
|
||||||
{
|
|
||||||
QPixmap pixmapForExtension(const QString &ext) const override
|
|
||||||
{
|
|
||||||
const std::wstring extWStr = QString(u'.' + ext).toStdWString();
|
|
||||||
|
|
||||||
SHFILEINFOW sfi {};
|
|
||||||
const HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(),
|
|
||||||
FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), (SHGFI_ICON | SHGFI_USEFILEATTRIBUTES));
|
|
||||||
if (FAILED(hr))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
const auto iconPixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon));
|
|
||||||
::DestroyIcon(sfi.hIcon);
|
|
||||||
return iconPixmap;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#elif defined(Q_OS_MACOS)
|
|
||||||
// There is a similar bug on macOS, to be reported to Qt
|
|
||||||
// https://github.com/qbittorrent/qBittorrent/pull/6156#issuecomment-316302615
|
// https://github.com/qbittorrent/qBittorrent/pull/6156#issuecomment-316302615
|
||||||
class MacFileIconProvider final : public CachingFileIconProvider
|
class MacFileIconProvider final : public CachingFileIconProvider
|
||||||
{
|
{
|
||||||
|
@ -145,7 +121,7 @@ namespace
|
||||||
return MacUtils::pixmapForExtension(ext, QSize(32, 32));
|
return MacUtils::pixmapForExtension(ext, QSize(32, 32));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#else
|
#elif !defined(Q_OS_WIN)
|
||||||
/**
|
/**
|
||||||
* @brief Tests whether QFileIconProvider actually works
|
* @brief Tests whether QFileIconProvider actually works
|
||||||
*
|
*
|
||||||
|
@ -189,7 +165,7 @@ TorrentContentModel::TorrentContentModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Total Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
, m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Total Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
, m_fileIconProvider {new WinShellFileIconProvider}
|
, m_fileIconProvider {new QFileIconProvider}
|
||||||
#elif defined(Q_OS_MACOS)
|
#elif defined(Q_OS_MACOS)
|
||||||
, m_fileIconProvider {new MacFileIconProvider}
|
, m_fileIconProvider {new MacFileIconProvider}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -147,10 +147,19 @@ void TorrentContentModelFolder::recalculateProgress()
|
||||||
tRemaining += child->remaining();
|
tRemaining += child->remaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRootItem() && (tSize > 0))
|
if (!isRootItem())
|
||||||
|
{
|
||||||
|
if (tSize > 0)
|
||||||
{
|
{
|
||||||
m_progress = tProgress / tSize;
|
m_progress = tProgress / tSize;
|
||||||
m_remaining = tRemaining;
|
m_remaining = tRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_progress = 1.0;
|
||||||
|
m_remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Q_ASSERT(m_progress <= 1.);
|
Q_ASSERT(m_progress <= 1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -56,6 +56,19 @@
|
||||||
#include "gui/macutilities.h"
|
#include "gui/macutilities.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
QList<QPersistentModelIndex> toPersistentIndexes(const QModelIndexList &indexes)
|
||||||
|
{
|
||||||
|
QList<QPersistentModelIndex> persistentIndexes;
|
||||||
|
persistentIndexes.reserve(indexes.size());
|
||||||
|
for (const QModelIndex &index : indexes)
|
||||||
|
persistentIndexes.emplaceBack(index);
|
||||||
|
|
||||||
|
return persistentIndexes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TorrentContentWidget::TorrentContentWidget(QWidget *parent)
|
TorrentContentWidget::TorrentContentWidget(QWidget *parent)
|
||||||
: QTreeView(parent)
|
: QTreeView(parent)
|
||||||
{
|
{
|
||||||
|
@ -173,10 +186,20 @@ Path TorrentContentWidget::getItemPath(const QModelIndex &index) const
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentContentWidget::setFilterPattern(const QString &patternText)
|
void TorrentContentWidget::setFilterPattern(const QString &patternText, const FilterPatternFormat format)
|
||||||
{
|
{
|
||||||
const QString pattern = Utils::String::wildcardToRegexPattern(patternText);
|
if (format == FilterPatternFormat::PlainText)
|
||||||
|
{
|
||||||
|
m_filterModel->setFilterFixedString(patternText);
|
||||||
|
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QString pattern = ((format == FilterPatternFormat::Regex)
|
||||||
|
? patternText : Utils::String::wildcardToRegexPattern(patternText));
|
||||||
m_filterModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
|
m_filterModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
|
||||||
|
}
|
||||||
|
|
||||||
if (patternText.isEmpty())
|
if (patternText.isEmpty())
|
||||||
{
|
{
|
||||||
collapseAll();
|
collapseAll();
|
||||||
|
@ -219,9 +242,9 @@ void TorrentContentWidget::keyPressEvent(QKeyEvent *event)
|
||||||
|
|
||||||
const Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked)
|
const Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked)
|
||||||
? Qt::Unchecked : Qt::Checked;
|
? Qt::Unchecked : Qt::Checked;
|
||||||
const QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
|
const QList<QPersistentModelIndex> selection = toPersistentIndexes(selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME));
|
||||||
|
|
||||||
for (const QModelIndex &index : selection)
|
for (const QPersistentModelIndex &index : selection)
|
||||||
model()->setData(index, state, Qt::CheckStateRole);
|
model()->setData(index, state, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,10 +271,10 @@ void TorrentContentWidget::renameSelectedFile()
|
||||||
|
|
||||||
void TorrentContentWidget::applyPriorities(const BitTorrent::DownloadPriority priority)
|
void TorrentContentWidget::applyPriorities(const BitTorrent::DownloadPriority priority)
|
||||||
{
|
{
|
||||||
const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
|
const QList<QPersistentModelIndex> selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
|
||||||
for (const QModelIndex &index : selectedRows)
|
for (const QPersistentModelIndex &index : selectedRows)
|
||||||
{
|
{
|
||||||
model()->setData(index.sibling(index.row(), Priority), static_cast<int>(priority));
|
model()->setData(index, static_cast<int>(priority));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +284,7 @@ void TorrentContentWidget::applyPrioritiesByOrder()
|
||||||
// a download priority that will apply to each item. The number of groups depends on how
|
// a download priority that will apply to each item. The number of groups depends on how
|
||||||
// many "download priority" are available to be assigned
|
// many "download priority" are available to be assigned
|
||||||
|
|
||||||
const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
|
const QList<QPersistentModelIndex> selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
|
||||||
|
|
||||||
const qsizetype priorityGroups = 3;
|
const qsizetype priorityGroups = 3;
|
||||||
const auto priorityGroupSize = std::max<qsizetype>((selectedRows.length() / priorityGroups), 1);
|
const auto priorityGroupSize = std::max<qsizetype>((selectedRows.length() / priorityGroups), 1);
|
||||||
|
@ -283,8 +306,8 @@ void TorrentContentWidget::applyPrioritiesByOrder()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QModelIndex &index = selectedRows[i];
|
const QPersistentModelIndex &index = selectedRows[i];
|
||||||
model()->setData(index.sibling(index.row(), Priority), static_cast<int>(priority));
|
model()->setData(index, static_cast<int>(priority));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2022-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "base/bittorrent/downloadpriority.h"
|
#include "base/bittorrent/downloadpriority.h"
|
||||||
#include "base/pathfwd.h"
|
#include "base/pathfwd.h"
|
||||||
|
#include "filterpatternformat.h"
|
||||||
|
|
||||||
class QShortcut;
|
class QShortcut;
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ public:
|
||||||
int getFileIndex(const QModelIndex &index) const;
|
int getFileIndex(const QModelIndex &index) const;
|
||||||
Path getItemPath(const QModelIndex &index) const;
|
Path getItemPath(const QModelIndex &index) const;
|
||||||
|
|
||||||
void setFilterPattern(const QString &patternText);
|
void setFilterPattern(const QString &patternText, FilterPatternFormat format = FilterPatternFormat::Wildcards);
|
||||||
|
|
||||||
void checkAll();
|
void checkAll();
|
||||||
void checkNone();
|
void checkNone();
|
||||||
|
|
|
@ -84,11 +84,7 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const Path &defaultP
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
m_ui->comboPieceSize->addItem(tr("Auto"), 0);
|
m_ui->comboPieceSize->addItem(tr("Auto"), 0);
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
|
||||||
for (int i = 4; i <= 18; ++i)
|
|
||||||
#else
|
|
||||||
for (int i = 4; i <= 17; ++i)
|
for (int i = 4; i <= 17; ++i)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
const int size = 1024 << i;
|
const int size = 1024 << i;
|
||||||
const QString displaySize = Utils::Misc::friendlyUnit(size, false, 0);
|
const QString displaySize = Utils::Misc::friendlyUnit(size, false, 0);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "autoexpandabledialog.h"
|
#include "autoexpandabledialog.h"
|
||||||
#include "flowlayout.h"
|
#include "flowlayout.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include "ui_torrenttagsdialog.h"
|
#include "ui_torrenttagsdialog.h"
|
||||||
|
|
||||||
|
@ -52,10 +53,10 @@ TorrentTagsDialog::TorrentTagsDialog(const TagSet &initialTags, QWidget *parent)
|
||||||
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
|
||||||
auto *tagsLayout = new FlowLayout(m_ui->scrollArea);
|
auto *tagsLayout = new FlowLayout(m_ui->scrollArea->widget());
|
||||||
for (const Tag &tag : asConst(initialTags.united(BitTorrent::Session::instance()->tags())))
|
for (const Tag &tag : asConst(initialTags.united(BitTorrent::Session::instance()->tags())))
|
||||||
{
|
{
|
||||||
auto *tagWidget = new QCheckBox(tag.toString());
|
auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
|
||||||
if (initialTags.contains(tag))
|
if (initialTags.contains(tag))
|
||||||
tagWidget->setChecked(true);
|
tagWidget->setChecked(true);
|
||||||
tagsLayout->addWidget(tagWidget);
|
tagsLayout->addWidget(tagWidget);
|
||||||
|
@ -78,12 +79,12 @@ TorrentTagsDialog::~TorrentTagsDialog()
|
||||||
TagSet TorrentTagsDialog::tags() const
|
TagSet TorrentTagsDialog::tags() const
|
||||||
{
|
{
|
||||||
TagSet tags;
|
TagSet tags;
|
||||||
auto *layout = m_ui->scrollArea->layout();
|
auto *layout = m_ui->scrollArea->widget()->layout();
|
||||||
for (int i = 0; i < (layout->count() - 1); ++i)
|
for (int i = 0; i < (layout->count() - 1); ++i)
|
||||||
{
|
{
|
||||||
const auto *tagWidget = static_cast<QCheckBox *>(layout->itemAt(i)->widget());
|
const auto *tagWidget = static_cast<QCheckBox *>(layout->itemAt(i)->widget());
|
||||||
if (tagWidget->isChecked())
|
if (tagWidget->isChecked())
|
||||||
tags.insert(Tag(tagWidget->text()));
|
tags.insert(Utils::Gui::widgetTextToTag(tagWidget->text()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
|
@ -111,9 +112,9 @@ void TorrentTagsDialog::addNewTag()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto *layout = m_ui->scrollArea->layout();
|
auto *layout = m_ui->scrollArea->widget()->layout();
|
||||||
auto *btn = layout->takeAt(layout->count() - 1);
|
auto *btn = layout->takeAt(layout->count() - 1);
|
||||||
auto *tagWidget = new QCheckBox(tag.toString());
|
auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
|
||||||
tagWidget->setChecked(true);
|
tagWidget->setChecked(true);
|
||||||
layout->addWidget(tagWidget);
|
layout->addWidget(tagWidget);
|
||||||
layout->addItem(btn);
|
layout->addItem(btn);
|
||||||
|
|
|
@ -488,11 +488,11 @@ QVariant TrackerListModel::headerData(const int section, const Qt::Orientation o
|
||||||
switch (section)
|
switch (section)
|
||||||
{
|
{
|
||||||
case COL_URL:
|
case COL_URL:
|
||||||
return tr("URL/Announce endpoint");
|
return tr("URL/Announce Endpoint");
|
||||||
case COL_TIER:
|
case COL_TIER:
|
||||||
return tr("Tier");
|
return tr("Tier");
|
||||||
case COL_PROTOCOL:
|
case COL_PROTOCOL:
|
||||||
return tr("Protocol");
|
return tr("BT Protocol");
|
||||||
case COL_STATUS:
|
case COL_STATUS:
|
||||||
return tr("Status");
|
return tr("Status");
|
||||||
case COL_PEERS:
|
case COL_PEERS:
|
||||||
|
@ -506,9 +506,9 @@ QVariant TrackerListModel::headerData(const int section, const Qt::Orientation o
|
||||||
case COL_MSG:
|
case COL_MSG:
|
||||||
return tr("Message");
|
return tr("Message");
|
||||||
case COL_NEXT_ANNOUNCE:
|
case COL_NEXT_ANNOUNCE:
|
||||||
return tr("Next announce");
|
return tr("Next Announce");
|
||||||
case COL_MIN_ANNOUNCE:
|
case COL_MIN_ANNOUNCE:
|
||||||
return tr("Min announce");
|
return tr("Min Announce");
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -585,7 +585,7 @@ QVariant TrackerListModel::data(const QModelIndex &index, const int role) const
|
||||||
case COL_TIER:
|
case COL_TIER:
|
||||||
return (isEndpoint || (index.row() < STICKY_ROW_COUNT)) ? QString() : QString::number(itemPtr->tier);
|
return (isEndpoint || (index.row() < STICKY_ROW_COUNT)) ? QString() : QString::number(itemPtr->tier);
|
||||||
case COL_PROTOCOL:
|
case COL_PROTOCOL:
|
||||||
return isEndpoint ? tr("v%1").arg(itemPtr->btVersion) : QString();
|
return isEndpoint ? (u'v' + QString::number(itemPtr->btVersion)) : QString();
|
||||||
case COL_STATUS:
|
case COL_STATUS:
|
||||||
if (isEndpoint)
|
if (isEndpoint)
|
||||||
return toString(itemPtr->status);
|
return toString(itemPtr->status);
|
||||||
|
|
|
@ -235,10 +235,7 @@ void StatusFilterWidget::applyFilter(int row)
|
||||||
|
|
||||||
void StatusFilterWidget::handleTorrentsLoaded(const QVector<BitTorrent::Torrent *> &torrents)
|
void StatusFilterWidget::handleTorrentsLoaded(const QVector<BitTorrent::Torrent *> &torrents)
|
||||||
{
|
{
|
||||||
for (const BitTorrent::Torrent *torrent : torrents)
|
update(torrents);
|
||||||
updateTorrentStatus(torrent);
|
|
||||||
|
|
||||||
updateTexts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
|
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
|
||||||
|
@ -273,6 +270,12 @@ void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torr
|
||||||
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
|
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
|
||||||
|
|
||||||
updateTexts();
|
updateTexts();
|
||||||
|
|
||||||
|
if (Preferences::instance()->getHideZeroStatusFilters())
|
||||||
|
{
|
||||||
|
hideZeroItems();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusFilterWidget::configure()
|
void StatusFilterWidget::configure()
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "base/algorithm.h"
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrent.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/bittorrent/trackerentrystatus.h"
|
#include "base/bittorrent/trackerentrystatus.h"
|
||||||
|
|
|
@ -193,6 +193,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
|
||||||
case TR_INFOHASH_V1: return tr("Info Hash v1", "i.e: torrent info hash v1");
|
case TR_INFOHASH_V1: return tr("Info Hash v1", "i.e: torrent info hash v1");
|
||||||
case TR_INFOHASH_V2: return tr("Info Hash v2", "i.e: torrent info hash v2");
|
case TR_INFOHASH_V2: return tr("Info Hash v2", "i.e: torrent info hash v2");
|
||||||
case TR_REANNOUNCE: return tr("Reannounce In", "Indicates the time until next trackers reannounce");
|
case TR_REANNOUNCE: return tr("Reannounce In", "Indicates the time until next trackers reannounce");
|
||||||
|
case TR_PRIVATE: return tr("Private", "Flags private torrents");
|
||||||
default: return {};
|
default: return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,6 +358,15 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
|
||||||
return Utils::Misc::userFriendlyDuration(time);
|
return Utils::Misc::userFriendlyDuration(time);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto privateString = [hideValues](const bool isPrivate, const bool hasMetadata) -> QString
|
||||||
|
{
|
||||||
|
if (hideValues && !isPrivate)
|
||||||
|
return {};
|
||||||
|
if (hasMetadata)
|
||||||
|
return isPrivate ? tr("Yes") : tr("No");
|
||||||
|
return tr("N/A");
|
||||||
|
};
|
||||||
|
|
||||||
switch (column)
|
switch (column)
|
||||||
{
|
{
|
||||||
case TR_NAME:
|
case TR_NAME:
|
||||||
|
@ -431,6 +441,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
|
||||||
return hashString(torrent->infoHash().v2());
|
return hashString(torrent->infoHash().v2());
|
||||||
case TR_REANNOUNCE:
|
case TR_REANNOUNCE:
|
||||||
return reannounceString(torrent->nextAnnounce());
|
return reannounceString(torrent->nextAnnounce());
|
||||||
|
case TR_PRIVATE:
|
||||||
|
return privateString(torrent->isPrivate(), torrent->hasMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -512,6 +524,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
|
||||||
return QVariant::fromValue(torrent->infoHash().v2());
|
return QVariant::fromValue(torrent->infoHash().v2());
|
||||||
case TR_REANNOUNCE:
|
case TR_REANNOUNCE:
|
||||||
return torrent->nextAnnounce();
|
return torrent->nextAnnounce();
|
||||||
|
case TR_PRIVATE:
|
||||||
|
return (torrent->hasMetadata() ? torrent->isPrivate() : QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
TR_INFOHASH_V1,
|
TR_INFOHASH_V1,
|
||||||
TR_INFOHASH_V2,
|
TR_INFOHASH_V2,
|
||||||
TR_REANNOUNCE,
|
TR_REANNOUNCE,
|
||||||
|
TR_PRIVATE,
|
||||||
|
|
||||||
NB_COLUMNS
|
NB_COLUMNS
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,17 @@ namespace
|
||||||
return isLeftValid ? -1 : 1;
|
return isLeftValid ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int compareAsBool(const QVariant &left, const QVariant &right)
|
||||||
|
{
|
||||||
|
const bool leftValid = left.isValid();
|
||||||
|
const bool rightValid = right.isValid();
|
||||||
|
if (leftValid && rightValid)
|
||||||
|
return threeWayCompare(left.toBool(), right.toBool());
|
||||||
|
if (!leftValid && !rightValid)
|
||||||
|
return 0;
|
||||||
|
return leftValid ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
int adjustSubSortColumn(const int column)
|
int adjustSubSortColumn(const int column)
|
||||||
{
|
{
|
||||||
return ((column >= 0) && (column < TransferListModel::NB_COLUMNS))
|
return ((column >= 0) && (column < TransferListModel::NB_COLUMNS))
|
||||||
|
@ -214,6 +225,9 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r
|
||||||
case TransferListModel::TR_UPSPEED:
|
case TransferListModel::TR_UPSPEED:
|
||||||
return customCompare(leftValue.toInt(), rightValue.toInt());
|
return customCompare(leftValue.toInt(), rightValue.toInt());
|
||||||
|
|
||||||
|
case TransferListModel::TR_PRIVATE:
|
||||||
|
return compareAsBool(leftValue, rightValue);
|
||||||
|
|
||||||
case TransferListModel::TR_PEERS:
|
case TransferListModel::TR_PEERS:
|
||||||
case TransferListModel::TR_SEEDS:
|
case TransferListModel::TR_SEEDS:
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -116,9 +116,10 @@ namespace
|
||||||
void removeTorrents(const QVector<BitTorrent::Torrent *> &torrents, const bool isDeleteFileSelected)
|
void removeTorrents(const QVector<BitTorrent::Torrent *> &torrents, const bool isDeleteFileSelected)
|
||||||
{
|
{
|
||||||
auto *session = BitTorrent::Session::instance();
|
auto *session = BitTorrent::Session::instance();
|
||||||
const DeleteOption deleteOption = isDeleteFileSelected ? DeleteTorrentAndFiles : DeleteTorrent;
|
const BitTorrent::TorrentRemoveOption removeOption = isDeleteFileSelected
|
||||||
|
? BitTorrent::TorrentRemoveOption::RemoveContent : BitTorrent::TorrentRemoveOption::KeepContent;
|
||||||
for (const BitTorrent::Torrent *torrent : torrents)
|
for (const BitTorrent::Torrent *torrent : torrents)
|
||||||
session->deleteTorrent(torrent->id(), deleteOption);
|
session->removeTorrent(torrent->id(), removeOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +184,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
|
||||||
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
|
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
|
||||||
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);
|
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);
|
||||||
setColumnHidden(TransferListModel::TR_REANNOUNCE, true);
|
setColumnHidden(TransferListModel::TR_REANNOUNCE, true);
|
||||||
|
setColumnHidden(TransferListModel::TR_PRIVATE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ensure that at least one column is visible at all times
|
//Ensure that at least one column is visible at all times
|
||||||
|
@ -442,7 +444,7 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
|
||||||
{
|
{
|
||||||
// Some torrents might be removed when waiting for user input, so refetch the torrent list
|
// Some torrents might be removed when waiting for user input, so refetch the torrent list
|
||||||
// NOTE: this will only work when dialog is modal
|
// NOTE: this will only work when dialog is modal
|
||||||
removeTorrents(getSelectedTorrents(), dialog->isDeleteFileSelected());
|
removeTorrents(getSelectedTorrents(), dialog->isRemoveContentSelected());
|
||||||
});
|
});
|
||||||
dialog->open();
|
dialog->open();
|
||||||
}
|
}
|
||||||
|
@ -465,7 +467,7 @@ void TransferListWidget::deleteVisibleTorrents()
|
||||||
{
|
{
|
||||||
// Some torrents might be removed when waiting for user input, so refetch the torrent list
|
// Some torrents might be removed when waiting for user input, so refetch the torrent list
|
||||||
// NOTE: this will only work when dialog is modal
|
// NOTE: this will only work when dialog is modal
|
||||||
removeTorrents(getVisibleTorrents(), dialog->isDeleteFileSelected());
|
removeTorrents(getVisibleTorrents(), dialog->isRemoveContentSelected());
|
||||||
});
|
});
|
||||||
dialog->open();
|
dialog->open();
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1192,7 @@ void TransferListWidget::displayListMenu()
|
||||||
const TagSet tags = BitTorrent::Session::instance()->tags();
|
const TagSet tags = BitTorrent::Session::instance()->tags();
|
||||||
for (const Tag &tag : asConst(tags))
|
for (const Tag &tag : asConst(tags))
|
||||||
{
|
{
|
||||||
auto *action = new TriStateAction(tag.toString(), tagsMenu);
|
auto *action = new TriStateAction(Utils::Gui::tagToWidgetText(tag), tagsMenu);
|
||||||
action->setCloseOnInteraction(false);
|
action->setCloseOnInteraction(false);
|
||||||
|
|
||||||
const Qt::CheckState initialState = tagsInAll.contains(tag) ? Qt::Checked
|
const Qt::CheckState initialState = tagsInAll.contains(tag) ? Qt::Checked
|
||||||
|
|
|
@ -80,6 +80,14 @@ UIThemeManager::UIThemeManager()
|
||||||
, m_useSystemIcons {Preferences::instance()->useSystemIcons()}
|
, m_useSystemIcons {Preferences::instance()->useSystemIcons()}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (const QString styleName = Preferences::instance()->getStyle(); styleName.compare(u"system", Qt::CaseInsensitive) != 0)
|
||||||
|
{
|
||||||
|
if (!QApplication::setStyle(styleName.isEmpty() ? u"Fusion"_s : styleName))
|
||||||
|
LogMsg(tr("Set app style failed. Unknown style: \"%1\"").arg(styleName), Log::WARNING);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: Qt::QueuedConnection can be omitted as soon as support for Qt 6.5 is dropped
|
// NOTE: Qt::QueuedConnection can be omitted as soon as support for Qt 6.5 is dropped
|
||||||
connect(QApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &UIThemeManager::onColorSchemeChanged, Qt::QueuedConnection);
|
connect(QApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &UIThemeManager::onColorSchemeChanged, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2017 Mike Tzou
|
* Copyright (C) 2017 Mike Tzou
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
|
#include "base/tag.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/version.h"
|
#include "base/utils/version.h"
|
||||||
|
|
||||||
|
@ -216,3 +218,29 @@ void Utils::Gui::openFolderSelect(const Path &path)
|
||||||
openPath(path.parentPath());
|
openPath(path.parentPath());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Utils::Gui::tagToWidgetText(const Tag &tag)
|
||||||
|
{
|
||||||
|
return tag.toString().replace(u'&', u"&&"_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag Utils::Gui::widgetTextToTag(const QString &text)
|
||||||
|
{
|
||||||
|
// replace pairs of '&' with single '&' and remove non-paired occurrences of '&'
|
||||||
|
QString cleanedText;
|
||||||
|
cleanedText.reserve(text.size());
|
||||||
|
bool amp = false;
|
||||||
|
for (const QChar c : text)
|
||||||
|
{
|
||||||
|
if (c == u'&')
|
||||||
|
{
|
||||||
|
amp = !amp;
|
||||||
|
if (amp)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanedText.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Tag(cleanedText);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2017 Mike Tzou
|
* Copyright (C) 2017 Mike Tzou
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -34,8 +35,11 @@ class QIcon;
|
||||||
class QPixmap;
|
class QPixmap;
|
||||||
class QPoint;
|
class QPoint;
|
||||||
class QSize;
|
class QSize;
|
||||||
|
class QString;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
||||||
|
class Tag;
|
||||||
|
|
||||||
namespace Utils::Gui
|
namespace Utils::Gui
|
||||||
{
|
{
|
||||||
bool isDarkTheme();
|
bool isDarkTheme();
|
||||||
|
@ -51,4 +55,7 @@ namespace Utils::Gui
|
||||||
|
|
||||||
void openPath(const Path &path);
|
void openPath(const Path &path);
|
||||||
void openFolderSelect(const Path &path);
|
void openFolderSelect(const Path &path);
|
||||||
|
|
||||||
|
QString tagToWidgetText(const Tag &tag);
|
||||||
|
Tag widgetTextToTag(const QString &text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
<path fill="#d0103a" d="M0 0h640v480H0z"/>
|
<path fill="#d0103a" d="M0 0h640v480H0z"/>
|
||||||
<path fill="#fedf00" d="M0 0h435.2v480H0z"/>
|
<path fill="#fedf00" d="M0 0h435.2v480H0z"/>
|
||||||
<path fill="#0018a8" d="M0 0h204.8v480H0z"/>
|
<path fill="#0018a8" d="M0 0h204.8v480H0z"/>
|
||||||
<path fill="#c7b37f" d="M300.4 136.6c7.7 0 10.9 6.6 18.6 6.6 4.7 0 7.5-1.5 11.7-3.9 2.9-1.6 4.7-2.5 8-2.5 3.4 0 5.5 1 7.3 4 1 1.6 1.8 4.9 1.3 6.7a40 40 0 0 1-2.7 8.3c-.7 1.6-1.3 2.5-1.3 4.2 0 4.1 5.6 5.5 9.4 5.6.8 0 7.7 0 12-4.2-2.3-.1-4.9-2-4.9-4.3 0-2.6 1.8-4.3 4.3-5.1.5-.1 1.3.3 1.7 0 .7-.3.4-1 1-1.4 1.2-1 2-1.6 3.6-1.6 1 0 1.6.1 2.5.7.4.4.6.8 1 .8 1.2 0 1.8-.8 3-.8a5 5 0 0 1 2.3.6c.6.3.6 1.5 1.4 1.5.4 0 2.4-.9 3.5-.9 2.2 0 3.4.8 4.8 2.5.4.5.6 1.4 1 1.4a6.2 6.2 0 0 1 4.8 3c.3.4.7 1.4 1.1 1.5.6.3 1 .2 1.7.7a6 6 0 0 1 2.8 4.8c0 .7-.3 1.6-.5 2.2-1.8 6.5-6.3 8.6-10.8 14.3-2 2.4-3.5 4.3-3.5 7.4 0 .7 1 2.1 1.3 2.7-.2-1.4.5-3.2 2-3.3a4 4 0 0 1 4 3.6 4.5 4.5 0 0 1-.3 1.8 9.6 9.6 0 0 1 4-1.4h1.9c3.3 0 7 1.9 9.3 3.8a21 21 0 0 1 7.3 16.8c-.8 5.2-.3 14.8-13.8 18.6 2.5 1 4.2 3 4.2 5.2a4.5 4.5 0 0 1-4.4 4.7 4.4 4.4 0 0 1-3.5-1.4c-2.8 2.8-3.3 5.7-3.3 9.7 0 2.4.4 3.8 1.4 6 1 2.2 1.8 3.5 3.7 5.1 1-1.5 2.1-2.6 4-2.6 1.7 0 3.2.6 3.9 2.2.2.5 0 .9.3 1.4.3.6.8.7 1.1 1.3.5 1 0 1.8.5 2.7.3.7.9.8 1.2 1.4.4 1 .5 1.6.5 2.7 0 3-2.7 5.2-5.7 5.2-1 0-1.4-.4-2.3-.3 1.7 1.7 3 2.5 4.3 4.5a17.7 17.7 0 0 1 3 10.3 22 22 0 0 1-2.8 11.2 20 20 0 0 1-7 8.5 35 35 0 0 1-16 6.4 74.4 74.4 0 0 1-11 1.4l-14.1.8c-7.2.4-12.2 1.5-17.3 6.6 2.4 1.7 4 3.5 4 6.4 0 3-1.8 5.3-4.7 6.2-.7.2-1.2 0-1.9.4s-.7 1.3-1.4 1.7a6.2 6.2 0 0 1-3.8 1 8 8 0 0 1-6.4-2.5c-2.2 1.8-3 3.4-5.5 4.9-.8.4-1.2 1-2.1 1-1.5 0-2.2-1-3.4-1.8a23 23 0 0 1-4.4-4c-2.3 1.3-3.6 2.4-6.3 2.4a7 7 0 0 1-4-1c-.6-.5-.8-1.2-1.5-1.6-.7-.5-1.3-.3-2.1-.7-3-1.3-5-3.5-5-6.8 0-2.9 1.8-4.7 4.4-6-5-5-10-5.8-17-6.2l-14-.8c-4.4-.3-6.8-.7-11-1.4-3.3-.5-5.2-.7-8.2-2.1-10.2-4.8-16.8-11.3-18-22.5-.2-1-.2-1.5-.2-2.5 0-5.8 2.3-9.4 6.4-13.5-1-.3-1.7 0-2.8-.3-2.5-1-4.4-2.7-4.4-5.5 0-1 0-1.7.5-2.6.4-.6 1-.7 1.2-1.4.2-1 0-1.6.4-2.5.3-.5.8-.6 1-1.2 1-1.9 2-3.4 4.1-3.4 1.8 0 3 1 3.8 2.5 1.8-.8 2.2-2.1 3.2-3.7a15.5 15.5 0 0 0 1.4-13.3c-.4-1.5-.6-2.5-1.8-3.7-1 1-2 1.4-3.4 1.4-2.9 0-5-2.5-5-5.3a4.8 4.8 0 0 1 3-4.6c-1.6-1.4-3-1.5-4.7-2.6-2.6-1.6-3.5-3.4-5.2-6-1.2-1.6-1.5-2.8-2-4.7a19 19 0 0 1-1-7.8c.6-5 1.5-8 4.6-11.9 1.8-2.3 3-3.7 5.8-4.9 2.3-1 3.7-1.7 6.2-1.7l2 .1a6.9 6.9 0 0 1 2.8.8c.4.2 1.1.9 1.1.4s-.3-.8-.3-1.3c0-2 1.5-4 3.6-4 1.5 0 2.1 1.4 2.9 2.7.4-.8.7-1.4.7-2.3 0-3.4-1.9-5.2-4-7.9-4.7-5.8-10.5-8.5-10.5-16 0-2.2 1-3.7 3-4.9.5-.3 1.3 0 1.8-.3s.4-1 .7-1.4c.5-.7 1-1 1.6-1.6 1-1 2-.6 3.1-1.5.6-.4.8-1 1.2-1.4 1.3-1.6 2.5-2.4 4.6-2.4 1 0 1.6 0 2.5.4l1 .5c.3-.2.8-.8 1.5-1.1a4 4 0 0 1 2.2-.6c1.1 0 1.8.6 3 .6.3 0 .4-.4.8-.6 1-.7 1.5-1 2.7-1 1.2 0 1.8.3 2.8 1 1 .5 1 1.3 2 1.8.5.3 1 .2 1.5.4 2.6.9 4.5 2.6 4.5 5.3 0 1.5-.3 2.5-1.4 3.5-.9.7-1.7.6-2.8 1a16 16 0 0 0 11.3 3.5c4.2 0 9.3-1.7 9.3-5.9 0-2-1-3-1.8-4.8a18.8 18.8 0 0 1-2.1-8.5c0-2.8.3-4.5 1.9-6.7 1.6-2.3 3.6-2.9 6.5-2.9z"/>
|
<path fill="#c7b37f" d="M300.4 136.6c7.7 0 10.9 6.6 18.6 6.6 4.7 0 7.5-1.5 11.7-3.9 2.9-1.6 4.7-2.5 8-2.5 3.4 0 5.5 1 7.3 4 1 1.6 1.8 4.9 1.3 6.7a40 40 0 0 1-2.7 8.3c-.7 1.6-1.3 2.5-1.3 4.2 0 4.1 5.6 5.5 9.4 5.6.8 0 7.7 0 12-4.2-2.3-.1-4.9-2-4.9-4.3 0-2.6 1.8-4.3 4.3-5.1.5-.1 1.3.3 1.7 0 .7-.3.4-1 1-1.4 1.2-1 2-1.6 3.6-1.6 1 0 1.6.1 2.5.7.4.4.6.8 1 .8 1.2 0 1.8-.8 3-.8a5 5 0 0 1 2.3.6c.6.3.6 1.5 1.4 1.5.4 0 2.4-.9 3.5-.9 2.2 0 3.4.8 4.8 2.5.4.5.6 1.4 1 1.4a6.2 6.2 0 0 1 4.8 3c.3.4.7 1.4 1.1 1.5.6.3 1 .2 1.7.7a6 6 0 0 1 2.8 4.8c0 .7-.3 1.6-.5 2.2-1.8 6.5-6.3 8.6-10.8 14.3-2 2.4-3.5 4.3-3.5 7.4 0 .7 1 2.1 1.3 2.7-.2-1.4.5-3.2 2-3.3a4 4 0 0 1 4 3.6 4.5 4.5 0 0 1-.3 1.8 9.6 9.6 0 0 1 4-1.4h1.9c3.3 0 7 1.9 9.3 3.8a21 21 0 0 1 7.3 16.8c-.8 5.2-.3 14.8-13.8 18.6 2.5 1 4.2 3 4.2 5.2a4.5 4.5 0 0 1-4.4 4.7 4.4 4.4 0 0 1-3.5-1.4c-2.8 2.8-3.3 5.7-3.3 9.7 0 2.4.4 3.8 1.4 6 1 2.2 1.8 3.5 3.7 5.1 1-1.5 2.1-2.6 4-2.6 1.7 0 3.2.6 3.9 2.2.2.5 0 .9.3 1.4.3.6.8.7 1.1 1.3.5 1 0 1.8.5 2.7.3.7.9.8 1.2 1.4.4 1 .5 1.6.5 2.7 0 3-2.7 5.2-5.7 5.2-1 0-1.4-.4-2.3-.3 1.7 1.7 3 2.5 4.3 4.5a17.7 17.7 0 0 1 3 10.3 22 22 0 0 1-2.8 11.2 20 20 0 0 1-7 8.5 35 35 0 0 1-16 6.4 74.4 74.4 0 0 1-11 1.4l-14.1.8c-7.2.4-12.2 1.5-17.3 6.6 2.4 1.7 4 3.5 4 6.4 0 3-1.8 5.3-4.7 6.2-.7.2-1.2 0-1.9.4s-.7 1.3-1.4 1.7a6.2 6.2 0 0 1-3.8 1 8 8 0 0 1-6.4-2.5c-2.2 1.8-3 3.4-5.5 4.9-.8.4-1.2 1-2.1 1-1.5 0-2.2-1-3.4-1.8a23 23 0 0 1-4.4-4c-2.3 1.3-3.6 2.4-6.3 2.4a7 7 0 0 1-4-1c-.6-.5-.8-1.2-1.5-1.6-.7-.5-1.3-.3-2.1-.7-3-1.3-5-3.5-5-6.8 0-2.9 1.8-4.7 4.4-6-5-5-10-5.8-17-6.2l-14-.8c-4.4-.3-6.8-.7-11-1.4-3.3-.5-5.2-.7-8.2-2.1-10.2-4.8-16.8-11.3-18-22.5-.2-1-.2-1.5-.2-2.5 0-5.8 2.3-9.4 6.4-13.5-1-.3-1.7 0-2.8-.3-2.5-1-4.4-2.7-4.4-5.5 0-1 0-1.7.5-2.6.4-.6 1-.7 1.2-1.4.2-1 0-1.6.4-2.5.3-.5.8-.6 1-1.2 1-1.9 2-3.4 4.1-3.4 1.8 0 3 1 3.8 2.5 1.8-.8 2.2-2.1 3.2-3.7a15.5 15.5 0 0 0 1.4-13.3c-.4-1.5-.6-2.5-1.8-3.7-1 1-2 1.4-3.4 1.4-2.9 0-5-2.5-5-5.3a4.8 4.8 0 0 1 3-4.6c-1.6-1.4-3-1.5-4.7-2.6-2.6-1.6-3.5-3.4-5.2-6-1.2-1.6-1.5-2.8-2-4.7a19 19 0 0 1-1-7.8c.6-5 1.5-8 4.6-11.9 1.8-2.3 3-3.7 5.8-4.9 2.3-1 3.7-1.7 6.2-1.7l2 .1a6.9 6.9 0 0 1 2.8.8c.4.2 1.1.9 1.1.4s-.3-.8-.3-1.3c0-2 1.5-4 3.6-4 1.5 0 2.1 1.4 2.9 2.7.4-.8.7-1.4.7-2.3 0-3.4-1.9-5.2-4-7.9-4.7-5.8-10.5-8.5-10.5-16 0-2.2 1-3.7 3-4.9.5-.3 1.3 0 1.8-.3s.4-1 .7-1.4c.5-.7 1-1 1.6-1.6 1-1 2-.6 3.1-1.5.6-.4.8-1 1.2-1.4 1.3-1.6 2.5-2.4 4.6-2.4 1 0 1.6 0 2.5.4l1 .5c.3-.2.8-.8 1.5-1.1a4 4 0 0 1 2.2-.6c1.1 0 1.8.6 3 .6.3 0 .4-.4.8-.6 1-.7 1.5-1 2.7-1 1.2 0 1.8.3 2.8 1 1 .5 1 1.3 2 1.8.5.3 1 .2 1.5.4 2.6.9 4.5 2.6 4.5 5.3 0 1.5-.3 2.5-1.4 3.5-.9.7-1.7.6-2.8 1a16 16 0 0 0 11.3 3.5c4.2 0 9.3-1.7 9.3-5.9 0-2-1-3-1.8-4.8a18.8 18.8 0 0 1-2.1-8.5c0-2.8.3-4.5 1.9-6.7 1.6-2.3 3.6-2.9 6.5-2.9"/>
|
||||||
<g fill="none" stroke="#703d29">
|
<g fill="none" stroke="#703d29">
|
||||||
<path stroke-linejoin="round" stroke-width=".7" d="M272.4 159a3.6 3.6 0 0 0 2.4 2.4c.8.3 2.7.2 3.8-1.4 1-1.2 1-2.8.6-4a4.7 4.7 0 0 0-1.7-2.2l-5.1 5.2z"/>
|
<path stroke-linejoin="round" stroke-width=".7" d="M272.4 159a3.6 3.6 0 0 0 2.4 2.4c.8.3 2.7.2 3.8-1.4 1-1.2 1-2.8.6-4a4.7 4.7 0 0 0-1.7-2.2z"/>
|
||||||
<path stroke-linecap="round" stroke-width=".7" d="M401 236.1c-1.2-2.9-4.3-1.6-4.4 0-.5 3.7 2.7 4.8 5 4.2a4 4 0 0 0 2.5-2c.6-1 .8-2.4.4-3.7a4.9 4.9 0 0 0-.8-1.6 5 5 0 0 0-1.3-1.2c-.9-.6-1.9-.6-3.4-.6-5.5 0-10.4 6.5-12 13.4-.6 2.2-1.3 7.3-.3 12a22.4 22.4 0 0 0 5.9 11.3 25.7 25.7 0 0 0 9.9 5.8 7.9 7.9 0 0 0 4 .1c3.2-.7 4.7-3.8 3-7-1.3-2.5-5.3-4-7.2-.6-.1.3-.4.9-.4 1.5 0 .9.4 2 1 2.4 1.5.9 3.8.6 3.7-2"/>
|
<path stroke-linecap="round" stroke-width=".7" d="M401 236.1c-1.2-2.9-4.3-1.6-4.4 0-.5 3.7 2.7 4.8 5 4.2a4 4 0 0 0 2.5-2c.6-1 .8-2.4.4-3.7a4.9 4.9 0 0 0-.8-1.6 5 5 0 0 0-1.3-1.2c-.9-.6-1.9-.6-3.4-.6-5.5 0-10.4 6.5-12 13.4-.6 2.2-1.3 7.3-.3 12a22.4 22.4 0 0 0 5.9 11.3 25.7 25.7 0 0 0 9.9 5.8 7.9 7.9 0 0 0 4 .1c3.2-.7 4.7-3.8 3-7-1.3-2.5-5.3-4-7.2-.6-.1.3-.4.9-.4 1.5 0 .9.4 2 1 2.4 1.5.9 3.8.6 3.7-2"/>
|
||||||
<path stroke-width=".8" d="M383.8 274a11.3 11.3 0 0 1 6.6-3.7c3-.4 5.6.5 8.2 2a18.5 18.5 0 0 1 10.8 17c0 3.6-1 7.5-2 9.4-.8 1.7-3 9-15.3 14-7.1 3-18 3.6-25.7 4-10.4.3-20 .7-25.5 7.6"/>
|
<path stroke-width=".8" d="M383.8 274a11.3 11.3 0 0 1 6.6-3.7c3-.4 5.6.5 8.2 2a18.5 18.5 0 0 1 10.8 17c0 3.6-1 7.5-2 9.4-.8 1.7-3 9-15.3 14-7.1 3-18 3.6-25.7 4-10.4.3-20 .7-25.5 7.6"/>
|
||||||
<g stroke-width=".7">
|
<g stroke-width=".7">
|
||||||
<path d="M386.4 285.7c-.3-1 0-2.1.8-3.3 1.2-1.6 3.7-2.1 6-1a7.4 7.4 0 0 1 2.5 2.2l1.1 1.6c.7 1.1 1 2 1 2.5 2.5 7-1.4 14.5-6.5 17.6-4 2.4-8.7 3.4-14.4 4-2.5.4-4 .3-6.5.5h-9.6a70.1 70.1 0 0 0-7.2 0c-2.9.3-5 .4-7.6.8-1.6.2-3.4.5-5.4 1-.6 0-1.2.2-1.8.4l-1.2.3c-3.6 1.1-7 2.4-9.8 4.2-.8.5-1.8 1-2.5 1.7l-1.3 1.2c-2 2-3.9 4-4.4 6.7v1.6c0 1.8 1.4 4.3 5.4 5m5.5-170c.8 1.4 1.3 2.3.8 3.9-.6 1.7-1.8 2.8-3.6 2.8-4 0-6.3-4.8-4.5-7.8 3.2-5.3 9.3-2.3 15 .3-.3-1.3-.8-1.8-.7-3.5.1-4.2 3.2-6 4.5-10 .7-2.3 1-4.3-.7-6-1.5-1.3-3.2-1.3-5.1-.6-3.8 1.5-8.5 5.9-16.6 6-8.2-.1-12.8-4.5-16.7-6-2-.7-3.6-.7-5.1.7-1.7 1.6-1.4 3.6-.7 6 1.3 3.8 4.4 5.7 4.5 10 0 1.6-.4 2-.7 3.4 5.7-2.6 12-5.9 15-.3 1.7 3.2-.5 7.7-4.5 7.7-1.8 0-3-1-3.6-2.7-.4-1.5 0-2.8.8-4"/>
|
<path d="M386.4 285.7c-.3-1 0-2.1.8-3.3 1.2-1.6 3.7-2.1 6-1a7.4 7.4 0 0 1 2.5 2.2l1.1 1.6c.7 1.1 1 2 1 2.5 2.5 7-1.4 14.5-6.5 17.6-4 2.4-8.7 3.4-14.4 4-2.5.4-4 .3-6.5.5h-9.6a70.1 70.1 0 0 0-7.2 0c-2.9.3-5 .4-7.6.8-1.6.2-3.4.5-5.4 1-.6 0-1.2.2-1.8.4l-1.2.3c-3.6 1.1-7 2.4-9.8 4.2-.8.5-1.8 1-2.5 1.7l-1.3 1.2c-2 2-3.9 4-4.4 6.7v1.6c0 1.8 1.4 4.3 5.4 5m5.5-170c.8 1.4 1.3 2.3.8 3.9-.6 1.7-1.8 2.8-3.6 2.8-4 0-6.3-4.8-4.5-7.8 3.2-5.3 9.3-2.3 15 .3-.3-1.3-.8-1.8-.7-3.5.1-4.2 3.2-6 4.5-10 .7-2.3 1-4.3-.7-6-1.5-1.3-3.2-1.3-5.1-.6-3.8 1.5-8.5 5.9-16.6 6-8.2-.1-12.8-4.5-16.7-6-2-.7-3.6-.7-5.1.7-1.7 1.6-1.4 3.6-.7 6 1.3 3.8 4.4 5.7 4.5 10 0 1.6-.4 2-.7 3.4 5.7-2.6 12-5.9 15-.3 1.7 3.2-.5 7.7-4.5 7.7-1.8 0-3-1-3.6-2.7-.4-1.5 0-2.8.8-4"/>
|
||||||
<path stroke-linecap="round" d="M314.6 159.9a5.3 5.3 0 0 1 2.4 5c-.2 2.5-.8 3.1-2.8 4.5m2.4-3.8c-.1 1.5-.7 2.5-2.3 3.1"/>
|
<path stroke-linecap="round" d="M314.6 159.9a5.3 5.3 0 0 1 2.4 5c-.2 2.5-.8 3.1-2.8 4.5m2.4-3.8c-.1 1.5-.7 2.5-2.3 3.1"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#c7b37f" stroke="none" d="m276.7 153.3.7.5.8.8.5 1 .2.8v1.9l-.2.8-.5.6-.6.6-.9.5-1 .2-1 .2-1-.5-.9-.6-.5-.8-.4-1v-.4l4.8-4.6z"/>
|
<path fill="#c7b37f" stroke="none" d="m276.7 153.3.7.5.8.8.5 1 .2.8v1.9l-.2.8-.5.6-.6.6-.9.5-1 .2-1 .2-1-.5-.9-.6-.5-.8-.4-1v-.4z"/>
|
||||||
<path stroke-linecap="round" stroke-width=".7" d="M275.2 157.2c-.3-1.7-2.2-2-3-1-1.1 1.5-.3 4 2 4.7a4 4 0 0 0 3.9-1.4c1-1.3.9-2.8.5-4a4.5 4.5 0 0 0-1.7-2.2c-2.7-2-7.1-1.6-8.6 2-1.8 4.4 2.2 7.8 6 10.3 4.6 3.2 10 3.8 14 3.8 9.2-.1 16.2-4.5 20.7-7 1-.6 2.1-.5 2.7.2a2 2 0 0 1-.3 2.7"/>
|
<path stroke-linecap="round" stroke-width=".7" d="M275.2 157.2c-.3-1.7-2.2-2-3-1-1.1 1.5-.3 4 2 4.7a4 4 0 0 0 3.9-1.4c1-1.3.9-2.8.5-4a4.5 4.5 0 0 0-1.7-2.2c-2.7-2-7.1-1.6-8.6 2-1.8 4.4 2.2 7.8 6 10.3 4.6 3.2 10 3.8 14 3.8 9.2-.1 16.2-4.5 20.7-7 1-.6 2.1-.5 2.7.2a2 2 0 0 1-.3 2.7"/>
|
||||||
<path stroke-width=".7" d="m248 281.2-2 .7-2 1.6-1 1.3-1.1 2-.5 1.5-.4 1.8-.2 1.4m19-10.1-.1 1.8-.3 1.2-1 2.2-1.3 1.8-1.5 1.2-1.1.5-1.6.4"/>
|
<path stroke-width=".7" d="m248 281.2-2 .7-2 1.6-1 1.3-1.1 2-.5 1.5-.4 1.8-.2 1.4m19-10.1-.1 1.8-.3 1.2-1 2.2-1.3 1.8-1.5 1.2-1.1.5-1.6.4"/>
|
||||||
<path stroke-width=".8" d="M319.7 329.1c-.3 1.7-1.9 3.6-5.3 4.2l-.6.2"/>
|
<path stroke-width=".8" d="M319.7 329.1c-.3 1.7-1.9 3.6-5.3 4.2l-.6.2"/>
|
||||||
|
@ -96,11 +96,11 @@
|
||||||
<path d="M245.7 198.5c-2-1.9-6-2.4-10.1.2L234 200a8.8 8.8 0 0 0-1.4 1.6 17.5 17.5 0 0 0-2.4 5c-.7 3-.7 5.6-.6 6.3 0 1 .2 1.9.3 2.7.6 2.8 1.4 4.8 2.3 6.2.9 1.5 3 5 7.7 5.4 1.8.1 4.8-.7 5-3"/>
|
<path d="M245.7 198.5c-2-1.9-6-2.4-10.1.2L234 200a8.8 8.8 0 0 0-1.4 1.6 17.5 17.5 0 0 0-2.4 5c-.7 3-.7 5.6-.6 6.3 0 1 .2 1.9.3 2.7.6 2.8 1.4 4.8 2.3 6.2.9 1.5 3 5 7.7 5.4 1.8.1 4.8-.7 5-3"/>
|
||||||
<path stroke-linecap="round" d="M363.8 157c.3-1.6 2.3-1.9 3-1 1.2 1.6.4 4.2-2 4.9a4 4 0 0 1-3.8-1.4c-1-1.3-.9-2.8-.5-4 .2-.8.9-1.5 1.7-2.2 2.7-2 7.1-1.6 8.6 2 1.8 4.4-2.2 7.8-6 10.3-4.6 3.2-10 3.8-14 3.7-9.2 0-16.1-4.4-20.7-7-1-.5-2.1-.4-2.7.3a2 2 0 0 0 .3 2.7"/>
|
<path stroke-linecap="round" d="M363.8 157c.3-1.6 2.3-1.9 3-1 1.2 1.6.4 4.2-2 4.9a4 4 0 0 1-3.8-1.4c-1-1.3-.9-2.8-.5-4 .2-.8.9-1.5 1.7-2.2 2.7-2 7.1-1.6 8.6 2 1.8 4.4-2.2 7.8-6 10.3-4.6 3.2-10 3.8-14 3.7-9.2 0-16.1-4.4-20.7-7-1-.5-2.1-.4-2.7.3a2 2 0 0 0 .3 2.7"/>
|
||||||
<path stroke-linecap="round" d="M365.6 155.5c1 0 1.2.4 1.5.8 1.2 1.5.3 4.1-2 4.9m17.8 51.5c-3.5 3.8-.2 10.3 2.4 11.8.9.7 1.3.3 2 .7"/>
|
<path stroke-linecap="round" d="M365.6 155.5c1 0 1.2.4 1.5.8 1.2 1.5.3 4.1-2 4.9m17.8 51.5c-3.5 3.8-.2 10.3 2.4 11.8.9.7 1.3.3 2 .7"/>
|
||||||
<path d="M383.1 205.4c-1.1.8-1.5 1.7-1.6 3.3a5.3 5.3 0 0 0 1.4 4 14 14 0 0 0 9.3 3.7c2 0 4-.4 6-1.7a9 9 0 0 0 3.8-5.4m-20.8 61.8-.2 2.5a18.9 18.9 0 0 1-2 7 18.7 18.7 0 0 1-4.2 5.6 19.6 19.6 0 0 1-5.9 4 24.6 24.6 0 0 1-6.5 2.3 43.8 43.8 0 0 1-13.2.6c-2.7-.2-4.1-.5-6.8-.8-2.2-.1-3.4-.3-5.6-.3a28.3 28.3 0 0 0-10.9 1.9c-2.7 1-5.7 3-6.4 3.8-.6-.9-3.7-2.8-6.3-3.8a22 22 0 0 0-5.2-1.5c-2.2-.4-3.5-.4-5.8-.4-2.2 0-3.4.2-5.6.4-2.6.2-4 .6-6.7.7-2.5.2-3.9.3-6.3.2a33 33 0 0 1-7-.8 24.6 24.6 0 0 1-6.5-2.2 19.6 19.6 0 0 1-5.8-4.1 18.7 18.7 0 0 1-4.2-5.7 19 19 0 0 1-2-6.9c-.2-1-.2-2.5-.2-2.5V169.3h123.2v101.8z"/>
|
<path d="M383.1 205.4c-1.1.8-1.5 1.7-1.6 3.3a5.3 5.3 0 0 0 1.4 4 14 14 0 0 0 9.3 3.7c2 0 4-.4 6-1.7a9 9 0 0 0 3.8-5.4m-20.8 61.8-.2 2.5a18.9 18.9 0 0 1-2 7 18.7 18.7 0 0 1-4.2 5.6 19.6 19.6 0 0 1-5.9 4 24.6 24.6 0 0 1-6.5 2.3 43.8 43.8 0 0 1-13.2.6c-2.7-.2-4.1-.5-6.8-.8-2.2-.1-3.4-.3-5.6-.3a28.3 28.3 0 0 0-10.9 1.9c-2.7 1-5.7 3-6.4 3.8-.6-.9-3.7-2.8-6.3-3.8a22 22 0 0 0-5.2-1.5c-2.2-.4-3.5-.4-5.8-.4-2.2 0-3.4.2-5.6.4-2.6.2-4 .6-6.7.7-2.5.2-3.9.3-6.3.2a33 33 0 0 1-7-.8 24.6 24.6 0 0 1-6.5-2.2 19.6 19.6 0 0 1-5.8-4.1 18.7 18.7 0 0 1-4.2-5.7 19 19 0 0 1-2-6.9c-.2-1-.2-2.5-.2-2.5V169.3h123.2z"/>
|
||||||
</g>
|
</g>
|
||||||
<g fill="#c7b37f" stroke="#c7b37f">
|
<g fill="#c7b37f" stroke="#c7b37f">
|
||||||
<path stroke-width=".3" d="M248 285.6a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0zM232.5 268c0-1.3.8-2.3 1.8-2.3s1.7 1 1.7 2.3c0 1.2-.8 2.2-1.7 2.2-1 0-1.8-1-1.8-2.2z"/>
|
<path stroke-width=".3" d="M248 285.6a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0zM232.5 268c0-1.3.8-2.3 1.8-2.3s1.7 1 1.7 2.3c0 1.2-.8 2.2-1.7 2.2-1 0-1.8-1-1.8-2.2z"/>
|
||||||
<path stroke="none" d="M241.3 223.6c0-1 .8-1.8 1.7-1.8 1 0 1.7.8 1.7 1.8s-.7 1.8-1.7 1.8-1.7-.8-1.7-1.8zM272 158c0-1 .5-2 1.4-2 .9-.1 1.7.6 1.8 1.6 0 1-.5 2-1.4 2-.9.1-1.6-.6-1.8-1.6z"/>
|
<path stroke="none" d="M241.3 223.6c0-1 .8-1.8 1.7-1.8 1 0 1.7.8 1.7 1.8s-.7 1.8-1.7 1.8-1.7-.8-1.7-1.8M272 158c0-1 .5-2 1.4-2 .9-.1 1.7.6 1.8 1.6 0 1-.5 2-1.4 2-.9.1-1.6-.6-1.8-1.6"/>
|
||||||
</g>
|
</g>
|
||||||
<g stroke="#c7b37f" stroke-linecap="round" stroke-width=".6">
|
<g stroke="#c7b37f" stroke-linecap="round" stroke-width=".6">
|
||||||
<path d="M239.3 234c-.4.1-.6.2-.8.5-.3.3-.4.4-.6.9l-.2 1.2m4.7 26.7 1-1 .6-1 .5-1 .7-1.3m-1.3 14-1.5.7-1.1.6a17.4 17.4 0 0 0-1.3.8l-1.2 1m15-37.9-.8-.8-1-.8-.9-.8"/>
|
<path d="M239.3 234c-.4.1-.6.2-.8.5-.3.3-.4.4-.6.9l-.2 1.2m4.7 26.7 1-1 .6-1 .5-1 .7-1.3m-1.3 14-1.5.7-1.1.6a17.4 17.4 0 0 0-1.3.8l-1.2 1m15-37.9-.8-.8-1-.8-.9-.8"/>
|
||||||
|
@ -110,17 +110,17 @@
|
||||||
<path fill="#703d29" stroke-width=".2" d="M333.3 151.6c0-1.7-1.7-1.8-2.4-1.8-1.8 0-2.3 1.1-4.6 2.3a11.9 11.9 0 0 1-6.7 2 12 12 0 0 1-6.7-2c-2.3-1.2-2.7-2.3-4.6-2.3a2.3 2.3 0 0 0-2.2 2.4v.9l.3.2c0-.8.1-1.2.5-1.7a2.2 2.2 0 0 1 1.6-.8c1.8 0 2.5 1.2 4.8 2.4 3 1.6 4.2 1.9 6.7 2a12 12 0 0 0 6.8-2c2.3-1.2 3-2.5 4.8-2.5.6 0 1 .4 1.3 1v.9l.2.1c0-.3.2-.4.2-1z"/>
|
<path fill="#703d29" stroke-width=".2" d="M333.3 151.6c0-1.7-1.7-1.8-2.4-1.8-1.8 0-2.3 1.1-4.6 2.3a11.9 11.9 0 0 1-6.7 2 12 12 0 0 1-6.7-2c-2.3-1.2-2.7-2.3-4.6-2.3a2.3 2.3 0 0 0-2.2 2.4v.9l.3.2c0-.8.1-1.2.5-1.7a2.2 2.2 0 0 1 1.6-.8c1.8 0 2.5 1.2 4.8 2.4 3 1.6 4.2 1.9 6.7 2a12 12 0 0 0 6.8-2c2.3-1.2 3-2.5 4.8-2.5.6 0 1 .4 1.3 1v.9l.2.1c0-.3.2-.4.2-1z"/>
|
||||||
</g>
|
</g>
|
||||||
<g fill="#703d29">
|
<g fill="#703d29">
|
||||||
<path d="M264.4 294c.5-.5.9-.3 1-.6 0-.2 0-.2-.3-.3l-.9-.2-.8-.4c-.1 0-.4-.2-.5 0-.1.4 1 .4.6 1.4a3.7 3.7 0 0 1-.8 1.2l-2.6 3-.2.1v-4.3l.1-1.8c.2-.4.8 0 .9-.4 0-.1 0-.2-.3-.3-.2 0-.5 0-1.1-.3l-1-.5c-.2 0-.5-.2-.6 0l.1.3c.4.2.5.4.5 1v7.4c0 .5.1.6.2.7.1 0 .2 0 .4-.3l5.3-5.7z"/>
|
<path d="M264.4 294c.5-.5.9-.3 1-.6 0-.2 0-.2-.3-.3l-.9-.2-.8-.4c-.1 0-.4-.2-.5 0-.1.4 1 .4.6 1.4a3.7 3.7 0 0 1-.8 1.2l-2.6 3-.2.1v-4.3l.1-1.8c.2-.4.8 0 .9-.4 0-.1 0-.2-.3-.3-.2 0-.5 0-1.1-.3l-1-.5c-.2 0-.5-.2-.6 0l.1.3c.4.2.5.4.5 1v7.4c0 .5.1.6.2.7.1 0 .2 0 .4-.3z"/>
|
||||||
<path d="M267.5 295.2c.3-1.1 1-.4 1-.8.1-.2 0-.2-.2-.3l-1.3-.4c-.4 0-.8-.3-1.2-.4 0 0-.3-.1-.4 0-.1.5 1.1.5.8 1.5l-1.7 5.5c-.3 1-1 .6-1.1 1v.1l1.2.4 1.6.5h.3c.2-.4-1.2-.3-.7-1.7l1.7-5.4zm3.7 1c.2-.6.5-.5.9-.4 1 .3 1.4 1.3 1 2.5-.2.6-.4 1.2-2 .8-.3-.1-.7-.2-.6-.5l.7-2.3zm-2.8 5c-.5 1.4-1.2.8-1.3 1.2 0 .2.2.2.3.3l1.6.4.8.3h.4c.1-.5-1-.3-.7-1.5l.6-2c.1-.4.1-.5.6-.3.6.1.7.3.8.8l.3 2c.2.9.3 1.7 1 2 .5 0 1.2 0 1.4-.4l-.2-.2h-.3s-.3 0-.3-.3l-.7-3.6c0-.2.4-.2.8-.3a2 2 0 0 0 1-1.3c.1-.5.4-2.2-1.8-2.9l-2.1-.5-1.2-.4h-.3c-.1.5 1.1.4.7 1.7l-1.5 5zm8.4 2.5c-.4 1.4-1.4.5-1.5 1 0 .2.1.3.3.3l1.5.3 1.4.4c.3 0 .5.2.6-.1 0-.3-1.3-.3-1-1.8l1.3-5.2c0-.6.2-.6.6-.5l1 .2c1.1.3.5 1.5 1 1.6.2 0 .2-.4.2-.6l.1-1v-.4l-3.3-.7-3.2-.8c-.1 0-.2 0-.2.2l-.5 1.5c-.1.1-.2.4 0 .4.5.1.5-1.5 1.7-1.2l.9.2c.4.1.5.2.4.8l-1.3 5.4zm12.7-3.3c.4-.6.8-.5.9-.7 0-.2-.2-.2-.4-.3h-.9l-.9-.3c-.1 0-.4-.1-.4.1-.1.4 1 .2.8 1.3 0 .2-.1.6-.6 1.3l-2 3.3-.3.2v-.2l-.7-4a5.4 5.4 0 0 1-.1-1.8c0-.5.7-.2.7-.5 0-.2 0-.2-.4-.3l-1.1-.1c-.4 0-.7-.2-1-.3-.2 0-.5-.1-.6.1l.1.2c.5.2.6.4.7.9l1.3 7.3c.1.5.2.7.3.7.1 0 .2 0 .4-.3l4.2-6.6zm.6 6.8c0 .3 0 .3.2.5.6.2 1 .6 1.7.7 1.4.2 2.6-.7 2.8-2.2.3-1.5-.3-2.1-1.4-2.9-1.3-.9-1.8-1.1-1.7-2 .1-.7.7-1 1.4-1 1.8.3 1.6 2.6 1.8 2.6.3 0 .3-.1.3-.4l.2-1.6v-.4h-.6c-.4 0-.7-.5-1.6-.7-1.2-.2-2.3.7-2.5 2-.2 1.2.4 1.8 1.2 2.4 1.6 1.1 2.2 1.4 2 2.4-.1 1-.9 1.4-1.7 1.3-1.2-.2-1.6-1.4-1.8-2.6 0-.2 0-.3-.2-.3s-.2.3-.2.5v1.7zm15.8-4.5c.3-.7.8-.6.8-.9 0-.2-.1-.1-.4-.2h-.9l-.9-.1c-.1 0-.4 0-.4.2 0 .4 1 0 1 1.1 0 .2-.1.6-.5 1.4l-1.8 3.5-.1.3-.1-.3-1.1-4a5.4 5.4 0 0 1-.3-1.6c0-.5.7-.3.7-.6 0-.2 0-.2-.4-.2h-1.2l-1-.2c-.2 0-.5-.1-.6.1l.2.2c.4.2.6.3.7.8l2.1 7.1.4.7c.1 0 .2 0 .3-.4l3.5-7z"/>
|
<path d="M267.5 295.2c.3-1.1 1-.4 1-.8.1-.2 0-.2-.2-.3l-1.3-.4c-.4 0-.8-.3-1.2-.4 0 0-.3-.1-.4 0-.1.5 1.1.5.8 1.5l-1.7 5.5c-.3 1-1 .6-1.1 1v.1l1.2.4 1.6.5h.3c.2-.4-1.2-.3-.7-1.7zm3.7 1c.2-.6.5-.5.9-.4 1 .3 1.4 1.3 1 2.5-.2.6-.4 1.2-2 .8-.3-.1-.7-.2-.6-.5l.7-2.3zm-2.8 5c-.5 1.4-1.2.8-1.3 1.2 0 .2.2.2.3.3l1.6.4.8.3h.4c.1-.5-1-.3-.7-1.5l.6-2c.1-.4.1-.5.6-.3.6.1.7.3.8.8l.3 2c.2.9.3 1.7 1 2 .5 0 1.2 0 1.4-.4l-.2-.2h-.3s-.3 0-.3-.3l-.7-3.6c0-.2.4-.2.8-.3a2 2 0 0 0 1-1.3c.1-.5.4-2.2-1.8-2.9l-2.1-.5-1.2-.4h-.3c-.1.5 1.1.4.7 1.7zm8.4 2.5c-.4 1.4-1.4.5-1.5 1 0 .2.1.3.3.3l1.5.3 1.4.4c.3 0 .5.2.6-.1 0-.3-1.3-.3-1-1.8l1.3-5.2c0-.6.2-.6.6-.5l1 .2c1.1.3.5 1.5 1 1.6.2 0 .2-.4.2-.6l.1-1v-.4l-3.3-.7-3.2-.8c-.1 0-.2 0-.2.2l-.5 1.5c-.1.1-.2.4 0 .4.5.1.5-1.5 1.7-1.2l.9.2c.4.1.5.2.4.8zm12.7-3.3c.4-.6.8-.5.9-.7 0-.2-.2-.2-.4-.3h-.9l-.9-.3c-.1 0-.4-.1-.4.1-.1.4 1 .2.8 1.3 0 .2-.1.6-.6 1.3l-2 3.3-.3.2v-.2l-.7-4a5.4 5.4 0 0 1-.1-1.8c0-.5.7-.2.7-.5 0-.2 0-.2-.4-.3l-1.1-.1c-.4 0-.7-.2-1-.3-.2 0-.5-.1-.6.1l.1.2c.5.2.6.4.7.9l1.3 7.3c.1.5.2.7.3.7.1 0 .2 0 .4-.3zm.6 6.8c0 .3 0 .3.2.5.6.2 1 .6 1.7.7 1.4.2 2.6-.7 2.8-2.2.3-1.5-.3-2.1-1.4-2.9-1.3-.9-1.8-1.1-1.7-2 .1-.7.7-1 1.4-1 1.8.3 1.6 2.6 1.8 2.6.3 0 .3-.1.3-.4l.2-1.6v-.4h-.6c-.4 0-.7-.5-1.6-.7-1.2-.2-2.3.7-2.5 2-.2 1.2.4 1.8 1.2 2.4 1.6 1.1 2.2 1.4 2 2.4-.1 1-.9 1.4-1.7 1.3-1.2-.2-1.6-1.4-1.8-2.6 0-.2 0-.3-.2-.3s-.2.3-.2.5v1.7zm15.8-4.5c.3-.7.8-.6.8-.9 0-.2-.1-.1-.4-.2h-.9l-.9-.1c-.1 0-.4 0-.4.2 0 .4 1 0 1 1.1 0 .2-.1.6-.5 1.4l-1.8 3.5-.1.3-.1-.3-1.1-4a5.4 5.4 0 0 1-.3-1.6c0-.5.7-.3.7-.6 0-.2 0-.2-.4-.2h-1.2l-1-.2c-.2 0-.5-.1-.6.1l.2.2c.4.2.6.3.7.8l2.1 7.1.4.7c.1 0 .2 0 .3-.4z"/>
|
||||||
<path d="M307.6 308.5c0 1.2-1 1-1 1.5 0 .2.1.1.3.1h2.2l.4-.1c0-.6-1.4.2-1.4-2v-4.2l.1-.1.2.1 5.1 6.3.3.1.2-.3v-6.7c0-1.3 1-1 1-1.3 0 0 0-.2-.3-.2h-2.3c-.2 0-.2.1-.2.2 0 .4 1.3.2 1.3 1.3v4l-.1.4-.4-.3-4.2-5.3c-.2-.3-.1-.3-.4-.3h-1.8l-.2.1c0 .6 1.2-.2 1.2 2.1v4.6zM318 303c0-1.1.8-.7.8-1.1 0-.1 0-.2-.4-.2h-2.6s-.3 0-.3.2c0 .4 1.1 0 1.1 1.2v5.7c0 1.1-.8.8-.8 1.2 0 0 0 .2.2.2h2.8c.2 0 .3 0 .3-.2 0-.4-1.2.2-1.2-1.3l.1-5.7zm4.5 5.5c0 1.5-1.2 1-1.2 1.4 0 .2.2.2.4.2h3c.3 0 .5 0 .5-.3s-1.4 0-1.4-1.4V303c0-.6 0-.6.5-.6h1c1.2-.1.8 1.2 1.3 1.2.2 0 .1-.4.1-.6l-.1-1c0-.2 0-.4-.2-.4l-3.3.1h-3.3l-.2.3-.1 1.6.1.4c.5 0 .2-1.6 1.4-1.6h.9c.4 0 .5 0 .6.6v5.6zm6.3-2.2h-.4l.1-.5.7-2.2v-.2l.2.1 1 2.1.2.4c0 .2-.2.2-.4.2h-1.4zm1.8.5c.3 0 .3 0 .8 1l.2.8c0 .7-.7.6-.7 1 0 .1.2.1.4 0h1.2l1.3-.1c.3 0 .4 0 .4-.2 0-.4-.6 0-1-.7l-3.4-7-.3-.4c-.2 0-.2.2-.3.4L327 309c-.2.7-.8.7-.7 1h2.3c.2-.1.5 0 .5-.3s-1.2 0-1.3-.9l.2-1c.2-.8.4-.8.6-.8l2.1-.2zm8.3-5c-.1-.8 0-.8 1.2-1 2-.2 1.4 1.3 2 1.2.2 0 0-.4 0-.6l-.1-1.1c0-.1-.1-.2-.3-.2-1 0-1.7.2-2.4.3l-2.8.4c-.2 0-.3 0-.3.2.1.5 1.3 0 1.4 1l.7 5.5c.2 1.5-.7 1-.6 1.5 0 0 0 .1.2 0l1.4-.1 1.2-.1c.3 0 .5 0 .5-.3s-1.2.1-1.4-1.2l-.2-1.7c-.1-.7-.1-.9.3-1h.8c1.1-.2 1 1.1 1.3 1 .3 0 .2-.4.1-.5l-.3-2.1c0-.3-.2-.3-.2-.3-.3 0-.1 1.1-1 1.2l-.7.1c-.5.1-.5 0-.6-.5l-.2-1.7zm4 2.8c.4 2.3 2.1 3.7 4.2 3.3 3.4-.7 3.5-3.6 3.2-5.3-.5-2.5-2.3-3.7-4.4-3.3-2.5.5-3.5 2.7-3 5.3zm1.1-1c-.3-1.6 0-3.4 1.7-3.7 1.4-.3 3 .8 3.4 3.4.3 2 0 3.6-1.8 4-1.9.4-3-2-3.3-3.6zm8.3-4.1c-.1-.7.2-.8.6-.9 1-.2 1.8.5 2.1 1.6.2.7.3 1.4-1.3 1.8-.3 0-.7.1-.8-.2l-.5-2.3zm0 5.7c.4 1.4-.5 1.3-.5 1.6.1.3.3.2.4.1.6 0 1-.3 1.6-.4l1-.2c.2 0 .2-.1.2-.2 0-.4-1 .3-1.3-1l-.5-2c0-.4-.2-.4.4-.5.5-.2.7-.1 1.1.3l1.3 1.6c.5.6 1 1.3 1.8 1.1.5-.1 1-.5 1-.9l-.2-.1-.3.1s-.3.1-.4 0l-2.4-2.9.5-.6c.2-.4.4-.9.2-1.6-.1-.5-.7-2.1-3-1.6l-2.1.6-1.2.2c-.2 0-.3.1-.2.2 0 .5 1.1-.2 1.4 1l1.2 5.2zm8.7-2c.3 1.4-1 1.2-.9 1.6 0 .3.3.2.5.2l1.4-.5 1.5-.3c.3 0 .5 0 .4-.4 0-.3-1.3.4-1.7-1l-1.3-5.3c-.2-.5 0-.6.3-.7l1-.2c1.1-.4 1.1 1 1.5.9.3 0 0-.5 0-.7l-.4-1s0-.3-.2-.2l-3.2.9-3.2.7v.3l.1 1.6c0 .2 0 .4.3.4.5-.1-.3-1.6 1-1.9l.8-.2c.4-.1.6 0 .7.5l1.4 5.3zm5.5-7.3c-.3-1 .6-.9.4-1.3h-.3l-1.4.4-1.2.3s-.3 0-.3.2c.1.4 1.2-.2 1.5.8l1.6 5.6c.2 1-.6 1-.5 1.3 0 .1 0 .2.2.1l1.1-.3 1.6-.4c.3 0 .3-.1.3-.3-.1-.3-1.1.5-1.5-.9l-1.5-5.5zm2.3 2.7c.7 2.3 2.6 3.4 4.7 2.7 3.2-1.1 3-4.1 2.4-5.7-.8-2.4-2.8-3.3-4.8-2.7-2.4.9-3.2 3.2-2.3 5.7zm1-1c-.6-1.7-.6-3.5 1.1-4 1.3-.5 3 .4 3.9 2.9.6 1.8.5 3.6-1.2 4.2-1.8.6-3.2-1.5-3.8-3.2zm7.6-5.5c-.2-.7 0-.8.4-1 1-.3 2 .3 2.4 1.4.2.6.4 1.3-1.1 1.9-.3 0-.7.2-.8 0l-.9-2.3zm.8 5.6c.6 1.4-.4 1.4-.2 1.7 0 .3.2.1.4.1l1.5-.7.9-.2c.2-.1.2-.2.2-.3-.2-.4-1 .4-1.4-.8l-.8-1.9c-.2-.4-.2-.5.3-.7.5-.2.7-.1 1.1.3l1.6 1.4c.5.5 1.1 1.1 2 .8.3-.2.9-.7.7-1l-.2-.1-.2.2h-.5l-2.8-2.5.4-.7a2 2 0 0 0 0-1.6c-.1-.6-1-2-3.1-1.2l-2 .9-1.2.4-.2.2c.2.4 1.1-.4 1.6.8l2 5z"/>
|
<path d="M307.6 308.5c0 1.2-1 1-1 1.5 0 .2.1.1.3.1h2.2l.4-.1c0-.6-1.4.2-1.4-2v-4.2l.1-.1.2.1 5.1 6.3.3.1.2-.3v-6.7c0-1.3 1-1 1-1.3 0 0 0-.2-.3-.2h-2.3c-.2 0-.2.1-.2.2 0 .4 1.3.2 1.3 1.3v4l-.1.4-.4-.3-4.2-5.3c-.2-.3-.1-.3-.4-.3h-1.8l-.2.1c0 .6 1.2-.2 1.2 2.1zM318 303c0-1.1.8-.7.8-1.1 0-.1 0-.2-.4-.2h-2.6s-.3 0-.3.2c0 .4 1.1 0 1.1 1.2v5.7c0 1.1-.8.8-.8 1.2 0 0 0 .2.2.2h2.8c.2 0 .3 0 .3-.2 0-.4-1.2.2-1.2-1.3zm4.5 5.5c0 1.5-1.2 1-1.2 1.4 0 .2.2.2.4.2h3c.3 0 .5 0 .5-.3s-1.4 0-1.4-1.4V303c0-.6 0-.6.5-.6h1c1.2-.1.8 1.2 1.3 1.2.2 0 .1-.4.1-.6l-.1-1c0-.2 0-.4-.2-.4l-3.3.1h-3.3l-.2.3-.1 1.6.1.4c.5 0 .2-1.6 1.4-1.6h.9c.4 0 .5 0 .6.6v5.6zm6.3-2.2h-.4l.1-.5.7-2.2v-.2l.2.1 1 2.1.2.4c0 .2-.2.2-.4.2zm1.8.5c.3 0 .3 0 .8 1l.2.8c0 .7-.7.6-.7 1 0 .1.2.1.4 0h1.2l1.3-.1c.3 0 .4 0 .4-.2 0-.4-.6 0-1-.7l-3.4-7-.3-.4c-.2 0-.2.2-.3.4L327 309c-.2.7-.8.7-.7 1h2.3c.2-.1.5 0 .5-.3s-1.2 0-1.3-.9l.2-1c.2-.8.4-.8.6-.8l2.1-.2zm8.3-5c-.1-.8 0-.8 1.2-1 2-.2 1.4 1.3 2 1.2.2 0 0-.4 0-.6l-.1-1.1c0-.1-.1-.2-.3-.2-1 0-1.7.2-2.4.3l-2.8.4c-.2 0-.3 0-.3.2.1.5 1.3 0 1.4 1l.7 5.5c.2 1.5-.7 1-.6 1.5 0 0 0 .1.2 0l1.4-.1 1.2-.1c.3 0 .5 0 .5-.3s-1.2.1-1.4-1.2l-.2-1.7c-.1-.7-.1-.9.3-1h.8c1.1-.2 1 1.1 1.3 1 .3 0 .2-.4.1-.5l-.3-2.1c0-.3-.2-.3-.2-.3-.3 0-.1 1.1-1 1.2l-.7.1c-.5.1-.5 0-.6-.5zm4 2.8c.4 2.3 2.1 3.7 4.2 3.3 3.4-.7 3.5-3.6 3.2-5.3-.5-2.5-2.3-3.7-4.4-3.3-2.5.5-3.5 2.7-3 5.3m1.1-1c-.3-1.6 0-3.4 1.7-3.7 1.4-.3 3 .8 3.4 3.4.3 2 0 3.6-1.8 4-1.9.4-3-2-3.3-3.6zm8.3-4.1c-.1-.7.2-.8.6-.9 1-.2 1.8.5 2.1 1.6.2.7.3 1.4-1.3 1.8-.3 0-.7.1-.8-.2l-.5-2.3zm0 5.7c.4 1.4-.5 1.3-.5 1.6.1.3.3.2.4.1.6 0 1-.3 1.6-.4l1-.2c.2 0 .2-.1.2-.2 0-.4-1 .3-1.3-1l-.5-2c0-.4-.2-.4.4-.5.5-.2.7-.1 1.1.3l1.3 1.6c.5.6 1 1.3 1.8 1.1.5-.1 1-.5 1-.9l-.2-.1-.3.1s-.3.1-.4 0l-2.4-2.9.5-.6c.2-.4.4-.9.2-1.6-.1-.5-.7-2.1-3-1.6l-2.1.6-1.2.2c-.2 0-.3.1-.2.2 0 .5 1.1-.2 1.4 1zm8.7-2c.3 1.4-1 1.2-.9 1.6 0 .3.3.2.5.2l1.4-.5 1.5-.3c.3 0 .5 0 .4-.4 0-.3-1.3.4-1.7-1l-1.3-5.3c-.2-.5 0-.6.3-.7l1-.2c1.1-.4 1.1 1 1.5.9.3 0 0-.5 0-.7l-.4-1s0-.3-.2-.2l-3.2.9-3.2.7v.3l.1 1.6c0 .2 0 .4.3.4.5-.1-.3-1.6 1-1.9l.8-.2c.4-.1.6 0 .7.5zm5.5-7.3c-.3-1 .6-.9.4-1.3h-.3l-1.4.4-1.2.3s-.3 0-.3.2c.1.4 1.2-.2 1.5.8l1.6 5.6c.2 1-.6 1-.5 1.3 0 .1 0 .2.2.1l1.1-.3 1.6-.4c.3 0 .3-.1.3-.3-.1-.3-1.1.5-1.5-.9zm2.3 2.7c.7 2.3 2.6 3.4 4.7 2.7 3.2-1.1 3-4.1 2.4-5.7-.8-2.4-2.8-3.3-4.8-2.7-2.4.9-3.2 3.2-2.3 5.7m1-1c-.6-1.7-.6-3.5 1.1-4 1.3-.5 3 .4 3.9 2.9.6 1.8.5 3.6-1.2 4.2-1.8.6-3.2-1.5-3.8-3.2zm7.6-5.5c-.2-.7 0-.8.4-1 1-.3 2 .3 2.4 1.4.2.6.4 1.3-1.1 1.9-.3 0-.7.2-.8 0zm.8 5.6c.6 1.4-.4 1.4-.2 1.7 0 .3.2.1.4.1l1.5-.7.9-.2c.2-.1.2-.2.2-.3-.2-.4-1 .4-1.4-.8l-.8-1.9c-.2-.4-.2-.5.3-.7.5-.2.7-.1 1.1.3l1.6 1.4c.5.5 1.1 1.1 2 .8.3-.2.9-.7.7-1l-.2-.1-.2.2h-.5l-2.8-2.5.4-.7a2 2 0 0 0 0-1.6c-.1-.6-1-2-3.1-1.2l-2 .9-1.2.4-.2.2c.2.4 1.1-.4 1.6.8l2 5z"/>
|
||||||
</g>
|
</g>
|
||||||
<g fill="#fedf00" transform="matrix(.64 0 0 .64 0 16)">
|
<g fill="#fedf00" transform="matrix(.64 0 0 .64 0 16)">
|
||||||
<path fill="#d52b1e" d="M412.7 249.3h82.1v82h-82.1z"/>
|
<path fill="#d52b1e" d="M412.7 249.3h82.1v82h-82.1z"/>
|
||||||
<path id="ad-a" fill="#fff" d="M451.2 313.8s0 3-.8 5.3c-1 2.7-1 2.7-1.9 4a13.2 13.2 0 0 1-3.8 4c-2 1.2-4 1.8-6 1.6-5.4-.4-8-6.4-9.2-11.2-1.3-5.1-5-8-7.5-6-1.4 1-1.4 2.8-.3 4.6a9 9 0 0 0 4.1 2.8l-2.9 3.7s-6.3-.8-7.5-7.4c-.5-2.5.7-7.1 4.9-8.5 5.3-1.8 8.6 2 10.3 5.2 2.2 4.4 3.2 12.4 9.4 11.2 3.4-.7 5-5.6 5-7.9l2.4-2.6 3.7 1.2h.1z"/>
|
<path id="ad-a" fill="#fff" d="M451.2 313.8s0 3-.8 5.3c-1 2.7-1 2.7-1.9 4a13.2 13.2 0 0 1-3.8 4c-2 1.2-4 1.8-6 1.6-5.4-.4-8-6.4-9.2-11.2-1.3-5.1-5-8-7.5-6-1.4 1-1.4 2.8-.3 4.6a9 9 0 0 0 4.1 2.8l-2.9 3.7s-6.3-.8-7.5-7.4c-.5-2.5.7-7.1 4.9-8.5 5.3-1.8 8.6 2 10.3 5.2 2.2 4.4 3.2 12.4 9.4 11.2 3.4-.7 5-5.6 5-7.9l2.4-2.6 3.7 1.2z"/>
|
||||||
<use xlink:href="#ad-a" width="100%" height="100%" transform="matrix(-1 0 0 1 907.5 0)"/>
|
<use xlink:href="#ad-a" width="100%" height="100%" transform="matrix(-1 0 0 1 907.5 0)"/>
|
||||||
<path d="m461.1 279 10.8-11.7s1.6-1.3 1.6-3.4l-2.2.4-.5-1.2-.1-1.1 3-.7V260l.3-1.3-3.2.2.3-1.4.5-1 1.9-.4h1.9c1.8-3.4 9.2-6.4 14.4-1 3.8 4 3 11.2-2 13.2a6.3 6.3 0 0 1-6.8-1.1l2-4c2.7 1.7 5-.3 4.8-2.4-.2-2.7-2-4.3-4.3-4.5-2.3-.2-4 1-5 3-.6 1.3-.3 2.2-.5 3.6-.2 1.5 0 2.3-.5 3.8a8.8 8.8 0 0 1-2.4 3.6l-11 12-43 46.4-3.2-3 43.2-46.7z"/>
|
<path d="m461.1 279 10.8-11.7s1.6-1.3 1.6-3.4l-2.2.4-.5-1.2-.1-1.1 3-.7V260l.3-1.3-3.2.2.3-1.4.5-1 1.9-.4h1.9c1.8-3.4 9.2-6.4 14.4-1 3.8 4 3 11.2-2 13.2a6.3 6.3 0 0 1-6.8-1.1l2-4c2.7 1.7 5-.3 4.8-2.4-.2-2.7-2-4.3-4.3-4.5-2.3-.2-4 1-5 3-.6 1.3-.3 2.2-.5 3.6-.2 1.5 0 2.3-.5 3.8a8.8 8.8 0 0 1-2.4 3.6l-11 12-43 46.4-3.2-3z"/>
|
||||||
<path fill="#fff" d="M429.5 283s2.7 13.4 11.9 33.5c4.7-1.7 7.4-2.8 12.4-2.8 4.9 0 7.6 1 12.3 2.8A171 171 0 0 0 478 283l-24.2-31-24.4 31z"/>
|
<path fill="#fff" d="M429.5 283s2.7 13.4 11.9 33.5c4.7-1.7 7.4-2.8 12.4-2.8 4.9 0 7.6 1 12.3 2.8A171 171 0 0 0 478 283l-24.2-31z"/>
|
||||||
<path d="m456.1 262.4 16.8 21.7s-2.2 10.5-9 26.3c-2.7-.6-5-1.1-7.8-1.3v-46.7zm-4.7 0-16.8 21.7s2.2 10.5 9 26.3c2.7-.6 5-1.1 7.8-1.3v-46.7z"/>
|
<path d="m456.1 262.4 16.8 21.7s-2.2 10.5-9 26.3c-2.7-.6-5-1.1-7.8-1.3zm-4.7 0-16.8 21.7s2.2 10.5 9 26.3c2.7-.6 5-1.1 7.8-1.3z"/>
|
||||||
</g>
|
</g>
|
||||||
<g fill="#d52b1e">
|
<g fill="#d52b1e">
|
||||||
<path fill="#fedf00" d="M322.3 175.5h52.6V228h-52.6z"/>
|
<path fill="#fedf00" d="M322.3 175.5h52.6V228h-52.6z"/>
|
||||||
|
@ -128,21 +128,21 @@
|
||||||
</g>
|
</g>
|
||||||
<g fill="#d52b1e" stroke="#d52b1e" stroke-width=".5">
|
<g fill="#d52b1e" stroke="#d52b1e" stroke-width=".5">
|
||||||
<path fill="#fedf00" stroke="none" d="M264.3 273.5c.1 1 .5 2.6 1.4 4.3 1 1.5.6 1.4 2.7 3.8a15.3 15.3 0 0 0 4 2.9 32.7 32.7 0 0 0 15 2.6c2.7-.1 4.8-.4 6.6-.7a71 71 0 0 1 11-.6c1.5 0 3 .3 4.7.6 3.5.7 7 2 7 2v-54.7h-52.6V271l.2 2.4z"/>
|
<path fill="#fedf00" stroke="none" d="M264.3 273.5c.1 1 .5 2.6 1.4 4.3 1 1.5.6 1.4 2.7 3.8a15.3 15.3 0 0 0 4 2.9 32.7 32.7 0 0 0 15 2.6c2.7-.1 4.8-.4 6.6-.7a71 71 0 0 1 11-.6c1.5 0 3 .3 4.7.6 3.5.7 7 2 7 2v-54.7h-52.6V271l.2 2.4z"/>
|
||||||
<path stroke-width=".3" d="m270.4 283.1 2.5 1.5 3.4 1.2v-52.2h-5.9zm29.2 2.4v-51.9h-5.8v52.8l5.8-.7zm11.7-51.9h-5.8v52.1c1.9.2 3.8.6 5.8 1v-53zm-23.4 0V287s-3.8.2-5.8 0v-53.4z"/>
|
<path stroke-width=".3" d="m270.4 283.1 2.5 1.5 3.4 1.2v-52.2h-5.9zm29.2 2.4v-51.9h-5.8v52.8l5.8-.7zm11.7-51.9h-5.8v52.1c1.9.2 3.8.6 5.8 1zm-23.4 0V287s-3.8.2-5.8 0v-53.4z"/>
|
||||||
</g>
|
</g>
|
||||||
<g transform="matrix(.64 0 0 .64 0 16)">
|
<g transform="matrix(.64 0 0 .64 0 16)">
|
||||||
<path fill="#fedf00" d="M585.5 402.4a20.8 20.8 0 0 1-2.2 6.6c-1.5 2.3-1 2.3-4.3 6a26.3 26.3 0 0 1-13 7 51.8 51.8 0 0 1-16.6 1.6c-4.3-.2-7.5-.7-10.3-1-3.8-.6-6.7-.9-11-1a62.9 62.9 0 0 0-6.2 0 83.3 83.3 0 0 0-18.3 4.2V340h82.2v58.5l-.3 3.8z"/>
|
<path fill="#fedf00" d="M585.5 402.4a20.8 20.8 0 0 1-2.2 6.6c-1.5 2.3-1 2.3-4.3 6a26.3 26.3 0 0 1-13 7 51.8 51.8 0 0 1-16.6 1.6c-4.3-.2-7.5-.7-10.3-1-3.8-.6-6.7-.9-11-1a62.9 62.9 0 0 0-6.2 0 83.3 83.3 0 0 0-18.3 4.2V340h82.2v58.5z"/>
|
||||||
<g id="ad-b">
|
<g id="ad-b">
|
||||||
<path fill="#d52b1e" d="m524.6 347-.6.2-.8.8c-.4.4-.7.5-1.2.8l-.6.5c-.3.3 0 .6-.3 1-.1.4-.3.6-.6 1-.4.4-.7.5-1 1l-1.2 1-.3.1h-.6c-.4.2-.5.6-.8.8l.3.6.8 1.4c.2.3.2.7.5.8.5.2.9.2 1.3.1.8.2 1.3.2 2 .5l1.5.8c.5.3.8.4 1.3.5h1.8v.3l2 1a1.7 1.7 0 0 0-.1.4c-.1.3-.2.7-.1.8.6 1.9 1.2 3 1.5 3.2.6.2.8.9 1.1 1.5l-.3.3c-.6.6-1.2 1-1.7 1.8-.7 1.2-1.2 1.2-.3 2.8l1.5 2.4c.4.7.6 1.2.8 2 .2.7.3 1.2.3 2l1 .3.7-.6.6-1.2v-1c-.2-.1-.3-.4-.2-.7 0-.4.5-.3.7-.6.3-.5-.4-.8-.7-1.1-.6-.7-1.4-.9-1.6-1.9 0-.2 0-.4.4-.7l2-1.8c.2.1.6.2 1 .1l1.3.4c.6.2.9 0 1.2 0h.4l.1.6c.1 1-.1 3 .2 3.5l.3.6.2.6v2l-.2 1.7c0 .4-.2.7-.5 1-.2.4-.6.4-1 .7v1l1.1.5 1.3.3.7-.3.1-.6.5-.5c.4-.2.8 0 .9-.1.2-.3 0-.4 0-.8 0-.6-.2-1-.3-1.6a11.8 11.8 0 0 1-.1-2.8c0-.6 0-1 .2-1.5.1-1 .4-1.4.6-2.2.3-1 .3-1.6.4-2.5a24.4 24.4 0 0 0 10.1-.6c.8.7 1.7 1.2 2.7 1.6v1c0 .3 0 .4.2.7l.3.3c.3 0 .5 0 .7-.2.2-.2.2-.4.2-.7v-.7h1.8v1.1c.1.3.3.4.5.4a.7.7 0 0 0 .6 0c.3-.2.2-.6.3-1v-.7l1-.4a5.1 5.1 0 0 1 0 .9l-.3.9c-.2.6-.5.8-.8 1.4-.4.6-.5 1-1 1.5l-.6.7-.6.9-.9 1c-.7.6-1.2.2-2 .9l-.3 1 1.4.6 1.3.2.4-.2c0-.3 0-.6.3-.8.2-.3.4-.3.7-.4.4 0 .8 0 1-.2.4-.3.4-1 .7-1.5a12.7 12.7 0 0 1 3-3.9l1.7-1.4c.2-.4.5-.5.5-1l-.2-.6-.2-1c1.5.7 1 .7 1.2 1.4.3.6 0 1 .1 1.7.1.8.5 1.1.5 1.9.1.9-.1 1.4-.3 2.3-.1.8-.1 1.3-.5 2a3.8 3.8 0 0 1-1.1 1.5l-.6.5-.1 1 1.1.4 1.6.4.4-.3c.2-.7 0-1.7.4-1.7.4-.1.7 0 .8-.3v-.7l.7-4.5.4-1.9.4-1.7c.7-2-.2-2.3-1-3.6-.5-.7-.7-1-.7-1.5V362a42.7 42.7 0 0 1 0-2.8l.4-.2c1.2-.7 1.7-.9 2.4-2.5a3.4 3.4 0 0 0 .3-1.5v-1l-.4-1a3.2 3.2 0 0 0-.6-.8c-.7-1-1.7-1.1-2.7-1.5-1.5-.5-2.5-.4-4-.5-1.8-.2-2.7-.2-4.4 0-2 0-3.1.4-5.1.7l-4.9.4c-2.3 0-4.4-.5-5.8-.4-2.4.2-2.5.8-6.2 1.1a67 67 0 0 1-3.8.2l-2.2-.7c.9-.3 1.1-.5 1.5-1 .3-.4.2-.7.6-1.1l.7-1a2.2 2.2 0 0 0-.9-.4h-1a3 3 0 0 0-1.2.3l-.8.6-2.2-1.2a8.8 8.8 0 0 0-3-.9zm2 11.8z"/>
|
<path fill="#d52b1e" d="m524.6 347-.6.2-.8.8c-.4.4-.7.5-1.2.8l-.6.5c-.3.3 0 .6-.3 1-.1.4-.3.6-.6 1-.4.4-.7.5-1 1l-1.2 1-.3.1h-.6c-.4.2-.5.6-.8.8l.3.6.8 1.4c.2.3.2.7.5.8.5.2.9.2 1.3.1.8.2 1.3.2 2 .5l1.5.8c.5.3.8.4 1.3.5h1.8v.3l2 1a1.7 1.7 0 0 0-.1.4c-.1.3-.2.7-.1.8.6 1.9 1.2 3 1.5 3.2.6.2.8.9 1.1 1.5l-.3.3c-.6.6-1.2 1-1.7 1.8-.7 1.2-1.2 1.2-.3 2.8l1.5 2.4c.4.7.6 1.2.8 2 .2.7.3 1.2.3 2l1 .3.7-.6.6-1.2v-1c-.2-.1-.3-.4-.2-.7 0-.4.5-.3.7-.6.3-.5-.4-.8-.7-1.1-.6-.7-1.4-.9-1.6-1.9 0-.2 0-.4.4-.7l2-1.8c.2.1.6.2 1 .1l1.3.4c.6.2.9 0 1.2 0h.4l.1.6c.1 1-.1 3 .2 3.5l.3.6.2.6v2l-.2 1.7c0 .4-.2.7-.5 1-.2.4-.6.4-1 .7v1l1.1.5 1.3.3.7-.3.1-.6.5-.5c.4-.2.8 0 .9-.1.2-.3 0-.4 0-.8 0-.6-.2-1-.3-1.6a11.8 11.8 0 0 1-.1-2.8c0-.6 0-1 .2-1.5.1-1 .4-1.4.6-2.2.3-1 .3-1.6.4-2.5a24.4 24.4 0 0 0 10.1-.6c.8.7 1.7 1.2 2.7 1.6v1c0 .3 0 .4.2.7l.3.3c.3 0 .5 0 .7-.2.2-.2.2-.4.2-.7v-.7h1.8v1.1c.1.3.3.4.5.4a.7.7 0 0 0 .6 0c.3-.2.2-.6.3-1v-.7l1-.4a5.1 5.1 0 0 1 0 .9l-.3.9c-.2.6-.5.8-.8 1.4-.4.6-.5 1-1 1.5l-.6.7-.6.9-.9 1c-.7.6-1.2.2-2 .9l-.3 1 1.4.6 1.3.2.4-.2c0-.3 0-.6.3-.8.2-.3.4-.3.7-.4.4 0 .8 0 1-.2.4-.3.4-1 .7-1.5a12.7 12.7 0 0 1 3-3.9l1.7-1.4c.2-.4.5-.5.5-1l-.2-.6-.2-1c1.5.7 1 .7 1.2 1.4.3.6 0 1 .1 1.7.1.8.5 1.1.5 1.9.1.9-.1 1.4-.3 2.3-.1.8-.1 1.3-.5 2a3.8 3.8 0 0 1-1.1 1.5l-.6.5-.1 1 1.1.4 1.6.4.4-.3c.2-.7 0-1.7.4-1.7.4-.1.7 0 .8-.3v-.7l.7-4.5.4-1.9.4-1.7c.7-2-.2-2.3-1-3.6-.5-.7-.7-1-.7-1.5V362a42.7 42.7 0 0 1 0-2.8l.4-.2c1.2-.7 1.7-.9 2.4-2.5a3.4 3.4 0 0 0 .3-1.5v-1l-.4-1a3.2 3.2 0 0 0-.6-.8c-.7-1-1.7-1.1-2.7-1.5-1.5-.5-2.5-.4-4-.5-1.8-.2-2.7-.2-4.4 0-2 0-3.1.4-5.1.7l-4.9.4c-2.3 0-4.4-.5-5.8-.4-2.4.2-2.5.8-6.2 1.1a67 67 0 0 1-3.8.2l-2.2-.7c.9-.3 1.1-.5 1.5-1 .3-.4.2-.7.6-1.1l.7-1a2.2 2.2 0 0 0-.9-.4h-1a3 3 0 0 0-1.2.3l-.8.6-2.2-1.2a8.8 8.8 0 0 0-3-.9zm2 11.8"/>
|
||||||
<g fill="none" stroke="#fedf00" stroke-linecap="round">
|
<g fill="none" stroke="#fedf00" stroke-linecap="round">
|
||||||
<path d="m568.8 359.5-.8.3c-.9.4-1.6.4-2.6.5-2.6.2-4.3-1.1-7-.9-1.4.1-2 1.2-3.5 1.6a9.3 9.3 0 0 1-1.7.2l.5-1s-1.2.3-2 .3a7.5 7.5 0 0 1-1.6-.2l1-1-1.3-.2a4 4 0 0 1-1-.7 20.5 20.5 0 0 0 1.7-.3c1.5-.4 2-1.2 3.9-1.4 1.1 0 3 0 7.6.8 3 .5 4.4.2 5.5-.3.8-.3 1-1 1.1-1.8.1-.8-.4-1.4-.8-1.8-.1 0-.5-.3-1.1-.4"/>
|
<path d="m568.8 359.5-.8.3c-.9.4-1.6.4-2.6.5-2.6.2-4.3-1.1-7-.9-1.4.1-2 1.2-3.5 1.6a9.3 9.3 0 0 1-1.7.2l.5-1s-1.2.3-2 .3a7.5 7.5 0 0 1-1.6-.2l1-1-1.3-.2a4 4 0 0 1-1-.7 20.5 20.5 0 0 0 1.7-.3c1.5-.4 2-1.2 3.9-1.4 1.1 0 3 0 7.6.8 3 .5 4.4.2 5.5-.3.8-.3 1-1 1.1-1.8.1-.8-.4-1.4-.8-1.8-.1 0-.5-.3-1.1-.4"/>
|
||||||
<path fill="#fcd900" stroke-linecap="butt" stroke-width=".5" d="M524.8 350.6c-.5 0-.9 0-1.3.3-.5.3-.6.7-1 1.1.5.1.8.4 1.2.3.4 0 .5-.2.8-.5.3-.4.4-.7.4-1.2h-.1z"/>
|
<path fill="#fcd900" stroke-linecap="butt" stroke-width=".5" d="M524.8 350.6c-.5 0-.9 0-1.3.3-.5.3-.6.7-1 1.1.5.1.8.4 1.2.3.4 0 .5-.2.8-.5.3-.4.4-.7.4-1.2z"/>
|
||||||
<path d="M536 363.8a13.6 13.6 0 0 0 1 2.3c.2.8 0 1.2.2 2v1.6m6.8-7-.3 1.3-1 3.5v.7m-11-4c.9.2.6 3.3 1.9 4"/>
|
<path d="M536 363.8a13.6 13.6 0 0 0 1 2.3c.2.8 0 1.2.2 2v1.6m6.8-7-.3 1.3-1 3.5v.7m-11-4c.9.2.6 3.3 1.9 4"/>
|
||||||
<path stroke-linecap="butt" d="m560.1 369.8.4-.3a8.2 8.2 0 0 0 2.7-1.8"/>
|
<path stroke-linecap="butt" d="m560.1 369.8.4-.3a8.2 8.2 0 0 0 2.7-1.8"/>
|
||||||
<path d="M552.4 368c3.5-.9 5.9-2.6 7.6-2.9m-4-1.5h.8c1.5-.3 1.7.6 2.7 1.2 1.9 1 2.1 2.3 4.3 3.4l.4.1.8.4"/>
|
<path d="M552.4 368c3.5-.9 5.9-2.6 7.6-2.9m-4-1.5h.8c1.5-.3 1.7.6 2.7 1.2 1.9 1 2.1 2.3 4.3 3.4l.4.1.8.4"/>
|
||||||
<path fill="#fcd900" stroke-linecap="butt" stroke-width=".5" d="M517.7 354.5h.7l.8-.2c.3 0 .5 0 .7.2.2 0 .2.1.3.3 0 .2.2.3.1.5 0 .2-.3.4-.6.4-.2 0-.4 0-.5-.3a.5.5 0 0 1 0-.4 1 1 0 0 1-.9 0 1 1 0 0 1-.6-.5z"/>
|
<path fill="#fcd900" stroke-linecap="butt" stroke-width=".5" d="M517.7 354.5h.7l.8-.2c.3 0 .5 0 .7.2.2 0 .2.1.3.3 0 .2.2.3.1.5 0 .2-.3.4-.6.4-.2 0-.4 0-.5-.3a.5.5 0 0 1 0-.4 1 1 0 0 1-.9 0 1 1 0 0 1-.6-.5z"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#0065bd" d="m525.1 364.2-2-.9c.4-.2.7-.2 1-.5.3-.4.3-.8.5-1.3s.2-1 .7-1.4c.3-.2.8-.2 1.1-.1.4 0 .8.4.9.7 0 .6-.2 1-.3 1.5 0 .6-.3.9-.2 1.4 0 .4.2.6.4 1l-2-.4zm-1 1a.6.6 0 1 1 .7.5.6.6 0 0 1-.7-.6zm-1.7-16.6h-.2c-.4-.4-.4-.8-.6-1.2a4 4 0 0 1-.3-1.2v-2c0-.3 0-.6-.2-.9 0-.2-.4-.3-.3-.4 0-.1.3 0 .4 0 .4 0 .6.1 1 .4.3.3.5.6.6 1l.4 1.5.3.8.5.6-.7.8-.9.6zm3.6 10.6 2.2 1a9.2 9.2 0 0 0 3.5-3.8c.9-1.8 1-2.7 1.4-4.4l-1.8-.5h-.4c-.5 1.8-.7 2.7-1.6 4.2-.8 1.3-1.7 2.3-2.6 3l-.7.5zm5 18.2.8-1.3 1.4-1.1h.4a8.7 8.7 0 0 1-.5 2.8l-.4 1-.5.5c-.5-.8-1.3-1.3-1.3-2zm33 1.8 1.4.6 1.5.9v.5l-1.5.2a8.4 8.4 0 0 1-1.3 0h-1l-.6-.4c.5-.7.8-1.6 1.4-1.8zm-9.8-2 1.4.5 1.5 1c0 .1.1.3 0 .4a9 9 0 0 1-2.7.3l-1-.1-.7-.3c.6-.7.9-1.7 1.5-1.8zm-17.4 2.1 1.5.5 1.5 1v.5a9 9 0 0 1-2.8.2h-1l-.6-.4c.5-.7.8-1.6 1.4-1.8zm-9-29.8c-.6-.3-1-1-.6-1.6.1-.2.4-.2.6-.4.2-.3.1-.5 0-.8l-.1-1-.2-1c0-.6 0-1 .4-1.6.2-.3.7-.6.8-.6.2.1 0 .5 0 .8 0 .5.1.7.3 1.2l.7 1.3c.2.6.4.8.4 1.4 0 .5 0 .7-.2 1.2a2 2 0 0 1-.6.8 2 2 0 0 1-.8.4 1.1 1.1 0 0 1-.6 0z"/>
|
<path fill="#0065bd" d="m525.1 364.2-2-.9c.4-.2.7-.2 1-.5.3-.4.3-.8.5-1.3s.2-1 .7-1.4c.3-.2.8-.2 1.1-.1.4 0 .8.4.9.7 0 .6-.2 1-.3 1.5 0 .6-.3.9-.2 1.4 0 .4.2.6.4 1l-2-.4zm-1 1a.6.6 0 1 1 .7.5.6.6 0 0 1-.7-.6zm-1.7-16.6h-.2c-.4-.4-.4-.8-.6-1.2a4 4 0 0 1-.3-1.2v-2c0-.3 0-.6-.2-.9 0-.2-.4-.3-.3-.4 0-.1.3 0 .4 0 .4 0 .6.1 1 .4.3.3.5.6.6 1l.4 1.5.3.8.5.6-.7.8zm3.6 10.6 2.2 1a9.2 9.2 0 0 0 3.5-3.8c.9-1.8 1-2.7 1.4-4.4l-1.8-.5h-.4c-.5 1.8-.7 2.7-1.6 4.2-.8 1.3-1.7 2.3-2.6 3zm5 18.2.8-1.3 1.4-1.1h.4a8.7 8.7 0 0 1-.5 2.8l-.4 1-.5.5c-.5-.8-1.3-1.3-1.3-2zm33 1.8 1.4.6 1.5.9v.5l-1.5.2a8.4 8.4 0 0 1-1.3 0h-1l-.6-.4c.5-.7.8-1.6 1.4-1.8zm-9.8-2 1.4.5 1.5 1c0 .1.1.3 0 .4a9 9 0 0 1-2.7.3l-1-.1-.7-.3c.6-.7.9-1.7 1.5-1.8m-17.4 2.1 1.5.5 1.5 1v.5a9 9 0 0 1-2.8.2h-1l-.6-.4c.5-.7.8-1.6 1.4-1.8m-9-29.8c-.6-.3-1-1-.6-1.6.1-.2.4-.2.6-.4.2-.3.1-.5 0-.8l-.1-1-.2-1c0-.6 0-1 .4-1.6.2-.3.7-.6.8-.6.2.1 0 .5 0 .8 0 .5.1.7.3 1.2l.7 1.3c.2.6.4.8.4 1.4 0 .5 0 .7-.2 1.2a2 2 0 0 1-.6.8 2 2 0 0 1-.8.4 1.1 1.1 0 0 1-.6 0z"/>
|
||||||
</g>
|
</g>
|
||||||
<use xlink:href="#ad-b" width="100%" height="100%" y="36.6"/>
|
<use xlink:href="#ad-b" width="100%" height="100%" y="36.6"/>
|
||||||
</g>
|
</g>
|
||||||
|
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ae" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ae" viewBox="0 0 640 480">
|
||||||
<path fill="#00732f" d="M0 0h640v160H0z"/>
|
<path fill="#00732f" d="M0 0h640v160H0z"/>
|
||||||
<path fill="#fff" d="M0 160h640v160H0z"/>
|
<path fill="#fff" d="M0 160h640v160H0z"/>
|
||||||
<path d="M0 320h640v160H0z"/>
|
<path fill="#000001" d="M0 320h640v160H0z"/>
|
||||||
<path fill="red" d="M0 0h220v480H0z"/>
|
<path fill="red" d="M0 0h220v480H0z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 266 B |
|
@ -1,29 +1,29 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-af" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-af" viewBox="0 0 640 480">
|
||||||
<g fill-rule="evenodd" stroke-width="1pt">
|
<g fill-rule="evenodd" stroke-width="1pt">
|
||||||
<path d="M0 0h640v480H0z"/>
|
<path fill="#000001" d="M0 0h640v480H0z"/>
|
||||||
<path fill="#090" d="M426.7 0H640v480H426.7z"/>
|
<path fill="#090" d="M426.7 0H640v480H426.7z"/>
|
||||||
<path fill="#bf0000" d="M213.3 0h213.4v480H213.3z"/>
|
<path fill="#bf0000" d="M213.3 0h213.4v480H213.3z"/>
|
||||||
</g>
|
</g>
|
||||||
<g fill="#fff" fill-rule="evenodd" stroke="#bd6b00" stroke-width=".5" transform="translate(1 27.3)scale(1.06346)">
|
<g fill="#fff" fill-rule="evenodd" stroke="#bd6b00" stroke-width=".5" transform="translate(1 27.3)scale(1.06346)">
|
||||||
<path d="M319.5 225.8h8.3c0 3.2 2 6.6 4.5 8.5h-16c2.5-2.2 3.2-5 3.2-8.5z"/>
|
<path d="M319.5 225.8h8.3c0 3.2 2 6.6 4.5 8.5h-16c2.5-2.2 3.2-5 3.2-8.5z"/>
|
||||||
<path stroke="none" d="m266.7 178.5 4.6 5 57 .2 4.6-5-14.6-.3-7-5h-23l-6.6 5.1h-15z"/>
|
<path stroke="none" d="m266.7 178.5 4.6 5 57 .2 4.6-5-14.6-.3-7-5h-23l-6.6 5.1z"/>
|
||||||
<path d="M290 172.7h19.7c2.6-1.4 3.5-5.9 3.5-8.4 0-7.4-5.3-11-10.5-11.2-.8 0-1.7-.6-1.9-1.3-.5-1.6-.4-2.7-1-2.6-.4 0-.3 1-.7 2.4-.3.8-1.1 1.5-2 1.6-6.4.3-10.6 5-10.5 11.1.1 4 .6 6.4 3.4 8.4z"/>
|
<path d="M290 172.7h19.7c2.6-1.4 3.5-5.9 3.5-8.4 0-7.4-5.3-11-10.5-11.2-.8 0-1.7-.6-1.9-1.3-.5-1.6-.4-2.7-1-2.6-.4 0-.3 1-.7 2.4-.3.8-1.1 1.5-2 1.6-6.4.3-10.6 5-10.5 11.1.1 4 .6 6.4 3.4 8.4z"/>
|
||||||
<path stroke="none" d="M257.7 242.8H342l-7.5-6.1h-69.4l-7.5 6.1z"/>
|
<path stroke="none" d="M257.7 242.8H342l-7.5-6.1h-69.4z"/>
|
||||||
<path d="m296.4 219.7 1.5 4.6h3.5l-2.8-4.6h-2.2zm-2 4.6 1 4.6h4l-1.5-4.6h-3.5zm7 0 2.8 4.6h5.9l-4.6-4.6h-4.1zm-34.5 10.4c3.1-2.9 5.1-5.3 5.1-8.8h7.6c0 2 .7 3.1 1.8 3h7.7v-4.5h-5.6v-24.7c-.2-8.8 10.6-13.8 15-13.8h-26.3v-.8h55.3v.8H301c7.9 0 15.5 7.5 15.6 13.8v7h-1l-.1-6.9c0-6.9-8.7-13.3-15.7-13.1-6 .1-15.4 5.9-15.3 13v2.2l14.3.1-.1 2.5 2.2 1.4 4.5 1.4v3.8l3.2.9v3.7l3.8 1.7v3.8l2.5 1.5-.1 3.9 3.3 2.3h-7.8l4.9 5.5h-7.3l-3.6-5.5h-4.7l2.1 5.4h-5l-1.3-5.4h-6.2v5.8H267zm22.2-15v4.6h5.3l-1-4.6H289z"/>
|
<path d="m296.4 219.7 1.5 4.6h3.5l-2.8-4.6zm-2 4.6 1 4.6h4l-1.5-4.6zm7 0 2.8 4.6h5.9l-4.6-4.6zm-34.5 10.4c3.1-2.9 5.1-5.3 5.1-8.8h7.6c0 2 .7 3.1 1.8 3h7.7v-4.5h-5.6v-24.7c-.2-8.8 10.6-13.8 15-13.8h-26.3v-.8h55.3v.8H301c7.9 0 15.5 7.5 15.6 13.8v7h-1l-.1-6.9c0-6.9-8.7-13.3-15.7-13.1-6 .1-15.4 5.9-15.3 13v2.2l14.3.1-.1 2.5 2.2 1.4 4.5 1.4v3.8l3.2.9v3.7l3.8 1.7v3.8l2.5 1.5-.1 3.9 3.3 2.3h-7.8l4.9 5.5h-7.3l-3.6-5.5h-4.7l2.1 5.4h-5l-1.3-5.4h-6.2v5.8H267zm22.2-15v4.6h5.3l-1-4.6H289z"/>
|
||||||
<path fill="none" d="M289.4 211.7h3.3v7.6h-3.3z"/>
|
<path fill="none" d="M289.4 211.7h3.3v7.6h-3.3z"/>
|
||||||
<path fill="none" d="M284.7 219.8h3.2v-5.6c0-2.4 2.2-4.9 3.2-5 1.2 0 2.9 2.3 3 4.8v5.8h3.4v-14.4h-12.8v14.4zm25.6 3.3h4v3.2h-4zm-2.4-5.3h4v3.1h-4zm-3.9-5.4h4v3.1h-4zm-3.3-4.5h4v3.1h-4z"/>
|
<path fill="none" d="M284.7 219.8h3.2v-5.6c0-2.4 2.2-4.9 3.2-5 1.2 0 2.9 2.3 3 4.8v5.8h3.4v-14.4h-12.8zm25.6 3.3h4v3.2h-4zm-2.4-5.3h4v3.1h-4zm-3.9-5.4h4v3.1h-4zm-3.3-4.5h4v3.1h-4z"/>
|
||||||
<path fill="none" d="m298 219.8 4.2.2 7.3 6.4v-3.8l-2.5-1.8v-3l-3.6-2v-3.3l-3.5-1.2V207l-1.7-1.5-.1 14.4z"/>
|
<path fill="none" d="m298 219.8 4.2.2 7.3 6.4v-3.8l-2.5-1.8v-3l-3.6-2v-3.3l-3.5-1.2V207l-1.7-1.5z"/>
|
||||||
<path d="M315.4 210.3h1v7.1h-1z"/>
|
<path d="M315.4 210.3h1v7.1h-1z"/>
|
||||||
<g id="af-a">
|
<g id="af-a">
|
||||||
<path d="M257.3 186.5c-1.2-2-2.7 2.8-7.8 6.3-2.3 1.6-4 5.9-4 8.7 0 2 .2 3.9 0 5.8-.1 1.1-1.4 3.8-.5 4.5 2.2 1.6 5.1 5.4 6.4 6.7 1.2 1 2.2-5.3 3-8 1-3 .6-6.7 3.2-9.4 1.8-2 6.4-3.8 6-4.6l-6.3-10z"/>
|
<path d="M257.3 186.5c-1.2-2-2.7 2.8-7.8 6.3-2.3 1.6-4 5.9-4 8.7 0 2 .2 3.9 0 5.8-.1 1.1-1.4 3.8-.5 4.5 2.2 1.6 5.1 5.4 6.4 6.7 1.2 1 2.2-5.3 3-8 1-3 .6-6.7 3.2-9.4 1.8-2 6.4-3.8 6-4.6z"/>
|
||||||
<path fill="#bf0000" d="M257 201.9a10 10 0 0 0-1.6-2.6 6.1 6.1 0 0 0-2.4-1.8 5.3 5.3 0 0 1-2.4-1.5 3.6 3.6 0 0 1-.8-1.5 5.9 5.9 0 0 1 0-2l-.3.3c-2.3 1.6-4 5.9-4 8.7a28.5 28.5 0 0 0 0 2.3c.2.5.3 1 .6 1.3l1.1.8 2.7.7a7.1 7.1 0 0 1 2.6 2 10.5 10.5 0 0 1 1.8 2.6l.2-.8c.8-2.7.7-5.9 2.6-8.5z"/>
|
<path fill="#bf0000" d="M257 201.9a10 10 0 0 0-1.6-2.6 6.1 6.1 0 0 0-2.4-1.8 5.3 5.3 0 0 1-2.4-1.5 3.6 3.6 0 0 1-.8-1.5 5.9 5.9 0 0 1 0-2l-.3.3c-2.3 1.6-4 5.9-4 8.7a28.5 28.5 0 0 0 0 2.3c.2.5.3 1 .6 1.3l1.1.8 2.7.7a7.1 7.1 0 0 1 2.6 2 10.5 10.5 0 0 1 1.8 2.6l.2-.8c.8-2.7.7-5.9 2.6-8.5z"/>
|
||||||
<path fill="none" d="M249.8 192.4c-.5 3.3 1.4 4.5 3.2 5.1 1.8.7 3.3 2.6 4 4.4m-11.7 1.5c.8 3 2.8 2.6 4.6 3.2 1.8.7 3.7 3 4.5 4.8"/>
|
<path fill="none" d="M249.8 192.4c-.5 3.3 1.4 4.5 3.2 5.1 1.8.7 3.3 2.6 4 4.4m-11.7 1.5c.8 3 2.8 2.6 4.6 3.2 1.8.7 3.7 3 4.5 4.8"/>
|
||||||
<path d="m255.6 184.5 1-.6 17.7 29.9-1 .6-17.7-30z"/>
|
<path d="m255.6 184.5 1-.6 17.7 29.9-1 .6z"/>
|
||||||
<path d="M257.5 183.3a2 2 0 1 1-4 0 2 2 0 1 1 4 0zm15.2-24h7.2v1.6h-7.2zm0 3.1h7.2v13.8h-7.2zm-.4-5h8c.2-2.7-2.5-5.6-4-5.6-1.6.1-4.1 3-4 5.6z"/>
|
<path d="M257.5 183.3a2 2 0 1 1-4 0 2 2 0 1 1 4 0zm15.2-24h7.2v1.6h-7.2zm0 3.1h7.2v13.8h-7.2zm-.4-5h8c.2-2.7-2.5-5.6-4-5.6-1.6.1-4.1 3-4 5.6z"/>
|
||||||
<path fill="#bd6b00" stroke="none" d="M292.6 155.8c-1.5.6-2.7 2.3-3.4 4.3-.7 2-1 4.3-.6 6.1 0 .7.3 1.1.5 1.5.2.3.4.5.6.5.3 0 .6 0 .7-.3l.2-.8c-.1-2-.1-3.8.3-5.4a7.7 7.7 0 0 1 3-4.4c.3-.2.4-.5.5-.7a1 1 0 0 0-.3-.7c-.4-.3-1-.4-1.5-.1zm.2.4c.4-.2.8 0 1 .1l.1.2c0 .1 0 .2-.3.4a8.2 8.2 0 0 0-3.1 4.6 16.7 16.7 0 0 0-.3 5.6 1 1 0 0 1-.2.6s0 .1-.2 0c0 0-.2 0-.4-.3a3.9 3.9 0 0 1-.4-1.2c-.3-1.8 0-4 .7-6 .7-1.8 1.8-3.4 3-4z"/>
|
<path fill="#bd6b00" stroke="none" d="M292.6 155.8c-1.5.6-2.7 2.3-3.4 4.3-.7 2-1 4.3-.6 6.1 0 .7.3 1.1.5 1.5.2.3.4.5.6.5.3 0 .6 0 .7-.3l.2-.8c-.1-2-.1-3.8.3-5.4a7.7 7.7 0 0 1 3-4.4c.3-.2.4-.5.5-.7a1 1 0 0 0-.3-.7c-.4-.3-1-.4-1.5-.1m.2.4c.4-.2.8 0 1 .1l.1.2c0 .1 0 .2-.3.4a8.2 8.2 0 0 0-3.1 4.6 16.7 16.7 0 0 0-.3 5.6 1 1 0 0 1-.2.6s0 .1-.2 0c0 0-.2 0-.4-.3a3.9 3.9 0 0 1-.4-1.2c-.3-1.8 0-4 .7-6 .7-1.8 1.8-3.4 3-4z"/>
|
||||||
<path fill="#bd6b00" stroke="none" d="M295.2 157.7c-1.5.7-2.5 2.3-3 4.2a13.6 13.6 0 0 0-.3 5.9c.2 1.3 1 2 1.6 2 .3.1.6 0 .8-.3.2-.3.3-.6.2-1-.4-1.6-.5-3.4-.3-5.1.3-1.7 1-3.2 2.2-4.1.3-.3.5-.5.5-.8a.8.8 0 0 0-.2-.6c-.4-.3-1-.4-1.5-.2zm.2.5c.4-.2.8-.1 1 0l.1.3-.3.4a6.5 6.5 0 0 0-2.4 4.4c-.3 1.8-.1 3.7.2 5.2.1.4 0 .6 0 .8l-.5.1c-.3 0-1-.5-1.2-1.7-.3-1.7-.2-3.9.3-5.7.5-1.8 1.5-3.3 2.8-3.8z"/>
|
<path fill="#bd6b00" stroke="none" d="M295.2 157.7c-1.5.7-2.5 2.3-3 4.2a13.6 13.6 0 0 0-.3 5.9c.2 1.3 1 2 1.6 2 .3.1.6 0 .8-.3.2-.3.3-.6.2-1-.4-1.6-.5-3.4-.3-5.1.3-1.7 1-3.2 2.2-4.1.3-.3.5-.5.5-.8a.8.8 0 0 0-.2-.6c-.4-.3-1-.4-1.5-.2m.2.5c.4-.2.8-.1 1 0l.1.3-.3.4a6.5 6.5 0 0 0-2.4 4.4c-.3 1.8-.1 3.7.2 5.2.1.4 0 .6 0 .8l-.5.1c-.3 0-1-.5-1.2-1.7-.3-1.7-.2-3.9.3-5.7.5-1.8 1.5-3.3 2.8-3.8"/>
|
||||||
<path d="M272.3 187.4h8v11h-8zm.5 17.4h7.7v2.4h-7.7zm-.2 4.1h8v8.7h-8zm-.6 10.5h8.7v4.9H272zm1.1-16.6h7l1.4-2.4h-9.6l1.2 2.4zm9.4-8.6.1-6h4.8a17.4 17.4 0 0 0-4.9 6z"/>
|
<path d="M272.3 187.4h8v11h-8zm.5 17.4h7.7v2.4h-7.7zm-.2 4.1h8v8.7h-8zm-.6 10.5h8.7v4.9H272zm1.1-16.6h7l1.4-2.4h-9.6zm9.4-8.6.1-6h4.8a17.4 17.4 0 0 0-4.9 6z"/>
|
||||||
<path fill="none" d="M273.6 196.7c0 1.3 1.5.8 1.5.1v-5.6c0-1 2.4-.8 2.4-.1v6c0 1 1.7.9 1.6 0v-7c0-2.2-5.5-2.1-5.5-.1v6.7zm0 13.3h5.7v7h-5.7z"/>
|
<path fill="none" d="M273.6 196.7c0 1.3 1.5.8 1.5.1v-5.6c0-1 2.4-.8 2.4-.1v6c0 1 1.7.9 1.6 0v-7c0-2.2-5.5-2.1-5.5-.1zm0 13.3h5.7v7h-5.7z"/>
|
||||||
<path d="M277.2 213h2v1h-2zm-3.5 0h2v1h-2zm2-3h1.5v3h-1.5zm0 4h1.5v3.1h-1.5zM244 139c.4 5.5-1.4 8.6-4.3 8.1-.8-3 1-5.1 4.3-8.1zm-6.5 12.3c-2.6-1.3-.7-11.5.3-15.8.7 5.5 2 13.3-.3 15.8z"/>
|
<path d="M277.2 213h2v1h-2zm-3.5 0h2v1h-2zm2-3h1.5v3h-1.5zm0 4h1.5v3.1h-1.5zM244 139c.4 5.5-1.4 8.6-4.3 8.1-.8-3 1-5.1 4.3-8.1zm-6.5 12.3c-2.6-1.3-.7-11.5.3-15.8.7 5.5 2 13.3-.3 15.8z"/>
|
||||||
<path d="M238.4 151.8c4.4 1.5 8-3.2 9.1-8.7-3.6 5-9.5 5-9 8.7zm-3.3 5.1c-3.4-.9-1.4-11.7-.7-16 .7 4.5 3.1 14.5.7 16zm1.2-.3c.2-3.7 3.9-2.7 6.5-4.7-.5 2-2 5.2-6.5 4.7zm-4.2 5c-3.4-1-1.4-12.6-1.6-17.4 1 4.2 4.2 16.3 1.6 17.4zm1.6-.5c2.8.9 6.5-1 6.8-4.3-2.5 1.7-6.3.4-6.8 4.3z"/>
|
<path d="M238.4 151.8c4.4 1.5 8-3.2 9.1-8.7-3.6 5-9.5 5-9 8.7zm-3.3 5.1c-3.4-.9-1.4-11.7-.7-16 .7 4.5 3.1 14.5.7 16zm1.2-.3c.2-3.7 3.9-2.7 6.5-4.7-.5 2-2 5.2-6.5 4.7zm-4.2 5c-3.4-1-1.4-12.6-1.6-17.4 1 4.2 4.2 16.3 1.6 17.4zm1.6-.5c2.8.9 6.5-1 6.8-4.3-2.5 1.7-6.3.4-6.8 4.3z"/>
|
||||||
<path d="M229.5 166.7c-3.2.3-1.8-9.6-1.8-18.8 1.2 8.6 4.5 16.5 1.8 18.8z"/>
|
<path d="M229.5 166.7c-3.2.3-1.8-9.6-1.8-18.8 1.2 8.6 4.5 16.5 1.8 18.8z"/>
|
||||||
|
@ -59,23 +59,23 @@
|
||||||
<path d="M209.8 192.3c1.7 5.7 4.2 11.4 7.2 11 1.5-3.3-2.9-3.7-7.2-11z"/>
|
<path d="M209.8 192.3c1.7 5.7 4.2 11.4 7.2 11 1.5-3.3-2.9-3.7-7.2-11z"/>
|
||||||
<path d="M218.1 202.4c-1.2-2.5 3-3.7 3.8-6.9.5 4.6.1 7.6-3.8 6.9zm-7.1-3.6c2.5 5.1 3.6 11 7 10.1 1.3-4-3.8-4.8-7-10.1z"/>
|
<path d="M218.1 202.4c-1.2-2.5 3-3.7 3.8-6.9.5 4.6.1 7.6-3.8 6.9zm-7.1-3.6c2.5 5.1 3.6 11 7 10.1 1.3-4-3.8-4.8-7-10.1z"/>
|
||||||
<path d="M218.7 208c-1.5-2.8 2.7-3.7 3.8-7.4.5 4.8 0 8.3-3.8 7.3zm7.2-34.5c2.4.6 5-2.1 4.1-6.2-2.8.6-4 3.2-4.1 6.2zm-7.9-2.1c.2 1.2 1.7 1.3 1.2-.4a5.3 5.3 0 0 1 0-3.4 7.5 7.5 0 0 0 0-4.6c-.4-1-1.8-.4-1.2.4.6.9.7 2.8.2 3.7-.6 1.3-.4 3-.2 4.3zm22.9 16c-1 1.3-2.9.4-1.4-1.5 1.2-1.5 3-2.8 3-4.4.2-2 1.3-5 2.4-6.1 1.1-1.1 2.4.4 1.2 1.2-1.3.8-2.2 4.4-2.1 5.8-.1 2-2 3.5-3.1 5zm-3-2.3c-1 1.4-2.4.5-1.6-1.7.7-1.5.8-3.5 1.6-4.6 1.2-1.7 3-3.1 4.1-4.2 1.2-1 2 0 1 1a27 27 0 0 0-3.3 4c-1.4 2.2-.8 4-1.8 5.5zm-15.7-7.2c-.1 2 1.5 2.4 1.4-.4 0-3-2.2-5.8-1-10.3.8-2.2.8-6.3.4-8.4-.4-2.2-2-.8-1.3.9.6 2-.1 5.6-.6 7.5-1.5 5.4 1.2 8 1 10.7zm4.3-11c-.2 1.9-1.8 2-1.3-.5.4-2 .4-3.6 0-5.3-.6-2.1-.4-5.7 0-7.2.5-1.6 2-.7 1.4.5a9.9 9.9 0 0 0-.3 5.9c.6 2 .5 4.8.2 6.7zM210.9 204c.8.9 2 .3 1-1-1-1-.7-1.2-1.3-2.4-.6-1.4-.5-2.1-1.2-3-.7-1-1.6 0-1 .7.8 1 .6 1.6 1 2.5 1 1.5.7 2.3 1.5 3.2zm20.4 24.6a8.6 8.6 0 0 1 4.4 6.7 16 16 0 0 0 2 7.1c-2-.5-3-3.7-3.3-6.8-.3-3.2-2-4.5-3-7zm5.1 5.9c1.7 3.1 4 4.3 4.2 6.6.2 2.7.4 2.8 1.1 5.4-2-.5-2.5-.7-3-4.7-.3-2.8-2.6-4.7-2.3-7.3z"/>
|
<path d="M218.7 208c-1.5-2.8 2.7-3.7 3.8-7.4.5 4.8 0 8.3-3.8 7.3zm7.2-34.5c2.4.6 5-2.1 4.1-6.2-2.8.6-4 3.2-4.1 6.2zm-7.9-2.1c.2 1.2 1.7 1.3 1.2-.4a5.3 5.3 0 0 1 0-3.4 7.5 7.5 0 0 0 0-4.6c-.4-1-1.8-.4-1.2.4.6.9.7 2.8.2 3.7-.6 1.3-.4 3-.2 4.3zm22.9 16c-1 1.3-2.9.4-1.4-1.5 1.2-1.5 3-2.8 3-4.4.2-2 1.3-5 2.4-6.1 1.1-1.1 2.4.4 1.2 1.2-1.3.8-2.2 4.4-2.1 5.8-.1 2-2 3.5-3.1 5zm-3-2.3c-1 1.4-2.4.5-1.6-1.7.7-1.5.8-3.5 1.6-4.6 1.2-1.7 3-3.1 4.1-4.2 1.2-1 2 0 1 1a27 27 0 0 0-3.3 4c-1.4 2.2-.8 4-1.8 5.5zm-15.7-7.2c-.1 2 1.5 2.4 1.4-.4 0-3-2.2-5.8-1-10.3.8-2.2.8-6.3.4-8.4-.4-2.2-2-.8-1.3.9.6 2-.1 5.6-.6 7.5-1.5 5.4 1.2 8 1 10.7zm4.3-11c-.2 1.9-1.8 2-1.3-.5.4-2 .4-3.6 0-5.3-.6-2.1-.4-5.7 0-7.2.5-1.6 2-.7 1.4.5a9.9 9.9 0 0 0-.3 5.9c.6 2 .5 4.8.2 6.7zM210.9 204c.8.9 2 .3 1-1-1-1-.7-1.2-1.3-2.4-.6-1.4-.5-2.1-1.2-3-.7-1-1.6 0-1 .7.8 1 .6 1.6 1 2.5 1 1.5.7 2.3 1.5 3.2zm20.4 24.6a8.6 8.6 0 0 1 4.4 6.7 16 16 0 0 0 2 7.1c-2-.5-3-3.7-3.3-6.8-.3-3.2-2-4.5-3-7zm5.1 5.9c1.7 3.1 4 4.3 4.2 6.6.2 2.7.4 2.8 1.1 5.4-2-.5-2.5-.7-3-4.7-.3-2.8-2.6-4.7-2.3-7.3z"/>
|
||||||
<path stroke="none" d="M289 263.3c1 1.8 2 4.5 4 4 0-1.3-2.1-2.3-4-4zm3 .6c3.7 1.6 7 1.2 7.5 3.6-3.6.4-5-1-7.6-3.6zm-16.1-12.7a14 14 0 0 1 5 7.7 29 29 0 0 0 3.6 7.8 13 13 0 0 1-5.3-7.4c-.7-3-1.6-5.3-3.3-8zm3.1 0c2.8 2.2 5.4 4.8 6.2 7.9.8 2.9 1.3 5.1 3.2 8-3-1.9-4.1-4.7-5-7.8-.7-3-2.5-5.2-4.4-8zm9.2 7.3a1.1 1.1 0 0 1 .7-1.2 33.4 33.4 0 0 1 2.6-.8c1-.3 1.6.4 1.6.9v2c0 .7-.2.8-.7.9-.7.1-1.7.2-2.4.7-.6.4-1.2.1-1.5-.5l-.3-2zm10.6 0c0-.6-.2-1.1-.6-1.2a5.4 5.4 0 0 0-2.4-.4c-1 0-1.1.2-1.1.6v2.1c0 .8 0 .8.4 1 .7 0 1.8 0 2.5.6.5.3 1 0 1.1-.6l.1-2.1z"/>
|
<path stroke="none" d="M289 263.3c1 1.8 2 4.5 4 4 0-1.3-2.1-2.3-4-4m3 .6c3.7 1.6 7 1.2 7.5 3.6-3.6.4-5-1-7.6-3.6zm-16.1-12.7a14 14 0 0 1 5 7.7 29 29 0 0 0 3.6 7.8 13 13 0 0 1-5.3-7.4c-.7-3-1.6-5.3-3.3-8zm3.1 0c2.8 2.2 5.4 4.8 6.2 7.9.8 2.9 1.3 5.1 3.2 8-3-1.9-4.1-4.7-5-7.8-.7-3-2.5-5.2-4.4-8zm9.2 7.3a1.1 1.1 0 0 1 .7-1.2 33.4 33.4 0 0 1 2.6-.8c1-.3 1.6.4 1.6.9v2c0 .7-.2.8-.7.9-.7.1-1.7.2-2.4.7-.6.4-1.2.1-1.5-.5zm10.6 0c0-.6-.2-1.1-.6-1.2a5.4 5.4 0 0 0-2.4-.4c-1 0-1.1.2-1.1.6v2.1c0 .8 0 .8.4 1 .7 0 1.8 0 2.5.6.5.3 1 0 1.1-.6z"/>
|
||||||
</g>
|
</g>
|
||||||
<use xlink:href="#af-a" width="100%" height="100%" x="-600" transform="scale(-1 1)"/>
|
<use xlink:href="#af-a" width="100%" height="100%" x="-600" transform="scale(-1 1)"/>
|
||||||
<g stroke="none">
|
<g stroke="none">
|
||||||
<path d="M328.5 286.6c0 1.2.2 2.2 1 3.1a19 19 0 0 0-13.8 1.1c-1.8.8-4-1-1.9-2.7 3-2.3 9.7-1 14.7-1.5zm-57.5 0a7 7 0 0 1-.4 3c4.4-1.7 9.1-.2 13.6 1.6 3 1.3 3.3-1 2.8-1.7a6.5 6.5 0 0 0-5-2.9h-11zm3.8-21.7c-1.3-.5-2.7 0-4 1.4-4.3 4.2-9.4 8.3-13.5 11.6-1.5 1.3-3 3.7 3.4 6 .3.2 5 2 8 2 1.3 0 1.3 1.8 1 2.3-.5 1-.1 1.4-1.1 2.3-1.1 1 0 2.1 1 1.3 3.6-3.2 9.6-1.1 15.3.7 1.4.4 3.8.3 3.8-1.6 0-2 1.5-3.4 2.4-3.5 2.4.4 14 .5 17.5.1 2-.3 2.2 2.9 3.3 4 .8.9 3.7 1.1 5.8.2 4-1.8 10-1.8 12.5 0 1 .7 1.9 0 1.3-.7-.8-1-.7-1.6-1.1-2.4-1-2-.2-2.4.8-2.5 11-1.5 14.6-5.2 11.2-8.3-4.4-3.8-9.2-7.7-13.4-12.2-1.2-1.2-2-1.7-4.3-.7a66.5 66.5 0 0 1-25.3 5.9 76 76 0 0 1-24.6-5.8z"/>
|
<path d="M328.5 286.6c0 1.2.2 2.2 1 3.1a19 19 0 0 0-13.8 1.1c-1.8.8-4-1-1.9-2.7 3-2.3 9.7-1 14.7-1.5m-57.5 0a7 7 0 0 1-.4 3c4.4-1.7 9.1-.2 13.6 1.6 3 1.3 3.3-1 2.8-1.7a6.5 6.5 0 0 0-5-2.9zm3.8-21.7c-1.3-.5-2.7 0-4 1.4-4.3 4.2-9.4 8.3-13.5 11.6-1.5 1.3-3 3.7 3.4 6 .3.2 5 2 8 2 1.3 0 1.3 1.8 1 2.3-.5 1-.1 1.4-1.1 2.3-1.1 1 0 2.1 1 1.3 3.6-3.2 9.6-1.1 15.3.7 1.4.4 3.8.3 3.8-1.6 0-2 1.5-3.4 2.4-3.5 2.4.4 14 .5 17.5.1 2-.3 2.2 2.9 3.3 4 .8.9 3.7 1.1 5.8.2 4-1.8 10-1.8 12.5 0 1 .7 1.9 0 1.3-.7-.8-1-.7-1.6-1.1-2.4-1-2-.2-2.4.8-2.5 11-1.5 14.6-5.2 11.2-8.3-4.4-3.8-9.2-7.7-13.4-12.2-1.2-1.2-2-1.7-4.3-.7a66.5 66.5 0 0 1-25.3 5.9 76 76 0 0 1-24.6-5.8z"/>
|
||||||
<path fill="#bd6b00" d="m326.6 265.5-1.6.4c-9 3.2-17.2 5.4-25.7 5.4-8.3 0-17-2.4-24.9-5.6a2.3 2.3 0 0 0-1.5 0c-.5.1-1 .4-1.3.7a115.5 115.5 0 0 1-11.8 10.3c-.7.5-.6 1.8.5 2.2 8.3 3 16.4 8.5 39.6 8.3 23.5-.2 31.8-5.6 39.2-8.1.5-.2 1-.5 1.3-1a1 1 0 0 0 .1-.8 2 2 0 0 0-.6-.8c-4.3-3.5-8.8-6.3-11.8-10.4-.3-.5-.9-.6-1.5-.5zm0 .5c.5 0 1 0 1.1.3 3 4.3 7.7 7 11.9 10.5l.4.7a.5.5 0 0 1 0 .4c-.1.3-.6.6-1 .7-7.6 2.6-15.7 8-39 8.2-23.2.2-31.2-5.3-39.5-8.3-.8-.4-.7-1.2-.4-1.4 4.2-3.2 8.2-6.8 11.8-10.4a2.5 2.5 0 0 1 1.1-.6h1.2a68 68 0 0 0 25 5.6c8.7 0 17-2.2 26-5.3a6.7 6.7 0 0 1 1.5-.4z"/>
|
<path fill="#bd6b00" d="m326.6 265.5-1.6.4c-9 3.2-17.2 5.4-25.7 5.4-8.3 0-17-2.4-24.9-5.6a2.3 2.3 0 0 0-1.5 0c-.5.1-1 .4-1.3.7a115.5 115.5 0 0 1-11.8 10.3c-.7.5-.6 1.8.5 2.2 8.3 3 16.4 8.5 39.6 8.3 23.5-.2 31.8-5.6 39.2-8.1.5-.2 1-.5 1.3-1a1 1 0 0 0 .1-.8 2 2 0 0 0-.6-.8c-4.3-3.5-8.8-6.3-11.8-10.4-.3-.5-.9-.6-1.5-.5zm0 .5c.5 0 1 0 1.1.3 3 4.3 7.7 7 11.9 10.5l.4.7a.5.5 0 0 1 0 .4c-.1.3-.6.6-1 .7-7.6 2.6-15.7 8-39 8.2-23.2.2-31.2-5.3-39.5-8.3-.8-.4-.7-1.2-.4-1.4 4.2-3.2 8.2-6.8 11.8-10.4a2.5 2.5 0 0 1 1.1-.6h1.2a68 68 0 0 0 25 5.6c8.7 0 17-2.2 26-5.3a6.7 6.7 0 0 1 1.5-.4z"/>
|
||||||
<path d="M269.7 114.6c0-1.4 2-1.5 1.8.4-.3 2.3 4.5 8.3 4.9 12 .3 2.5-1.5 4.6-3.2 6a6.6 6.6 0 0 1-6.8.5c-.9-.8-1.7-3.3-1-4.3.2-.3 1.3 3.7 3.7 3.7 3.3 0 6-2.5 6-4.7.2-3.8-5.3-9.8-5.4-13.6zm9.5 9.4c.6-.4 1.4 1.3.8 1.7-.5.3-1.5-1.3-.8-1.8zm1.5-3.5c-.3.2-.8 0-.7-.2a12 12 0 0 1 3.6-3.3c.4-.2 1 .4.8.7a11 11 0 0 1-3.7 2.8zm12.6-10c.3-.6 2.1-1.3 2.6-1.7.4-.5.6.4.4.7-.3.7-1.9 1.7-2.6 1.8-.3 0-.6-.4-.4-.7zm4.3.3a8.3 8.3 0 0 1 2.5-3.4c.5-.3 1.3 0 1.1.4a9 9 0 0 1-2.9 3.3c-.3.3-.8 0-.7-.3zm-3.7 2.7c-.3.2-.1.7.1.8.6.2 1.5.2 2 0 .6-.4.3-2.9-.5-1.6-.6.8-1 .6-1.6.8zm-7.3 5.6c-1.3-1 .4-2.4 1.7-1.4 2.7 2-4 9.8-7.6 13.4-.7.7-1.3-1-.4-1.9a33.7 33.7 0 0 0 6.7-7.6c.4-.5.7-1.6-.4-2.5zm15.3-6.6c.1-1-1.6 0-1.6-1.3 0-.7 1.9-1.2 2.7-.4 1.3 1.4.3 3.7-2 3.9-1.8 0-5 2.7-4.5 3.2.5.7 5.4 1.1 8.3.7 1.8-.3 1.4 1.3-.4 1.5-1.8.2-3.2 0-4.8.6-2 .5-2.8 3-3.9 4-.2.2-.8-.8-.6-1.2.8-1.2 2-3 3.4-3.6.8-.3-2.4-.4-3.4-.7-.8-.2-.6-1.3-.3-1.9.4-.8 3.4-3.9 4.7-3.8 1.1 0 2.3-.3 2.4-1zm5 .2c.6-.5 1-1.3 1.5-1.8.3-.3.9 0 .8.8-.1.7-1 1.2-1.5 1.7-.5.3-1-.4-.7-.7zm6.5-2.3c.9 0 1 1.6.2 1.8-.6.2-1-1.7-.2-1.8zm-2.1 5c0 1.5.7 1.4 2 1.3 1.3 0 2.4 0 2.4-1.2 0-1.3-.7-2.5-1-1.6-.1.8-.3 2.2-.8 1.6-.4-.5-.2-.6-1 .2-.5.5-.5-.2-.8-.6-.2-.3-.8.2-.8.4zm-9.2 7.2c-.3 1.9 0 4.5.9 4.5 1.2 0 3.6-4 4.8-6.2.7-1.2 1.8-1.4 1.3-.1-.7 1.9-.6 6 0 7.2.4.6 3-.6 3.4-1.5.8-1.7.1-4.8.4-6.7.1-1.2 1.3-1.5 1.2-.3a75.6 75.6 0 0 0-.1 7.5c0 1 2.9 2.4 3.3-.6.2-1.8 1.2-3.7 0-5.7-.8-1.3 1.1-1.2 2.1.6.7 1.2-.6 3.2-.5 4.7 0 2.4-1.8 3.8-3.1 3.8-1.2 0-2-1.5-3-1.5s-2.2 1.7-3 1.6c-3.6-.2-1.7-5.3-2.8-5.4-1.2 0-2.5 5-4 4.9-1.4-.2-3-4.2-2.3-5.8.5-1.6 1.5-2 1.4-1zm16.9-8c-1.7-1 0-3.7.9-2.8 1.6 2 3.2 6.5 4.4 6.9.7.2.6-3.4 1.1-5 .4-1.3 1.8-.9 1.6.7-.1.5-2 6.4-1.8 6.6a47.1 47.1 0 0 1 3.3 7.8c.3 1.2-1.1.4-1.3.2-.9-1.4-2.4-6.5-2.4-6.2l-1.7 7.7c-.2 1-1.7.8-1.3-1 .3-1.4 2.3-8.3 2.2-8.6a17.2 17.2 0 0 0-5-6.3z"/>
|
<path d="M269.7 114.6c0-1.4 2-1.5 1.8.4-.3 2.3 4.5 8.3 4.9 12 .3 2.5-1.5 4.6-3.2 6a6.6 6.6 0 0 1-6.8.5c-.9-.8-1.7-3.3-1-4.3.2-.3 1.3 3.7 3.7 3.7 3.3 0 6-2.5 6-4.7.2-3.8-5.3-9.8-5.4-13.6m9.5 9.4c.6-.4 1.4 1.3.8 1.7-.5.3-1.5-1.3-.8-1.8zm1.5-3.5c-.3.2-.8 0-.7-.2a12 12 0 0 1 3.6-3.3c.4-.2 1 .4.8.7a11 11 0 0 1-3.7 2.8m12.6-10c.3-.6 2.1-1.3 2.6-1.7.4-.5.6.4.4.7-.3.7-1.9 1.7-2.6 1.8-.3 0-.6-.4-.4-.7zm4.3.3a8.3 8.3 0 0 1 2.5-3.4c.5-.3 1.3 0 1.1.4a9 9 0 0 1-2.9 3.3c-.3.3-.8 0-.7-.3m-3.7 2.7c-.3.2-.1.7.1.8.6.2 1.5.2 2 0 .6-.4.3-2.9-.5-1.6-.6.8-1 .6-1.6.8m-7.3 5.6c-1.3-1 .4-2.4 1.7-1.4 2.7 2-4 9.8-7.6 13.4-.7.7-1.3-1-.4-1.9a33.7 33.7 0 0 0 6.7-7.6c.4-.5.7-1.6-.4-2.5m15.3-6.6c.1-1-1.6 0-1.6-1.3 0-.7 1.9-1.2 2.7-.4 1.3 1.4.3 3.7-2 3.9-1.8 0-5 2.7-4.5 3.2.5.7 5.4 1.1 8.3.7 1.8-.3 1.4 1.3-.4 1.5-1.8.2-3.2 0-4.8.6-2 .5-2.8 3-3.9 4-.2.2-.8-.8-.6-1.2.8-1.2 2-3 3.4-3.6.8-.3-2.4-.4-3.4-.7-.8-.2-.6-1.3-.3-1.9.4-.8 3.4-3.9 4.7-3.8 1.1 0 2.3-.3 2.4-1m5 .2c.6-.5 1-1.3 1.5-1.8.3-.3.9 0 .8.8-.1.7-1 1.2-1.5 1.7-.5.3-1-.4-.7-.7zm6.5-2.3c.9 0 1 1.6.2 1.8-.6.2-1-1.7-.2-1.8m-2.1 5c0 1.5.7 1.4 2 1.3 1.3 0 2.4 0 2.4-1.2 0-1.3-.7-2.5-1-1.6-.1.8-.3 2.2-.8 1.6-.4-.5-.2-.6-1 .2-.5.5-.5-.2-.8-.6-.2-.3-.8.2-.8.4zm-9.2 7.2c-.3 1.9 0 4.5.9 4.5 1.2 0 3.6-4 4.8-6.2.7-1.2 1.8-1.4 1.3-.1-.7 1.9-.6 6 0 7.2.4.6 3-.6 3.4-1.5.8-1.7.1-4.8.4-6.7.1-1.2 1.3-1.5 1.2-.3a75.6 75.6 0 0 0-.1 7.5c0 1 2.9 2.4 3.3-.6.2-1.8 1.2-3.7 0-5.7-.8-1.3 1.1-1.2 2.1.6.7 1.2-.6 3.2-.5 4.7 0 2.4-1.8 3.8-3.1 3.8-1.2 0-2-1.5-3-1.5s-2.2 1.7-3 1.6c-3.6-.2-1.7-5.3-2.8-5.4-1.2 0-2.5 5-4 4.9-1.4-.2-3-4.2-2.3-5.8.5-1.6 1.5-2 1.4-1m16.9-8c-1.7-1 0-3.7.9-2.8 1.6 2 3.2 6.5 4.4 6.9.7.2.6-3.4 1.1-5 .4-1.3 1.8-.9 1.6.7-.1.5-2 6.4-1.8 6.6a47.1 47.1 0 0 1 3.3 7.8c.3 1.2-1.1.4-1.3.2-.9-1.4-2.4-6.5-2.4-6.2l-1.7 7.7c-.2 1-1.7.8-1.3-1 .3-1.4 2.3-8.3 2.2-8.6a17.2 17.2 0 0 0-5-6.3"/>
|
||||||
<path d="M322 131.2c-.4 0-1.2 1 1.2 1.5 3.1.6 6.6-.5 7.6-3.6 1.3-3.7 2-7.2 2.7-8.5.8-1.5 1.8-1.4 1-3.6-.5-1.7-1.5-1.2-1.7-.3-.5 2.3-2.6 10-3.3 11.3-1.2 2.6-3.7 3.6-7.5 3.2z"/>
|
<path d="M322 131.2c-.4 0-1.2 1 1.2 1.5 3.1.6 6.6-.5 7.6-3.6 1.3-3.7 2-7.2 2.7-8.5.8-1.5 1.8-1.4 1-3.6-.5-1.7-1.5-1.2-1.7-.3-.5 2.3-2.6 10-3.3 11.3-1.2 2.6-3.7 3.6-7.5 3.2"/>
|
||||||
<path d="M328.4 119c-.4-.7-1.2 0-1 .7a1.2 1.2 0 0 0 1.2 1c.7 0 2.2.1 2.2-1 0-.8-.7-1.5-1.1-.6-.5.8-1 .7-1.3 0zm.7-3c-.2.2 0 1.1.3 1a7 7 0 0 0 3.3-.8c.2-.2.1-.7-.2-.7-1 0-2.6 0-3.4.5zm8.8 2.3c.8-1.2 2.8-1.3 2 .4a614.3 614.3 0 0 1-6.3 12.3c-.8 1.4-1.4.7-.8-.4.7-1.4 4.9-12 5.1-12.3z"/>
|
<path d="M328.4 119c-.4-.7-1.2 0-1 .7a1.2 1.2 0 0 0 1.2 1c.7 0 2.2.1 2.2-1 0-.8-.7-1.5-1.1-.6-.5.8-1 .7-1.3 0zm.7-3c-.2.2 0 1.1.3 1a7 7 0 0 0 3.3-.8c.2-.2.1-.7-.2-.7-1 0-2.6 0-3.4.5m8.8 2.3c.8-1.2 2.8-1.3 2 .4a614.3 614.3 0 0 1-6.3 12.3c-.8 1.4-1.4.7-.8-.4.7-1.4 4.9-12 5.1-12.3"/>
|
||||||
<path d="M330.2 133c-.2-.8-1.5-2-1.3.2.2 3.8 5.5 2.6 7 1.3s.3 4.3 2.2 4.9c1 .3 3-1.1 4-2.4 2.7-3.5 4.5-8.6 7-12 1-1.4-.5-2.4-1-1.3-2.4 3.8-5.2 11.6-8.3 13.6-2.5 1.6-1.7-2-1.8-3.2-.1-.8-1.1-2-2.4-.9a5.5 5.5 0 0 1-3.7 1.2c-.7 0-1.4 0-1.7-1.4z"/>
|
<path d="M330.2 133c-.2-.8-1.5-2-1.3.2.2 3.8 5.5 2.6 7 1.3s.3 4.3 2.2 4.9c1 .3 3-1.1 4-2.4 2.7-3.5 4.5-8.6 7-12 1-1.4-.5-2.4-1-1.3-2.4 3.8-5.2 11.6-8.3 13.6-2.5 1.6-1.7-2-1.8-3.2-.1-.8-1.1-2-2.4-.9a5.5 5.5 0 0 1-3.7 1.2c-.7 0-1.4 0-1.7-1.4"/>
|
||||||
<path d="M339.6 126c0-.3-1.1-.4-1 .7 0 .8 1 1 1.1 1 1.5-1.2-.3-.6-.1-1.8zm-2.3 4.4c-.3 0-.6 1 .2 1.1l3.9-.2c.4 0 .6-.9-.4-.8-1.2 0-2.7-.3-3.7 0zm-62-16.6c.5 0 1.6 1.4 1.5 1.9 0 .2-1.2 0-1.5-.3-.3-.3-.2-1.6 0-1.6zm-5.3 10.4c-1 .6.2 1.7 1 1.2 2.8-1.9 7-3.8 8-7.5.3-1.2 1.4-3.1 2.5-3.5 1-.5 2.6 1.9 3.6 0 .6-1 2.7.7 3.2-.4.6-1.3.3-2 .3-3.4 0-.8-.7-1-1.2.3-.2.6 0 1.2-.1 1.6-.2.2-.6.4-1 .2-.2-.2 0-.7-.6-1-.2 0-.6-.1-.8.2-.7 1.3-1 2.5-2.1 1-.9-1-1.4-3.1-2-.3-.2 1-1.7 2.4-2.6 2.4-1.1 0-.8-3-3.2-2.5-1.3.3-1.2 2.7-1 3.5.3 1.3 4 .4 3.7 1.2-.6 2.7-4.4 5.4-7.7 7zm-22.7 13.2c-.1.5.5 1.7 1.1 1.8.6 0 1-1.3.8-1.8-.2-.3-1.8-.3-1.9 0zm3.3 4.9c-.4-.4-1.6.7-.6 1.5.5.5 2.5 1.1 3 .2.8-1.2-.7-5.5 0-6 .5-.5 2.8 2.8 4 3 2.7.4 2-4.6 5-4.2 1.9.2 2.1-2.2 1.8-3.8-.2-1.5-2.6-3.6-3.7-4.6-1.4-1.2-2.1 1-1.2 1.6 1.2 1 3.3 2.9 3.6 4.1.1.6-1.4 1.8-2 1.5-1.4-.8-2.6-4-3.8-4.7-.4-.2-1.4.3-1 1.3.6 1.1 3 2.7 3.1 3.9.1 1-1 3.2-1.8 3.2-.9 0-3-2.7-3.7-4-.4-.5-1.5-.5-1.7.4a22 22 0 0 0 .5 5.5c.2 1.6-.9 1.7-1.5 1.1zm-4-8.6c-.4.4.8 1.2 1 1 .4-.4 2.1-2.3 1.8-3-.3-.6-2.6-2-3-1.3-.7 1.1 2.2 1.7 1.7 2a7 7 0 0 0-1.5 1.3zm4.1-8.4s.8 2.5 1.4 1.4c.4-.7-1.4-1.4-1.4-1.4zm1.2 4c-.2 0-1 .7-.5 1 .8.4 2.9.8 2.4-.7-.3-.9 3.2 0 2.3-2.4a3.7 3.7 0 0 0-1.7-1.7c-.4 0-1.5.5-.8.9.5.2 2 1.1 1.5 1.7-.7.6-1.1-.3-1.9-.1-.4 0-.1 1.2-.4 1.5 0 .2-.7-.4-.9-.3zm5.5-9.5a3.5 3.5 0 0 0-1.2 2c0 .2.3.6.5.5a3.2 3.2 0 0 0 1.2-1.9c0-.3-.2-.8-.5-.6zm2.8-.3c-.8-1 1-2.6 1.7-.5.5 1.3 5.5 7.9 6.5 10.1.8 1.5 0 2.1-.9 1-2.5-3.2-4.6-7.2-7.3-10.6zm5.2.1c.9-1 2.7-3 2.2-4-.4-1-1.5-1-1.7-.7-1 1.3.8 1 .5 1.4-.5 1-1 1.6-1.3 2.6-.1.3.1.9.3.7zm77.8 3.2c-.7-.5.6-3 1.5-2 2.3 2.7 3.4 11.6 4.1 18.3 0 0-1 .9-1 .7 0-3.5-1.5-14.4-4.6-17zm-53.1-8.6c-.8-1.8 1.1-2.4 1.4-1.2 1.3 5.8 4.5 10.2 7 14.1.7 1.2 0 2-1.7.8-1.2-.8-2.5-3.9-3-4-1.2-.2-3.8 5-9.1 3.5-1.4-.4-1.3-4.5-1.4-6.3 0-.9 1-1 1 0 0 1.7 0 5.2 2.1 5.4 1.8 0 5.6-2.4 6.4-4.4.8-2-1.9-5.9-2.7-8z"/>
|
<path d="M339.6 126c0-.3-1.1-.4-1 .7 0 .8 1 1 1.1 1 1.5-1.2-.3-.6-.1-1.8zm-2.3 4.4c-.3 0-.6 1 .2 1.1l3.9-.2c.4 0 .6-.9-.4-.8-1.2 0-2.7-.3-3.7 0zm-62-16.6c.5 0 1.6 1.4 1.5 1.9 0 .2-1.2 0-1.5-.3-.3-.3-.2-1.6 0-1.6m-5.3 10.4c-1 .6.2 1.7 1 1.2 2.8-1.9 7-3.8 8-7.5.3-1.2 1.4-3.1 2.5-3.5 1-.5 2.6 1.9 3.6 0 .6-1 2.7.7 3.2-.4.6-1.3.3-2 .3-3.4 0-.8-.7-1-1.2.3-.2.6 0 1.2-.1 1.6-.2.2-.6.4-1 .2-.2-.2 0-.7-.6-1-.2 0-.6-.1-.8.2-.7 1.3-1 2.5-2.1 1-.9-1-1.4-3.1-2-.3-.2 1-1.7 2.4-2.6 2.4-1.1 0-.8-3-3.2-2.5-1.3.3-1.2 2.7-1 3.5.3 1.3 4 .4 3.7 1.2-.6 2.7-4.4 5.4-7.7 7m-22.7 13.2c-.1.5.5 1.7 1.1 1.8.6 0 1-1.3.8-1.8-.2-.3-1.8-.3-1.9 0m3.3 4.9c-.4-.4-1.6.7-.6 1.5.5.5 2.5 1.1 3 .2.8-1.2-.7-5.5 0-6 .5-.5 2.8 2.8 4 3 2.7.4 2-4.6 5-4.2 1.9.2 2.1-2.2 1.8-3.8-.2-1.5-2.6-3.6-3.7-4.6-1.4-1.2-2.1 1-1.2 1.6 1.2 1 3.3 2.9 3.6 4.1.1.6-1.4 1.8-2 1.5-1.4-.8-2.6-4-3.8-4.7-.4-.2-1.4.3-1 1.3.6 1.1 3 2.7 3.1 3.9.1 1-1 3.2-1.8 3.2-.9 0-3-2.7-3.7-4-.4-.5-1.5-.5-1.7.4a22 22 0 0 0 .5 5.5c.2 1.6-.9 1.7-1.5 1.1m-4-8.6c-.4.4.8 1.2 1 1 .4-.4 2.1-2.3 1.8-3-.3-.6-2.6-2-3-1.3-.7 1.1 2.2 1.7 1.7 2a7 7 0 0 0-1.5 1.3m4.1-8.4s.8 2.5 1.4 1.4c.4-.7-1.4-1.4-1.4-1.4m1.2 4c-.2 0-1 .7-.5 1 .8.4 2.9.8 2.4-.7-.3-.9 3.2 0 2.3-2.4a3.7 3.7 0 0 0-1.7-1.7c-.4 0-1.5.5-.8.9.5.2 2 1.1 1.5 1.7-.7.6-1.1-.3-1.9-.1-.4 0-.1 1.2-.4 1.5 0 .2-.7-.4-.9-.3zm5.5-9.5a3.5 3.5 0 0 0-1.2 2c0 .2.3.6.5.5a3.2 3.2 0 0 0 1.2-1.9c0-.3-.2-.8-.5-.6m2.8-.3c-.8-1 1-2.6 1.7-.5.5 1.3 5.5 7.9 6.5 10.1.8 1.5 0 2.1-.9 1-2.5-3.2-4.6-7.2-7.3-10.6m5.2.1c.9-1 2.7-3 2.2-4-.4-1-1.5-1-1.7-.7-1 1.3.8 1 .5 1.4-.5 1-1 1.6-1.3 2.6-.1.3.1.9.3.7m77.8 3.2c-.7-.5.6-3 1.5-2 2.3 2.7 3.4 11.6 4.1 18.3 0 0-1 .9-1 .7 0-3.5-1.5-14.4-4.6-17m-53.1-8.6c-.8-1.8 1.1-2.4 1.4-1.2 1.3 5.8 4.5 10.2 7 14.1.7 1.2 0 2-1.7.8-1.2-.8-2.5-3.9-3-4-1.2-.2-3.8 5-9.1 3.5-1.4-.4-1.3-4.5-1.4-6.3 0-.9 1-1 1 0 0 1.7 0 5.2 2.1 5.4 1.8 0 5.6-2.4 6.4-4.4.8-2-1.9-5.9-2.7-8z"/>
|
||||||
<path d="M344.6 138.4c.4-1.2 6.1-10.8 6.9-12.9.4-1 2 1.8.4 3.3-1.4 1.2-5.5 8-6.3 10.4-.4 1-1.4.5-1-.8z"/>
|
<path d="M344.6 138.4c.4-1.2 6.1-10.8 6.9-12.9.4-1 2 1.8.4 3.3-1.4 1.2-5.5 8-6.3 10.4-.4 1-1.4.5-1-.8"/>
|
||||||
<path d="M354.3 129.3c1-4 3.6.6 1.3 2.8-3.4 3.4-4.5 9.9-10 10.9-1.4.3-4-.7-4.8-1.3-.3-.2.2-1.6 1.1-.9 1.3 1 4.1 1.3 5.6.1a25.4 25.4 0 0 0 6.8-11.6zm-57 12.7c-.3.3-1 .3-1.1.7-.3 1.4 0 2.2-.3 3.6s-1.3 1.4-1.2.3c0-1.4 1.3-3.5.4-3.6-.6-.1-1-.9-.4-1.3 1.1-.7 1.7-.6 2.4-.4.3.1.4.5.2.7z"/>
|
<path d="M354.3 129.3c1-4 3.6.6 1.3 2.8-3.4 3.4-4.5 9.9-10 10.9-1.4.3-4-.7-4.8-1.3-.3-.2.2-1.6 1.1-.9 1.3 1 4.1 1.3 5.6.1a25.4 25.4 0 0 0 6.8-11.6m-57 12.7c-.3.3-1 .3-1.1.7-.3 1.4 0 2.2-.3 3.6s-1.3 1.4-1.2.3c0-1.4 1.3-3.5.4-3.6-.6-.1-1-.9-.4-1.3 1.1-.7 1.7-.6 2.4-.4.3.1.4.5.2.7"/>
|
||||||
<path d="M296.5 140c-1.4 1.4-2.8 1.9-4.1 3.5-.6.6-.5 1.5-.9 2.4-.3.9-1.4 1-1.7.9-.5-.4-.4-2-1-1.2-.6.9-.9 2-1.7 2-.7 0-2-1.5-1.3-1.5 2.3-.3 2.2-2 3-2.2 1-.1 1 1.5 1.7 1.2.4-.2.7-2.1 1.2-2.6 1.5-1.6 2.7-2.4 4.3-3.6.7-.6 1.3.5.5 1.2zm5.3 5c-1.2.2-1 1.7-.6 1.8.5.3 1.4.4 1.7-1.3.2-.7.3 3.5 1.8 1.9 1-1 3.1.2 4-1 .7-.9 1-1.5.4-2.7-.2-.3-1-.2-1 .7 0 .8-.5 1.7-1.3 1.6-.4-.1.2-1.9-.2-2.4a.5.5 0 0 0-.7 0c-.3.4.3 2.2-.6 2.4-1.2.2-.6-1.2-1-1.4-1.7-.8-1.8.2-2.5.3zm9-3c.9-.2.6-.2 2-1.3.5-.4.6.8.5 1.3 0 .7-1 .2-1.3.9-.4.9-.2 3-.4 3.8 0 .4-.8.4-.8 0-.2-1 .1-2 0-3.3 0-.4-.5-1.1 0-1.3zm-5-2.5c-.2.9-.2 1.6-.2 2.3 0 .5 1 .2 1 .1 0-.8.2-2 0-2.3-.2-.1-.7-.3-.8-.1z"/>
|
<path d="M296.5 140c-1.4 1.4-2.8 1.9-4.1 3.5-.6.6-.5 1.5-.9 2.4-.3.9-1.4 1-1.7.9-.5-.4-.4-2-1-1.2-.6.9-.9 2-1.7 2-.7 0-2-1.5-1.3-1.5 2.3-.3 2.2-2 3-2.2 1-.1 1 1.5 1.7 1.2.4-.2.7-2.1 1.2-2.6 1.5-1.6 2.7-2.4 4.3-3.6.7-.6 1.3.5.5 1.2zm5.3 5c-1.2.2-1 1.7-.6 1.8.5.3 1.4.4 1.7-1.3.2-.7.3 3.5 1.8 1.9 1-1 3.1.2 4-1 .7-.9 1-1.5.4-2.7-.2-.3-1-.2-1 .7 0 .8-.5 1.7-1.3 1.6-.4-.1.2-1.9-.2-2.4a.5.5 0 0 0-.7 0c-.3.4.3 2.2-.6 2.4-1.2.2-.6-1.2-1-1.4-1.7-.8-1.8.2-2.5.3zm9-3c.9-.2.6-.2 2-1.3.5-.4.6.8.5 1.3 0 .7-1 .2-1.3.9-.4.9-.2 3-.4 3.8 0 .4-.8.4-.8 0-.2-1 .1-2 0-3.3 0-.4-.5-1.1 0-1.3zm-5-2.5c-.2.9-.2 1.6-.2 2.3 0 .5 1 .2 1 .1 0-.8.2-2 0-2.3-.2-.1-.7-.3-.8-.1"/>
|
||||||
<path d="m299.5 130.2-1.4 5.6-2-3.8v3.9l-4.4-5.2 1.5 5.6-4-3.4 2.2 3.8-7-4.5 4.4 5.2-5.6-2.8 4 3.4-9-3.4 8.7 4.3a29 29 0 0 1 12.6-2.6c4.9 0 9.3 1 12.5 2.6l8.8-4.3-9 3.4 4-3.4-5.5 2.8 4.3-5.2-7 4.5 2.2-3.8-4 3.3 1.5-5.5-4.3 5.2V132l-2 3.8-1.5-5.6z"/>
|
<path d="m299.5 130.2-1.4 5.6-2-3.8v3.9l-4.4-5.2 1.5 5.6-4-3.4 2.2 3.8-7-4.5 4.4 5.2-5.6-2.8 4 3.4-9-3.4 8.7 4.3a29 29 0 0 1 12.6-2.6c4.9 0 9.3 1 12.5 2.6l8.8-4.3-9 3.4 4-3.4-5.5 2.8 4.3-5.2-7 4.5 2.2-3.8-4 3.3 1.5-5.5-4.3 5.2V132l-2 3.8z"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#fff" d="m311.3 295-.3 2.6h-.4l-.1-1.8a9.3 9.3 0 0 0-.5-1.6 7.3 7.3 0 0 0-.5-1.3l-1-1.4.8-2.2a6.6 6.6 0 0 1 1.5 2.4 9.4 9.4 0 0 1 .5 3.2m7-4.2c0 .7-.2 1.2-.5 1.5-.2.3-.6.6-1.3.7l.4 1.5a6.7 6.7 0 0 1 0 2 22.5 22.5 0 0 1-.1 1.3h-.4a8.2 8.2 0 0 0-.1-1.3 5.5 5.5 0 0 0-.2-1l-.4-1a10.5 10.5 0 0 0-.7-1.4l-1-1.7.6-2 1 1c.3.2.6.3 1 .3.8 0 1.2-.4 1.2-1.3h.4v1.4m6.4 4.8-.5 2.1c-.4 0-.6-.3-.8-.7l-.4-1.3a12.4 12.4 0 0 1-.1-1.7 4 4 0 0 1-1 .2 2 2 0 0 1-1.3-.4 1.3 1.3 0 0 1-.5-1c0-.9.3-1.7.7-2.3.5-.7 1-1 1.5-1.1.5 0 .8.1 1 .4a2 2 0 0 1 .3.9v2c0 .9.1 1.5.3 1.9 0 .3.3.6.8 1m-2-3.5c0-.6-.3-.8-.8-.8a1 1 0 0 0-.6.1c-.2.1-.2.2-.2.3 0 .3.3.5 1 .5l.6-.1m8.7 3-.3 2.6c-.5-.4-1-1-1.4-2a25.4 25.4 0 0 1-1.3-4.1 52.8 52.8 0 0 1-1.8 5.5 2.9 2.9 0 0 1-.8.7v-2.5c.6-.7.9-1.1 1-1.5a7.6 7.6 0 0 0 .8-1.7l.5-2.7h.4l.9 2.7c.2.6.5 1.2.9 1.6l1 1.4"/>
|
<path fill="#fff" d="m311.3 295-.3 2.6h-.4l-.1-1.8a9.3 9.3 0 0 0-.5-1.6 7.3 7.3 0 0 0-.5-1.3l-1-1.4.8-2.2a6.6 6.6 0 0 1 1.5 2.4 9.4 9.4 0 0 1 .5 3.2m7-4.2c0 .7-.2 1.2-.5 1.5-.2.3-.6.6-1.3.7l.4 1.5a6.7 6.7 0 0 1 0 2 22.5 22.5 0 0 1-.1 1.3h-.4a8.2 8.2 0 0 0-.1-1.3 5.5 5.5 0 0 0-.2-1l-.4-1a10.5 10.5 0 0 0-.7-1.4l-1-1.7.6-2 1 1c.3.2.6.3 1 .3.8 0 1.2-.4 1.2-1.3h.4v1.4m6.4 4.8-.5 2.1c-.4 0-.6-.3-.8-.7l-.4-1.3a12.4 12.4 0 0 1-.1-1.7 4 4 0 0 1-1 .2 2 2 0 0 1-1.3-.4 1.3 1.3 0 0 1-.5-1c0-.9.3-1.7.7-2.3.5-.7 1-1 1.5-1.1.5 0 .8.1 1 .4a2 2 0 0 1 .3.9v2c0 .9.1 1.5.3 1.9 0 .3.3.6.8 1m-2-3.5c0-.6-.3-.8-.8-.8a1 1 0 0 0-.6.1c-.2.1-.2.2-.2.3 0 .3.3.5 1 .5zm8.7 3-.3 2.6c-.5-.4-1-1-1.4-2a25.4 25.4 0 0 1-1.3-4.1 52.8 52.8 0 0 1-1.8 5.5 2.9 2.9 0 0 1-.8.7v-2.5c.6-.7.9-1.1 1-1.5a7.6 7.6 0 0 0 .8-1.7l.5-2.7h.4l.9 2.7c.2.6.5 1.2.9 1.6l1 1.4"/>
|
||||||
<path fill="#bf0000" d="M350.8 319.4c.4.4.6.8.7 1.2l.4 1.6-.8.1a7.8 7.8 0 0 0-1-1.5 18.8 18.8 0 0 0-1.1-1.2 46 46 0 0 0-1.7-1.5 34.4 34.4 0 0 0-2-1.7c-.4-.2-.6-.4-.6-.5a1.9 1.9 0 0 1-.3-.8 11.2 11.2 0 0 1-.2-1.6l2.7 2.2a44.3 44.3 0 0 1 2.5 2.2l1.4 1.5m-9.5-5.8-.2 2H338l.3-2h3m8.4 8.9-7.6 2.3-1.3-2 6.5-2-.7-.8a2.8 2.8 0 0 0-.9-.6 1.4 1.4 0 0 1-.4 1 2 2 0 0 1-1 .6 3.4 3.4 0 0 1-1.8 0 2 2 0 0 1-1.3-.7 4 4 0 0 1-.7-2.2c0-1 .3-1.6.9-1.8.7-.2 1.8 0 3 .7a8.1 8.1 0 0 1 3 2.4l2.3 3.1m-5.8-4a3.8 3.8 0 0 0-.8-.3 1.1 1.1 0 0 0-.6 0 .7.7 0 0 0-.5.3.5.5 0 0 0 0 .6l.5.2h.6l.4-.3.4-.5m-8-1.6-.5 2-3.2-.3.5-2 3.1.3m7.5 7.7-1.7.4a5.3 5.3 0 0 1-1.7 0 3.6 3.6 0 0 1-1.5-.4c-.3.5-.8 1-1.5 1.2a7.4 7.4 0 0 1-1.6.6l-1.2.3-1-2 1.1-.3a9.1 9.1 0 0 0 1.3-.4l.9-.5-1-.5h-.7a.4.4 0 0 0-.2 0 .6.6 0 0 0-.2.3h-.5c-.5-.8-.6-1.5-.3-2s.9-.8 2-1a6.8 6.8 0 0 1 2.6-.2c.8.1 1.3.4 1.5.9.2.2.2.5.2.7l-.4 1.2h.5a2 2 0 0 0 .6 0l1.7-.3 1 2m-8 1.8-1.6.3a3 3 0 0 1-2.2-.4 5.5 5.5 0 0 1-1.7-2.6l-.8-2.2a2 2 0 0 0-.8-1 4.6 4.6 0 0 0-.9-.5l.6-2.1c.6.3 1 .6 1.4 1l1 1.7.5 1.5 1.1 2.2c.3.3.7.4 1 .3l1.7-.2.7 2m-7-7.5-1 1.9-3-.7 1-1.9 3 .7m1.8 8.4-7.5.7-.4-2 6.2-.7a2.3 2.3 0 0 0-.6-.8 8.3 8.3 0 0 0-1-.6l.5-2c.7.4 1.2.9 1.6 1.3.3.5.6 1.2.8 2.1l.4 2m-6 1a17 17 0 0 1-2.2-.2 10.5 10.5 0 0 1-1.7-.5 5.6 5.6 0 0 1-1.3.4 9.9 9.9 0 0 1-1.7 0h-2a2.5 2.5 0 0 1-1.2-.3c-.3-.2-.5-.5-.8-1a4.1 4.1 0 0 1-1.5 1l-1.7.1h-1.7l.2-2.1h1.7c.8 0 1.5 0 2.1-.4a2 2 0 0 0 1.3-1.8l.7.1a30.2 30.2 0 0 0-.1 1.3c0 .3 0 .5.3.7.3.2.6.3 1 .3h1.5c1 0 1.6 0 2-.2.6-.2.9-.5 1-1.1l.1-.4s.3 0 .5-.2l.5-.2v.4a8.9 8.9 0 0 1 0 .3l-.3 1.1a12.4 12.4 0 0 0 2 .5c.1-.2 0-.4-.1-.7l-.3-.6a.5.5 0 0 1 .1-.3l.3-.2 1-.9.5 1v1l-.2 2.9m-11.3-8.7-2 1.3-1.3-.9-1.4 1-1.9-1 1.8-1.3 1.5.8 1.5-1 1.8 1m-3 8.2-7.3-1.2.8-2 6.2 1c0-.4 0-.7-.2-1a5.2 5.2 0 0 0-.5-.8l1.6-1.7c.4.6.6 1 .7 1.6 0 .5-.2 1.2-.5 2.1l-.8 2m-6.1-1-1.6-.3c-.9-.2-1.4-.6-1.5-1.2-.2-.6.1-1.5.8-2.8l1.2-2c.3-.5.4-.9.3-1.2a2.2 2.2 0 0 0-.3-.7l2.2-1.6c.3.5.3 1 .3 1.4 0 .5-.3 1.1-.7 1.8l-.8 1.4a5.8 5.8 0 0 0-.9 2.2c0 .4.2.6.5.7l1.6.4-1.1 2m-3.8-8-2.5 1.1-1.8-1.7 2.6-1 1.7 1.7m-1 6.6a6.8 6.8 0 0 1-1.6 1.4 4.2 4.2 0 0 1-1.7.6l-2.4-.1a14.8 14.8 0 0 1-2.8-.7 7.7 7.7 0 0 1-3.4-2c-.6-.8-.6-1.5 0-2.2a7 7 0 0 1 2-1.6c.8-.5 2-1 3.8-1.6l.4.5-2.8 1.2c-.5.3-1 .6-1.3 1-.4.4-.3 1 .2 1.6a10.5 10.5 0 0 0 6.3 2.2c1.2 0 2-.3 2.3-.7.3-.3.4-.6.5-1l.2-1.6 2.5-1.5a8 8 0 0 1-.1 1.5 4.4 4.4 0 0 1-1 1.6l-1.2 1.4"/>
|
<path fill="#bf0000" d="M350.8 319.4c.4.4.6.8.7 1.2l.4 1.6-.8.1a7.8 7.8 0 0 0-1-1.5 18.8 18.8 0 0 0-1.1-1.2 46 46 0 0 0-1.7-1.5 34.4 34.4 0 0 0-2-1.7c-.4-.2-.6-.4-.6-.5a1.9 1.9 0 0 1-.3-.8 11.2 11.2 0 0 1-.2-1.6l2.7 2.2a44.3 44.3 0 0 1 2.5 2.2zm-9.5-5.8-.2 2H338l.3-2zm8.4 8.9-7.6 2.3-1.3-2 6.5-2-.7-.8a2.8 2.8 0 0 0-.9-.6 1.4 1.4 0 0 1-.4 1 2 2 0 0 1-1 .6 3.4 3.4 0 0 1-1.8 0 2 2 0 0 1-1.3-.7 4 4 0 0 1-.7-2.2c0-1 .3-1.6.9-1.8.7-.2 1.8 0 3 .7a8.1 8.1 0 0 1 3 2.4zm-5.8-4a3.8 3.8 0 0 0-.8-.3 1.1 1.1 0 0 0-.6 0 .7.7 0 0 0-.5.3.5.5 0 0 0 0 .6l.5.2h.6l.4-.3zm-8-1.6-.5 2-3.2-.3.5-2zm7.5 7.7-1.7.4a5.3 5.3 0 0 1-1.7 0 3.6 3.6 0 0 1-1.5-.4c-.3.5-.8 1-1.5 1.2a7.4 7.4 0 0 1-1.6.6l-1.2.3-1-2 1.1-.3a9.1 9.1 0 0 0 1.3-.4l.9-.5-1-.5h-.7a.4.4 0 0 0-.2 0 .6.6 0 0 0-.2.3h-.5c-.5-.8-.6-1.5-.3-2s.9-.8 2-1a6.8 6.8 0 0 1 2.6-.2c.8.1 1.3.4 1.5.9.2.2.2.5.2.7l-.4 1.2h.5a2 2 0 0 0 .6 0l1.7-.3zm-8 1.8-1.6.3a3 3 0 0 1-2.2-.4 5.5 5.5 0 0 1-1.7-2.6l-.8-2.2a2 2 0 0 0-.8-1 4.6 4.6 0 0 0-.9-.5l.6-2.1c.6.3 1 .6 1.4 1l1 1.7.5 1.5 1.1 2.2c.3.3.7.4 1 .3l1.7-.2zm-7-7.5-1 1.9-3-.7 1-1.9zm1.8 8.4-7.5.7-.4-2 6.2-.7a2.3 2.3 0 0 0-.6-.8 8.3 8.3 0 0 0-1-.6l.5-2c.7.4 1.2.9 1.6 1.3.3.5.6 1.2.8 2.1zm-6 1a17 17 0 0 1-2.2-.2 10.5 10.5 0 0 1-1.7-.5 5.6 5.6 0 0 1-1.3.4 9.9 9.9 0 0 1-1.7 0h-2a2.5 2.5 0 0 1-1.2-.3c-.3-.2-.5-.5-.8-1a4.1 4.1 0 0 1-1.5 1l-1.7.1h-1.7l.2-2.1h1.7c.8 0 1.5 0 2.1-.4a2 2 0 0 0 1.3-1.8l.7.1a30.2 30.2 0 0 0-.1 1.3c0 .3 0 .5.3.7.3.2.6.3 1 .3h1.5c1 0 1.6 0 2-.2.6-.2.9-.5 1-1.1l.1-.4s.3 0 .5-.2l.5-.2v.4a8.9 8.9 0 0 1 0 .3l-.3 1.1a12.4 12.4 0 0 0 2 .5c.1-.2 0-.4-.1-.7l-.3-.6a.5.5 0 0 1 .1-.3l.3-.2 1-.9.5 1v1zm-11.3-8.7-2 1.3-1.3-.9-1.4 1-1.9-1 1.8-1.3 1.5.8 1.5-1 1.8 1m-3 8.2-7.3-1.2.8-2 6.2 1c0-.4 0-.7-.2-1a5.2 5.2 0 0 0-.5-.8l1.6-1.7c.4.6.6 1 .7 1.6 0 .5-.2 1.2-.5 2.1zm-6.1-1-1.6-.3c-.9-.2-1.4-.6-1.5-1.2-.2-.6.1-1.5.8-2.8l1.2-2c.3-.5.4-.9.3-1.2a2.2 2.2 0 0 0-.3-.7l2.2-1.6c.3.5.3 1 .3 1.4 0 .5-.3 1.1-.7 1.8l-.8 1.4a5.8 5.8 0 0 0-.9 2.2c0 .4.2.6.5.7l1.6.4zm-3.8-8-2.5 1.1-1.8-1.7 2.6-1zm-1 6.6a6.8 6.8 0 0 1-1.6 1.4 4.2 4.2 0 0 1-1.7.6l-2.4-.1a14.8 14.8 0 0 1-2.8-.7 7.7 7.7 0 0 1-3.4-2c-.6-.8-.6-1.5 0-2.2a7 7 0 0 1 2-1.6c.8-.5 2-1 3.8-1.6l.4.5-2.8 1.2c-.5.3-1 .6-1.3 1-.4.4-.3 1 .2 1.6a10.5 10.5 0 0 0 6.3 2.2c1.2 0 2-.3 2.3-.7.3-.3.4-.6.5-1l.2-1.6 2.5-1.5a8 8 0 0 1-.1 1.5 4.4 4.4 0 0 1-1 1.6z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
@ -5,10 +5,10 @@
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
<g fill-rule="evenodd" clip-path="url(#ag-a)" transform="translate(74.7)scale(.9375)">
|
<g fill-rule="evenodd" clip-path="url(#ag-a)" transform="translate(74.7)scale(.9375)">
|
||||||
<path fill="#fff" d="M-79.7 0H603v512H-79.7V0Z"/>
|
<path fill="#fff" d="M-79.7 0H603v512H-79.7z"/>
|
||||||
<path d="M-79.6 0H603v204.8H-79.7L-79.6 0Z"/>
|
<path fill="#000001" d="M-79.6 0H603v204.8H-79.7z"/>
|
||||||
<path fill="#0072c6" d="M21.3 203.2h480v112h-480v-112Z"/>
|
<path fill="#0072c6" d="M21.3 203.2h480v112h-480z"/>
|
||||||
<path fill="#ce1126" d="M603 .1V512H261.6L603 0v.1ZM-79.7.1V512h341.3L-79.7 0v.1Z"/>
|
<path fill="#ce1126" d="M603 .1V512H261.6L603 0zM-79.7.1V512h341.3L-79.7 0z"/>
|
||||||
<path fill="#fcd116" d="M440.4 203.3 364 184l64.9-49-79.7 11.4 41-69.5-70.7 41L332.3 37l-47.9 63.8-19.3-74-21.7 76.3-47.8-65 13.7 83.2L138.5 78l41 69.5-77.4-12.5 63.8 47.8L86 203.3h354.3z"/>
|
<path fill="#fcd116" d="M440.4 203.3 364 184l64.9-49-79.7 11.4 41-69.5-70.7 41L332.3 37l-47.9 63.8-19.3-74-21.7 76.3-47.8-65 13.7 83.2L138.5 78l41 69.5-77.4-12.5 63.8 47.8L86 203.3z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 756 B After Width: | Height: | Size: 743 B |
|
@ -1,17 +1,17 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-ai" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-ai" viewBox="0 0 640 480">
|
||||||
<defs>
|
<defs>
|
||||||
<path id="ai-b" fill="#f90" d="M271 87c1.5 3.6 6.5 7.6 7.8 9.6-1.7 2-2 1.8-1.8 5.4 3-3.1 3-3.5 5-3 4.2 4.2.8 13.3-2.8 15.3-3.4 2.1-2.8 0-8 2.6 2.3 2 5.1-.3 7.4.3 1.2 1.5-.6 4.1.4 6.7 2-.2 1.8-4.3 2.2-5.8 1.5-5.4 10.4-9.1 10.8-14.1 1.9-.9 3.7-.3 6 1-1.1-4.6-4.9-4.6-5.9-6-2.4-3.7-4.5-7.8-9.6-9-3.8-.7-3.5.3-6-1.4-1.6-1.2-6.3-3.4-5.5-1.6z"/>
|
<path id="ai-b" fill="#f90" d="M271 87c1.5 3.6 6.5 7.6 7.8 9.6-1.7 2-2 1.8-1.8 5.4 3-3.1 3-3.5 5-3 4.2 4.2.8 13.3-2.8 15.3-3.4 2.1-2.8 0-8 2.6 2.3 2 5.1-.3 7.4.3 1.2 1.5-.6 4.1.4 6.7 2-.2 1.8-4.3 2.2-5.8 1.5-5.4 10.4-9.1 10.8-14.1 1.9-.9 3.7-.3 6 1-1.1-4.6-4.9-4.6-5.9-6-2.4-3.7-4.5-7.8-9.6-9-3.8-.7-3.5.3-6-1.4-1.6-1.2-6.3-3.4-5.5-1.6"/>
|
||||||
</defs>
|
</defs>
|
||||||
<clipPath id="ai-a">
|
<clipPath id="ai-a">
|
||||||
<path d="M0 0v120h373.3v120H320L0 0Zm320 0H160v280H0v-40L320 0Z"/>
|
<path d="M0 0v120h373.3v120H320zm320 0H160v280H0v-40z"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
<path fill="#012169" d="M0 0h640v480H0V0Z"/>
|
<path fill="#012169" d="M0 0h640v480H0z"/>
|
||||||
<path stroke="#fff" stroke-width="50" d="m0 0 320 240m0-240L0 240"/>
|
<path stroke="#fff" stroke-width="50" d="m0 0 320 240m0-240L0 240"/>
|
||||||
<path stroke="#c8102e" stroke-width="30" d="m0 0 320 240m0-240L0 240" clip-path="url(#ai-a)"/>
|
<path stroke="#c8102e" stroke-width="30" d="m0 0 320 240m0-240L0 240" clip-path="url(#ai-a)"/>
|
||||||
<path stroke="#fff" stroke-width="75" d="M160 0v280M0 120h373.3"/>
|
<path stroke="#fff" stroke-width="75" d="M160 0v280M0 120h373.3"/>
|
||||||
<path stroke="#c8102e" stroke-width="50" d="M160 0v280M0 120h373.3"/>
|
<path stroke="#c8102e" stroke-width="50" d="M160 0v280M0 120h373.3"/>
|
||||||
<path fill="#012169" d="M0 240h320V0h106.7v320H0v-80Z"/>
|
<path fill="#012169" d="M0 240h320V0h106.7v320H0z"/>
|
||||||
<path fill="#fff" d="M424 191.8c0 90.4 9.7 121.5 29.3 142.5a179.4 179.4 0 0 0 35 30 179.7 179.7 0 0 0 35-30c19.5-21 29.3-52.1 29.3-142.5-14.2 6.5-22.3 9.7-34 9.5a78.4 78.4 0 0 1-30.3-9.5 78.4 78.4 0 0 1-30.3 9.5c-11.7.2-19.8-3-34-9.5z"/>
|
<path fill="#fff" d="M424 191.8c0 90.4 9.7 121.5 29.3 142.5a179.4 179.4 0 0 0 35 30 179.7 179.7 0 0 0 35-30c19.5-21 29.3-52.1 29.3-142.5-14.2 6.5-22.3 9.7-34 9.5a78.4 78.4 0 0 1-30.3-9.5 78.4 78.4 0 0 1-30.3 9.5c-11.7.2-19.8-3-34-9.5"/>
|
||||||
<g transform="matrix(1.96 0 0 2.002 -40.8 62.9)">
|
<g transform="matrix(1.96 0 0 2.002 -40.8 62.9)">
|
||||||
<use xlink:href="#ai-b"/>
|
<use xlink:href="#ai-b"/>
|
||||||
<circle cx="281.3" cy="91.1" r=".8" fill="#fff" fill-rule="evenodd"/>
|
<circle cx="281.3" cy="91.1" r=".8" fill="#fff" fill-rule="evenodd"/>
|
||||||
|
@ -25,5 +25,5 @@
|
||||||
<circle cx="281.3" cy="91.1" r=".8" fill="#fff" fill-rule="evenodd"/>
|
<circle cx="281.3" cy="91.1" r=".8" fill="#fff" fill-rule="evenodd"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#9cf" d="M440 315.1a78 78 0 0 0 13.3 19.2 179.4 179.4 0 0 0 35 30 180 180 0 0 0 35-30 78 78 0 0 0 13.2-19.2z"/>
|
<path fill="#9cf" d="M440 315.1a78 78 0 0 0 13.3 19.2 179.4 179.4 0 0 0 35 30 180 180 0 0 0 35-30 78 78 0 0 0 13.2-19.2z"/>
|
||||||
<path fill="#fdc301" d="M421.2 188.2c0 94.2 10.2 126.6 30.6 148.5a187 187 0 0 0 36.5 31.1 186.3 186.3 0 0 0 36.4-31.1c20.4-21.9 30.6-54.3 30.6-148.5-14.8 6.8-23.3 10.1-35.5 10-11-.3-22.6-5.7-31.5-10-9 4.3-20.6 9.7-31.5 10-12.3.1-20.7-3.2-35.6-10zm4 5c14 6.5 22 9.6 33.5 9.4a76.4 76.4 0 0 0 29.6-9.4c8.4 4 19.3 9.2 29.6 9.4 11.5.2 19.4-3 33.4-9.4 0 89-9.6 119.6-28.8 140.2a176 176 0 0 1-34.2 29.4 175.6 175.6 0 0 1-34.3-29.4c-19.2-20.6-28.7-51.3-28.7-140.2z"/>
|
<path fill="#fdc301" d="M421.2 188.2c0 94.2 10.2 126.6 30.6 148.5a187 187 0 0 0 36.5 31.1 186.3 186.3 0 0 0 36.4-31.1c20.4-21.9 30.6-54.3 30.6-148.5-14.8 6.8-23.3 10.1-35.5 10-11-.3-22.6-5.7-31.5-10-9 4.3-20.6 9.7-31.5 10-12.3.1-20.7-3.2-35.6-10m4 5c14 6.5 22 9.6 33.5 9.4a76.4 76.4 0 0 0 29.6-9.4c8.4 4 19.3 9.2 29.6 9.4 11.5.2 19.4-3 33.4-9.4 0 89-9.6 119.6-28.8 140.2a176 176 0 0 1-34.2 29.4 175.6 175.6 0 0 1-34.3-29.4c-19.2-20.6-28.7-51.3-28.7-140.2z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -1,5 +1,5 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-al" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-al" viewBox="0 0 640 480">
|
||||||
<path fill="red" d="M0 0h640v480H0z"/>
|
<path fill="red" d="M0 0h640v480H0z"/>
|
||||||
<path id="al-a" d="M272 93.3c-4.6 0-12.3 1.5-12.2 5-13-2.1-14.3 3.2-13.5 8 1.2-1.9 2.7-3 3.9-3.1 1.7-.3 3.5.3 5.4 1.4a21.6 21.6 0 0 1 4.8 4.1c-4.6 1.1-8.2.4-11.8-.2a16.5 16.5 0 0 1-5.7-2.4c-1.5-1-2-2-4.3-4.3-2.7-2.8-5.6-2-4.7 2.3 2.1 4 5.6 5.8 10 6.6 2.1.3 5.3 1 8.9 1 3.6 0 7.6-.5 9.8 0-1.3.8-2.8 2.3-5.8 2.8-3 .6-7.5-1.8-10.3-2.4.3 2.3 3.3 4.5 9.1 5.7 9.6 2 17.5 3.6 22.8 6.5a37.3 37.3 0 0 1 10.9 9.2c4.7 5.5 5 9.8 5.2 10.8 1 8.8-2.1 13.8-7.9 15.4-2.8.7-8-.7-9.8-2.9-2-2.2-3.7-6-3.2-12 .5-2.2 3.1-8.3.9-9.5a273.7 273.7 0 0 0-32.3-15.1c-2.5-1-4.5 2.4-5.3 3.8a50.2 50.2 0 0 1-36-23.7c-4.2-7.6-11.3 0-10.1 7.3 1.9 8 8 13.8 15.4 18 7.5 4.1 17 8.2 26.5 8 5.2 1 5.1 7.6-1 8.9-12.1 0-21.8-.2-30.9-9-6.9-6.3-10.7 1.2-8.8 5.4 3.4 13.1 22.1 16.8 41 12.6 7.4-1.2 3 6.6 1 6.7-8 5.7-22.1 11.2-34.6 0-5.7-4.4-9.6-.8-7.4 5.5 5.5 16.5 26.7 13 41.2 5 3.7-2.1 7.1 2.7 2.6 6.4-18.1 12.6-27.1 12.8-35.3 8-10.2-4.1-11 7.2-5 11 6.7 4 23.8 1 36.4-7 5.4-4 5.6 2.3 2.2 4.8-14.9 12.9-20.8 16.3-36.3 14.2-7.7-.6-7.6 8.9-1.6 12.6 8.3 5.1 24.5-3.3 37-13.8 5.3-2.8 6.2 1.8 3.6 7.3a53.9 53.9 0 0 1-21.8 18c-7 2.7-13.6 2.3-18.3.7-5.8-2-6.5 4-3.3 9.4 1.9 3.3 9.8 4.3 18.4 1.3 8.6-3 17.8-10.2 24.1-18.5 5.5-4.9 4.9 1.6 2.3 6.2-12.6 20-24.2 27.4-39.5 26.2-6.7-1.2-8.3 4-4 9 7.6 6.2 17 6 25.4-.2 7.3-7 21.4-22.4 28.8-30.6 5.2-4.1 6.9 0 5.3 8.4-1.4 4.8-4.8 10-14.3 13.6-6.5 3.7-1.6 8.8 3.2 9 2.7 0 8.1-3.2 12.3-7.8 5.4-6.2 5.8-10.3 8.8-19.9 2.8-4.6 7.9-2.4 7.9 2.4-2.5 9.6-4.5 11.3-9.5 15.2-4.7 4.5 3.3 6 6 4.1 7.8-5.2 10.6-12 13.2-18.2 2-4.4 7.4-2.3 4.8 5-6 17.4-16 24.2-33.3 27.8-1.7.3-2.8 1.3-2.2 3.3l7 7c-10.7 3.2-19.4 5-30.2 8l-14.8-9.8c-1.3-3.2-2-8.2-9.8-4.7-5.2-2.4-7.7-1.5-10.6 1 4.2 0 6 1.2 7.7 3.1 2.2 5.7 7.2 6.3 12.3 4.7 3.3 2.7 5 4.9 8.4 7.7l-16.7-.5c-6-6.3-10.6-6-14.8-1-3.3.5-4.6.5-6.8 4.4 3.4-1.4 5.6-1.8 7.1-.3 6.3 3.7 10.4 2.9 13.5 0l17.5 1.1c-2.2 2-5.2 3-7.5 4.8-9-2.6-13.8 1-15.4 8.3a17 17 0 0 0-1.2 9.3c.8-3 2.3-5.5 4.9-7 8 2 11-1.3 11.5-6.1 4-3.2 9.8-3.9 13.7-7.1 4.6 1.4 6.8 2.3 11.4 3.8 1.6 5 5.3 6.9 11.3 5.6 7 .2 5.8 3.2 6.4 5.5 2-3.3 1.9-6.6-2.5-9.6-1.6-4.3-5.2-6.3-9.8-3.8-4.4-1.2-5.5-3-9.9-4.3 11-3.5 18.8-4.3 29.8-7.8l7.7 6.8c1.5.9 2.9 1.1 3.8 0 6.9-10 10-18.7 16.3-25.3 2.5-2.8 5.6-6.4 9-7.3 1.7-.5 3.8-.2 5.2 1.3 1.3 1.4 2.4 4.1 2 8.2-.7 5.7-2.1 7.6-3.7 11-1.7 3.5-3.6 5.6-5.7 8.3-4 5.3-9.4 8.4-12.6 10.5-6.4 4.1-9 2.3-14 2-6.4.7-8 3.8-2.8 8.1 4.8 2.6 9.2 2.9 12.8 2.2 3-.6 6.6-4.5 9.2-6.6 2.8-3.3 7.6.6 4.3 4.5-5.9 7-11.7 11.6-19 11.5-7.7 1-6.2 5.3-1.2 7.4 9.2 3.7 17.4-3.3 21.6-8 3.2-3.5 5.5-3.6 5 1.9-3.3 9.9-7.6 13.7-14.8 14.2-5.8-.6-5.9 4-1.6 7 9.6 6.6 16.6-4.8 19.9-11.6 2.3-6.2 5.9-3.3 6.3 1.8 0 6.9-3 12.4-11.3 19.4 6.3 10.1 13.7 20.4 20 30.5l19.2-214L320 139c-2-1.8-8.8-9.8-10.5-11-.7-.6-1-1-.1-1.4.9-.4 3-.8 4.5-1-4-4.1-7.6-5.4-15.3-7.6 1.9-.8 3.7-.4 9.3-.6a30.2 30.2 0 0 0-13.5-10.2c4.2-3 5-3.2 9.2-6.7a86.3 86.3 0 0 1-19.5-3.8 37.4 37.4 0 0 0-12-3.4zm.8 8.4c3.8 0 6.1 1.3 6.1 2.9 0 1.6-2.3 2.9-6.1 2.9s-6.2-1.5-6.2-3c0-1.6 2.4-2.8 6.2-2.8z"/>
|
<path id="al-a" fill="#000001" d="M272 93.3c-4.6 0-12.3 1.5-12.2 5-13-2.1-14.3 3.2-13.5 8 1.2-1.9 2.7-3 3.9-3.1 1.7-.3 3.5.3 5.4 1.4a21.6 21.6 0 0 1 4.8 4.1c-4.6 1.1-8.2.4-11.8-.2a16.5 16.5 0 0 1-5.7-2.4c-1.5-1-2-2-4.3-4.3-2.7-2.8-5.6-2-4.7 2.3 2.1 4 5.6 5.8 10 6.6 2.1.3 5.3 1 8.9 1 3.6 0 7.6-.5 9.8 0-1.3.8-2.8 2.3-5.8 2.8-3 .6-7.5-1.8-10.3-2.4.3 2.3 3.3 4.5 9.1 5.7 9.6 2 17.5 3.6 22.8 6.5a37.3 37.3 0 0 1 10.9 9.2c4.7 5.5 5 9.8 5.2 10.8 1 8.8-2.1 13.8-7.9 15.4-2.8.7-8-.7-9.8-2.9-2-2.2-3.7-6-3.2-12 .5-2.2 3.1-8.3.9-9.5a273.7 273.7 0 0 0-32.3-15.1c-2.5-1-4.5 2.4-5.3 3.8a50.2 50.2 0 0 1-36-23.7c-4.2-7.6-11.3 0-10.1 7.3 1.9 8 8 13.8 15.4 18 7.5 4.1 17 8.2 26.5 8 5.2 1 5.1 7.6-1 8.9-12.1 0-21.8-.2-30.9-9-6.9-6.3-10.7 1.2-8.8 5.4 3.4 13.1 22.1 16.8 41 12.6 7.4-1.2 3 6.6 1 6.7-8 5.7-22.1 11.2-34.6 0-5.7-4.4-9.6-.8-7.4 5.5 5.5 16.5 26.7 13 41.2 5 3.7-2.1 7.1 2.7 2.6 6.4-18.1 12.6-27.1 12.8-35.3 8-10.2-4.1-11 7.2-5 11 6.7 4 23.8 1 36.4-7 5.4-4 5.6 2.3 2.2 4.8-14.9 12.9-20.8 16.3-36.3 14.2-7.7-.6-7.6 8.9-1.6 12.6 8.3 5.1 24.5-3.3 37-13.8 5.3-2.8 6.2 1.8 3.6 7.3a53.9 53.9 0 0 1-21.8 18c-7 2.7-13.6 2.3-18.3.7-5.8-2-6.5 4-3.3 9.4 1.9 3.3 9.8 4.3 18.4 1.3 8.6-3 17.8-10.2 24.1-18.5 5.5-4.9 4.9 1.6 2.3 6.2-12.6 20-24.2 27.4-39.5 26.2-6.7-1.2-8.3 4-4 9 7.6 6.2 17 6 25.4-.2 7.3-7 21.4-22.4 28.8-30.6 5.2-4.1 6.9 0 5.3 8.4-1.4 4.8-4.8 10-14.3 13.6-6.5 3.7-1.6 8.8 3.2 9 2.7 0 8.1-3.2 12.3-7.8 5.4-6.2 5.8-10.3 8.8-19.9 2.8-4.6 7.9-2.4 7.9 2.4-2.5 9.6-4.5 11.3-9.5 15.2-4.7 4.5 3.3 6 6 4.1 7.8-5.2 10.6-12 13.2-18.2 2-4.4 7.4-2.3 4.8 5-6 17.4-16 24.2-33.3 27.8-1.7.3-2.8 1.3-2.2 3.3l7 7c-10.7 3.2-19.4 5-30.2 8l-14.8-9.8c-1.3-3.2-2-8.2-9.8-4.7-5.2-2.4-7.7-1.5-10.6 1 4.2 0 6 1.2 7.7 3.1 2.2 5.7 7.2 6.3 12.3 4.7 3.3 2.7 5 4.9 8.4 7.7l-16.7-.5c-6-6.3-10.6-6-14.8-1-3.3.5-4.6.5-6.8 4.4 3.4-1.4 5.6-1.8 7.1-.3 6.3 3.7 10.4 2.9 13.5 0l17.5 1.1c-2.2 2-5.2 3-7.5 4.8-9-2.6-13.8 1-15.4 8.3a17 17 0 0 0-1.2 9.3c.8-3 2.3-5.5 4.9-7 8 2 11-1.3 11.5-6.1 4-3.2 9.8-3.9 13.7-7.1 4.6 1.4 6.8 2.3 11.4 3.8 1.6 5 5.3 6.9 11.3 5.6 7 .2 5.8 3.2 6.4 5.5 2-3.3 1.9-6.6-2.5-9.6-1.6-4.3-5.2-6.3-9.8-3.8-4.4-1.2-5.5-3-9.9-4.3 11-3.5 18.8-4.3 29.8-7.8l7.7 6.8c1.5.9 2.9 1.1 3.8 0 6.9-10 10-18.7 16.3-25.3 2.5-2.8 5.6-6.4 9-7.3 1.7-.5 3.8-.2 5.2 1.3 1.3 1.4 2.4 4.1 2 8.2-.7 5.7-2.1 7.6-3.7 11-1.7 3.5-3.6 5.6-5.7 8.3-4 5.3-9.4 8.4-12.6 10.5-6.4 4.1-9 2.3-14 2-6.4.7-8 3.8-2.8 8.1 4.8 2.6 9.2 2.9 12.8 2.2 3-.6 6.6-4.5 9.2-6.6 2.8-3.3 7.6.6 4.3 4.5-5.9 7-11.7 11.6-19 11.5-7.7 1-6.2 5.3-1.2 7.4 9.2 3.7 17.4-3.3 21.6-8 3.2-3.5 5.5-3.6 5 1.9-3.3 9.9-7.6 13.7-14.8 14.2-5.8-.6-5.9 4-1.6 7 9.6 6.6 16.6-4.8 19.9-11.6 2.3-6.2 5.9-3.3 6.3 1.8 0 6.9-3 12.4-11.3 19.4 6.3 10.1 13.7 20.4 20 30.5l19.2-214L320 139c-2-1.8-8.8-9.8-10.5-11-.7-.6-1-1-.1-1.4.9-.4 3-.8 4.5-1-4-4.1-7.6-5.4-15.3-7.6 1.9-.8 3.7-.4 9.3-.6a30.2 30.2 0 0 0-13.5-10.2c4.2-3 5-3.2 9.2-6.7a86.3 86.3 0 0 1-19.5-3.8 37.4 37.4 0 0 0-12-3.4zm.8 8.4c3.8 0 6.1 1.3 6.1 2.9 0 1.6-2.3 2.9-6.1 2.9s-6.2-1.5-6.2-3c0-1.6 2.4-2.8 6.2-2.8"/>
|
||||||
<use xlink:href="#al-a" width="100%" height="100%" transform="matrix(-1 0 0 1 640 0)"/>
|
<use xlink:href="#al-a" width="100%" height="100%" transform="matrix(-1 0 0 1 640 0)"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -1,12 +1,12 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ao" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ao" viewBox="0 0 640 480">
|
||||||
<g fill-rule="evenodd" stroke-width="1pt">
|
<g fill-rule="evenodd" stroke-width="1pt">
|
||||||
<path fill="red" d="M0 0h640v243.6H0z"/>
|
<path fill="red" d="M0 0h640v243.6H0z"/>
|
||||||
<path d="M0 236.4h640V480H0z"/>
|
<path fill="#000001" d="M0 236.4h640V480H0z"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#ffec00" fill-rule="evenodd" d="M228.7 148.2c165.2 43.3 59 255.6-71.3 167.2l-8.8 13.6c76.7 54.6 152.6 10.6 174-46.4 22.2-58.8-7.6-141.5-92.6-150l-1.3 15.6z"/>
|
<path fill="#ffec00" fill-rule="evenodd" d="M228.7 148.2c165.2 43.3 59 255.6-71.3 167.2l-8.8 13.6c76.7 54.6 152.6 10.6 174-46.4 22.2-58.8-7.6-141.5-92.6-150z"/>
|
||||||
<path fill="#ffec00" fill-rule="evenodd" d="m170 330.8 21.7 10.1-10.2 21.8-21.7-10.2zm149-99.5h24v24h-24zm-11.7-38.9 22.3-8.6 8.7 22.3-22.3 8.7zm-26-29.1 17.1-16.9 16.9 17-17 16.9zm-26.2-39.8 22.4 8.4-8.5 22.4-22.4-8.4zM316 270l22.3 8.9-9 22.2-22.2-8.9zm-69.9 70 22-9.3 9.5 22-22 9.4zm-39.5 2.8h24v24h-24zm41.3-116-20.3-15-20.3 14.6 8-23-20.3-15h24.5l8.5-22.6 7.8 22.7 24.7-.3-19.6 15.3 7 23.4z"/>
|
<path fill="#ffec00" fill-rule="evenodd" d="m170 330.8 21.7 10.1-10.2 21.8-21.7-10.2zm149-99.5h24v24h-24zm-11.7-38.9 22.3-8.6 8.7 22.3-22.3 8.7zm-26-29.1 17.1-16.9 16.9 17-17 16.9zm-26.2-39.8 22.4 8.4-8.5 22.4-22.4-8.4zM316 270l22.3 8.9-9 22.2-22.2-8.9zm-69.9 70 22-9.3 9.5 22-22 9.4zm-39.5 2.8h24v24h-24zm41.3-116-20.3-15-20.3 14.6 8-23-20.3-15h24.5l8.5-22.6 7.8 22.7 24.7-.3-19.6 15.3z"/>
|
||||||
<path fill="#fe0" fill-rule="evenodd" d="M336 346.4c-1.2.4-6.2 12.4-9.7 18.2l3.7 1c13.6 4.8 20.4 9.2 26.2 17.5a7.9 7.9 0 0 0 10.2.7s2.8-1 6.4-5c3-4.5 2.2-8-1.4-11.1-11-8-22.9-14-35.4-21.3z"/>
|
<path fill="#fe0" fill-rule="evenodd" d="M336 346.4c-1.2.4-6.2 12.4-9.7 18.2l3.7 1c13.6 4.8 20.4 9.2 26.2 17.5a7.9 7.9 0 0 0 10.2.7s2.8-1 6.4-5c3-4.5 2.2-8-1.4-11.1-11-8-22.9-14-35.4-21.3"/>
|
||||||
<path fill-rule="evenodd" d="M365.3 372.8a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.6 0zm-21.4-13.6a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0zm10.9 7a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0z"/>
|
<path fill="#000001" fill-rule="evenodd" d="M365.3 372.8a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.6 0zm-21.4-13.6a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0m10.9 7a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0"/>
|
||||||
<path fill="#fe0" fill-rule="evenodd" d="M324.5 363.7c-42.6-24.3-87.3-50.5-130-74.8-18.7-11.7-19.6-33.4-7-49.9 1.2-2.3 2.8-1.8 3.4-.5 1.5 8 6 16.3 11.4 21.5A5288 5288 0 0 1 334 345.6c-3.4 5.8-6 12.3-9.5 18z"/>
|
<path fill="#fe0" fill-rule="evenodd" d="M324.5 363.7c-42.6-24.3-87.3-50.5-130-74.8-18.7-11.7-19.6-33.4-7-49.9 1.2-2.3 2.8-1.8 3.4-.5 1.5 8 6 16.3 11.4 21.5A5288 5288 0 0 1 334 345.6c-3.4 5.8-6 12.3-9.5 18z"/>
|
||||||
<path fill="#ffec00" fill-rule="evenodd" d="m297.2 305.5 17.8 16-16 17.8-17.8-16z"/>
|
<path fill="#ffec00" fill-rule="evenodd" d="m297.2 305.5 17.8 16-16 17.8-17.8-16z"/>
|
||||||
<path fill="none" stroke="#000" stroke-width="3" d="m331.5 348.8-125-75.5m109.6 58.1L274 304.1m18.2 42.7L249.3 322"/>
|
<path fill="none" stroke="#000" stroke-width="3" d="m331.5 348.8-125-75.5m109.6 58.1L274 304.1m18.2 42.7L249.3 322"/>
|
||||||
|
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -20,13 +20,13 @@
|
||||||
<use xlink:href="#ar-e" width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)"/>
|
<use xlink:href="#ar-e" width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)"/>
|
||||||
<use xlink:href="#ar-f" width="100%" height="100%" transform="translate(18.1)"/>
|
<use xlink:href="#ar-f" width="100%" height="100%" transform="translate(18.1)"/>
|
||||||
<use xlink:href="#ar-g" width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)"/>
|
<use xlink:href="#ar-g" width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)"/>
|
||||||
<path fill="#85340a" d="M316 243.7a1.8 1.8 0 1 0 1.8 2.9 4 4 0 0 0 2.2.6h.2c.6 0 1.6-.1 2.3-.6.3.5.9.7 1.5.7a1.8 1.8 0 0 0 .3-3.6c.5.2.8.6.8 1.2a1.2 1.2 0 0 1-2.4 0 3 3 0 0 1-2.6 1.7 3 3 0 0 1-2.5-1.7c0 .7-.6 1.2-1.3 1.2-.6 0-1.2-.6-1.2-1.2s.3-1 .8-1.2zm2 5.4c-2.1 0-3 2-4.8 3.1 1-.4 1.8-1.2 3.3-2 1.4-.8 2.6.2 3.5.2.8 0 2-1 3.5-.2 1.4.8 2.3 1.6 3.3 2-1.9-1.2-2.7-3-4.8-3-.4 0-1.2.2-2 .6l-2-.7z"/>
|
<path fill="#85340a" d="M316 243.7a1.8 1.8 0 1 0 1.8 2.9 4 4 0 0 0 2.2.6h.2c.6 0 1.6-.1 2.3-.6.3.5.9.7 1.5.7a1.8 1.8 0 0 0 .3-3.6c.5.2.8.6.8 1.2a1.2 1.2 0 0 1-2.4 0 3 3 0 0 1-2.6 1.7 3 3 0 0 1-2.5-1.7c0 .7-.6 1.2-1.3 1.2-.6 0-1.2-.6-1.2-1.2s.3-1 .8-1.2zm2 5.4c-2.1 0-3 2-4.8 3.1 1-.4 1.8-1.2 3.3-2 1.4-.8 2.6.2 3.5.2.8 0 2-1 3.5-.2 1.4.8 2.3 1.6 3.3 2-1.9-1.2-2.7-3-4.8-3-.4 0-1.2.2-2 .6z"/>
|
||||||
<path fill="#85340a" d="M317.2 251.6c-.8 0-1.8.2-3.4.6 3.7-.8 4.5.5 6.2.5 1.6 0 2.5-1.3 6.1-.5-4-1.2-4.9-.4-6.1-.4-.8 0-1.4-.3-2.8-.2z"/>
|
<path fill="#85340a" d="M317.2 251.6c-.8 0-1.8.2-3.4.6 3.7-.8 4.5.5 6.2.5 1.6 0 2.5-1.3 6.1-.5-4-1.2-4.9-.4-6.1-.4-.8 0-1.4-.3-2.8-.2"/>
|
||||||
<path fill="#85340a" d="M314 252.2h-.8c4.3.5 2.3 3 6.8 3s2.5-2.5 6.8-3c-4.5-.4-3.1 2.3-6.8 2.3-3.5 0-2.4-2.3-6-2.3z"/>
|
<path fill="#85340a" d="M314 252.2h-.8c4.3.5 2.3 3 6.8 3s2.5-2.5 6.8-3c-4.5-.4-3.1 2.3-6.8 2.3-3.5 0-2.4-2.3-6-2.3"/>
|
||||||
<path fill="#85340a" d="M323.7 258.9a3.7 3.7 0 0 0-7.4 0 3.8 3.8 0 0 1 7.4 0z"/>
|
<path fill="#85340a" d="M323.7 258.9a3.7 3.7 0 0 0-7.4 0 3.8 3.8 0 0 1 7.4 0"/>
|
||||||
<path id="ar-e" fill="#85340a" stroke-width="1" d="M303.4 234.3c4.7-4.1 10.7-4.8 14-1.7a8 8 0 0 1 1.5 3.4c.4 2.4-.3 4.9-2.1 7.5l.8.4c1.6-3.1 2.2-6.3 1.6-9.4l-.6-2.3c-4.5-3.7-10.7-4-15.2 2z"/>
|
<path id="ar-e" fill="#85340a" stroke-width="1" d="M303.4 234.3c4.7-4.1 10.7-4.8 14-1.7a8 8 0 0 1 1.5 3.4c.4 2.4-.3 4.9-2.1 7.5l.8.4c1.6-3.1 2.2-6.3 1.6-9.4l-.6-2.3c-4.5-3.7-10.7-4-15.2 2z"/>
|
||||||
<path id="ar-d" fill="#85340a" stroke-width="1" d="M310.8 233c2.7 0 3.3.6 4.5 1.7 1.2 1 1.9.8 2 1 .3.2 0 .8-.3.6-.5-.2-1.3-.6-2.5-1.6s-2.5-1-3.7-1c-3.7 0-5.7 3-6.1 2.8-.5-.2 2-3.5 6.1-3.5z"/>
|
<path id="ar-d" fill="#85340a" stroke-width="1" d="M310.8 233c2.7 0 3.3.6 4.5 1.7 1.2 1 1.9.8 2 1 .3.2 0 .8-.3.6-.5-.2-1.3-.6-2.5-1.6s-2.5-1-3.7-1c-3.7 0-5.7 3-6.1 2.8-.5-.2 2-3.5 6.1-3.5"/>
|
||||||
<use xlink:href="#ar-h" width="100%" height="100%" transform="translate(-18.4)"/>
|
<use xlink:href="#ar-h" width="100%" height="100%" transform="translate(-18.4)"/>
|
||||||
<circle id="ar-f" cx="310.9" cy="236.3" r="1.8" fill="#85340a" stroke-width="1"/>
|
<circle id="ar-f" cx="310.9" cy="236.3" r="1.8" fill="#85340a" stroke-width="1"/>
|
||||||
<path id="ar-g" fill="#85340a" stroke-width="1" d="M305.9 237.5c3.5 2.7 7 2.5 9 1.3 2-1.3 2-1.7 1.6-1.7-.4 0-.8.4-2.4 1.3-1.7.8-4.1.8-8.2-.9z"/>
|
<path id="ar-g" fill="#85340a" stroke-width="1" d="M305.9 237.5c3.5 2.7 7 2.5 9 1.3 2-1.3 2-1.7 1.6-1.7-.4 0-.8.4-2.4 1.3-1.7.8-4.1.8-8.2-.9"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -14,7 +14,7 @@
|
||||||
<path stroke-width=".4" d="m1158.7 2747.4-.5 7.9 12.6 1.2 10.1-7.6z" transform="matrix(.36355 0 0 .3308 -130 -670.9)"/>
|
<path stroke-width=".4" d="m1158.7 2747.4-.5 7.9 12.6 1.2 10.1-7.6z" transform="matrix(.36355 0 0 .3308 -130 -670.9)"/>
|
||||||
<path d="m1265.2 2599.8 3.7-.8-.4 10.3-2.3.9z" transform="matrix(.36355 0 0 .3308 -130 -670.9)"/>
|
<path d="m1265.2 2599.8 3.7-.8-.4 10.3-2.3.9z" transform="matrix(.36355 0 0 .3308 -130 -670.9)"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#fff" d="M320 326.3c51.6 0 93.6-38.2 93.6-85.2a81.9 81.9 0 0 0-32.6-64.4 70.2 70.2 0 0 1 19.2 48c0 40.8-35.9 73.9-80.2 73.9-44.3 0-80.2-33.1-80.2-74 0-18.3 7.2-35.1 19.2-48a81.8 81.8 0 0 0-32.6 64.6c0 46.9 42 85.1 93.6 85.1z" class="arab-fil2"/>
|
<path fill="#fff" d="M320 326.3c51.6 0 93.6-38.2 93.6-85.2a81.9 81.9 0 0 0-32.6-64.4 70.2 70.2 0 0 1 19.2 48c0 40.8-35.9 73.9-80.2 73.9-44.3 0-80.2-33.1-80.2-74 0-18.3 7.2-35.1 19.2-48a81.8 81.8 0 0 0-32.6 64.6c0 46.9 42 85.1 93.6 85.1" class="arab-fil2"/>
|
||||||
<g fill="#fff" stroke="#000" stroke-width="8">
|
<g fill="#fff" stroke="#000" stroke-width="8">
|
||||||
<path d="M-54 1623c-88 44-198 32-291-28-4-2-6 1-2 12 10 29 18 52-12 95-13 19 2 22 24 20 112-11 222-36 275-57zm-2 52c-35 14-95 31-162 43-27 4-26 21 22 27 49 5 112-30 150-61z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
<path d="M-54 1623c-88 44-198 32-291-28-4-2-6 1-2 12 10 29 18 52-12 95-13 19 2 22 24 20 112-11 222-36 275-57zm-2 52c-35 14-95 31-162 43-27 4-26 21 22 27 49 5 112-30 150-61z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
||||||
<path d="M0 1579c12 0 34-5 56-8 41-7 11 56-56 56v21c68 0 139-74 124-107-21-48-79-7-124-7s-103-41-124 7c-15 33 56 107 124 107v-21c-67 0-97-63-56-56 22 3 44 8 56 8z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
<path d="M0 1579c12 0 34-5 56-8 41-7 11 56-56 56v21c68 0 139-74 124-107-21-48-79-7-124-7s-103-41-124 7c-15 33 56 107 124 107v-21c-67 0-97-63-56-56 22 3 44 8 56 8z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
<path d="M-187 1619c-144 23-211-86-253-96-22-5-6-14 5-15 96-11 218 34 255 84 15 20 15 24-7 27z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
<path d="M-187 1619c-144 23-211-86-253-96-22-5-6-14 5-15 96-11 218 34 255 84 15 20 15 24-7 27z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
||||||
<path d="M-333 1448c29 95 137 173 218 179 38 3 38-1 24-26-65-118-178-138-218-168-34-26-27 6-24 15z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
<path d="M-333 1448c29 95 137 173 218 179 38 3 38-1 24-26-65-118-178-138-218-168-34-26-27 6-24 15z" class="arab-fil2 arab-str2" transform="matrix(.23458 0 0 .21345 320 27.3)"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#006233" d="M359.6 128.9c-4.4-3-20.8-1.3-23.9-3.3 5.9 4.5 19 1.3 24 3.3zm39.7 7.6c-3.5-5.7-24.4-9.6-27.5-14.7 5.5 9.8 21.6 8.5 27.5 14.7zm-3 6.6c-7.8-6.8-25.8-4-31.3-8 12.7 10.4 19.7 2.3 31.2 8zM351 112.8c4.9 2.4 11 4.7 14 10.3-3.5-4.3-9.8-6-15-9.6.3 0 .7-.4 1-.7zm77 44c-3.1-6.4-14-13.4-14.9-15.8 3 8.3 12 10.3 14.8 15.8zm2.7 11.3c-9.4-13.4-24.1-12-30-17 4.5 4.9 21.4 8 30 17zm21.8 20.7c.7-14.3-11-19.6-11.4-27.7-.3 9.6 12 22.6 11.4 27.7zm-5.8 7.7c-2.4-12.4-18.3-13.2-21.1-20.5 0 6.8 18.7 13.9 21 20.5zm13.1-7c8.5 9.4 2.6 23.7 6.1 34.1-4.2-7.7-2.1-26.9-6-34.1zm-13.8 40c12.6 12.5 7.5 26.3 12.6 32.3-6.3-8.3-5.4-24.5-12.6-32.2zm26.3 1.8c-10.9 10.9-4.3 27.3-10 35 6.4-6.6 5.5-27 10-35zm-13.7 0c-1.4-12.6-14.3-19.2-15.4-26-1.5 6.8 12.4 17.5 15.4 26zm-6.5 30c2 8.8-5.7 27.6-3.3 33.4-5.2-10 4.4-29 3.3-33.3zm16.6 20.1c-5.1 15.6-15.5 14.6-18.7 24 2.3-9 16-17.1 18.7-24zm-33.5 7.3c-6.8 10.5-1.2 22.4-6.8 29.9 8-7.5 3.7-21.4 6.8-29.9zm16.4 28.6c-8.2 13.9-25.1 12.6-31.9 22.6 6.8-12.6 27.7-14.7 32-22.6zm-29.8-1.7c-14.5 9.2-10 18.8-21.1 29 13.8-10.2 12.7-21.5 21.1-29zm-6.8 37.2c-14-.5-34.2 16.2-46.4 14.9 12.2 2.4 34.7-12.6 46.4-15zm-22.7-15c-1 13-37.6 21.4-41.5 30.1 4.4-11.5 36.6-20 41.5-30zm-82.8-240c-4.7-3.7-10.4-6.7-12-10.3 1.2 4.7 5.8 8 10.5 11.3.5-.2 1-.9 1.5-1.1zm-8 3.7c-7.3-3.2-15.7-3-19.5-7.4 2.4 4.4 10.3 6.1 17.1 8.5.7-.4 1.7-.9 2.4-1zm-21.1 27.3c4.4-3 20.8-1.2 23.9-3.2-5.9 4.5-19 1.3-24 3.2zm-39.7 7.7c3.5-5.7 24.4-9.6 27.5-14.7-5.4 9.8-21.6 8.5-27.5 14.7zm3 6.6c7.8-6.8 25.9-4 31.3-8-12.7 10.4-19.7 2.3-31.2 8zm31.3-20c4.4-8.6 17-9.6 20.4-14.8-5 7.7-15.7 9-20.4 14.8zm36-7.5c13-5.5 25.7-.8 31.8-3.4-7.5 3.6-25.4 1.9-31.7 3.4zm-98.9 41.2c3-6.4 13.8-13.5 14.8-15.8-3 8.3-12 10.3-14.8 15.8zm-2.8 11.3c9.4-13.4 24.1-12 30-17-4.4 4.9-21.3 8-30 17zm-21.8 20.7c-.7-14.3 11-19.6 11.5-27.7.2 9.6-12 22.6-11.5 27.7zm5.8 7.7c2.4-12.4 18.3-13.2 21.1-20.5 0 6.8-18.7 13.9-21 20.5zm-13.1-7c-8.4 9.4-2.6 23.6-6 34.1 4.1-7.7 2-26.9 6-34.1zm13.8 40c-12.6 12.5-7.5 26.3-12.6 32.3 6.3-8.3 5.4-24.5 12.6-32.2zm-26.2 1.8c10.8 10.9 4.2 27.3 9.8 35-6.3-6.6-5.4-27-9.8-35zm13.6 0c1.4-12.6 14.3-19.2 15.4-26 1.5 6.8-12.4 17.5-15.4 26zm6.5 30c-2 8.8 5.7 27.6 3.3 33.4 5.2-10-4.4-29-3.3-33.3zm-16.6 20.1c5.2 15.6 15.5 14.6 18.8 24-2.4-9-16-17.1-18.8-24zm33.5 7.3c6.8 10.5 1.2 22.4 6.8 29.9-8-7.5-3.7-21.4-6.8-29.9zm-16.4 28.6c8.2 13.9 25.1 12.6 32 22.6-6.9-12.6-27.8-14.7-32-22.6zm29.8-1.7c14.5 9.2 10.1 18.8 21.1 29-13.8-10.2-12.6-21.5-21.1-29zm6.8 37.1c14-.4 34.3 16.3 46.4 15-12.1 2.3-34.7-12.6-46.4-15zm22.8-15c.9 13.1 37.5 21.4 41.5 30.2-4.5-11.5-36.6-20-41.6-30.1zM301 116c2.8-11.5 17-13.6 18.8-20.5-.7 7.3-17.4 15.4-18.8 20.5zm41.5-28.6c-2 8.8-17.3 13.7-19.4 20.3.7-9 16.4-14 19.4-20.3zm-12 20.8c7.3-10.7 22.3-8 27.5-14.1-3.8 7.2-22.3 7.4-27.5 14z" class="arab-fil0"/>
|
<path fill="#006233" d="M359.6 128.9c-4.4-3-20.8-1.3-23.9-3.3 5.9 4.5 19 1.3 24 3.3zm39.7 7.6c-3.5-5.7-24.4-9.6-27.5-14.7 5.5 9.8 21.6 8.5 27.5 14.7m-3 6.6c-7.8-6.8-25.8-4-31.3-8 12.7 10.4 19.7 2.3 31.2 8zM351 112.8c4.9 2.4 11 4.7 14 10.3-3.5-4.3-9.8-6-15-9.6.3 0 .7-.4 1-.7m77 44c-3.1-6.4-14-13.4-14.9-15.8 3 8.3 12 10.3 14.8 15.8zm2.7 11.3c-9.4-13.4-24.1-12-30-17 4.5 4.9 21.4 8 30 17m21.8 20.7c.7-14.3-11-19.6-11.4-27.7-.3 9.6 12 22.6 11.4 27.7m-5.8 7.7c-2.4-12.4-18.3-13.2-21.1-20.5 0 6.8 18.7 13.9 21 20.5zm13.1-7c8.5 9.4 2.6 23.7 6.1 34.1-4.2-7.7-2.1-26.9-6-34.1zm-13.8 40c12.6 12.5 7.5 26.3 12.6 32.3-6.3-8.3-5.4-24.5-12.6-32.2zm26.3 1.8c-10.9 10.9-4.3 27.3-10 35 6.4-6.6 5.5-27 10-35m-13.7 0c-1.4-12.6-14.3-19.2-15.4-26-1.5 6.8 12.4 17.5 15.4 26m-6.5 30c2 8.8-5.7 27.6-3.3 33.4-5.2-10 4.4-29 3.3-33.3zm16.6 20.1c-5.1 15.6-15.5 14.6-18.7 24 2.3-9 16-17.1 18.7-24m-33.5 7.3c-6.8 10.5-1.2 22.4-6.8 29.9 8-7.5 3.7-21.4 6.8-29.9m16.4 28.6c-8.2 13.9-25.1 12.6-31.9 22.6 6.8-12.6 27.7-14.7 32-22.6zm-29.8-1.7c-14.5 9.2-10 18.8-21.1 29 13.8-10.2 12.7-21.5 21.1-29m-6.8 37.2c-14-.5-34.2 16.2-46.4 14.9 12.2 2.4 34.7-12.6 46.4-15zm-22.7-15c-1 13-37.6 21.4-41.5 30.1 4.4-11.5 36.6-20 41.5-30zm-82.8-240c-4.7-3.7-10.4-6.7-12-10.3 1.2 4.7 5.8 8 10.5 11.3.5-.2 1-.9 1.5-1.1zm-8 3.7c-7.3-3.2-15.7-3-19.5-7.4 2.4 4.4 10.3 6.1 17.1 8.5.7-.4 1.7-.9 2.4-1zm-21.1 27.3c4.4-3 20.8-1.2 23.9-3.2-5.9 4.5-19 1.3-24 3.2zm-39.7 7.7c3.5-5.7 24.4-9.6 27.5-14.7-5.4 9.8-21.6 8.5-27.5 14.7m3 6.6c7.8-6.8 25.9-4 31.3-8-12.7 10.4-19.7 2.3-31.2 8zm31.3-20c4.4-8.6 17-9.6 20.4-14.8-5 7.7-15.7 9-20.4 14.8m36-7.5c13-5.5 25.7-.8 31.8-3.4-7.5 3.6-25.4 1.9-31.7 3.4zm-98.9 41.2c3-6.4 13.8-13.5 14.8-15.8-3 8.3-12 10.3-14.8 15.8m-2.8 11.3c9.4-13.4 24.1-12 30-17-4.4 4.9-21.3 8-30 17m-21.8 20.7c-.7-14.3 11-19.6 11.5-27.7.2 9.6-12 22.6-11.5 27.7m5.8 7.7c2.4-12.4 18.3-13.2 21.1-20.5 0 6.8-18.7 13.9-21 20.5zm-13.1-7c-8.4 9.4-2.6 23.6-6 34.1 4.1-7.7 2-26.9 6-34.1m13.8 40c-12.6 12.5-7.5 26.3-12.6 32.3 6.3-8.3 5.4-24.5 12.6-32.2zm-26.2 1.8c10.8 10.9 4.2 27.3 9.8 35-6.3-6.6-5.4-27-9.8-35m13.6 0c1.4-12.6 14.3-19.2 15.4-26 1.5 6.8-12.4 17.5-15.4 26m6.5 30c-2 8.8 5.7 27.6 3.3 33.4 5.2-10-4.4-29-3.3-33.3zm-16.6 20.1c5.2 15.6 15.5 14.6 18.8 24-2.4-9-16-17.1-18.8-24m33.5 7.3c6.8 10.5 1.2 22.4 6.8 29.9-8-7.5-3.7-21.4-6.8-29.9m-16.4 28.6c8.2 13.9 25.1 12.6 32 22.6-6.9-12.6-27.8-14.7-32-22.6m29.8-1.7c14.5 9.2 10.1 18.8 21.1 29-13.8-10.2-12.6-21.5-21.1-29m6.8 37.1c14-.4 34.3 16.3 46.4 15-12.1 2.3-34.7-12.6-46.4-15m22.8-15c.9 13.1 37.5 21.4 41.5 30.2-4.5-11.5-36.6-20-41.6-30.1zM301 116c2.8-11.5 17-13.6 18.8-20.5-.7 7.3-17.4 15.4-18.8 20.5m41.5-28.6c-2 8.8-17.3 13.7-19.4 20.3.7-9 16.4-14 19.4-20.3m-12 20.8c7.3-10.7 22.3-8 27.5-14.1-3.8 7.2-22.3 7.4-27.5 14z" class="arab-fil0"/>
|
||||||
<path fill="none" stroke="#f7c608" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M429.8 240c0 55.5-49.3 100.4-110.3 100.4-60.9 0-110.3-44.9-110.3-100.3 0-55.5 49.4-100.4 110.3-100.4 61 0 110.3 45 110.3 100.4z"/>
|
<path fill="none" stroke="#f7c608" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M429.8 240c0 55.5-49.3 100.4-110.3 100.4-60.9 0-110.3-44.9-110.3-100.3 0-55.5 49.4-100.4 110.3-100.4 61 0 110.3 45 110.3 100.4z"/>
|
||||||
<path fill="#f7c608" d="m298 340.5-.5 1.2c-.3.8-1.1 1.3-2.1 1.2l-8-1.9 2.6-7.7 8 1.7c.9.2 1.4 1 1 1.8l-.2 1m-19-4.8.4-1.2c.2-.9 1.1-1.3 2-1a95 95 0 0 0 7.8 2.5l-2.5 7.7c-2.8-.7-5.4-1.4-7.9-2.3-.8-.4-1-2-.7-2.9"/>
|
<path fill="#f7c608" d="m298 340.5-.5 1.2c-.3.8-1.1 1.3-2.1 1.2l-8-1.9 2.6-7.7 8 1.7c.9.2 1.4 1 1 1.8l-.2 1m-19-4.8.4-1.2c.2-.9 1.1-1.3 2-1a95 95 0 0 0 7.8 2.5l-2.5 7.7c-2.8-.7-5.4-1.4-7.9-2.3-.8-.4-1-2-.7-2.9"/>
|
||||||
<path fill="#006233" d="m296.4 339.8-.3.9c-.2.6-1 .9-1.7.8l-6.6-1.6 1.8-5.6c2.4.7 4.9 1.2 6.6 1.5.8.2 1.2.8 1 1.4l-.2.7m-15.8-4 .3-1c.2-.5.9-.8 1.6-.6 1.9.6 4 1.4 6.5 2l-1.8 5.6a98.9 98.9 0 0 1-6.5-1.9c-.7-.4-1-1.5-.7-2.1"/>
|
<path fill="#006233" d="m296.4 339.8-.3.9c-.2.6-1 .9-1.7.8l-6.6-1.6 1.8-5.6c2.4.7 4.9 1.2 6.6 1.5.8.2 1.2.8 1 1.4l-.2.7m-15.8-4 .3-1c.2-.5.9-.8 1.6-.6 1.9.6 4 1.4 6.5 2l-1.8 5.6a98.9 98.9 0 0 1-6.5-1.9c-.7-.4-1-1.5-.7-2.1"/>
|
||||||
|
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -6,67 +6,67 @@
|
||||||
<path fill="#ffc221" d="M442.3 314.6c-5.5 3.2-4.5 5-4 6s.5 2-1 3.6c-1.5 1.5-1.4 2-1.4 2 .3 5.4 4 6.6 5.7 8 1.4 1 3.6 4.5 3.6 4.5 2.9 4.1 5.9 4.2 8.1 4.2 2.3 0 2-.3 1-1.3l-3.4-2.7a17.6 17.6 0 0 1 5.9 4.1c5.6 6.2 10.8 5.4 13.1 5.2 2.3-.3 2-1.7 2-1.7a9 9 0 0 0-2.4-.4c-8.5-.8-11-6.4-11-6.4a24.1 24.1 0 0 0 15.6 6c2.4-.1 2.3.6 1.7.8l-2.4-.2c-1.1 0-1.1.3-.9.8.3.4 1.4.4 2.7.4 1.4 0 .3.1 3.8 2.8 3.6 2.8 12.3.5 12.3.5-5.7-1.3-6.4-4-6.4-4-7.7 1-10.8-3.6-10.8-3.6a32.5 32.5 0 0 0-5.6-3.5 8.9 8.9 0 0 1-5-5.8c1.3 1.8 3.7 3.8 6.7 4.6 3 .8 3.8 1.2 3.8 1.2a3.8 3.8 0 0 1-2.3-.2c-3-1-1.3.3-1.3.3 3.4 2.7 4.3 2.5 4.3 2.5 8.6.9 4.3-2.6 4.3-2.6 6.2 1.5 7.2-.8 7.2-.8 1.3 2.7 6 1.7 6 1.7-6.2 3-1.5 2.1-1.5 2.1 6.3-1.1 7.6.5 7.6.5 1.6 1.5 3.4 1.4 3.4 1.4s1.2 0 3.5.4c2.4.5 6.2 2.5 9.6 2.2 3.5-.5 4 .6 4 .6-.6-.3-2.2-.5-4.8.7-2.7 1.3-7.4 1.6-14.2 0s-7.4-1.3-7.4-1.3a8.7 8.7 0 0 1 3.4 4c.3 1.2 1.5 1.2 1.5 1.2.5-1.5 2.5-2.1 2.5-2.1a27 27 0 0 0 5 2.8c.4-.7 0-1.3 0-1.3 2.6 2.5 5.6 1.7 5.6 1.7.8-.5.6-2 .6-2 1 0 1.2.6 2 1.2.7.4 3 .1 3 .1-.8-.4-1.5-1.7-1.5-1.7 3.5-2.3 11-1.3 11-1.3 5.3 1 4.7 4.5 4.7 4.5a10 10 0 0 1 2.5 2.1c.5-1.2 0-2.5 0-2.5 2.6 1.2 3 4 3 4 3-3.2-2.7-6.8-2.7-6.8 2.7-.4 5.7-.2 7.5 0a13.8 13.8 0 0 1 6.6 3.1c2.1 1.7 5.9 2.5 5.9 2.5-.1-.7-2.2-2-2.7-2.2-.4-.2-.6-.9-.6-.9 1.9.4 3.1.2 3.1.2-6.4-4-8.1-5.9-8.1-5.9 2.4.3 3.8-1.2 3.8-1.2-5.1 0-5.4-1.2-5.4-1.2.7.1 3.1.7 6.2.1s7.2 0 7.2 0c-2.2-3.6-10.7-3-13.5-2.8-2.8.2-3.8-.2-3.8-.2.4-.2.9-.6 3-.7 2.2 0 4.3.2 6.8-1.6 2.3-1.6 5.7-1 5.7-1-.8-1.6-4.7-2.2-8 0-3.5 2.1-6.5 1.5-6.5 1.5 5.3-.8 6.9-2.7 6.9-2.7-1.6-.4-2.5.1-5.8.8-3.2.6-4-.5-4-.5 3.5-2.1 6-3 6-3-3-.6-5.8-2-5.8-2-3.2 3-5.6 4.6-11.7 1.6-6-3.2-9.2-2.8-9.2-2.8a14.2 14.2 0 0 1 14.8.6c4 2.3 5 .4 5 .4-1.2-.7-1-1.5-1-1.5 9.6 4.9 13.8 2 15.9.5 2.1-1.5-1-3.4-1-3.4-.2 3-4 4.6-7.2 3.5-3-1-6-2.4-10.4-4.3-4.4-1.8-10-.8-15.1.2-5.2 1.1-5.9.6-6.4.2-.5-.4-.7-1.7-3.4-.6-2.6 1.1-8.8-1.8-12.6-2.7-3.8-1-10.1-.5-15.5 2.5-5.4 3.1-8.2 2.3-9.8 1.6-1.6-.8-2.7-2.8-.9-4.6s2-2.3 1.8-5c-.2-2.6-2.8-4.2-2.8-4.2 2.4-2.5 3-3 2.2-4-.8-1.2.4-1.2 1.8-1.8 1.4-.6.8-.7.5-1.5-.4-.8-1.2-.6-1.2-.6-3.1.1-4.9-.8-4.9-.8-5.2-2.4-10.1 2.3-10.1 2.3-3-2.3-3.7-.7-4.2-.2-.5.5-1.6 1-3 1-1.2.2-3.1.7-3.8 1.9 0 0-.6 1 .1 2 0 0 .8 1.2-.6 2.7-1.5 1.5-2 1.8-1.5 3.3.4 1.3.3 2.4-.3 3.3 0 0-.7-.7-.5-1.7.2-1 .2-1.6 0-2 0 0-1.5 1.4-1.8 2.4 0 0-.6-1.6 1.6-3.7 2-2 3-3.2 2.4-4-.4-.6-2 .4-2.3.6z"/>
|
<path fill="#ffc221" d="M442.3 314.6c-5.5 3.2-4.5 5-4 6s.5 2-1 3.6c-1.5 1.5-1.4 2-1.4 2 .3 5.4 4 6.6 5.7 8 1.4 1 3.6 4.5 3.6 4.5 2.9 4.1 5.9 4.2 8.1 4.2 2.3 0 2-.3 1-1.3l-3.4-2.7a17.6 17.6 0 0 1 5.9 4.1c5.6 6.2 10.8 5.4 13.1 5.2 2.3-.3 2-1.7 2-1.7a9 9 0 0 0-2.4-.4c-8.5-.8-11-6.4-11-6.4a24.1 24.1 0 0 0 15.6 6c2.4-.1 2.3.6 1.7.8l-2.4-.2c-1.1 0-1.1.3-.9.8.3.4 1.4.4 2.7.4 1.4 0 .3.1 3.8 2.8 3.6 2.8 12.3.5 12.3.5-5.7-1.3-6.4-4-6.4-4-7.7 1-10.8-3.6-10.8-3.6a32.5 32.5 0 0 0-5.6-3.5 8.9 8.9 0 0 1-5-5.8c1.3 1.8 3.7 3.8 6.7 4.6 3 .8 3.8 1.2 3.8 1.2a3.8 3.8 0 0 1-2.3-.2c-3-1-1.3.3-1.3.3 3.4 2.7 4.3 2.5 4.3 2.5 8.6.9 4.3-2.6 4.3-2.6 6.2 1.5 7.2-.8 7.2-.8 1.3 2.7 6 1.7 6 1.7-6.2 3-1.5 2.1-1.5 2.1 6.3-1.1 7.6.5 7.6.5 1.6 1.5 3.4 1.4 3.4 1.4s1.2 0 3.5.4c2.4.5 6.2 2.5 9.6 2.2 3.5-.5 4 .6 4 .6-.6-.3-2.2-.5-4.8.7-2.7 1.3-7.4 1.6-14.2 0s-7.4-1.3-7.4-1.3a8.7 8.7 0 0 1 3.4 4c.3 1.2 1.5 1.2 1.5 1.2.5-1.5 2.5-2.1 2.5-2.1a27 27 0 0 0 5 2.8c.4-.7 0-1.3 0-1.3 2.6 2.5 5.6 1.7 5.6 1.7.8-.5.6-2 .6-2 1 0 1.2.6 2 1.2.7.4 3 .1 3 .1-.8-.4-1.5-1.7-1.5-1.7 3.5-2.3 11-1.3 11-1.3 5.3 1 4.7 4.5 4.7 4.5a10 10 0 0 1 2.5 2.1c.5-1.2 0-2.5 0-2.5 2.6 1.2 3 4 3 4 3-3.2-2.7-6.8-2.7-6.8 2.7-.4 5.7-.2 7.5 0a13.8 13.8 0 0 1 6.6 3.1c2.1 1.7 5.9 2.5 5.9 2.5-.1-.7-2.2-2-2.7-2.2-.4-.2-.6-.9-.6-.9 1.9.4 3.1.2 3.1.2-6.4-4-8.1-5.9-8.1-5.9 2.4.3 3.8-1.2 3.8-1.2-5.1 0-5.4-1.2-5.4-1.2.7.1 3.1.7 6.2.1s7.2 0 7.2 0c-2.2-3.6-10.7-3-13.5-2.8-2.8.2-3.8-.2-3.8-.2.4-.2.9-.6 3-.7 2.2 0 4.3.2 6.8-1.6 2.3-1.6 5.7-1 5.7-1-.8-1.6-4.7-2.2-8 0-3.5 2.1-6.5 1.5-6.5 1.5 5.3-.8 6.9-2.7 6.9-2.7-1.6-.4-2.5.1-5.8.8-3.2.6-4-.5-4-.5 3.5-2.1 6-3 6-3-3-.6-5.8-2-5.8-2-3.2 3-5.6 4.6-11.7 1.6-6-3.2-9.2-2.8-9.2-2.8a14.2 14.2 0 0 1 14.8.6c4 2.3 5 .4 5 .4-1.2-.7-1-1.5-1-1.5 9.6 4.9 13.8 2 15.9.5 2.1-1.5-1-3.4-1-3.4-.2 3-4 4.6-7.2 3.5-3-1-6-2.4-10.4-4.3-4.4-1.8-10-.8-15.1.2-5.2 1.1-5.9.6-6.4.2-.5-.4-.7-1.7-3.4-.6-2.6 1.1-8.8-1.8-12.6-2.7-3.8-1-10.1-.5-15.5 2.5-5.4 3.1-8.2 2.3-9.8 1.6-1.6-.8-2.7-2.8-.9-4.6s2-2.3 1.8-5c-.2-2.6-2.8-4.2-2.8-4.2 2.4-2.5 3-3 2.2-4-.8-1.2.4-1.2 1.8-1.8 1.4-.6.8-.7.5-1.5-.4-.8-1.2-.6-1.2-.6-3.1.1-4.9-.8-4.9-.8-5.2-2.4-10.1 2.3-10.1 2.3-3-2.3-3.7-.7-4.2-.2-.5.5-1.6 1-3 1-1.2.2-3.1.7-3.8 1.9 0 0-.6 1 .1 2 0 0 .8 1.2-.6 2.7-1.5 1.5-2 1.8-1.5 3.3.4 1.3.3 2.4-.3 3.3 0 0-.7-.7-.5-1.7.2-1 .2-1.6 0-2 0 0-1.5 1.4-1.8 2.4 0 0-.6-1.6 1.6-3.7 2-2 3-3.2 2.4-4-.4-.6-2 .4-2.3.6z"/>
|
||||||
<path d="M448.4 338s-2.7-2-2.4-4.9c.3-2.7.3-3 0-3.7 0 0-.5.3-.4 1.4 0 1-.2 2.1-.3 2.3 0 0-1.3-2.3-2-2.8 0 0 .6-2.4-.2-3.4-.7-1.1-1.5-1.2-2.4-.8-1.2.4-2.1 1.5 2 4.8 0 0 1.5 1.3 2.5 3.9 1 2.6 2.8 3 3.1 3.2zm13-7.8s-.1-1.5 1.3-4.3a6.1 6.1 0 0 0 .3-5.6c-.3-.8-.6-.5.9-1.7 1.7-1.5-.7-3.4 2.3-6 0 0 1.8-1.6 2.3-2.3 0 0-3 1.6-5.2 2.5-2 .8-9.6 4.6-8 7.1 1.8 2.5 1.6 2.7 1.3 3.8 0 0-4.6-2.5-3-6.4 0 0 .8-1.5 2.7-3.4 1.8-1.6.8.4 4.3-1.7 0 0 2.7-1.6 4.3-3.9 0 0-2 1.2-2.6 1.4 0 0-4 .8-5.8 2.5-1.6 1.7-5.1 4.7-4 8 0 0-4-.4-5-4.7 0 0-7.6 9.4 8.4 13.8 0 0 3 .8 5.6 1z"/>
|
<path d="M448.4 338s-2.7-2-2.4-4.9c.3-2.7.3-3 0-3.7 0 0-.5.3-.4 1.4 0 1-.2 2.1-.3 2.3 0 0-1.3-2.3-2-2.8 0 0 .6-2.4-.2-3.4-.7-1.1-1.5-1.2-2.4-.8-1.2.4-2.1 1.5 2 4.8 0 0 1.5 1.3 2.5 3.9 1 2.6 2.8 3 3.1 3.2zm13-7.8s-.1-1.5 1.3-4.3a6.1 6.1 0 0 0 .3-5.6c-.3-.8-.6-.5.9-1.7 1.7-1.5-.7-3.4 2.3-6 0 0 1.8-1.6 2.3-2.3 0 0-3 1.6-5.2 2.5-2 .8-9.6 4.6-8 7.1 1.8 2.5 1.6 2.7 1.3 3.8 0 0-4.6-2.5-3-6.4 0 0 .8-1.5 2.7-3.4 1.8-1.6.8.4 4.3-1.7 0 0 2.7-1.6 4.3-3.9 0 0-2 1.2-2.6 1.4 0 0-4 .8-5.8 2.5-1.6 1.7-5.1 4.7-4 8 0 0-4-.4-5-4.7 0 0-7.6 9.4 8.4 13.8 0 0 3 .8 5.6 1z"/>
|
||||||
<path fill="#ffc221" d="M531.6 299c6-1 40.4-6.2 43.6-6.5 3.4-.3 4.7-.8 5.9 2 1.3 3-4.8 3.1-4.8 3.1l-41.1 4.7c-2 .2-2.5-.6-2.5-.6l-1.5-2s-.5-.6.4-.8z"/>
|
<path fill="#ffc221" d="M531.6 299c6-1 40.4-6.2 43.6-6.5 3.4-.3 4.7-.8 5.9 2 1.3 3-4.8 3.1-4.8 3.1l-41.1 4.7c-2 .2-2.5-.6-2.5-.6l-1.5-2s-.5-.6.4-.8z"/>
|
||||||
<path fill="#5a3719" d="M447.3 317.7s-4.4 9.3 13 11.6c0 0 .1-1 .8-2.5.8-1.5 2.3-4.5.8-6.4-1.4-1.9 1.2-.9 1.5-3.4.5-2.5-.2-2.2 1-3.8 0 0-5.4 2-7.6 4.5-2 2.4 2.9 4.2 0 6.9 0 0-2.5-1-4-3.6 0 0-3.3 0-5.5-3.3z"/>
|
<path fill="#5a3719" d="M447.3 317.7s-4.4 9.3 13 11.6c0 0 .1-1 .8-2.5.8-1.5 2.3-4.5.8-6.4-1.4-1.9 1.2-.9 1.5-3.4.5-2.5-.2-2.2 1-3.8 0 0-5.4 2-7.6 4.5-2 2.4 2.9 4.2 0 6.9 0 0-2.5-1-4-3.6 0 0-3.3 0-5.5-3.3"/>
|
||||||
<path d="M464.5 329.2s4.3 3.7 9.4 3.6c5.1-.3 7.4-1.6 8.7-3.6 0 0 1 1.5 1 2.6 0 0 4.4-3.7 12-.5s5.4 2.3 7.1 2.5c0 0-3.3-.5-10.7 2.9-7.7 3.5-27.7 2.3-27.6-7.5z"/>
|
<path d="M464.5 329.2s4.3 3.7 9.4 3.6c5.1-.3 7.4-1.6 8.7-3.6 0 0 1 1.5 1 2.6 0 0 4.4-3.7 12-.5s5.4 2.3 7.1 2.5c0 0-3.3-.5-10.7 2.9-7.7 3.5-27.7 2.3-27.6-7.5z"/>
|
||||||
<path fill="#5a3719" d="M457.3 312.6s1.9.3 3.8-1.9c0 0-2.6.5-3.8 2zM442.6 330s-3.6-2.8-1.3-3.4c0 0 1.7-.3 1.3 3.4z"/>
|
<path fill="#5a3719" d="M457.3 312.6s1.9.3 3.8-1.9c0 0-2.6.5-3.8 2zM442.6 330s-3.6-2.8-1.3-3.4c0 0 1.7-.3 1.3 3.4"/>
|
||||||
<path d="M521.2 347.8s2-3.5 7.5-3.5 6.1 2.6 13.1 3c0 0-8.4 2.4-14.2.3-3-1.1-5.8-.2-6.4.2z"/>
|
<path d="M521.2 347.8s2-3.5 7.5-3.5 6.1 2.6 13.1 3c0 0-8.4 2.4-14.2.3-3-1.1-5.8-.2-6.4.2"/>
|
||||||
<path fill="#5a3719" d="M466.3 331.7s8.4 5 15.7-.5c0 0 .6.6 1.2 2 0 0 5.6-5.4 15.5.4 0 0-1.2-.1-5.9 1.8-6.1 2.7-21.4 4.5-26.5-3.8z"/>
|
<path fill="#5a3719" d="M466.3 331.7s8.4 5 15.7-.5c0 0 .6.6 1.2 2 0 0 5.6-5.4 15.5.4 0 0-1.2-.1-5.9 1.8-6.1 2.7-21.4 4.5-26.5-3.8z"/>
|
||||||
<path d="M498.3 336.7s8 1 14.7.6c4.1-.2 8.6-1 6.4.4-2.3 1.3-1.1 1.5 8.4.7 9.4-1-.1 1.7 6.4 2.6 0 0-15.9 8-35.9-4.3z"/>
|
<path d="M498.3 336.7s8 1 14.7.6c4.1-.2 8.6-1 6.4.4-2.3 1.3-1.1 1.5 8.4.7 9.4-1-.1 1.7 6.4 2.6 0 0-15.9 8-35.9-4.3"/>
|
||||||
<path fill="#5a3719" d="M519.2 331.7s4.6-1.7 9 .3c4.3 2 3.6 2.2 6.5 2.5 0 0-2 2.9-6.7.6-4.8-2.3-6-2.8-8.8-3.4zm5.2 14.3s4.6-2.3 9.6 0c.6.4 2 1 3.3 1.2 0 0-3.8 1.3-7.8 0-1.7-.5-3-.9-5.1-1.2zm-22.7-8.2s10.3 1 15.8-.1c0 0-6.4 3 9.7 1.7 0 0 3.5-.4 3 .1-.3.5-.6 1 1.2 1.5 0 0-12 5.4-29.7-3.2z"/>
|
<path fill="#5a3719" d="M519.2 331.7s4.6-1.7 9 .3c4.3 2 3.6 2.2 6.5 2.5 0 0-2 2.9-6.7.6-4.8-2.3-6-2.8-8.8-3.4m5.2 14.3s4.6-2.3 9.6 0c.6.4 2 1 3.3 1.2 0 0-3.8 1.3-7.8 0-1.7-.5-3-.9-5.1-1.2m-22.7-8.2s10.3 1 15.8-.1c0 0-6.4 3 9.7 1.7 0 0 3.5-.4 3 .1-.3.5-.6 1 1.2 1.5 0 0-12 5.4-29.7-3.2"/>
|
||||||
<path d="M450.7 329.2s.2.7 2.4 1.7a8.7 8.7 0 0 1 4 3.9 5.6 5.6 0 0 0 3.5 2.9s-8 1.7-11.6-2.6c0 0-2.7-3 1.6-6"/>
|
<path d="M450.7 329.2s.2.7 2.4 1.7a8.7 8.7 0 0 1 4 3.9 5.6 5.6 0 0 0 3.5 2.9s-8 1.7-11.6-2.6c0 0-2.7-3 1.6-6"/>
|
||||||
<path fill="#5a3719" d="M513.7 347.6s-3.1-.2-7.5-1.7c-4.3-1.5-5.4-.2-7.9-2-2.4-1.9-7.3-.7-8.2-.6-1 .1-3.6 0-.3-2.1 0 0-2.6 0-3.6-1.4 0 0-1.2 1.2-5.6.8 0 0 2 3-6 2.1a10.3 10.3 0 0 0 11.1 3c0 .2-.5 2.5 3 3.5 3.8.9 4.5 1.6 6.4 2.3 0 0 .3-1.5-4.6-5 0 0 2.6-.2 6.4.7s12.2 3.1 16.8.4zm2 3.7s.8 1.8 3.2 1.4a17 17 0 0 1 10.2.8s.7-3.2-7-3.4c0 0-4.8.2-6.4 1.2zm-65.2-21s-3 2.5-.3 5c2.4 2.3 6.2 2.1 8 2 0 0-1-.6-2-2-1-1.5-1-2.5-3-3.4-2.1-.9-2.3-1.1-2.7-1.6zm-3-12.6s-4.6 9.3 13 11.6c0 0 0-1 .7-2.5.6-1.5 2.1-4.5.8-6.4-1.6-1.9 1.1-.9 1.5-3.4.4-2.5-.3-2.2 1-3.8 0 0-5.5 2-7.7 4.5-2 2.4 2.9 4.2 0 6.9 0 0-2.5-1-4-3.6 0 0-3.3 0-5.5-3.3z"/>
|
<path fill="#5a3719" d="M513.7 347.6s-3.1-.2-7.5-1.7c-4.3-1.5-5.4-.2-7.9-2-2.4-1.9-7.3-.7-8.2-.6-1 .1-3.6 0-.3-2.1 0 0-2.6 0-3.6-1.4 0 0-1.2 1.2-5.6.8 0 0 2 3-6 2.1a10.3 10.3 0 0 0 11.1 3c0 .2-.5 2.5 3 3.5 3.8.9 4.5 1.6 6.4 2.3 0 0 .3-1.5-4.6-5 0 0 2.6-.2 6.4.7s12.2 3.1 16.8.4m2 3.7s.8 1.8 3.2 1.4a17 17 0 0 1 10.2.8s.7-3.2-7-3.4c0 0-4.8.2-6.4 1.2m-65.2-21s-3 2.5-.3 5c2.4 2.3 6.2 2.1 8 2 0 0-1-.6-2-2-1-1.5-1-2.5-3-3.4-2.1-.9-2.3-1.1-2.7-1.6m-3-12.6s-4.6 9.3 13 11.6c0 0 0-1 .7-2.5.6-1.5 2.1-4.5.8-6.4-1.6-1.9 1.1-.9 1.5-3.4.4-2.5-.3-2.2 1-3.8 0 0-5.5 2-7.7 4.5-2 2.4 2.9 4.2 0 6.9 0 0-2.5-1-4-3.6 0 0-3.3 0-5.5-3.3z"/>
|
||||||
<path d="M493.3 339.3s3.7-.6 13 2.9c9.4 3.4 13.3 2.6 14.6 2.5 0 0-5.2 2.8-13.4-.8-7.2-3.2-7.6-2-14.2-4.6z"/>
|
<path d="M493.3 339.3s3.7-.6 13 2.9c9.4 3.4 13.3 2.6 14.6 2.5 0 0-5.2 2.8-13.4-.8-7.2-3.2-7.6-2-14.2-4.6"/>
|
||||||
<path fill="#ffc221" d="M551.8 337.2s2 0 3.4.5c0 0 .7-.7 2.7-1 0 0-1.3-1.2-6.1.5zm-6.4-5.2s2.1 0 2.8-1.2c0 0-1.1-1.3-2.8-2 0 0 .4 1.6 0 3.2zm-71.7-23.8s-.5-1 1.8-1.4l31.3-4.5s1.5 0 1.7 1c.3 1.1-.1 1.9-7.2 2.7l-25.6 3.2s-1.9.3-2-1z"/>
|
<path fill="#ffc221" d="M551.8 337.2s2 0 3.4.5c0 0 .7-.7 2.7-1 0 0-1.3-1.2-6.1.5m-6.4-5.2s2.1 0 2.8-1.2c0 0-1.1-1.3-2.8-2 0 0 .4 1.6 0 3.2m-71.7-23.8s-.5-1 1.8-1.4l31.3-4.5s1.5 0 1.7 1c.3 1.1-.1 1.9-7.2 2.7l-25.6 3.2s-1.9.3-2-1"/>
|
||||||
<path fill="#ffc221" d="M502 306.9s0 4.1 4.2 4.7c4 .6 5.5-.2 6.5-2.3.3-.7 1.6-5-.2-5.3-.8-.1-2 0-2.9.3-1.4.7-2.7 1.4-2.3 2 1 1.6 1.2 2 1 2-1.2.3-1.8-.6-2-1.2-.3-.8.5-1.2-2.2-.8-1.2.1-2 .1-2 .6zm17.5-3.2c2 .3 1.9 4.8-.6 6.9-2.8 2.2-5.4 1.3-5.4 1.3-1.4-.5-1.2-.4-.1-2 1-1.5 1.5-3.6.9-5-.2-.5.3-.9 1-1 0 0 2-.4 4.2-.2z"/>
|
<path fill="#ffc221" d="M502 306.9s0 4.1 4.2 4.7c4 .6 5.5-.2 6.5-2.3.3-.7 1.6-5-.2-5.3-.8-.1-2 0-2.9.3-1.4.7-2.7 1.4-2.3 2 1 1.6 1.2 2 1 2-1.2.3-1.8-.6-2-1.2-.3-.8.5-1.2-2.2-.8-1.2.1-2 .1-2 .6zm17.5-3.2c2 .3 1.9 4.8-.6 6.9-2.8 2.2-5.4 1.3-5.4 1.3-1.4-.5-1.2-.4-.1-2 1-1.5 1.5-3.6.9-5-.2-.5.3-.9 1-1 0 0 2-.4 4.2-.2"/>
|
||||||
<path fill="#ffc221" d="M521.3 304.1s1.6 2-.4 5.5c0 0-.8 1 1.1.9 1.8-.2 6.1-2.2 5.7-4.8 0 0-.2-.6-1.3-.6s-.2-.5.3-.8c.4 0 1.9-.6-1.9-3 0 0-.6-.6-1.3-.3-.6.2-2.6 1-2.6 2.2 0 .5.4 1 .4 1z"/>
|
<path fill="#ffc221" d="M521.3 304.1s1.6 2-.4 5.5c0 0-.8 1 1.1.9 1.8-.2 6.1-2.2 5.7-4.8 0 0-.2-.6-1.3-.6s-.2-.5.3-.8c.4 0 1.9-.6-1.9-3 0 0-.6-.6-1.3-.3-.6.2-2.6 1-2.6 2.2 0 .5.4 1 .4 1z"/>
|
||||||
<path fill="#ffc221" d="M525.4 300.9s3 2.1 3 2.8c0 .6-.3 1.5.5 1.3.8 0 4-.7 3-2.8-.8-2.1-1.7-3-3.2-3.4-1.5-.6-1.9.1-3.2 1.1 0 0-.9.6-.1 1zm-16.1 3s.5-1.5-2.2-2.2c0 0 1.1-1 3.4-.4 2.2.4 2 2 2 2.1 0 0-1.8 0-3.2.5zm5.8-.4s3-.5 4.5-.4c0 0-1.6-3.3-5.7-2.3 0 0 1.5 1.8 1.2 2.7zm5.3-.8s0-1.1 2.6-2.1c0 0-1.2-1.2-3-1-2 0-2.5.7-2.5.7s2.3.8 2.9 2.4zm1-3.6s1.7.4 2.7 1.3c0 0 1.5-1.7 2.8-2 0 0-2.5-1.4-5.5.7z"/>
|
<path fill="#ffc221" d="M525.4 300.9s3 2.1 3 2.8c0 .6-.3 1.5.5 1.3.8 0 4-.7 3-2.8-.8-2.1-1.7-3-3.2-3.4-1.5-.6-1.9.1-3.2 1.1 0 0-.9.6-.1 1m-16.1 3s.5-1.5-2.2-2.2c0 0 1.1-1 3.4-.4 2.2.4 2 2 2 2.1 0 0-1.8 0-3.2.5m5.8-.4s3-.5 4.5-.4c0 0-1.6-3.3-5.7-2.3 0 0 1.5 1.8 1.2 2.7m5.3-.8s0-1.1 2.6-2.1c0 0-1.2-1.2-3-1-2 0-2.5.7-2.5.7s2.3.8 2.9 2.4m1-3.6s1.7.4 2.7 1.3c0 0 1.5-1.7 2.8-2 0 0-2.5-1.4-5.5.7"/>
|
||||||
<path fill="#5a3719" d="M435.8 290.9s7.2-6.2 11.2-5.4c4 .8 2 .2 6.4-.5 4.4-.6 9-1.1 10.8-.9 0 0-5.4-3.8-14.9-3.7 0 0-6.6 2.3-11.3 5.3 0 0-8.9-4.9-18-2 0 0 9.9 3.7 15.8 7.2z"/>
|
<path fill="#5a3719" d="M435.8 290.9s7.2-6.2 11.2-5.4c4 .8 2 .2 6.4-.5 4.4-.6 9-1.1 10.8-.9 0 0-5.4-3.8-14.9-3.7 0 0-6.6 2.3-11.3 5.3 0 0-8.9-4.9-18-2 0 0 9.9 3.7 15.8 7.2"/>
|
||||||
<path fill="#ffc221" d="m512.2 301.4 1.2-.2s2 2.5.6 2.5c-1.2 0-.8-.3-1-1a2.3 2.3 0 0 0-.8-1.3zm-9 .2s-.8 1 .6.8c1.7-.3 1.4 0 3.1-1.3 0 0 1.2-1.1 3.2-.4 0 0 1.8.6 3.2-.1 1.4-.8 1.7-.7 2.5-.6.8 0 .8.2 1.7-.6 1-.7 2.8-.1 3.9-1 1.1-1 2.5-.2 0-2 0 0-.5-.5-.5-1 0 0 1 .4 1.8 1 .8.8 2 .5 2.2.4 0 0 .2-2.3 2.3-4.3 2.3-2 2.3-2.2 1-2.2s-3.5-.6-4.3 0-7.2 4.8-11 5.5c-3.8.7-7.3 1.8-9.7 5.8zm-101.3-23.4s11.7 3 14.3 4.2c0 0 .6-1.9-4.7-3.4 0 0 12.9-.4 26.4 5.8 0 0 6.6-5.6 27.7-3.9 0 0 0-1.8.2-3.3 0 0-14.8-.4-28.4-8.7 0 0-12.3 6-35.5 9.3zm64.7 5.6c-.7-11.8 3.8-13 3.8-13s2.1 0 4.4.5c0 0-3.6 4.3-2.6 12.8 0 0 .4 1.3-2.7 1.3s-2.9-1.5-2.9-1.5z"/>
|
<path fill="#ffc221" d="m512.2 301.4 1.2-.2s2 2.5.6 2.5c-1.2 0-.8-.3-1-1a2.3 2.3 0 0 0-.8-1.3m-9 .2s-.8 1 .6.8c1.7-.3 1.4 0 3.1-1.3 0 0 1.2-1.1 3.2-.4 0 0 1.8.6 3.2-.1 1.4-.8 1.7-.7 2.5-.6.8 0 .8.2 1.7-.6 1-.7 2.8-.1 3.9-1 1.1-1 2.5-.2 0-2 0 0-.5-.5-.5-1 0 0 1 .4 1.8 1 .8.8 2 .5 2.2.4 0 0 .2-2.3 2.3-4.3 2.3-2 2.3-2.2 1-2.2s-3.5-.6-4.3 0-7.2 4.8-11 5.5c-3.8.7-7.3 1.8-9.7 5.8m-101.3-23.4s11.7 3 14.3 4.2c0 0 .6-1.9-4.7-3.4 0 0 12.9-.4 26.4 5.8 0 0 6.6-5.6 27.7-3.9 0 0 0-1.8.2-3.3 0 0-14.8-.4-28.4-8.7 0 0-12.3 6-35.5 9.3m64.7 5.6c-.7-11.8 3.8-13 3.8-13s2.1 0 4.4.5c0 0-3.6 4.3-2.6 12.8 0 0 .4 1.3-2.7 1.3s-2.9-1.5-2.9-1.5z"/>
|
||||||
<path fill="#5a3719" d="M469.8 291.7s-2.3-2.3-2.5-4.9c0 0 0-.6 2.2-.6 2.3 0 2.5-.2 3 1.1.6 1.3 2 4 2.3 4.3z"/>
|
<path fill="#5a3719" d="M469.8 291.7s-2.3-2.3-2.5-4.9c0 0 0-.6 2.2-.6 2.3 0 2.5-.2 3 1.1.6 1.3 2 4 2.3 4.3z"/>
|
||||||
<path fill="#ffc221" d="M474.5 285.7a28.3 28.3 0 0 1-.2-4.5c.1-6.6 1.2-6 1.7-5.2h2.3s-1.7-7.4-3.7-3a19 19 0 0 0-1.5 10.4c.1 2 .3 3.3.6 4z"/>
|
<path fill="#ffc221" d="M474.5 285.7a28.3 28.3 0 0 1-.2-4.5c.1-6.6 1.2-6 1.7-5.2h2.3s-1.7-7.4-3.7-3a19 19 0 0 0-1.5 10.4c.1 2 .3 3.3.6 4z"/>
|
||||||
<path fill="#5a3719" d="M500.2 285.7s4.3.8-2.3 2.3c0 0 .3 8.2 8.2 2.5 0 0 4.7-3 8-4.2 0 0 1.6-.6 1.4-1.8 0 0 .2-1.5-1.5-1.1 0 0-1.4 0-2.3-.3 0 0-1-1.2-1.6-.8-.6.5-2.1.2-.9 1.7 1.2 1.4 1.5 1 2 .6.6-.4 3.1-1.4.9.7s-4.2-1.2-5-1.8zm-22 1h-2s-1 1.6-1.7-1l-.7 1.6s2.3 8.8 4.4-.6z"/>
|
<path fill="#5a3719" d="M500.2 285.7s4.3.8-2.3 2.3c0 0 .3 8.2 8.2 2.5 0 0 4.7-3 8-4.2 0 0 1.6-.6 1.4-1.8 0 0 .2-1.5-1.5-1.1 0 0-1.4 0-2.3-.3 0 0-1-1.2-1.6-.8-.6.5-2.1.2-.9 1.7 1.2 1.4 1.5 1 2 .6.6-.4 3.1-1.4.9.7s-4.2-1.2-5-1.8zm-22 1h-2s-1 1.6-1.7-1l-.7 1.6s2.3 8.8 4.4-.6"/>
|
||||||
<path fill="#ffc221" d="M475.4 276.6s-1 5.8.3 9.2l21.1.5s-.2-4 0-9.7H494s-.5 4.6 0 7.5h-.5s-.4-4 0-7.5H491s-.4 4.3 0 7.5h-.5s-.4-3.7 0-7.5H488s-.5 3.9 0 7.5h-.6s-.5-3.9 0-7.5h-2.7s-.6 3.6 0 7.5h-.5s-.6-3.6 0-7.5h-2.7s-.6 4.2 0 7.5h-.6s-.4-4 .1-7.5h-2.5s-.7 3.5 0 7.5h-.7s-.4-3 .2-7.5h-2.6zm22.3 10.4s-.5-10.2 1.4-13c2-2.6 2.5-2 5.8 0 3.4 2.2 7.7 4.5 8.5 4.8.6.3 1.6.5 1.6 2.4s.3 2.4-2.6 0a9 9 0 0 0-2.7-1.8c-2.6-.9.6.5 1.5 1.9.8 1 1.5 1-.6 1.5a219 219 0 0 0-12.9 4.2z"/>
|
<path fill="#ffc221" d="M475.4 276.6s-1 5.8.3 9.2l21.1.5s-.2-4 0-9.7H494s-.5 4.6 0 7.5h-.5s-.4-4 0-7.5H491s-.4 4.3 0 7.5h-.5s-.4-3.7 0-7.5H488s-.5 3.9 0 7.5h-.6s-.5-3.9 0-7.5h-2.7s-.6 3.6 0 7.5h-.5s-.6-3.6 0-7.5h-2.7s-.6 4.2 0 7.5h-.6s-.4-4 .1-7.5h-2.5s-.7 3.5 0 7.5h-.7s-.4-3 .2-7.5zm22.3 10.4s-.5-10.2 1.4-13c2-2.6 2.5-2 5.8 0 3.4 2.2 7.7 4.5 8.5 4.8.6.3 1.6.5 1.6 2.4s.3 2.4-2.6 0a9 9 0 0 0-2.7-1.8c-2.6-.9.6.5 1.5 1.9.8 1 1.5 1-.6 1.5a219 219 0 0 0-12.9 4.2"/>
|
||||||
<path d="M505 279.6s-1.5-1.8.5-2.3c2-.4 2.1 3 2.5 5.1.3 2.2-2.5-2.1-2.8-2.7zm-2.7 9s-2.3.9-.7 1.6c1.4.7 5.5-2.7 4.2-2.5-1.6.3-3.5 1-3.5 1zm3-3s2-.3 1.6.5c-.3 1-1 .4-1.4.2-.3-.2-1.6-.7-.1-.8z"/>
|
<path d="M505 279.6s-1.5-1.8.5-2.3c2-.4 2.1 3 2.5 5.1.3 2.2-2.5-2.1-2.8-2.7zm-2.7 9s-2.3.9-.7 1.6c1.4.7 5.5-2.7 4.2-2.5-1.6.3-3.5 1-3.5 1zm3-3s2-.3 1.6.5c-.3 1-1 .4-1.4.2-.3-.2-1.6-.7-.1-.8z"/>
|
||||||
<path fill="#ffc221" d="M516 282.8s.6 4 4 5c0 0 2 .4 1.5-1.3 0 0-.3-1.5-.6-2-.3-.7-1.6-1-1.8-1.1-.2 0-.3-.5.6-.2 1 .3 1 .4 1-.3s-.6-.4-1.4-.8c-.4-.2 0-.4.3-.3.4 0 1.3.3 1.3-1 0 0 .1-.8-.9-.8-1.1 0-1-.6-.7-.7.3 0 1.5.8 1.9-.6.3-1.3-1.6-.5-1.4-1.2.3-.8 1.7.3 1.7-.5.2-.8 1.3-1.1-.6-1.4-.9-.1 0-.6 1-.4 1 .1 1.6-1.2 2.3-1.6.6-.5 4.2-2.6-.6-1.9-4.7.7-6.1 3-6.3 3.5a13 13 0 0 0-1.3 7.6z"/>
|
<path fill="#ffc221" d="M516 282.8s.6 4 4 5c0 0 2 .4 1.5-1.3 0 0-.3-1.5-.6-2-.3-.7-1.6-1-1.8-1.1-.2 0-.3-.5.6-.2 1 .3 1 .4 1-.3s-.6-.4-1.4-.8c-.4-.2 0-.4.3-.3.4 0 1.3.3 1.3-1 0 0 .1-.8-.9-.8-1.1 0-1-.6-.7-.7.3 0 1.5.8 1.9-.6.3-1.3-1.6-.5-1.4-1.2.3-.8 1.7.3 1.7-.5.2-.8 1.3-1.1-.6-1.4-.9-.1 0-.6 1-.4 1 .1 1.6-1.2 2.3-1.6.6-.5 4.2-2.6-.6-1.9-4.7.7-6.1 3-6.3 3.5a13 13 0 0 0-1.3 7.6"/>
|
||||||
<path fill="#ffc221" d="M527 285.8c.7 0 1.2 0 1.4.5.8 1.6-1 1-2 2.2s-1 1-2.4.5c-1.4-.4-2-2.5-2-2.5 0-.7.5-.8 1.2-.6 0 0 2.3.2 3.9 0zm-5-.8s0 .4.9.5c.7 0 3 .3 4.5-.1 0 0 .4-.1.2-1 0 0 0-.7-1.2-.4-1.3.2-3 0-3.7-.1-.6-.2-1 0-.8 1zm-.2-2.9s-.1 1.3 1.1 1.4c1.3.2 2.9.2 3.5 0 .5 0 1.4-.2 1.5-1 0-.7.2-1.2-1.3-.8s-3.4 0-3.6 0c-.1 0-1.2-.3-1.2.4zm.5-2.5s-.3.6-.2 1.2c0 .5.9.7 2.5.7s3-.2 3.2-.7c.1-.7.5-1.3-.7-1-1.3.1-3 .2-3.6 0-.6-.3-1.1-.4-1.2-.2z"/>
|
<path fill="#ffc221" d="M527 285.8c.7 0 1.2 0 1.4.5.8 1.6-1 1-2 2.2s-1 1-2.4.5c-1.4-.4-2-2.5-2-2.5 0-.7.5-.8 1.2-.6 0 0 2.3.2 3.9 0zm-5-.8s0 .4.9.5c.7 0 3 .3 4.5-.1 0 0 .4-.1.2-1 0 0 0-.7-1.2-.4-1.3.2-3 0-3.7-.1-.6-.2-1 0-.8 1zm-.2-2.9s-.1 1.3 1.1 1.4c1.3.2 2.9.2 3.5 0 .5 0 1.4-.2 1.5-1 0-.7.2-1.2-1.3-.8s-3.4 0-3.6 0c-.1 0-1.2-.3-1.2.4m.5-2.5s-.3.6-.2 1.2c0 .5.9.7 2.5.7s3-.2 3.2-.7c.1-.7.5-1.3-.7-1-1.3.1-3 .2-3.6 0-.6-.3-1.1-.4-1.2-.2"/>
|
||||||
<path fill="#5a3719" d="M582.1 286s0 1 .9 2.2l-45.2-1.3s.6-.4.8-2.2z"/>
|
<path fill="#5a3719" d="M582.1 286s0 1 .9 2.2l-45.2-1.3s.6-.4.8-2.2z"/>
|
||||||
<path fill="#ffc221" d="M522.7 277.8s-.4 1.1.4 1.4c.7.2 2.2.4 4 .1 0 0 1 0 1.3-1 .3-1 .3-.4-2.3-.8 0 0-.8-.3 1.5-.3 0 0 1.4 0 1.5-.2.3-.2 2-1.7-.3-1.5-2.3 0-1.1-.5 0-.5 1.2 0 1.6.3 2 0s0-.2-.7-.8-.1-.5.3-.1c.5.3.8.5 1.3 0s-.4-1.2 0-1c.3 0 .6.8 2 0 1.6-.7 3.5-.3 4 0 .6.5 2.2 1 3.1 0 1-.8-1.1-1.7-.3-1.8 1-.1 1.6.2 1.9-.5.4-.8-1.4-1.4.3-1.8 1.6-.5.2-5-.3-5.5 0 0-1.9 1.1-3.8 4.3-2.1 3.3-3.3 5.2-6 4.2-3.9-1.5-6 .6-6.5 1-1 .6 2 .8.2.9-1.7 0-1.7.2-1.8.4-.2.3 0 .5.3.6.3 0 .9.6-.1.6s-1.8-.3-1.5.9c0 0 0 .2.6.3.6 0 .8.8-.3.8-.8 0-.8.2-.8.3zm4.1 11.3s-.7.5.3.6c1.2 0 1.7.3 2.1-.3s1.8-.4.8-1.2c-1-.8-1.6-.3-3.2 1z"/>
|
<path fill="#ffc221" d="M522.7 277.8s-.4 1.1.4 1.4c.7.2 2.2.4 4 .1 0 0 1 0 1.3-1 .3-1 .3-.4-2.3-.8 0 0-.8-.3 1.5-.3 0 0 1.4 0 1.5-.2.3-.2 2-1.7-.3-1.5-2.3 0-1.1-.5 0-.5 1.2 0 1.6.3 2 0s0-.2-.7-.8-.1-.5.3-.1c.5.3.8.5 1.3 0s-.4-1.2 0-1c.3 0 .6.8 2 0 1.6-.7 3.5-.3 4 0 .6.5 2.2 1 3.1 0 1-.8-1.1-1.7-.3-1.8 1-.1 1.6.2 1.9-.5.4-.8-1.4-1.4.3-1.8 1.6-.5.2-5-.3-5.5 0 0-1.9 1.1-3.8 4.3-2.1 3.3-3.3 5.2-6 4.2-3.9-1.5-6 .6-6.5 1-1 .6 2 .8.2.9-1.7 0-1.7.2-1.8.4-.2.3 0 .5.3.6.3 0 .9.6-.1.6s-1.8-.3-1.5.9c0 0 0 .2.6.3.6 0 .8.8-.3.8-.8 0-.8.2-.8.3m4.1 11.3s-.7.5.3.6c1.2 0 1.7.3 2.1-.3s1.8-.4.8-1.2c-1-.8-1.6-.3-3.2 1z"/>
|
||||||
<path fill="#ffc221" d="M531.5 275.5s3.8-3.5 6.9-1.2c3.2 2.5 3.4 2.8 3.5 2.9 0 0 .4.3-.4 1-.9.8 0 .8.9.3s1 0 1.4.5c.5.5 1.1.8-.3.8h-4.6s-2.1.2-1-.7c1-.9.8-1.9.3-2-.6 0 0 .6-.3 1-.4.4-1.1.7-1.9.7s-1.4.6-.2 1c1.1.4-.2.7-.8.7s-3.5.2-.5.6c3 .3-.3.3 2 1.5 2.4 1.4.6 4.3-.3 4.6 0 0-1 .5.2.4 1.3-.2 2-.3 1 .4-.8.6-2.6 2.9-5 1.2 0 0-1.2-.6.8-.7 2 0-1.6-.5-2.3-1-.5-.3-3-2.7-1.5-2.5 1.6.4 1-.5.1-.8-.8-.3-1-1.6 0-1.4 1 .3 2 .9 3 .8.7 0 .5-.3-1.2-.8-1.7-.6-2.4-.7-2-2 .4-1.5 2.3.5 1.8-.6-.4-1-2-.5-1.2-1.9s1-.8 1.5-.6c.3.1 1 0-.1-.8-.8-.5 0-1.3.2-1.4z"/>
|
<path fill="#ffc221" d="M531.5 275.5s3.8-3.5 6.9-1.2c3.2 2.5 3.4 2.8 3.5 2.9 0 0 .4.3-.4 1-.9.8 0 .8.9.3s1 0 1.4.5c.5.5 1.1.8-.3.8h-4.6s-2.1.2-1-.7c1-.9.8-1.9.3-2-.6 0 0 .6-.3 1-.4.4-1.1.7-1.9.7s-1.4.6-.2 1c1.1.4-.2.7-.8.7s-3.5.2-.5.6c3 .3-.3.3 2 1.5 2.4 1.4.6 4.3-.3 4.6 0 0-1 .5.2.4 1.3-.2 2-.3 1 .4-.8.6-2.6 2.9-5 1.2 0 0-1.2-.6.8-.7 2 0-1.6-.5-2.3-1-.5-.3-3-2.7-1.5-2.5 1.6.4 1-.5.1-.8-.8-.3-1-1.6 0-1.4 1 .3 2 .9 3 .8.7 0 .5-.3-1.2-.8-1.7-.6-2.4-.7-2-2 .4-1.5 2.3.5 1.8-.6-.4-1-2-.5-1.2-1.9s1-.8 1.5-.6c.3.1 1 0-.1-.8-.8-.5 0-1.3.2-1.4"/>
|
||||||
<path d="M534.2 276.5s0-.5.8-.4c.6 0 .4-.2.6-.4.2 0 1.9.5.3 1-.6.3-1.6.2-1.6-.2z"/>
|
<path d="M534.2 276.5s0-.5.8-.4c.6 0 .4-.2.6-.4.2 0 1.9.5.3 1-.6.3-1.6.2-1.6-.2z"/>
|
||||||
<path fill="#ffc221" d="M537.9 280.5s-1.3.6-.2 2c1 1 1 1.5 1 2.2-.1.8 43.4 1.3 43.4 1.3s0-2.9 1.8-4.5l-46-1z"/>
|
<path fill="#ffc221" d="M537.9 280.5s-1.3.6-.2 2c1 1 1 1.5 1 2.2-.1.8 43.4 1.3 43.4 1.3s0-2.9 1.8-4.5z"/>
|
||||||
<path fill="#5a3719" d="M582.8 285.2s.2-2.4 1.6-3.1c.7-.5 1.6-.3 2 1.6.6 2.7-1.7 5.1-2.7 4-1-1-.8-2.5-.8-2.5z"/>
|
<path fill="#5a3719" d="M582.8 285.2s.2-2.4 1.6-3.1c.7-.5 1.6-.3 2 1.6.6 2.7-1.7 5.1-2.7 4-1-1-.8-2.5-.8-2.5z"/>
|
||||||
<path fill="#7b3c20" d="M532.9 295.4s2.9-2.5 3.4-3.6c0 0 7.8 5.6 7.3.4l.2-2.6s2.9.3 3.3-2l-7.3-.3s-.8-.1-2 1.1c-1 1.2-3.4 2.5-5.5 1.4 0 0-1-.8-1.9 0-1 .5-1 .7-.2 1.5s2.4 2.9 2.7 4zm16.8-15.4-4.3-.2s-1.5-2.2-4.6-4.6c0 0-.9-.4.8-1.8 1.8-1.4 2.3-2.8 2.3-3.5 0-.6 0-1.7.6-1 .6.8 5 4.9 5.8 3.7.6-1.2.7-1.7.7-2.1.2-.4.3-1.5 1-.3.6 1.1 1 .8 1.1 3.8 0 0 0 3 .5 4 0 0-5.6-1.7-3.8 2zm-18.6-9.2s3.3 2 5-.6c1.5-2.5 2.6-2.8 1.4-5.3-1.2-2.3 0-3.4.9-4.4 1-1 1.8-.8 1.8-4.6.2-3.9 2.8-5 4-6.3 1.2-1.2 4.2-3-.4-3.7-4.4-.8-13.4-3-15.7-6.5-2.3-3.5-3.3-1.5-3.3-1.3 0 .2-.8 2.7 1.5 7.3s4.2 7.6 6.5 9c2.2 1.5 4.2 2.3 3 5.4s-3 8.6-4.7 11z"/>
|
<path fill="#7b3c20" d="M532.9 295.4s2.9-2.5 3.4-3.6c0 0 7.8 5.6 7.3.4l.2-2.6s2.9.3 3.3-2l-7.3-.3s-.8-.1-2 1.1c-1 1.2-3.4 2.5-5.5 1.4 0 0-1-.8-1.9 0-1 .5-1 .7-.2 1.5s2.4 2.9 2.7 4zm16.8-15.4-4.3-.2s-1.5-2.2-4.6-4.6c0 0-.9-.4.8-1.8 1.8-1.4 2.3-2.8 2.3-3.5 0-.6 0-1.7.6-1 .6.8 5 4.9 5.8 3.7.6-1.2.7-1.7.7-2.1.2-.4.3-1.5 1-.3.6 1.1 1 .8 1.1 3.8 0 0 0 3 .5 4 0 0-5.6-1.7-3.8 2zm-18.6-9.2s3.3 2 5-.6c1.5-2.5 2.6-2.8 1.4-5.3-1.2-2.3 0-3.4.9-4.4 1-1 1.8-.8 1.8-4.6.2-3.9 2.8-5 4-6.3 1.2-1.2 4.2-3-.4-3.7-4.4-.8-13.4-3-15.7-6.5-2.3-3.5-3.3-1.5-3.3-1.3 0 .2-.8 2.7 1.5 7.3s4.2 7.6 6.5 9c2.2 1.5 4.2 2.3 3 5.4s-3 8.6-4.7 11"/>
|
||||||
<path fill="#5a3719" d="M543.2 261s.6 8 6.3 10.8c0 0 1.3-3 .8-6.1 0 0 1.9.1 2.4 1 0 0 0-2.3-2.6-3.2-2.7-.7-1.4-6-.4-6.5.9-.6.6-1.7 0-2.6-.7-1-.8-2.3 1.4-1.7 2.3.6 2-.6.5-1.7-1.3-1.1-1.3-2.5.7-2.5s5-1.9 3.2-2.4c-2-.6-2.5-1.3 0-2 2.7-.8 4-1.7 2-2-2-.2-3.3-.9-1.4-1.2 1.9-.3-.3-2.3-2.5-2.3-2.3-.2-7 .7-3.3-2.3 3.8-3-5.4-.8-1.6-2.8 3.8-2-1.3-1.1-2-1.1s-.7 0-.4-1c.2-1-.5-1.6-1.7-.9-1 .6-1 .6-1-.7 0-1.5-1.3-.4-2.1 0-.9.3-3 1.9-3.9 1-.7-.9-1.2-1.7-3.8-.2-2.6 1.5-2 .2-2-.5s1-3.4-2.4-.5-.7-3-3.5-1c-2.7 2-3 2.4-3.5 1.5-.5-1-1-1.7-4 .3-3.1 1.9-.8-1.3-.5-2 .5-.6 1.8-5-.9-1.6 0 0-1.3 2.4-4.2-1.9 0 0-3 4.3-3.9 2.4-.8-2-1.5-2-2.6-.8-1 1.2-.2-.1-.7-1.2-.4-1-.7-2.9-5.8.8-5.1 3.8 1.8 1-2.1 2.7s-13.5 7-4.8 5.9c8.7-1.3-4.2 3.3-1.2 4.2 3 .8 2 3.5 13.4.3 11.2-3 9.4-.4 15.2-3 5.8-2.4-1.4.9 6.4.8 7.7-.2 1.3 0 2.8 1.6 1.5 1.6 8 5.3 14.1 6 6.1.6 7.7-1.7 5.9 1-1.8 2.6-2.4 3.6-3.4 4.6-1 .8-4 3-4 6.6 0 3.7-4.8 4.3-3 8.3l4.1-4z"/>
|
<path fill="#5a3719" d="M543.2 261s.6 8 6.3 10.8c0 0 1.3-3 .8-6.1 0 0 1.9.1 2.4 1 0 0 0-2.3-2.6-3.2-2.7-.7-1.4-6-.4-6.5.9-.6.6-1.7 0-2.6-.7-1-.8-2.3 1.4-1.7 2.3.6 2-.6.5-1.7-1.3-1.1-1.3-2.5.7-2.5s5-1.9 3.2-2.4c-2-.6-2.5-1.3 0-2 2.7-.8 4-1.7 2-2-2-.2-3.3-.9-1.4-1.2 1.9-.3-.3-2.3-2.5-2.3-2.3-.2-7 .7-3.3-2.3 3.8-3-5.4-.8-1.6-2.8 3.8-2-1.3-1.1-2-1.1s-.7 0-.4-1c.2-1-.5-1.6-1.7-.9-1 .6-1 .6-1-.7 0-1.5-1.3-.4-2.1 0-.9.3-3 1.9-3.9 1-.7-.9-1.2-1.7-3.8-.2-2.6 1.5-2 .2-2-.5s1-3.4-2.4-.5-.7-3-3.5-1c-2.7 2-3 2.4-3.5 1.5-.5-1-1-1.7-4 .3-3.1 1.9-.8-1.3-.5-2 .5-.6 1.8-5-.9-1.6 0 0-1.3 2.4-4.2-1.9 0 0-3 4.3-3.9 2.4-.8-2-1.5-2-2.6-.8-1 1.2-.2-.1-.7-1.2-.4-1-.7-2.9-5.8.8-5.1 3.8 1.8 1-2.1 2.7s-13.5 7-4.8 5.9c8.7-1.3-4.2 3.3-1.2 4.2 3 .8 2 3.5 13.4.3 11.2-3 9.4-.4 15.2-3 5.8-2.4-1.4.9 6.4.8 7.7-.2 1.3 0 2.8 1.6 1.5 1.6 8 5.3 14.1 6 6.1.6 7.7-1.7 5.9 1-1.8 2.6-2.4 3.6-3.4 4.6-1 .8-4 3-4 6.6 0 3.7-4.8 4.3-3 8.3l4.1-4z"/>
|
||||||
<path fill="#5a3719" d="M553.3 269.9s-1.4-1-1.4-2.8c0 0 1 .2 1.4.8 0 0 3.5-4-.8-5.4-4.1-1.4-2-5.3-.6-5.3s1.7-.3.4-2c-1.2-1.5-1-1.6 1.3-2 2.3-.4 2.1-1 1-1.5a7.7 7.7 0 0 1-1.9-1.6s6.8-2.9 4.6-4.3c-2.2-1.3 0-1 2-2.3 2-1.4 2.2-1.7 2.5-2.3 0 0-2 .3-3.4 0 0 0 1.7-.9 0-2.3s-2.3-2.6-5-2c-2.7.7-1.8-.2-.8-1.3s.6-1.7-1.3-2c0 0 .2-1.2 1.7-2.5 0 0-3.7.2-5-.4 0 0 1.6-1 1.6-2.3 0 0-2 .7-4.5.5 0 0 1.5-1.3 1.5-2.4 0 0-4.4 1-6.4 2.5 0 0-.5 0-.8-.6-.4-.4-.6-1-5.5.6 0 0 .5-2.2 1.7-3 1.2-.8 1-2.6-6.5 2.1 0 0-1-.6-1.9-2.9 0 0-1.7 2.3-2.9 3.1 0 0-1 .5-1-1 .2-1.5-.7-.5-1.4 0-.8.4-1.3 1.5-1-1.5s-1-3.6-1-3.6-2.3 3.3-3.7 3.7c0 0-2.5-2.4-3.4-4-.8-1.6-.8-2.2-1.7.6-.9 2.7-2 3-2 3s-1.5-1.3-1.6-2c0 0-.3.7-.8 1 0 0-1.3-1.5-1.2-3.7 0 0-8.2 4.5-9.2 7.2 0 0-7.7-.5-10.8.1 0 0 .7-2.4 2.7-3.7 0 0-2-.2-2-2.3 0 0 1.6.2 2.6 0s-1.4-3.1 1.1-3.2c2.5-.1 4.2 1.2 3-2.2-1-3.3-.6-3.3-.6-3.3s4.4 2.6 5.1 1.9c.8-.6-.5-2 3.4-1.4 3.9.7 2.8-1.5 4.4-1.7 1.5 0 2.3 1 1.3-6.1s4.8 3.5.9-7.2c0 0-1-3.3-3.3-4.7 0 0-.6 2.3-3.2.3-2.6-2-7.8-2.8-5.6-4.4 2.2-1.7 3.2-3.9 2.6-5.2 0 0-2.6 2.6-7 .7-3.6-1.5-4.4 1.3-8 .5 0 0 0-1 3.1-3.4 3-2.3-1.8.8-3.6 1.3-1.9.4-2.4 0 1.5-3.1 4-3 12-8.5 11-13 0 0 1.8 2.3 6.7.6 5-1.7 8.6-2.3 10-5a23 23 0 0 1 6.4-5.6c1.1-.5 2.4-1 .9 1.5-1.6 2.4-4 6.6-10.8 9.4-6.8 2.8-9.5 4.8-10.7 6.3-1.2 1.5-7.4 4.8-3.3 4.3 4-.7 10.9 0 7.6-1-3.2-.9-6.9.6-3.9-2.1 3-2.7 3.5-3.6 7.9-5.4 4.4-1.9 9.2-6.1 8.7-1.6-.5 4.4-8.6 9.1-10.6 10.6-2 1.4-1.2 1.2-1.2 1.8 0 .6-.4 1.8-1.2 2.3-.8.6-.5 1.2-.3 2.4.2 1.3-.2 1.8.4 2 .6.1 1.2.2 1.4 1.1.2 1 .6 1 1.8 1 1.1-.2 2 0 2 .6 0 .7 1.2 1.7 1.3-.4.1-2.2 1-2.5-1.2-1.5-2.2.9-2.6.6-2.6-.4s-.2-.8-1-.9c-1 0-1.3-1.3.3-2.2 1.6-.8 1.6 0 3.6-1.6 2-1.7 2-2 2.3-3 .3-.7-2.9 2.4-4.4 3-1.5.8-1-.5-.8-2.1.3-1.7 4-4 5.7-4 1.8 0 5.6 1 4 3.3-1.7 2.3-6.4 5.2-4.5 5.4 2.1.2 2.4-.6 3.6.4 1.2 1 0 3.2-.4 4.4a8.4 8.4 0 0 1-2.2 2.7s-2.2-3.8-2.1-.8c0 3.1-.5 4.2 0 4.3.5.1 2.8 1.7 3.6 1.7s-4.1 2.3-2 2.5c2 .1 5.3-1 6.4-3 0 0-4.2-1-5.9-2.6 0 0 4.9-1.2 3.5-5.8 0 0 4.9 1.3 2.7 3.5-2 2.1-3.3 1.8-1.5 2.4 1.9.6 2.7 1.2 2.7 1.2s1.3.6.5 1.6c-.7 1-.7 2.6 0 2.5.5 0 2.6-1 .9-2-1.8-1 1.9-.8.4-1.7-1.6-1-2-1.1-2.4-1.6-.5-.3 19.7-12.2 9.5-7.8 0 0 2.1-4.6 5.1-4.6 3 0 3.2 2.3 1.5 4.2-1.7 1.7-2.8 4.6-6.7 5.2 0 0 5.6 2.7-1 7.2 0 0-1.5.7-1 1.2s4.5-1.7 5-3a5.5 5.5 0 0 1 3-3 38 38 0 0 0 11.2-9.6c2.3-3.9 2.8-4 7.2-7.5s3.6-2.8 4.2-3.6c.5-.9.7-2.3 2.7-3.4 2-1.2 9.8-5.4 12.3-7.2 2.4-1.8 7.4-5 9.6-7.8 2.1-2.7 8-6.2 9.4-5.6 1.4.7-.2 2.8-3.5 5.4-3.5 2.5-12 9.3-13.3 10.4a44.7 44.7 0 0 1-11.2 6.6c-2.7.3-2.4 1.3-4 3s-5.3 5.4-6.5 6.4c-1.3 1-4.3 3-4.4 4.5-.2 1.5.5 1.6-1.9 3.8a50 50 0 0 1-11.9 8.1s4.5 1.6 1.8 4.6c-2.6 3-2.5 2.6-2.6 2.8 0 0 6.7-1 2 4.3 0 0-1 1.5 1.1 0 2.3-1.9 1.4-4.1 1-4.5 0 0 3.7-2.3 7.9-2.3 4.1 0 4-.3.2-1.4 0 0 2.7-3.2 5-1.6 2.2 1.5 1.4 2.5-.9 3.8-2.4 1.2-5.8 1.7-8.5 3.2 0 0 5 1 7.6-1.1 2.6-2 2.8-1 3-.6.5.4.8 1-.4 2.6-1.2 1.7-1.3 1.8-1.2 2.2 0 .4-.1 1.5-2.5 2-2.3.3-3.5 1.3-2.6 2.4.7 1.2.7 4-1.2 3.7-2-.3-1.6-1.9-2.3-2.5-.8-.6-1.9-1.5-5.4.2-3.6 1.9-3.8-.3-3.7-1.5 0 0-2.3 2-4.2.2-2-1.9-.2-2.6 1-3.5 1-1 5.5-3 2.8-2.5-2.7.3-6.7.4-7.6-1.6-1-2.1 2-1.9 2.4-1.7.5.2 2.3 1.7 2.5-.3 0-2 3-2.3 2-2.6-1-.4-2.5.9-2.9 1.3 0 0-2-2.9-5.4-2-3.4 1 1 .7 2 .8.8.2.3 1.8-2.7 4.6-3 2.7-1.7 1.8.5 1.8 2.3 0 7.9 0 4.6 2.6-3.2 2.7-4.5 4-6 3.6-1.8-.5 0-1.6.8-2.1s1.2-1.2-.4-.6c-1.6.5-2.1.7-3.4-1.5-1.2-2.3-.8-1.6-.2-3.1.6-1.5 1.8-3 .4-2.5-1.6.6-1.4.7-1.3-1 .1-1.7-1.7-2.1-1.7-2.1s.8 1.7.1 2.8c-.6 1-.7 1.4.4 1.6 1 .4 2 1.3.6 2.3-1.4.9-1.2.7-.4 1.3 1 .7 2.3 1.3.9 2.7-1.4 1.4-.3 1 .4 1 .8 0 2.3.6 2.3 2 0 1.2 0 1.5 2.3.3 2.3-1.3 6.7-1.1 6.7.6 0 1.8-.6 2.3 1.8.8 2.4-1.5 3.5 1.4 5.2 0 1.6-1.5 2.6-2.8 4.6-.4 1.9 2.4 1.3 3-1 4.8-2.3 1.7 1.1.4 2.9-.5s6.7-1.5 9.5-.2c2.9 1.2 3.7 1 5.8 0 2.1-.8 3.2-1 6.3 1.1 3.3 2.2 5.7 2.6 7.4 2.5 0 0-3.5 1.4-7.5 1.6-4 .3-6 1-6.7 1.6 0 0 2.3 1.5 2.8 3.2 0 0 2.6-.3 3.8.2 0 0-.6 1.9 1 2.9s2.7 1.4 1.5 2.7c-1.2 1.4 1.9.8.1 2.7-1.7 2-2.1 3-2.2 4.5 0 1.6.4 1.8-1.1 2-1.6.1.2 1.9-.5 4-.7 2-5 1.7-4.8 7.2 0 0 1.2-2.7 3.8-5 2.5-2.4 2.6-2.6 2.5-4 0-1.4-.1-1.1 1.2-2.2 1.4-1-.6-2 .8-3.6 1.3-1.5.2-1.2 1.8-2.7 1.5-1.6-1.5-1.7.2-3.3 1.5-1.6-4-3.5-2.3-4.5 1.5-1 4.3-2.4-5-2.3 0 0 2.3-3.6 10-2.9 0 0-2 1.6-2.2 3l1.6.5s-.4 1.1-1.9 2.3c0 0 4.2 2.3 4.9 3.8 0 0-2.6.8-3.3 1.8 0 0 1.2 1.3 1.6 3 0 0-2.9-.4-3.2 1.7-.4 2.1-1.3.7-1.3 2s.1 1.7-.9 2c-1 0-.1 1.1 0 1.8.2.7.6 2.3.4 2.8 0 0-1.5 0-2.1.2 0 0 .4 3-1.3 3.5-1.7.4 1 1-.9 1.3-1.8.3-1.5.5-3.7 4.5 0 0 1.9-1 3.8-2.4 2-1.3-.2-1 3-4 3.3-3.3 2.7-3.5 2.4-5.1-.2-1.6-.3-3 .9-4.5s1.5-3.2 5.7-3c0 0-1.2-2.8-2.7-3.5 0 0 2-1.3 4-1.5 0 0-1.8-2.3-5.6-4.4 0 0 3-2.6 3.9-3.9 0 0-1.5.3-2.7 0 0 0 .6-1.3 3.4-3.1 0 0 1.5 1.4 1.4 2.9 0 0 4.8-2.7 7.5-2.4 0 0 1.4 3.4-5.3 10 0 0 4.2.3 6 0 0 0-1 3.2-6 5-5 2 1 4.2-4.1 3.8-5-.4-3.5 1.3-3.4 3.9.2 2.6.3 5.3.2 6 0 0-4-1.3-4 2.6.1 4-2 4.8-2.5 5.1 0 0-1.2-1-3-1.7 0 0-2.5 4.9-6.5 7.7z"/>
|
<path fill="#5a3719" d="M553.3 269.9s-1.4-1-1.4-2.8c0 0 1 .2 1.4.8 0 0 3.5-4-.8-5.4-4.1-1.4-2-5.3-.6-5.3s1.7-.3.4-2c-1.2-1.5-1-1.6 1.3-2 2.3-.4 2.1-1 1-1.5a7.7 7.7 0 0 1-1.9-1.6s6.8-2.9 4.6-4.3c-2.2-1.3 0-1 2-2.3 2-1.4 2.2-1.7 2.5-2.3 0 0-2 .3-3.4 0 0 0 1.7-.9 0-2.3s-2.3-2.6-5-2c-2.7.7-1.8-.2-.8-1.3s.6-1.7-1.3-2c0 0 .2-1.2 1.7-2.5 0 0-3.7.2-5-.4 0 0 1.6-1 1.6-2.3 0 0-2 .7-4.5.5 0 0 1.5-1.3 1.5-2.4 0 0-4.4 1-6.4 2.5 0 0-.5 0-.8-.6-.4-.4-.6-1-5.5.6 0 0 .5-2.2 1.7-3 1.2-.8 1-2.6-6.5 2.1 0 0-1-.6-1.9-2.9 0 0-1.7 2.3-2.9 3.1 0 0-1 .5-1-1 .2-1.5-.7-.5-1.4 0-.8.4-1.3 1.5-1-1.5s-1-3.6-1-3.6-2.3 3.3-3.7 3.7c0 0-2.5-2.4-3.4-4-.8-1.6-.8-2.2-1.7.6-.9 2.7-2 3-2 3s-1.5-1.3-1.6-2c0 0-.3.7-.8 1 0 0-1.3-1.5-1.2-3.7 0 0-8.2 4.5-9.2 7.2 0 0-7.7-.5-10.8.1 0 0 .7-2.4 2.7-3.7 0 0-2-.2-2-2.3 0 0 1.6.2 2.6 0s-1.4-3.1 1.1-3.2c2.5-.1 4.2 1.2 3-2.2-1-3.3-.6-3.3-.6-3.3s4.4 2.6 5.1 1.9c.8-.6-.5-2 3.4-1.4 3.9.7 2.8-1.5 4.4-1.7 1.5 0 2.3 1 1.3-6.1s4.8 3.5.9-7.2c0 0-1-3.3-3.3-4.7 0 0-.6 2.3-3.2.3-2.6-2-7.8-2.8-5.6-4.4 2.2-1.7 3.2-3.9 2.6-5.2 0 0-2.6 2.6-7 .7-3.6-1.5-4.4 1.3-8 .5 0 0 0-1 3.1-3.4 3-2.3-1.8.8-3.6 1.3-1.9.4-2.4 0 1.5-3.1 4-3 12-8.5 11-13 0 0 1.8 2.3 6.7.6 5-1.7 8.6-2.3 10-5a23 23 0 0 1 6.4-5.6c1.1-.5 2.4-1 .9 1.5-1.6 2.4-4 6.6-10.8 9.4-6.8 2.8-9.5 4.8-10.7 6.3-1.2 1.5-7.4 4.8-3.3 4.3 4-.7 10.9 0 7.6-1-3.2-.9-6.9.6-3.9-2.1 3-2.7 3.5-3.6 7.9-5.4 4.4-1.9 9.2-6.1 8.7-1.6-.5 4.4-8.6 9.1-10.6 10.6-2 1.4-1.2 1.2-1.2 1.8 0 .6-.4 1.8-1.2 2.3-.8.6-.5 1.2-.3 2.4.2 1.3-.2 1.8.4 2 .6.1 1.2.2 1.4 1.1.2 1 .6 1 1.8 1 1.1-.2 2 0 2 .6 0 .7 1.2 1.7 1.3-.4.1-2.2 1-2.5-1.2-1.5-2.2.9-2.6.6-2.6-.4s-.2-.8-1-.9c-1 0-1.3-1.3.3-2.2 1.6-.8 1.6 0 3.6-1.6 2-1.7 2-2 2.3-3 .3-.7-2.9 2.4-4.4 3-1.5.8-1-.5-.8-2.1.3-1.7 4-4 5.7-4 1.8 0 5.6 1 4 3.3-1.7 2.3-6.4 5.2-4.5 5.4 2.1.2 2.4-.6 3.6.4 1.2 1 0 3.2-.4 4.4a8.4 8.4 0 0 1-2.2 2.7s-2.2-3.8-2.1-.8c0 3.1-.5 4.2 0 4.3.5.1 2.8 1.7 3.6 1.7s-4.1 2.3-2 2.5c2 .1 5.3-1 6.4-3 0 0-4.2-1-5.9-2.6 0 0 4.9-1.2 3.5-5.8 0 0 4.9 1.3 2.7 3.5-2 2.1-3.3 1.8-1.5 2.4 1.9.6 2.7 1.2 2.7 1.2s1.3.6.5 1.6c-.7 1-.7 2.6 0 2.5.5 0 2.6-1 .9-2-1.8-1 1.9-.8.4-1.7-1.6-1-2-1.1-2.4-1.6-.5-.3 19.7-12.2 9.5-7.8 0 0 2.1-4.6 5.1-4.6 3 0 3.2 2.3 1.5 4.2-1.7 1.7-2.8 4.6-6.7 5.2 0 0 5.6 2.7-1 7.2 0 0-1.5.7-1 1.2s4.5-1.7 5-3a5.5 5.5 0 0 1 3-3 38 38 0 0 0 11.2-9.6c2.3-3.9 2.8-4 7.2-7.5s3.6-2.8 4.2-3.6c.5-.9.7-2.3 2.7-3.4 2-1.2 9.8-5.4 12.3-7.2 2.4-1.8 7.4-5 9.6-7.8 2.1-2.7 8-6.2 9.4-5.6 1.4.7-.2 2.8-3.5 5.4-3.5 2.5-12 9.3-13.3 10.4a44.7 44.7 0 0 1-11.2 6.6c-2.7.3-2.4 1.3-4 3s-5.3 5.4-6.5 6.4c-1.3 1-4.3 3-4.4 4.5-.2 1.5.5 1.6-1.9 3.8a50 50 0 0 1-11.9 8.1s4.5 1.6 1.8 4.6c-2.6 3-2.5 2.6-2.6 2.8 0 0 6.7-1 2 4.3 0 0-1 1.5 1.1 0 2.3-1.9 1.4-4.1 1-4.5 0 0 3.7-2.3 7.9-2.3 4.1 0 4-.3.2-1.4 0 0 2.7-3.2 5-1.6 2.2 1.5 1.4 2.5-.9 3.8-2.4 1.2-5.8 1.7-8.5 3.2 0 0 5 1 7.6-1.1 2.6-2 2.8-1 3-.6.5.4.8 1-.4 2.6-1.2 1.7-1.3 1.8-1.2 2.2 0 .4-.1 1.5-2.5 2-2.3.3-3.5 1.3-2.6 2.4.7 1.2.7 4-1.2 3.7-2-.3-1.6-1.9-2.3-2.5-.8-.6-1.9-1.5-5.4.2-3.6 1.9-3.8-.3-3.7-1.5 0 0-2.3 2-4.2.2-2-1.9-.2-2.6 1-3.5 1-1 5.5-3 2.8-2.5-2.7.3-6.7.4-7.6-1.6-1-2.1 2-1.9 2.4-1.7.5.2 2.3 1.7 2.5-.3 0-2 3-2.3 2-2.6-1-.4-2.5.9-2.9 1.3 0 0-2-2.9-5.4-2-3.4 1 1 .7 2 .8.8.2.3 1.8-2.7 4.6-3 2.7-1.7 1.8.5 1.8 2.3 0 7.9 0 4.6 2.6-3.2 2.7-4.5 4-6 3.6-1.8-.5 0-1.6.8-2.1s1.2-1.2-.4-.6c-1.6.5-2.1.7-3.4-1.5-1.2-2.3-.8-1.6-.2-3.1.6-1.5 1.8-3 .4-2.5-1.6.6-1.4.7-1.3-1 .1-1.7-1.7-2.1-1.7-2.1s.8 1.7.1 2.8c-.6 1-.7 1.4.4 1.6 1 .4 2 1.3.6 2.3-1.4.9-1.2.7-.4 1.3 1 .7 2.3 1.3.9 2.7-1.4 1.4-.3 1 .4 1 .8 0 2.3.6 2.3 2 0 1.2 0 1.5 2.3.3 2.3-1.3 6.7-1.1 6.7.6 0 1.8-.6 2.3 1.8.8 2.4-1.5 3.5 1.4 5.2 0 1.6-1.5 2.6-2.8 4.6-.4 1.9 2.4 1.3 3-1 4.8-2.3 1.7 1.1.4 2.9-.5s6.7-1.5 9.5-.2c2.9 1.2 3.7 1 5.8 0 2.1-.8 3.2-1 6.3 1.1 3.3 2.2 5.7 2.6 7.4 2.5 0 0-3.5 1.4-7.5 1.6-4 .3-6 1-6.7 1.6 0 0 2.3 1.5 2.8 3.2 0 0 2.6-.3 3.8.2 0 0-.6 1.9 1 2.9s2.7 1.4 1.5 2.7c-1.2 1.4 1.9.8.1 2.7-1.7 2-2.1 3-2.2 4.5 0 1.6.4 1.8-1.1 2-1.6.1.2 1.9-.5 4-.7 2-5 1.7-4.8 7.2 0 0 1.2-2.7 3.8-5 2.5-2.4 2.6-2.6 2.5-4 0-1.4-.1-1.1 1.2-2.2 1.4-1-.6-2 .8-3.6 1.3-1.5.2-1.2 1.8-2.7 1.5-1.6-1.5-1.7.2-3.3 1.5-1.6-4-3.5-2.3-4.5 1.5-1 4.3-2.4-5-2.3 0 0 2.3-3.6 10-2.9 0 0-2 1.6-2.2 3l1.6.5s-.4 1.1-1.9 2.3c0 0 4.2 2.3 4.9 3.8 0 0-2.6.8-3.3 1.8 0 0 1.2 1.3 1.6 3 0 0-2.9-.4-3.2 1.7-.4 2.1-1.3.7-1.3 2s.1 1.7-.9 2c-1 0-.1 1.1 0 1.8.2.7.6 2.3.4 2.8 0 0-1.5 0-2.1.2 0 0 .4 3-1.3 3.5-1.7.4 1 1-.9 1.3-1.8.3-1.5.5-3.7 4.5 0 0 1.9-1 3.8-2.4 2-1.3-.2-1 3-4 3.3-3.3 2.7-3.5 2.4-5.1-.2-1.6-.3-3 .9-4.5s1.5-3.2 5.7-3c0 0-1.2-2.8-2.7-3.5 0 0 2-1.3 4-1.5 0 0-1.8-2.3-5.6-4.4 0 0 3-2.6 3.9-3.9 0 0-1.5.3-2.7 0 0 0 .6-1.3 3.4-3.1 0 0 1.5 1.4 1.4 2.9 0 0 4.8-2.7 7.5-2.4 0 0 1.4 3.4-5.3 10 0 0 4.2.3 6 0 0 0-1 3.2-6 5-5 2 1 4.2-4.1 3.8-5-.4-3.5 1.3-3.4 3.9.2 2.6.3 5.3.2 6 0 0-4-1.3-4 2.6.1 4-2 4.8-2.5 5.1 0 0-1.2-1-3-1.7 0 0-2.5 4.9-6.5 7.7"/>
|
||||||
<path fill="#7b3c20" d="M547.4 220.5s1.4-.2 3.8 1.2c2.3 1.5 4.6-1.5 2-2.3-2.6-.8 0-1.8 2.4.2 2.4 1.9 3.3.9 4.2.3.8-.7 1.9-1.1.3-2.2-1.6-1.1 1-.6 2.3.3 1.2.7.7 1.5.6 1.7-.2.2-.3 2.9 2 .5 2.4-2.5 3.7-4.8 3.6-6 0 0 1.3.8 1.5 2.3.2 1.5 2-.8 2.6-1.6.6-.8 1.6-3 1.5-4.4 0 0 1.6 2.5 4 0s1.4-1 4.2-1.7a17.6 17.6 0 0 0 8.5-5.2c2-2.5 2.1-.8 4.6-1.4s7.7-4.2 8.2-6.1c.4-1.9.3-3.1-.4-2.4-.7.6-.4 0-1.5-.6-1.1-.7-2.7.9-2.7.9s1.6 1.2.3 1.7c-1.2.6-2.3 2.3-4.6 1.6-2.3-.6-4.8 2.2-4.8 2.2s2 1.6-.7 2.7c-2.7 1-2.3 1.4-3.9.2 0 0-2.9 3.7-4.6 4.5 0 0-.7 0-1.2-.8 0 0-2 2.1-2.8 2.5 0 0-1.3-1-2.3-1.5 0 0-2.3 2.9-4.2 3.7 0 0-.6-1-1.8-1.7 0 0-.6 3.6-4.6 5.8 0 0 .2-1-1.8-2.3 0 0-5 4.3-6.9 4.7-2 .4-.2-.9 0-1.5.4-.5 1.6-2.3-.8-3s-2 .5-2.5.7c-.6.2-.6-.4-2.2-.2s-1.3.9-2 1.2c-.8.2-3.6-.5-3.4 1.4.1 1.8 1.5 3.1-1 4.2-2.5 1 1 .8 4.1.4z"/>
|
<path fill="#7b3c20" d="M547.4 220.5s1.4-.2 3.8 1.2c2.3 1.5 4.6-1.5 2-2.3-2.6-.8 0-1.8 2.4.2 2.4 1.9 3.3.9 4.2.3.8-.7 1.9-1.1.3-2.2-1.6-1.1 1-.6 2.3.3 1.2.7.7 1.5.6 1.7-.2.2-.3 2.9 2 .5 2.4-2.5 3.7-4.8 3.6-6 0 0 1.3.8 1.5 2.3.2 1.5 2-.8 2.6-1.6.6-.8 1.6-3 1.5-4.4 0 0 1.6 2.5 4 0s1.4-1 4.2-1.7a17.6 17.6 0 0 0 8.5-5.2c2-2.5 2.1-.8 4.6-1.4s7.7-4.2 8.2-6.1c.4-1.9.3-3.1-.4-2.4-.7.6-.4 0-1.5-.6-1.1-.7-2.7.9-2.7.9s1.6 1.2.3 1.7c-1.2.6-2.3 2.3-4.6 1.6-2.3-.6-4.8 2.2-4.8 2.2s2 1.6-.7 2.7c-2.7 1-2.3 1.4-3.9.2 0 0-2.9 3.7-4.6 4.5 0 0-.7 0-1.2-.8 0 0-2 2.1-2.8 2.5 0 0-1.3-1-2.3-1.5 0 0-2.3 2.9-4.2 3.7 0 0-.6-1-1.8-1.7 0 0-.6 3.6-4.6 5.8 0 0 .2-1-1.8-2.3 0 0-5 4.3-6.9 4.7-2 .4-.2-.9 0-1.5.4-.5 1.6-2.3-.8-3s-2 .5-2.5.7c-.6.2-.6-.4-2.2-.2s-1.3.9-2 1.2c-.8.2-3.6-.5-3.4 1.4.1 1.8 1.5 3.1-1 4.2-2.5 1 1 .8 4.1.4"/>
|
||||||
<path fill="#5a3719" d="M557.5 215.3s.6-2.5-1.5-3.5c0 0 13.2-2.1 3.2-7.2 0 0 11.9-2.3 9-6.1-2.7-3.8-5.4-3-5.8-3-.4 0 2.5-2.1 3.3-1.8.7.3 10.2 3.9 7.8.7-2.4-3-2.2-2.9-2.6-3.8 0 0 3.1 0 7.9 4.6 0 0 1-1 .9-2.9 0 0 3.3 1 4.4 2 0 0 .6-1.2.3-1.8 0 0 3 1.5 4 3.2 0 0 1.3-1.2 1.5-2.6 0 0 3 1.3 3.7 2.2 0 0 1-1.3.6-3 0 0 4.9 1.3 5.5-1.6 0 0 4.9 1 1.7 2.9-4 2.5-.4-.6-4.6 2.3-3.2 2.3-5 4.9-6.6 4.4-1.1-.5-2.5 2.9-4 1.3-1.5-1.7-1.5-1-2.7.7a24.5 24.5 0 0 1-2.8 3.5s-.8-.5-1.6-1.2c0 0-.8 1.6-2 2.8 0 0-1-1.3-2.6-2 0 0-2.3 2.7-3.8 3.7 0 0-1.4-1.4-2.9-1.9 0 0-.2 3.8-3.1 5.7 0 0-.6-1.2-2.6-2 0 0-1.4 2.3-4.6 4.3z"/>
|
<path fill="#5a3719" d="M557.5 215.3s.6-2.5-1.5-3.5c0 0 13.2-2.1 3.2-7.2 0 0 11.9-2.3 9-6.1-2.7-3.8-5.4-3-5.8-3-.4 0 2.5-2.1 3.3-1.8.7.3 10.2 3.9 7.8.7-2.4-3-2.2-2.9-2.6-3.8 0 0 3.1 0 7.9 4.6 0 0 1-1 .9-2.9 0 0 3.3 1 4.4 2 0 0 .6-1.2.3-1.8 0 0 3 1.5 4 3.2 0 0 1.3-1.2 1.5-2.6 0 0 3 1.3 3.7 2.2 0 0 1-1.3.6-3 0 0 4.9 1.3 5.5-1.6 0 0 4.9 1 1.7 2.9-4 2.5-.4-.6-4.6 2.3-3.2 2.3-5 4.9-6.6 4.4-1.1-.5-2.5 2.9-4 1.3-1.5-1.7-1.5-1-2.7.7a24.5 24.5 0 0 1-2.8 3.5s-.8-.5-1.6-1.2c0 0-.8 1.6-2 2.8 0 0-1-1.3-2.6-2 0 0-2.3 2.7-3.8 3.7 0 0-1.4-1.4-2.9-1.9 0 0-.2 3.8-3.1 5.7 0 0-.6-1.2-2.6-2 0 0-1.4 2.3-4.6 4.3z"/>
|
||||||
<path fill="#5a3719" d="M550.6 209.5s-1.6 1.2-.6 2.5c1 1.4 1.1-.2 2.4-.3 1.3-.2 17.5-3 2.8-7.3 0 0 .7-.6 3.1-.8 2.6-.3 11.8-2.7 7.5-6-4.3-3.2-7.9 1.1-4.3-2.8 3-3.1.6-4.6.6-4.6s-8.5 5.6-10.4 6.7c-1.8 1-4.6 3-1.4 4 3.3 1 5.4-3.4 5.7-2.4.3 1-6.4 4.8-5.4 6.4.9 1.8.7 3.3 2.4 2.9 1.6-.3 6 .8 2.5.7-3.7-.1-5 1-5 1z"/>
|
<path fill="#5a3719" d="M550.6 209.5s-1.6 1.2-.6 2.5c1 1.4 1.1-.2 2.4-.3 1.3-.2 17.5-3 2.8-7.3 0 0 .7-.6 3.1-.8 2.6-.3 11.8-2.7 7.5-6-4.3-3.2-7.9 1.1-4.3-2.8 3-3.1.6-4.6.6-4.6s-8.5 5.6-10.4 6.7c-1.8 1-4.6 3-1.4 4 3.3 1 5.4-3.4 5.7-2.4.3 1-6.4 4.8-5.4 6.4.9 1.8.7 3.3 2.4 2.9 1.6-.3 6 .8 2.5.7-3.7-.1-5 1-5 1z"/>
|
||||||
<path d="M556.4 201.3s-1.5 1.1.5.6 5.9-1.4 5.2-2.4c-.8-1-3.4.2-5.7 1.8z"/>
|
<path d="M556.4 201.3s-1.5 1.1.5.6 5.9-1.4 5.2-2.4c-.8-1-3.4.2-5.7 1.8"/>
|
||||||
<path fill="#7b3c20" d="M582.4 184.5s7.5-.2 10.5 1.9c3 2 4.6 3.4 5.5 3.8 0 0-.1 2.8-5 .7 0 0 .4 1.4-.2 2.8 0 0-1.7-1.2-3.8-1.7 0 0-.4 1-1 1.7 0 0-2.1-2.2-4.6-2.9 0 0-.4 1.1-.8 1.6 0 0-2.6-1.6-4.6-1.6 0 0 .4 1.7 0 2.3 0 0-5.4-4.3-10.3-3.8 0 0 2.3 3.5 3.8 5.1 0 0-9.8-.7-8-6 1.5-5.3-.2-4 6.2-4h12.3z"/>
|
<path fill="#7b3c20" d="M582.4 184.5s7.5-.2 10.5 1.9c3 2 4.6 3.4 5.5 3.8 0 0-.1 2.8-5 .7 0 0 .4 1.4-.2 2.8 0 0-1.7-1.2-3.8-1.7 0 0-.4 1-1 1.7 0 0-2.1-2.2-4.6-2.9 0 0-.4 1.1-.8 1.6 0 0-2.6-1.6-4.6-1.6 0 0 .4 1.7 0 2.3 0 0-5.4-4.3-10.3-3.8 0 0 2.3 3.5 3.8 5.1 0 0-9.8-.7-8-6 1.5-5.3-.2-4 6.2-4z"/>
|
||||||
<path fill="#5a3719" d="M536.3 199.1s-1.1 1 0 1.7c1.1.8 5-2 5.5-2.4.6-.4 2-.4 0 1.1s-3.8 3-5 4.6c0 0 6.4-1.8 10.6-5.4 4.3-3.7-.1-1.3 7-4.8 7.3-3.5 11.1-9.1 7.2-8.5-3.8.6-7.3 5-10.4 6.7-3 1.7-4.7 2-4.2 1 .4-1 2.7-.6 6.9-4 4.1-3.3 3.2-3 3.2-4.2 0-1.2-1.5-4 4.7-7.4 6.2-3.3 25.6-14.5 27.3-18.5 0 0-5.7.6-13.2 6.1a69.7 69.7 0 0 1-13.4 8.8c-2 .8-1.8.2-3.1 1.9a171.8 171.8 0 0 1-10.1 9.8c-1.3 1-1.8 1.6-1.9 3.8 0 1-8.4 7.3-11 9.7z"/>
|
<path fill="#5a3719" d="M536.3 199.1s-1.1 1 0 1.7c1.1.8 5-2 5.5-2.4.6-.4 2-.4 0 1.1s-3.8 3-5 4.6c0 0 6.4-1.8 10.6-5.4 4.3-3.7-.1-1.3 7-4.8 7.3-3.5 11.1-9.1 7.2-8.5-3.8.6-7.3 5-10.4 6.7-3 1.7-4.7 2-4.2 1 .4-1 2.7-.6 6.9-4 4.1-3.3 3.2-3 3.2-4.2 0-1.2-1.5-4 4.7-7.4 6.2-3.3 25.6-14.5 27.3-18.5 0 0-5.7.6-13.2 6.1a69.7 69.7 0 0 1-13.4 8.8c-2 .8-1.8.2-3.1 1.9a171.8 171.8 0 0 1-10.1 9.8c-1.3 1-1.8 1.6-1.9 3.8 0 1-8.4 7.3-11 9.7z"/>
|
||||||
<path fill="#5a3719" d="M562 184.3s-1.5.6-3 0c-1.3-.7-.8-3.6 2.5-5.5a50 50 0 0 1 12.6-4.8s-.5 3.8-10.1 7.1c0 0 .6 2-2 3.2z"/>
|
<path fill="#5a3719" d="M562 184.3s-1.5.6-3 0c-1.3-.7-.8-3.6 2.5-5.5a50 50 0 0 1 12.6-4.8s-.5 3.8-10.1 7.1c0 0 .6 2-2 3.2"/>
|
||||||
<path fill="#aa5323" d="M565.4 181.8s.3 1 0 1.8c0 0 17.9 1.7 27.1-9.2 0 0-12.7 1.2-17.7 4.3 0 0 3.2-4 12.7-7.3s13.4-7.4 14.2-9.7c0 0-12 4.3-17.7 4.3 0 0-1.2 0-2.3.5-1.1.7-8.8 6.2-10.8 7.2 0 0 4.3-.4 5.9-1.8 0 0-3 8-11.4 10z"/>
|
<path fill="#aa5323" d="M565.4 181.8s.3 1 0 1.8c0 0 17.9 1.7 27.1-9.2 0 0-12.7 1.2-17.7 4.3 0 0 3.2-4 12.7-7.3s13.4-7.4 14.2-9.7c0 0-12 4.3-17.7 4.3 0 0-1.2 0-2.3.5-1.1.7-8.8 6.2-10.8 7.2 0 0 4.3-.4 5.9-1.8 0 0-3 8-11.4 10z"/>
|
||||||
<path fill="#5a3719" d="M531 192s-2.3 1.7-1.3 2.4c1 .9 2.6 1 6-1.9 3.6-3 12.1-10.2 6.8-10.5 0 0-7-.4-6.7 3.8.2 4.2-4.4 6-4.8 6.2zm-15.9-2.5s4.6 2.7 2.8 4.9c0 0 14-11.8 10-14.4-3.8-2.6-6.9 2.3-6 2.7 1 .6 3-.4 2.3.6a77.4 77.4 0 0 1-9 6.2zm-3.6-3.8s3 1 3.2 2.3c.1 1.2 9.2-6.4 6.8-9.7-1.1-1.5-6-2-6.4.8-.2 3 4.6-.3 3 1.8-2.2 2.7-5.9 4.4-6.6 4.8zm32.6-6.4s-1.9 1.4-.1 2.3c1.8.7 2.8-.6 3.7-1.3.9-.8 5.3-4 6.2-6 1-2 2.5-2.7 4.1-3.7 1.5-1 12.6-6.6 19.5-12.7 6.8-6.1 4-4.5 11-8.4s11.7-7.5 13.2-11.8c0 0-3.3 1-6.2 3a243 243 0 0 1-10.7 6.5c-1.3.5-3 .6-4 1.6s-1 2.3-4.3 5c-3.5 2.9-21 15.3-23.2 17a334.7 334.7 0 0 0-9.2 8.5z"/>
|
<path fill="#5a3719" d="M531 192s-2.3 1.7-1.3 2.4c1 .9 2.6 1 6-1.9 3.6-3 12.1-10.2 6.8-10.5 0 0-7-.4-6.7 3.8.2 4.2-4.4 6-4.8 6.2m-15.9-2.5s4.6 2.7 2.8 4.9c0 0 14-11.8 10-14.4-3.8-2.6-6.9 2.3-6 2.7 1 .6 3-.4 2.3.6a77.4 77.4 0 0 1-9 6.2zm-3.6-3.8s3 1 3.2 2.3c.1 1.2 9.2-6.4 6.8-9.7-1.1-1.5-6-2-6.4.8-.2 3 4.6-.3 3 1.8-2.2 2.7-5.9 4.4-6.6 4.8m32.6-6.4s-1.9 1.4-.1 2.3c1.8.7 2.8-.6 3.7-1.3.9-.8 5.3-4 6.2-6 1-2 2.5-2.7 4.1-3.7 1.5-1 12.6-6.6 19.5-12.7 6.8-6.1 4-4.5 11-8.4s11.7-7.5 13.2-11.8c0 0-3.3 1-6.2 3a243 243 0 0 1-10.7 6.5c-1.3.5-3 .6-4 1.6s-1 2.3-4.3 5c-3.5 2.9-21 15.3-23.2 17a334.7 334.7 0 0 0-9.2 8.5"/>
|
||||||
<path fill="#aa5323" d="M530 183.4s2-1 5.6-.8c3.6.2 17.8-13.6 22-16.3a341.6 341.6 0 0 0 18.7-13.8c1.8-1.8 2-3.6 3.6-4.6 1.5-1 3-.9 6.4-2.9 3.5-2 20.3-12 19.3-17.8 0 0-25 15-30.7 19.8a375 375 0 0 1-24.7 17.7c-2.8 1.9-5 5-9.9 8.8-4.7 3.9-9.5 7.2-10.3 10z"/>
|
<path fill="#aa5323" d="M530 183.4s2-1 5.6-.8c3.6.2 17.8-13.6 22-16.3a341.6 341.6 0 0 0 18.7-13.8c1.8-1.8 2-3.6 3.6-4.6 1.5-1 3-.9 6.4-2.9 3.5-2 20.3-12 19.3-17.8 0 0-25 15-30.7 19.8a375 375 0 0 1-24.7 17.7c-2.8 1.9-5 5-9.9 8.8-4.7 3.9-9.5 7.2-10.3 10z"/>
|
||||||
<path fill="#aa5323" d="M524.8 178s4.6-.4 5.2 1.9c0 0 10-6.8 12.2-9.6 2.2-2.8-.8-1.2 4.9-4.9a594.3 594.3 0 0 0 27-19.1c2.7-2.3 7.8-5.5 11.9-8.2 4-2.8 19.9-10.6 18.1-17l-14.2 9.5c-2.7 1.8-3.9.8-6.5 2.9-2.6 2.1-8.5 6.3-9.5 7.6a161.3 161.3 0 0 1-14.4 11c-4.4 3-14.1 8.6-18.9 12.8a602.8 602.8 0 0 1-15.8 13.2z"/>
|
<path fill="#aa5323" d="M524.8 178s4.6-.4 5.2 1.9c0 0 10-6.8 12.2-9.6 2.2-2.8-.8-1.2 4.9-4.9a594.3 594.3 0 0 0 27-19.1c2.7-2.3 7.8-5.5 11.9-8.2 4-2.8 19.9-10.6 18.1-17l-14.2 9.5c-2.7 1.8-3.9.8-6.5 2.9-2.6 2.1-8.5 6.3-9.5 7.6a161.3 161.3 0 0 1-14.4 11c-4.4 3-14.1 8.6-18.9 12.8a602.8 602.8 0 0 1-15.8 13.2z"/>
|
||||||
<path fill="#aa5323" d="M510.4 176.8s2.3 0 3.1.9c0 0 4.3-3.9 8.9 0 0 0 16.8-11.5 18.5-14.4 1.7-2.8 4.5-2.9 11-7.6 6.6-4.8 10.7-6.9 15-10.2 4.4-3.4 8.1-7.3 11.2-9.3 3.1-2 11-7.2 9.8-11.7 0 0-6.5 3.6-10.6 8.2-4.2 4.6-3.8.7-8.1 4.5a82.7 82.7 0 0 1-16.3 11.7c-5.5 2.7-2.2 2.4-6.2 5-3.9 2.5-3.6 2-5 2.5a10 10 0 0 0-5.1 3c-1.6 1.7-5.4 4-9.6 6.5a106.5 106.5 0 0 0-16.6 10.9z"/>
|
<path fill="#aa5323" d="M510.4 176.8s2.3 0 3.1.9c0 0 4.3-3.9 8.9 0 0 0 16.8-11.5 18.5-14.4 1.7-2.8 4.5-2.9 11-7.6 6.6-4.8 10.7-6.9 15-10.2 4.4-3.4 8.1-7.3 11.2-9.3 3.1-2 11-7.2 9.8-11.7 0 0-6.5 3.6-10.6 8.2-4.2 4.6-3.8.7-8.1 4.5a82.7 82.7 0 0 1-16.3 11.7c-5.5 2.7-2.2 2.4-6.2 5-3.9 2.5-3.6 2-5 2.5a10 10 0 0 0-5.1 3c-1.6 1.7-5.4 4-9.6 6.5a106.5 106.5 0 0 0-16.6 10.9"/>
|
||||||
<path fill="#aa5323" d="M515.5 168s-1-1.9.7-3.3c1.6-1.3 4.6-4.8 5-7 .5-2.3.1-1.9 4.8-3.8a188.2 188.2 0 0 0 38.2-21.6c1.8-1.5 6.4-4.6 8.3-6.2 0 0 .8 2.5-1.2 4.2a222.1 222.1 0 0 1-21.5 14.9 76.6 76.6 0 0 0-9.6 5.5c-1.9 1.6-1.6 2-10.2 6.3-8.5 4.1-9 4.6-8.7 4.9.3.4 4.2-1.3 6-2.4 1.8-1 8.8-4.3 11-6a69 69 0 0 1 7-5 296 296 0 0 0 18-11.2c3.5-2.7 4.5-3.5 5.3-3 .7.4 2 .4.4 2s-6.7 6-8.7 7.3c-2 1.3-8.1 5-9.8 5.8-1.7 1-2.4 2.5-3.4 3.2-.9.8-3.7 2.7-7 3.5s-4 3.3-6.3 4.8c-2.3 1.4-18 10-18.5 10.3 0 0 .9-1 .2-3.2z"/>
|
<path fill="#aa5323" d="M515.5 168s-1-1.9.7-3.3c1.6-1.3 4.6-4.8 5-7 .5-2.3.1-1.9 4.8-3.8a188.2 188.2 0 0 0 38.2-21.6c1.8-1.5 6.4-4.6 8.3-6.2 0 0 .8 2.5-1.2 4.2a222.1 222.1 0 0 1-21.5 14.9 76.6 76.6 0 0 0-9.6 5.5c-1.9 1.6-1.6 2-10.2 6.3-8.5 4.1-9 4.6-8.7 4.9.3.4 4.2-1.3 6-2.4 1.8-1 8.8-4.3 11-6a69 69 0 0 1 7-5 296 296 0 0 0 18-11.2c3.5-2.7 4.5-3.5 5.3-3 .7.4 2 .4.4 2s-6.7 6-8.7 7.3c-2 1.3-8.1 5-9.8 5.8-1.7 1-2.4 2.5-3.4 3.2-.9.8-3.7 2.7-7 3.5s-4 3.3-6.3 4.8c-2.3 1.4-18 10-18.5 10.3 0 0 .9-1 .2-3.2"/>
|
||||||
<path fill="#aa5323" d="M570.3 132.4s-.9.8-.4 1.2c.6.6 2.8 2.2 5.6-.6a106.5 106.5 0 0 1 12.5-10c2.3-1.5 3.6-2.8 3.5-4.7 0 0-11.4 6-21.2 14.1zm15.6-1s1.7-2.9 6-5.7c4.3-2.7 10.8-6.7 11.5-7.6 0 0 1.6 1.7-1.7 3.8a311.7 311.7 0 0 0-10.8 7c-.7.7-2 1.6-5 2.5z"/>
|
<path fill="#aa5323" d="M570.3 132.4s-.9.8-.4 1.2c.6.6 2.8 2.2 5.6-.6a106.5 106.5 0 0 1 12.5-10c2.3-1.5 3.6-2.8 3.5-4.7 0 0-11.4 6-21.2 14.1m15.6-1s1.7-2.9 6-5.7c4.3-2.7 10.8-6.7 11.5-7.6 0 0 1.6 1.7-1.7 3.8a311.7 311.7 0 0 0-10.8 7c-.7.7-2 1.6-5 2.5"/>
|
||||||
<path fill="#7b3c20" d="M499 163s-4.8 2.6-3.1 4.2c1.7 1.5 4.2 1 5.4.6l3.2-1c.4 0 4.5-1.3 5.6-3.2 1-2 3.8-4.2 6-5.8 2.2-1.5 3-3.2 2.7-4.3L499 163zm-28.4 22s3.4-2 8-.7c0 0-.2-1.1-1-1.7 0 0 5.7-1.5 6.9-4 1.2-2.5 1.5-2 2.5-2.6 1.2-.8 8.7-6.8 7.8-8.1-.9-1.3-1-3.1-1.7-3.7 0 0-1.5 2.1-9 5.7-7.2 3.6-15.4 6.2-21.4 14.2-5.9 8-5.3 12.6 2 14.7 0 0 5-3.2 17.6-2.1 12.4 1.1 16.6 5.8 17.4 6.6.8.9 3.3 4 .9 9.1 0 0 2.5 1.1 2.6-1.3.3-2.3.4-1.8 1-1.5.6.4 1.3.5 1-1.4a18 18 0 0 0-2.3-7.2c-1.1-1.5.2-.8.9-.6.7.3 3.3 2.5 1.8-1.5-1.5-3.8-2-2-2-1.8 0 .3-.4 1.2-3.8-1.4a26.8 26.8 0 0 0-8.8-4.4c-2.3-.6-.7-.6.7-1 1.4-.6 3.1-.8 3.8-2.4 0 0-1.4.3-3.8-.6a13.2 13.2 0 0 0-11.5 2s1.2-4.5-2.5-4.3c-3.6.3-6.2.2-10 3.2 0 0-.3-4.6 3.4-7 3.7-2.5 3.2-1 5.2-1.6 2-.6 2.3-2.7 1.4-3.4 0 0 4.8.9 12.8-5.8 0 0-4.3 5.7-9.5 6.8 0 0-.9 3-5.7 3.7-4.8.7-4.6 3.4-4.6 4.1z"/>
|
<path fill="#7b3c20" d="M499 163s-4.8 2.6-3.1 4.2c1.7 1.5 4.2 1 5.4.6l3.2-1c.4 0 4.5-1.3 5.6-3.2 1-2 3.8-4.2 6-5.8 2.2-1.5 3-3.2 2.7-4.3zm-28.4 22s3.4-2 8-.7c0 0-.2-1.1-1-1.7 0 0 5.7-1.5 6.9-4 1.2-2.5 1.5-2 2.5-2.6 1.2-.8 8.7-6.8 7.8-8.1-.9-1.3-1-3.1-1.7-3.7 0 0-1.5 2.1-9 5.7-7.2 3.6-15.4 6.2-21.4 14.2-5.9 8-5.3 12.6 2 14.7 0 0 5-3.2 17.6-2.1 12.4 1.1 16.6 5.8 17.4 6.6.8.9 3.3 4 .9 9.1 0 0 2.5 1.1 2.6-1.3.3-2.3.4-1.8 1-1.5.6.4 1.3.5 1-1.4a18 18 0 0 0-2.3-7.2c-1.1-1.5.2-.8.9-.6.7.3 3.3 2.5 1.8-1.5-1.5-3.8-2-2-2-1.8 0 .3-.4 1.2-3.8-1.4a26.8 26.8 0 0 0-8.8-4.4c-2.3-.6-.7-.6.7-1 1.4-.6 3.1-.8 3.8-2.4 0 0-1.4.3-3.8-.6a13.2 13.2 0 0 0-11.5 2s1.2-4.5-2.5-4.3c-3.6.3-6.2.2-10 3.2 0 0-.3-4.6 3.4-7 3.7-2.5 3.2-1 5.2-1.6 2-.6 2.3-2.7 1.4-3.4 0 0 4.8.9 12.8-5.8 0 0-4.3 5.7-9.5 6.8 0 0-.9 3-5.7 3.7-4.8.7-4.6 3.4-4.6 4.1z"/>
|
||||||
<path fill="#5a3719" d="M457 212.7s2.2-14.1 15.5-15.1c11.4-1 15.1.5 17.4 1.3s8 2.4 5.8 4.2c-2.2 1.8-3.5 1.5-3.5 1.5s2.5-2.9.2-3.3c-2.3-.5-2.4.9-2.7 2-.4 1.3-.5 2.6-1.6 3.6 0 0-1.2-1.4-2.9-.2s-.2 1.2.5 1c.6-.2 1.5-.5 1.3.5-.1 1-1 2.8-3.8 4.2-2.7 1.4-2.6 1.3-5.8 1.9-3.3.5-6.3 1.8-10.5 5.3-4.2 3.6-8.7 2.4-9.6-1.5-.8-3.4-.4-5.4-.4-5.4z"/>
|
<path fill="#5a3719" d="M457 212.7s2.2-14.1 15.5-15.1c11.4-1 15.1.5 17.4 1.3s8 2.4 5.8 4.2c-2.2 1.8-3.5 1.5-3.5 1.5s2.5-2.9.2-3.3c-2.3-.5-2.4.9-2.7 2-.4 1.3-.5 2.6-1.6 3.6 0 0-1.2-1.4-2.9-.2s-.2 1.2.5 1c.6-.2 1.5-.5 1.3.5-.1 1-1 2.8-3.8 4.2-2.7 1.4-2.6 1.3-5.8 1.9-3.3.5-6.3 1.8-10.5 5.3-4.2 3.6-8.7 2.4-9.6-1.5-.8-3.4-.4-5.4-.4-5.4z"/>
|
||||||
<path d="M472 212.2s1.2-2.7-1-4c0 0-6.9 1.2-9-.9 0 0 7.5-.4 12.2-2.3 4.6-1.7 3.3-3 1.7-3.4-1.6-.3-4.6.5-4.9 2 0 0-1-1.6.2-2.6a5 5 0 0 1 4.7-.8c1.7.4 3.1 1.2 8.6-1.6 0 0 3.1.7 3.3 2.8 0 2.2-.3 3-.6 3.3-.2.4-.6 1-1.3 1-.6-.2-1.5-.3-2.3 1.2a8.9 8.9 0 0 1-2.6 3.7s1.5-4.6-2.5-5.7c0 0-3.3 2-5.8 2.1 0 0 3.2 3-.8 5.2z"/>
|
<path d="M472 212.2s1.2-2.7-1-4c0 0-6.9 1.2-9-.9 0 0 7.5-.4 12.2-2.3 4.6-1.7 3.3-3 1.7-3.4-1.6-.3-4.6.5-4.9 2 0 0-1-1.6.2-2.6a5 5 0 0 1 4.7-.8c1.7.4 3.1 1.2 8.6-1.6 0 0 3.1.7 3.3 2.8 0 2.2-.3 3-.6 3.3-.2.4-.6 1-1.3 1-.6-.2-1.5-.3-2.3 1.2a8.9 8.9 0 0 1-2.6 3.7s1.5-4.6-2.5-5.7c0 0-3.3 2-5.8 2.1 0 0 3.2 3-.8 5.2z"/>
|
||||||
<path fill="#5a3719" d="M479.3 203.8s-1.6-1.6.4-1.9c2-.1 4.6 1.4 4.2 2.7-.6 1.2-3 1.1-4.6-.8z"/>
|
<path fill="#5a3719" d="M479.3 203.8s-1.6-1.6.4-1.9c2-.1 4.6 1.4 4.2 2.7-.6 1.2-3 1.1-4.6-.8"/>
|
||||||
<path fill="#fff" d="M592.6 181.6s-3.7 1-.2 3.3c3.4 2.3 5 4.2 7.5 4.8 2.5.7 5 1.5 5 4s-.5 3.5-1.9 5.2c-1.3 1.7.8 2.4 2.6 1.5 1.8-1 3.3-1.5 4.5-2.2 1.1-.7 3-.6 1.4.3-1.9 1-3.7 1.5-1.4 1.5 2.3.1 16.2.4 19.1-.6 3-.9 6.8-1.2 7-5 0 0 .2-1.6 1.3-2.4 1-.7 1.8-2.3.2-1.2-1.5 1.1-2.7 1.7-3 1.3-.3-.3-.5-.6.7-1.1 1.2-.5 1.8 0 2.9-1.5 1-1.6 1-1.4.4-2-.6-.6-1.8-1-1.2-1.8.6-.8 1.2-3-1.4-1.7-2.5 1.3-7.6 4.8-10 5.3-2.2.5-4 1.2-7.1 1.8-3 .7-5 1.4-8.5 3.3-3.3 1.8-3-1.1-2.5-1.5 0 0 1.3 2.3 4.7-.7 3.4-2.9 2.3-.1 10.6-2.9 8.3-2.7 6.3-3.1 9.5-4.8 3.3-1.7 6.4-1.8 4-4-2.2-2.4-2.4-2.5-5.3 0a34.5 34.5 0 0 1-16 6.4s18.8-8 16.9-9.2a20.8 20.8 0 0 0-5.3-2.5c-1.3-.3-1.7-.6-4.7.8-3 1.3-3.5 1.6-4.3 1.7-1 0-3.5.6-7 2.4-3.6 1.9-5.5 2.6-8 4 0 0 1.7-3.3 9.1-5.5 7.4-2.2 11.1-4.2 10.4-4.6s-2.7-.8-4-.5c-1.5.3-1-.1-5.6 1.7-4.5 1.8-2.6 1.4-6.2 2.2-3.7.7-5.1 1.5-6.9 2.3 0 0 .8-1 3.1-1.9 1.3-.4-1.3-.9 2.2-1h1a32.2 32.2 0 0 0 8.6-3.3c-.7-.1-5.1-.6-9.5 1.6-4.5 2-2.5 1.3-4 1.5-1.6.4-5 2.4-6 3.4-1.1.9-2.7 1.5-2.7 1.5z"/>
|
<path fill="#fff" d="M592.6 181.6s-3.7 1-.2 3.3c3.4 2.3 5 4.2 7.5 4.8 2.5.7 5 1.5 5 4s-.5 3.5-1.9 5.2c-1.3 1.7.8 2.4 2.6 1.5 1.8-1 3.3-1.5 4.5-2.2 1.1-.7 3-.6 1.4.3-1.9 1-3.7 1.5-1.4 1.5 2.3.1 16.2.4 19.1-.6 3-.9 6.8-1.2 7-5 0 0 .2-1.6 1.3-2.4 1-.7 1.8-2.3.2-1.2-1.5 1.1-2.7 1.7-3 1.3-.3-.3-.5-.6.7-1.1 1.2-.5 1.8 0 2.9-1.5 1-1.6 1-1.4.4-2-.6-.6-1.8-1-1.2-1.8.6-.8 1.2-3-1.4-1.7-2.5 1.3-7.6 4.8-10 5.3-2.2.5-4 1.2-7.1 1.8-3 .7-5 1.4-8.5 3.3-3.3 1.8-3-1.1-2.5-1.5 0 0 1.3 2.3 4.7-.7 3.4-2.9 2.3-.1 10.6-2.9 8.3-2.7 6.3-3.1 9.5-4.8 3.3-1.7 6.4-1.8 4-4-2.2-2.4-2.4-2.5-5.3 0a34.5 34.5 0 0 1-16 6.4s18.8-8 16.9-9.2a20.8 20.8 0 0 0-5.3-2.5c-1.3-.3-1.7-.6-4.7.8-3 1.3-3.5 1.6-4.3 1.7-1 0-3.5.6-7 2.4-3.6 1.9-5.5 2.6-8 4 0 0 1.7-3.3 9.1-5.5 7.4-2.2 11.1-4.2 10.4-4.6s-2.7-.8-4-.5c-1.5.3-1-.1-5.6 1.7-4.5 1.8-2.6 1.4-6.2 2.2-3.7.7-5.1 1.5-6.9 2.3 0 0 .8-1 3.1-1.9 1.3-.4-1.3-.9 2.2-1h1a32.2 32.2 0 0 0 8.6-3.3c-.7-.1-5.1-.6-9.5 1.6-4.5 2-2.5 1.3-4 1.5-1.6.4-5 2.4-6 3.4-1.1.9-2.7 1.5-2.7 1.5z"/>
|
||||||
<path fill="#5a3719" d="M482.7 201.8s1.8.5 2.2 1.8c.5 1.2 1.6-.6 1.6-1.1-.1-.6-1.2-3-3-1.9-2 1.1-1 1.1-.8 1.2z"/>
|
<path fill="#5a3719" d="M482.7 201.8s1.8.5 2.2 1.8c.5 1.2 1.6-.6 1.6-1.1-.1-.6-1.2-3-3-1.9-2 1.1-1 1.1-.8 1.2"/>
|
||||||
<path fill="#7b3c20" d="M477.9 226s3.7-1.8 6.9-1.5c0 0-1.3-4.4.9-3.7 2.1.8 1.5.4 2 .4 0 0 .1-2.9-.5-4 0 0 2.3.5 4.6.5 0 0-2.2-4.1.2-7a6.9 6.9 0 0 0 4.2 3.4v-2.3s1.7-.3 3 .4c1.4.8 2.5-7.6-1.5-9.3 0 0-1 1.5-4.7 2.3s-3.7 1.5-5.2 4.3-3 2.9-6.2 5c-3 2-5 6-5 6.4 0 0 1.5 2 1.3 5.1z"/>
|
<path fill="#7b3c20" d="M477.9 226s3.7-1.8 6.9-1.5c0 0-1.3-4.4.9-3.7 2.1.8 1.5.4 2 .4 0 0 .1-2.9-.5-4 0 0 2.3.5 4.6.5 0 0-2.2-4.1.2-7a6.9 6.9 0 0 0 4.2 3.4v-2.3s1.7-.3 3 .4c1.4.8 2.5-7.6-1.5-9.3 0 0-1 1.5-4.7 2.3s-3.7 1.5-5.2 4.3-3 2.9-6.2 5c-3 2-5 6-5 6.4 0 0 1.5 2 1.3 5.1"/>
|
||||||
<path fill="#999" d="M603.1 177.8c1.3-.2-1.4-.9 2-1h1a32.2 32.2 0 0 0 8.7-3.3c-.7-.1-5.1-.6-9.5 1.5s-2.5 1.4-4 1.7c-1.6.3-5 2.3-6 3.3-1.1.9-2.7 1.5-2.7 1.5s-3.7 1-.2 3.4c3.4 2.3 5 4.2 7.5 4.8 2.5.7 5 1.5 5 4a7 7 0 0 1-1.9 5.2c-1.3 1.7.8 2.4 2.6 1.5 1.8-1 3.3-1.5 4.5-2.2 1.1-.7 3-.6 1.3.3-1.8 1-3.6 1.5-1.3 1.5 2.3.1 16.2.4 19.1-.6 3-.9 6.8-1.2 7-5 0 0 .2-1.6 1.3-2.4 1-.7 1.8-2.3.2-1.2-1.5 1.1-2.8 1.7-3 1.3-.3-.3-.5-.6.7-1.1 1.2-.5 1.8 0 2.9-1.5 1-1.6 1-1.4.4-2l-1-.9s-.9-.7-1.9-.1a27.6 27.6 0 0 1-7 2.7c-1.6.1-3.5.9-6.5 2.4s-8.2 4.6-9 1.7l-2.8 1c-3.4 1.8-3-.7-2.5-1.4 0 0-1.8 2-1.7.2 0-1.8 1.2-1.5 3.3-2.1 2-.6 5-2 3.8-3-1.3-1-2.7 1-4.2 1.8-1.4.7-4.3 1.2-4.8-.9-.4-2.1-.4-3.6-4.3-3.8-4-.2-3.9-2.7-2.8-3.8 1.1-1 2-2.8 5.7-3.5z"/>
|
<path fill="#999" d="M603.1 177.8c1.3-.2-1.4-.9 2-1h1a32.2 32.2 0 0 0 8.7-3.3c-.7-.1-5.1-.6-9.5 1.5s-2.5 1.4-4 1.7c-1.6.3-5 2.3-6 3.3-1.1.9-2.7 1.5-2.7 1.5s-3.7 1-.2 3.4c3.4 2.3 5 4.2 7.5 4.8 2.5.7 5 1.5 5 4a7 7 0 0 1-1.9 5.2c-1.3 1.7.8 2.4 2.6 1.5 1.8-1 3.3-1.5 4.5-2.2 1.1-.7 3-.6 1.3.3-1.8 1-3.6 1.5-1.3 1.5 2.3.1 16.2.4 19.1-.6 3-.9 6.8-1.2 7-5 0 0 .2-1.6 1.3-2.4 1-.7 1.8-2.3.2-1.2-1.5 1.1-2.8 1.7-3 1.3-.3-.3-.5-.6.7-1.1 1.2-.5 1.8 0 2.9-1.5 1-1.6 1-1.4.4-2l-1-.9s-.9-.7-1.9-.1a27.6 27.6 0 0 1-7 2.7c-1.6.1-3.5.9-6.5 2.4s-8.2 4.6-9 1.7l-2.8 1c-3.4 1.8-3-.7-2.5-1.4 0 0-1.8 2-1.7.2 0-1.8 1.2-1.5 3.3-2.1 2-.6 5-2 3.8-3-1.3-1-2.7 1-4.2 1.8-1.4.7-4.3 1.2-4.8-.9-.4-2.1-.4-3.6-4.3-3.8-4-.2-3.9-2.7-2.8-3.8 1.1-1 2-2.8 5.7-3.5z"/>
|
||||||
<path d="M615.6 196.9s6.1-2.8 11.7-4.1c5.7-1.3 1.2.2.3.4-1 .3-9.7 3.2-11.8 4.2-2 1-1.7.2-.2-.4zm1.4 1.3s6.9-2.3 8.2-1.4c1.3 1 .2.6-1.3.8-1.6.1-5.7.8-6.8.8-1.1 0-.1-.2-.1-.2zm11-2.5s1.4-.2 1.5.4c.1.4-.6.5-1.3.4-.7-.1-1.3-.5-.1-.8z"/>
|
<path d="M615.6 196.9s6.1-2.8 11.7-4.1c5.7-1.3 1.2.2.3.4-1 .3-9.7 3.2-11.8 4.2-2 1-1.7.2-.2-.4zm1.4 1.3s6.9-2.3 8.2-1.4c1.3 1 .2.6-1.3.8-1.6.1-5.7.8-6.8.8-1.1 0-.1-.2-.1-.2m11-2.5s1.4-.2 1.5.4c.1.4-.6.5-1.3.4-.7-.1-1.3-.5-.1-.8z"/>
|
||||||
<path fill="#fff" d="M446 255.9s-.3-6.2 2.8-9.2 17.8-18.5 20.1-22.8c0 0 2 1.3 2 3.8 0 0 2.5-4.3 4.5-6 0 0 1.7 1.8 1.5 5.4 0 0 3.5-1.9 9-1.9 0 0-2 2.4-2.1 3.9 0 0 7.6-1 11.7-.3 0 0-10.6 6-7.7 6.5 3.1.5 6.2 0 6.2 0s-3.4 3.3-8.8 4c0 0 6.9 0 8.2 1.5 0 0-6.6 1-12 5 0 0-.4-.2-.4-1.7 0 0-.3 1.4-1.8 2.7-1.5 1.2-5.1 4-6.5 5.3-1.4 1.3-3.8 4-6.6 4 0 0 .6-2.1-1.4-2.8a5.7 5.7 0 0 0-6 1.5s-7 .1-9.4.5c0 0 1.6-2.6 3-2.6 1.6 0 7.6 1 8.1-3.2.6-4-3.8-3-2.2-5.4 1.7-2.4 1.3-2.2 1.4-2.6 0 0-1.4.8-2.2 3a10.7 10.7 0 0 1-4.2 6 15 15 0 0 0-4.8 5s-1.3 0-2.4.4z"/>
|
<path fill="#fff" d="M446 255.9s-.3-6.2 2.8-9.2 17.8-18.5 20.1-22.8c0 0 2 1.3 2 3.8 0 0 2.5-4.3 4.5-6 0 0 1.7 1.8 1.5 5.4 0 0 3.5-1.9 9-1.9 0 0-2 2.4-2.1 3.9 0 0 7.6-1 11.7-.3 0 0-10.6 6-7.7 6.5 3.1.5 6.2 0 6.2 0s-3.4 3.3-8.8 4c0 0 6.9 0 8.2 1.5 0 0-6.6 1-12 5 0 0-.4-.2-.4-1.7 0 0-.3 1.4-1.8 2.7-1.5 1.2-5.1 4-6.5 5.3-1.4 1.3-3.8 4-6.6 4 0 0 .6-2.1-1.4-2.8a5.7 5.7 0 0 0-6 1.5s-7 .1-9.4.5c0 0 1.6-2.6 3-2.6 1.6 0 7.6 1 8.1-3.2.6-4-3.8-3-2.2-5.4 1.7-2.4 1.3-2.2 1.4-2.6 0 0-1.4.8-2.2 3a10.7 10.7 0 0 1-4.2 6 15 15 0 0 0-4.8 5s-1.3 0-2.4.4"/>
|
||||||
<path fill="#fff" d="M452.8 252.2s.3-.8 2.3-1.2c2.2-.3 2.3-1.3 2-1.8-.3-.4-1.5-.4.5-2.8 0 0 .8.3 1.2.8.6.6 2.9 5.5-6 5z"/>
|
<path fill="#fff" d="M452.8 252.2s.3-.8 2.3-1.2c2.2-.3 2.3-1.3 2-1.8-.3-.4-1.5-.4.5-2.8 0 0 .8.3 1.2.8.6.6 2.9 5.5-6 5"/>
|
||||||
<path fill="#999" d="M447.9 247.9c0 4 5.3 2.5 5.3 2.5a21.4 21.4 0 0 0-3.8 3.6c.4-2-3-2.5-3-2.5a12.3 12.3 0 0 1 1.5-3.6zm19.3-21.5 1.7-2.5s2 1.3 2 3.8c0 0 2.5-4.3 4.5-6 0 0 1.7 1.8 1.5 5.4 0 0 3.5-1.9 9-1.9 0 0-2 2.4-2.1 3.9 0 0 7.6-1 11.7-.3 0 0-10.6 6-7.7 6.5 3.1.5 6.2 0 6.2 0s-3.4 3.3-8.8 4c0 0 6.9 0 8.2 1.5 0 0-2 .3-4.6 1.2 0 0-1.9-1.8-7.6-1.5 0 0 4.4-2.6 8-3.4 0 0-1.6-2-4-.1 0 0-4.9-3.3-.8-6.2 0 0-2.8-.5-4.7.8 0 0 0-2.3 2.1-3.3 0 0-5.4-1-6.7 3 0 0-1-1.5-.5-3.4 0 0-3.3 1.9-4.8 4 0 0-.5-4-2.6-5.5M456.8 252c-.9.2-2.3.3-4 .2 0 0 .2-.5 1.3-1 0 0 .4.8 2.7.8"/>
|
<path fill="#999" d="M447.9 247.9c0 4 5.3 2.5 5.3 2.5a21.4 21.4 0 0 0-3.8 3.6c.4-2-3-2.5-3-2.5a12.3 12.3 0 0 1 1.5-3.6m19.3-21.5 1.7-2.5s2 1.3 2 3.8c0 0 2.5-4.3 4.5-6 0 0 1.7 1.8 1.5 5.4 0 0 3.5-1.9 9-1.9 0 0-2 2.4-2.1 3.9 0 0 7.6-1 11.7-.3 0 0-10.6 6-7.7 6.5 3.1.5 6.2 0 6.2 0s-3.4 3.3-8.8 4c0 0 6.9 0 8.2 1.5 0 0-2 .3-4.6 1.2 0 0-1.9-1.8-7.6-1.5 0 0 4.4-2.6 8-3.4 0 0-1.6-2-4-.1 0 0-4.9-3.3-.8-6.2 0 0-2.8-.5-4.7.8 0 0 0-2.3 2.1-3.3 0 0-5.4-1-6.7 3 0 0-1-1.5-.5-3.4 0 0-3.3 1.9-4.8 4 0 0-.5-4-2.6-5.5M456.8 252c-.9.2-2.3.3-4 .2 0 0 .2-.5 1.3-1 0 0 .4.8 2.7.8"/>
|
||||||
<path d="M466.6 236.7s2.5 2 3.3 3c0 0 2.3-1.4 3-2.7 0 0 1.9 1.1 2.4 2.8 0 0 1.3-.8 1.5-2 0 0 3 .6 4.2 1.6 0 0 .4-3 0-4.8 0 0 2.1.2 3.4.7 0 0-1.2-2 5-4.5 0 0-4.7 1.1-6.5 3 0 0-2 .2-2.9-.4v4.5s-1.2-.6-3.5-1.1c0 0-.6 1-1 1.2 0 0-1.5-1.2-2.1-2.7 0 0-2.3 2.1-3 3 0 0-2.3-1.6-3.8-1.6z"/>
|
<path d="M466.6 236.7s2.5 2 3.3 3c0 0 2.3-1.4 3-2.7 0 0 1.9 1.1 2.4 2.8 0 0 1.3-.8 1.5-2 0 0 3 .6 4.2 1.6 0 0 .4-3 0-4.8 0 0 2.1.2 3.4.7 0 0-1.2-2 5-4.5 0 0-4.7 1.1-6.5 3 0 0-2 .2-2.9-.4v4.5s-1.2-.6-3.5-1.1c0 0-.6 1-1 1.2 0 0-1.5-1.2-2.1-2.7 0 0-2.3 2.1-3 3 0 0-2.3-1.6-3.8-1.6"/>
|
||||||
<path fill="#ffc221" d="M452.5 267.3s1 .4 3.3-1.4 8.7-5.9 9.2-9.2c.7-3.3-2-3.4-4-2.5-2.2 1-1.3 2.7-1.2 3.4 0 .6.2 2.9-3.3 6l-4 3.7z"/>
|
<path fill="#ffc221" d="M452.5 267.3s1 .4 3.3-1.4 8.7-5.9 9.2-9.2c.7-3.3-2-3.4-4-2.5-2.2 1-1.3 2.7-1.2 3.4 0 .6.2 2.9-3.3 6z"/>
|
||||||
<path fill="#ffc221" d="M451.9 268.3s-5.2-2.2-.6-4.5 6.7-2.9 7.2-4.9c.6-1.9.2-1.5-1.5-.7-1.7.7-8.2 3.8-9.2 1 0 0 2.7 1 6-.6 3.4-1.7 6.2-2.1 4-2.8a37 37 0 0 0-11 .5c-1.4.4-1 .3-1.3 1.6-.2 1.3-1.6 4-2.2 4.7-.5.8-1.8 4 .6 5.5a8.6 8.6 0 0 0 8 .2z"/>
|
<path fill="#ffc221" d="M451.9 268.3s-5.2-2.2-.6-4.5 6.7-2.9 7.2-4.9c.6-1.9.2-1.5-1.5-.7-1.7.7-8.2 3.8-9.2 1 0 0 2.7 1 6-.6 3.4-1.7 6.2-2.1 4-2.8a37 37 0 0 0-11 .5c-1.4.4-1 .3-1.3 1.6-.2 1.3-1.6 4-2.2 4.7-.5.8-1.8 4 .6 5.5a8.6 8.6 0 0 0 8 .2"/>
|
||||||
<path d="M449.9 257s-1.3.2-1 .7c.2.5.5.4 1 .4.3 0 1-.2 1.1-.5 0-.3-.8-.7-1.1-.5z"/>
|
<path d="M449.9 257s-1.3.2-1 .7c.2.5.5.4 1 .4.3 0 1-.2 1.1-.5 0-.3-.8-.7-1.1-.5z"/>
|
||||||
<path fill="#fff" d="M451.5 267.1s-2.4-1.1.4-2.6c2.7-1.5 5.6-3 6-3.6 0 0-1.3 1.9-6.4 6.2z"/>
|
<path fill="#fff" d="M451.5 267.1s-2.4-1.1.4-2.6c2.7-1.5 5.6-3 6-3.6 0 0-1.3 1.9-6.4 6.2"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -1,6 +1,4 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-at" viewBox="0 0 640 480">
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-at" viewBox="0 0 640 480">
|
||||||
<g fill-rule="evenodd">
|
<path fill="#fff" d="M0 160h640v160H0z"/>
|
||||||
<path fill="#fff" d="M640 480H0V0h640z"/>
|
<path fill="#c8102e" d="M0 0h640v160H0zm0 320h640v160H0z"/>
|
||||||
<path fill="#c8102e" d="M640 480H0V320h640zm0-319.9H0V.1h640z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 195 B |
|
@ -2,7 +2,7 @@
|
||||||
<path fill="#00008B" d="M0 0h640v480H0z"/>
|
<path fill="#00008B" d="M0 0h640v480H0z"/>
|
||||||
<path fill="#fff" d="m37.5 0 122 90.5L281 0h39v31l-120 89.5 120 89V240h-40l-120-89.5L40.5 240H0v-30l119.5-89L0 32V0z"/>
|
<path fill="#fff" d="m37.5 0 122 90.5L281 0h39v31l-120 89.5 120 89V240h-40l-120-89.5L40.5 240H0v-30l119.5-89L0 32V0z"/>
|
||||||
<path fill="red" d="M212 140.5 320 220v20l-135.5-99.5zm-92 10 3 17.5-96 72H0zM320 0v1.5l-124.5 94 1-22L295 0zM0 0l119.5 88h-30L0 21z"/>
|
<path fill="red" d="M212 140.5 320 220v20l-135.5-99.5zm-92 10 3 17.5-96 72H0zM320 0v1.5l-124.5 94 1-22L295 0zM0 0l119.5 88h-30L0 21z"/>
|
||||||
<path fill="#fff" d="M120.5 0v240h80V0h-80ZM0 80v80h320V80H0Z"/>
|
<path fill="#fff" d="M120.5 0v240h80V0zM0 80v80h320V80z"/>
|
||||||
<path fill="red" d="M0 96.5v48h320v-48zM136.5 0v240h48V0z"/>
|
<path fill="red" d="M0 96.5v48h320v-48zM136.5 0v240h48V0z"/>
|
||||||
<path fill="#fff" d="m527 396.7-20.5 2.6 2.2 20.5-14.8-14.4-14.7 14.5 2-20.5-20.5-2.4 17.3-11.2-10.9-17.5 19.6 6.5 6.9-19.5 7.1 19.4 19.5-6.7-10.7 17.6 17.4 11.1Zm-3.7-117.2 2.7-13-9.8-9 13.2-1.5 5.5-12.1 5.5 12.1 13.2 1.5-9.8 9 2.7 13-11.6-6.6-11.6 6.6Zm-104.1-60-20.3 2.2 1.8 20.3-14.4-14.5-14.8 14.1 2.4-20.3-20.2-2.7 17.3-10.8-10.5-17.5 19.3 6.8L387 178l6.7 19.3 19.4-6.3-10.9 17.3 17.1 11.2ZM623 186.7l-20.9 2.7 2.3 20.9-15.1-14.7-15 14.8 2.1-21-20.9-2.4 17.7-11.5-11.1-17.9 20 6.7 7-19.8 7.2 19.8 19.9-6.9-11 18 17.8 11.3Zm-96.1-83.5-20.7 2.3 1.9 20.8-14.7-14.8-15.1 14.4 2.4-20.7-20.7-2.8 17.7-11L467 73.5l19.7 6.9 7.3-19.5 6.8 19.7 19.8-6.5-11.1 17.6 17.4 11.5ZM234 385.7l-45.8 5.4 4.6 45.9-32.8-32.4-33 32.2 4.9-45.9-45.8-5.8 38.9-24.8-24-39.4 43.6 15 15.8-43.4 15.5 43.5 43.7-14.7-24.3 39.2 38.8 25.1Z"/>
|
<path fill="#fff" d="m527 396.7-20.5 2.6 2.2 20.5-14.8-14.4-14.7 14.5 2-20.5-20.5-2.4 17.3-11.2-10.9-17.5 19.6 6.5 6.9-19.5 7.1 19.4 19.5-6.7-10.7 17.6zm-3.7-117.2 2.7-13-9.8-9 13.2-1.5 5.5-12.1 5.5 12.1 13.2 1.5-9.8 9 2.7 13-11.6-6.6zm-104.1-60-20.3 2.2 1.8 20.3-14.4-14.5-14.8 14.1 2.4-20.3-20.2-2.7 17.3-10.8-10.5-17.5 19.3 6.8L387 178l6.7 19.3 19.4-6.3-10.9 17.3 17.1 11.2ZM623 186.7l-20.9 2.7 2.3 20.9-15.1-14.7-15 14.8 2.1-21-20.9-2.4 17.7-11.5-11.1-17.9 20 6.7 7-19.8 7.2 19.8 19.9-6.9-11 18zm-96.1-83.5-20.7 2.3 1.9 20.8-14.7-14.8-15.1 14.4 2.4-20.7-20.7-2.8 17.7-11L467 73.5l19.7 6.9 7.3-19.5 6.8 19.7 19.8-6.5-11.1 17.6zM234 385.7l-45.8 5.4 4.6 45.9-32.8-32.4-33 32.2 4.9-45.9-45.8-5.8 38.9-24.8-24-39.4 43.6 15 15.8-43.4 15.5 43.5 43.7-14.7-24.3 39.2 38.8 25.1Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -5,182 +5,182 @@
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
<g clip-path="url(#aw-a)" transform="scale(2.2222)">
|
<g clip-path="url(#aw-a)" transform="scale(2.2222)">
|
||||||
<path fill="#39c" d="M0 0v216h324V0H0z"/>
|
<path fill="#39c" d="M0 0v216h324V0z"/>
|
||||||
<path fill="#ff0" d="M0 144v12h324v-12H0zm0 24v12h324v-12H0z"/>
|
<path fill="#ff0" d="M0 144v12h324v-12zm0 24v12h324v-12z"/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#9cc" d="m142.7 28 2.9 3-3-3zm-3 6 3 3-3-3m5.9 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m142.7 28 2.9 3zm-3 6 3 3zm5.9 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m139.7 37 3 2.9-3-3m5.9 0 3 3-3-3z"/>
|
<path fill="#ccf" d="m139.7 37 3 2.9-3-3m5.9 0 3 3z"/>
|
||||||
<path fill="#6cc" d="m136.7 42.8 3 3-3-3z"/>
|
<path fill="#6cc" d="m136.7 42.8 3 3z"/>
|
||||||
<path fill="#c66" d="m142.7 42.8 2.9 3-3-3z"/>
|
<path fill="#c66" d="m142.7 42.8 2.9 3z"/>
|
||||||
<path fill="#6cc" d="m148.6 42.8 2.9 3-3-3z"/>
|
<path fill="#6cc" d="m148.6 42.8 2.9 3z"/>
|
||||||
<path fill="#ccf" d="m136.7 45.8 3 3-3-3zm11.9 0 2.9 3-3-3z"/>
|
<path fill="#ccf" d="m136.7 45.8 3 3zm11.9 0 2.9 3z"/>
|
||||||
<path fill="#fcc" d="m139.7 48.7 3 3-3-3m5.9 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m139.7 48.7 3 3zm5.9 0 3 3z"/>
|
||||||
<path fill="#6cc" d="m133.8 51.7 3 3-3-3z"/>
|
<path fill="#6cc" d="m133.8 51.7 3 3z"/>
|
||||||
<path fill="#c00" stroke="#fff" stroke-width="3.7" d="m142.2 34-20.7 78.5L42.8 134l78.4 20.5 21 78.4 20.9-78.4 78.4-21-78.4-20.9-21-78.4z"/>
|
<path fill="#c00" stroke="#fff" stroke-width="3.7" d="m142.2 34-20.7 78.5L42.8 134l78.4 20.5 21 78.4 20.9-78.4 78.4-21-78.4-20.9-21-78.4z"/>
|
||||||
<path fill="#6cc" d="m151.5 51.7 3 3-3-3z"/>
|
<path fill="#6cc" d="m151.5 51.7 3 3z"/>
|
||||||
<path fill="#9cf" d="m133.8 54.6 3 3-3-3m17.7 0 3 3-3-3z"/>
|
<path fill="#9cf" d="m133.8 54.6 3 3zm17.7 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m136.7 57.6 3 3-3-3m11.9 0 2.9 3-3-3z"/>
|
<path fill="#fcc" d="m136.7 57.6 3 3zm11.9 0 2.9 3z"/>
|
||||||
<path fill="#69c" d="m130.8 60.5 3 3-3-3z"/>
|
<path fill="#69c" d="m130.8 60.5 3 3z"/>
|
||||||
<path fill="#c33" d="m137.7 62.5 1 2-1-2m11.8 0 1 2-1-2z"/>
|
<path fill="#c33" d="m137.7 62.5 1 2zm11.8 0 1 2z"/>
|
||||||
<path fill="#69c" d="m154.5 60.5 3 3-3-3z"/>
|
<path fill="#69c" d="m154.5 60.5 3 3z"/>
|
||||||
<path fill="#9cf" d="m130.8 63.5 3 3-3-3m23.7 0 3 3-3-3z"/>
|
<path fill="#9cf" d="m130.8 63.5 3 3zm23.7 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m133.8 66.4 3 3-3-3m17.7 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m133.8 66.4 3 3zm17.7 0 3 3z"/>
|
||||||
<path fill="#69c" d="m127.9 69.4 3 3-3-3zm29.5 0 3 3-3-3z"/>
|
<path fill="#69c" d="m127.9 69.4 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m127.9 72.3 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m127.9 72.3 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#cff" d="m127.9 75.3 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#cff" d="m127.9 75.3 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#69c" d="m125 78.3 2.9 2.9-3-3z"/>
|
<path fill="#69c" d="m125 78.3 2.9 2.9z"/>
|
||||||
<path fill="#fcc" d="m130.8 78.3 3 2.9-3-3m23.7 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m130.8 78.3 3 2.9zm23.7 0 3 3z"/>
|
||||||
<path fill="#69c" d="m160.4 78.3 3 2.9-3-3z"/>
|
<path fill="#69c" d="m160.4 78.3 3 2.9z"/>
|
||||||
<path fill="#9cc" d="m125 81.2 2.9 3-3-3z"/>
|
<path fill="#9cc" d="m125 81.2 2.9 3z"/>
|
||||||
<path fill="#c33" d="m131.8 83.2 1 2-1-2m23.6 0 1 2-1-2z"/>
|
<path fill="#c33" d="m131.8 83.2 1 2zm23.6 0 1 2z"/>
|
||||||
<path fill="#9cc" d="m160.4 81.2 3 3-3-3z"/>
|
<path fill="#9cc" d="m160.4 81.2 3 3z"/>
|
||||||
<path fill="#cff" d="m125 84.2 2.9 3-3-3m35.5 0 3 3-3-3z"/>
|
<path fill="#cff" d="m125 84.2 2.9 3zm35.5 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m127.9 87.1 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m127.9 87.1 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m122 90 3 3-3-3z"/>
|
<path fill="#9cc" d="m122 90 3 3z"/>
|
||||||
<path fill="#c33" d="m128.9 92 1 2-1-2m29.5 0 1 2-1-2z"/>
|
<path fill="#c33" d="m128.9 92 1 2zm29.5 0 1 2z"/>
|
||||||
<path fill="#9cc" d="m163.3 90 3 3-3-3z"/>
|
<path fill="#9cc" d="m163.3 90 3 3z"/>
|
||||||
<path fill="#ccf" d="m122 93 3 3-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#ccf" d="m122 93 3 3zm41.3 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m125 96 2.9 3-3-3m35.5 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m125 96 2.9 3zm35.5 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m119 99 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m119 99 3 2.9z"/>
|
||||||
<path fill="#c33" d="m126 100.9.9 2-1-2m35.4 0 1 2-1-2z"/>
|
<path fill="#c33" d="m126 100.9.9 2zm35.4 0 1 2z"/>
|
||||||
<path fill="#9cc" d="m166.3 99 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m166.3 99 3 2.9z"/>
|
||||||
<path fill="#ccf" d="m119 101.9 3 3-3-3m47.3 0 3 3-3-3z"/>
|
<path fill="#ccf" d="m119 101.9 3 3zm47.3 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m122 104.8 3 3-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m122 104.8 3 3zm41.3 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m116 107.8 3 3-3-3z"/>
|
<path fill="#9cc" d="m116 107.8 3 3z"/>
|
||||||
<path fill="#c33" d="m122 107.8 3 3-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#c33" d="m122 107.8 3 3zm41.3 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m169.2 107.8 3 3-3-3m-62 3 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m169.2 107.8 3 3zm-62 3 3 2.9z"/>
|
||||||
<path fill="#ccf" d="m110.2 110.7 3 3-3-3m65 0 2.9 3-3-3z"/>
|
<path fill="#ccf" d="m110.2 110.7 3 3zm65 0 2.9 3z"/>
|
||||||
<path fill="#9cc" d="m178 110.7 3 3-3-3m-79.6 3 3 3-3-3z"/>
|
<path fill="#9cc" d="m178 110.7 3 3zm-79.6 3 3 3z"/>
|
||||||
<path fill="#ccf" d="m101.3 113.7 3 3-3-3z"/>
|
<path fill="#ccf" d="m101.3 113.7 3 3z"/>
|
||||||
<path fill="#fcc" d="m113.1 113.7 3 3-3-3z"/>
|
<path fill="#fcc" d="m113.1 113.7 3 3z"/>
|
||||||
<path fill="#c33" d="m116 113.7 3 3-3-3m53.2 0 3 3-3-3z"/>
|
<path fill="#c33" d="m116 113.7 3 3zm53.2 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m172.2 113.7 3 3-3-3z"/>
|
<path fill="#fcc" d="m172.2 113.7 3 3z"/>
|
||||||
<path fill="#ccf" d="m184 113.7 3 3-3-3z"/>
|
<path fill="#ccf" d="m184 113.7 3 3z"/>
|
||||||
<path fill="#9cc" d="m187 113.7 2.9 3-3-3z"/>
|
<path fill="#9cc" d="m187 113.7 2.9 3z"/>
|
||||||
<path fill="#69c" d="m86.6 116.6 3 3-3-3z"/>
|
<path fill="#69c" d="m86.6 116.6 3 3z"/>
|
||||||
<path fill="#9cc" d="m89.5 116.6 3 3-3-3z"/>
|
<path fill="#9cc" d="m89.5 116.6 3 3z"/>
|
||||||
<path fill="#cff" d="m92.5 116.6 3 3-3-3z"/>
|
<path fill="#cff" d="m92.5 116.6 3 3z"/>
|
||||||
<path fill="#fcc" d="m104.3 116.6 3 3-3-3z"/>
|
<path fill="#fcc" d="m104.3 116.6 3 3z"/>
|
||||||
<path fill="#c33" d="m109.2 117.6 2 1-2-1m67.9 0 2 1-2-1z"/>
|
<path fill="#c33" d="m109.2 117.6 2 1zm67.9 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m181 116.6 3 3-3-3z"/>
|
<path fill="#fcc" d="m181 116.6 3 3z"/>
|
||||||
<path fill="#cff" d="m192.8 116.6 3 3-3-3z"/>
|
<path fill="#cff" d="m192.8 116.6 3 3z"/>
|
||||||
<path fill="#9cc" d="m195.8 116.6 3 3-3-3z"/>
|
<path fill="#9cc" d="m195.8 116.6 3 3z"/>
|
||||||
<path fill="#69c" d="m198.7 116.6 3 3-3-3m-121 3 3 3-3-3z"/>
|
<path fill="#69c" d="m198.7 116.6 3 3zm-121 3 3 3z"/>
|
||||||
<path fill="#9cc" d="m80.7 119.6 3 3-3-3z"/>
|
<path fill="#9cc" d="m80.7 119.6 3 3z"/>
|
||||||
<path fill="#cff" d="m83.6 119.6 3 3-3-3z"/>
|
<path fill="#cff" d="m83.6 119.6 3 3z"/>
|
||||||
<path fill="#fcc" d="m95.4 119.6 3 3-3-3z"/>
|
<path fill="#fcc" d="m95.4 119.6 3 3z"/>
|
||||||
<path fill="#c33" d="m100.3 120.6 2 1-2-1m85.6 0 2 1-2-1z"/>
|
<path fill="#c33" d="m100.3 120.6 2 1zm85.6 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m189.9 119.6 3 3-3-3z"/>
|
<path fill="#fcc" d="m189.9 119.6 3 3z"/>
|
||||||
<path fill="#cff" d="m201.7 119.6 3 3-3-3z"/>
|
<path fill="#cff" d="m201.7 119.6 3 3z"/>
|
||||||
<path fill="#9cc" d="m204.6 119.6 3 3-3-3z"/>
|
<path fill="#9cc" d="m204.6 119.6 3 3z"/>
|
||||||
<path fill="#69c" d="m207.6 119.6 3 3-3-3m-138.8 3 3 2.9-3-3z"/>
|
<path fill="#69c" d="m207.6 119.6 3 3zm-138.8 3 3 2.9z"/>
|
||||||
<path fill="#9cf" d="m71.8 122.5 3 3-3-3z"/>
|
<path fill="#9cf" d="m71.8 122.5 3 3z"/>
|
||||||
<path fill="#fcc" d="m86.6 122.5 3 3-3-3z"/>
|
<path fill="#fcc" d="m86.6 122.5 3 3z"/>
|
||||||
<path fill="#c33" d="m91.5 123.5 2 1-2-1m103.3 0 2 1-2-1z"/>
|
<path fill="#c33" d="m91.5 123.5 2 1zm103.3 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m198.7 122.5 3 3-3-3z"/>
|
<path fill="#fcc" d="m198.7 122.5 3 3z"/>
|
||||||
<path fill="#9cf" d="m213.5 122.5 3 3-3-3z"/>
|
<path fill="#9cf" d="m213.5 122.5 3 3z"/>
|
||||||
<path fill="#69c" d="m216.4 122.5 3 3-3-3z"/>
|
<path fill="#69c" d="m216.4 122.5 3 3z"/>
|
||||||
<path fill="#6cc" d="m60 125.5 3 3-3-3z"/>
|
<path fill="#6cc" d="m60 125.5 3 3z"/>
|
||||||
<path fill="#9cf" d="m63 125.5 2.9 3-3-3z"/>
|
<path fill="#9cf" d="m63 125.5 2.9 3z"/>
|
||||||
<path fill="#fcc" d="m74.8 125.5 2.9 3-3-3zm135.8 0 2.9 3-3-3z"/>
|
<path fill="#fcc" d="m74.8 125.5 2.9 3zm135.8 0 2.9 3z"/>
|
||||||
<path fill="#9cf" d="m222.3 125.5 3 3-3-3z"/>
|
<path fill="#9cf" d="m222.3 125.5 3 3z"/>
|
||||||
<path fill="#6cc" d="m225.3 125.5 3 3-3-3m-174.2 3 3 2.9-3-3z"/>
|
<path fill="#6cc" d="m225.3 125.5 3 3zm-174.2 3 3 2.9z"/>
|
||||||
<path fill="#ccf" d="m54 128.4 3 3-3-3z"/>
|
<path fill="#ccf" d="m54 128.4 3 3z"/>
|
||||||
<path fill="#fcc" d="m65.9 128.4 3 3-3-3z"/>
|
<path fill="#fcc" d="m65.9 128.4 3 3z"/>
|
||||||
<path fill="#c33" d="m70.8 129.4 2 1-2-1m144.7 0 2 1-2-1z"/>
|
<path fill="#c33" d="m70.8 129.4 2 1zm144.7 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m219.4 128.4 3 3-3-3z"/>
|
<path fill="#fcc" d="m219.4 128.4 3 3z"/>
|
||||||
<path fill="#ccf" d="m231.2 128.4 3 3-3-3z"/>
|
<path fill="#ccf" d="m231.2 128.4 3 3z"/>
|
||||||
<path fill="#6cc" d="m234.2 128.4 3 3-3-3z"/>
|
<path fill="#6cc" d="m234.2 128.4 3 3z"/>
|
||||||
<path fill="#9cc" d="m42.3 131.4 3 3-3-3z"/>
|
<path fill="#9cc" d="m42.3 131.4 3 3z"/>
|
||||||
<path fill="#ccf" d="m45.2 131.4 3 3-3-3z"/>
|
<path fill="#ccf" d="m45.2 131.4 3 3z"/>
|
||||||
<path fill="#fcc" d="m57 131.4 3 3-3-3zm171.3 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m57 131.4 3 3zm171.3 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m240 131.4 3 3-3-3z"/>
|
<path fill="#ccf" d="m240 131.4 3 3z"/>
|
||||||
<path fill="#9cc" d="m243 131.4 3 3-3-3m-206.6 3 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m243 131.4 3 3zm-206.6 3 3 2.9z"/>
|
||||||
<path fill="#c66" d="m51.1 134.3 3 3-3-3zm183 0 3 3-3-3z"/>
|
<path fill="#c66" d="m51.1 134.3 3 3zm183 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m249 134.3 2.9 3-3-3m-206.6 3 3 3-3-3z"/>
|
<path fill="#9cc" d="m249 134.3 2.9 3zm-206.6 3 3 3z"/>
|
||||||
<path fill="#ccf" d="m45.2 137.3 3 3-3-3z"/>
|
<path fill="#ccf" d="m45.2 137.3 3 3z"/>
|
||||||
<path fill="#fcc" d="m57 137.3 3 3-3-3m171.3 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m57 137.3 3 3zm171.3 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m240 137.3 3 3-3-3z"/>
|
<path fill="#ccf" d="m240 137.3 3 3z"/>
|
||||||
<path fill="#9cc" d="m243 137.3 3 3-3-3z"/>
|
<path fill="#9cc" d="m243 137.3 3 3z"/>
|
||||||
<path fill="#6cc" d="m51.1 140.3 3 2.9-3-3z"/>
|
<path fill="#6cc" d="m51.1 140.3 3 2.9z"/>
|
||||||
<path fill="#ccf" d="m54 140.3 3 2.9-3-3z"/>
|
<path fill="#ccf" d="m54 140.3 3 2.9z"/>
|
||||||
<path fill="#fcc" d="m65.9 140.3 3 2.9-3-3z"/>
|
<path fill="#fcc" d="m65.9 140.3 3 2.9z"/>
|
||||||
<path fill="#c33" d="m70.8 141.2 2 1-2-1m144.7 0 2 1-2-1z"/>
|
<path fill="#c33" d="m70.8 141.2 2 1zm144.7 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m219.4 140.3 3 2.9-3-3z"/>
|
<path fill="#fcc" d="m219.4 140.3 3 2.9z"/>
|
||||||
<path fill="#ccf" d="m231.2 140.3 3 2.9-3-3z"/>
|
<path fill="#ccf" d="m231.2 140.3 3 2.9z"/>
|
||||||
<path fill="#6cc" d="m234.2 140.3 3 2.9-3-3m-174.2 3 3 3-3-3z"/>
|
<path fill="#6cc" d="m234.2 140.3 3 2.9zm-174.2 3 3 3z"/>
|
||||||
<path fill="#9cf" d="m63 143.2 2.9 3-3-3z"/>
|
<path fill="#9cf" d="m63 143.2 2.9 3z"/>
|
||||||
<path fill="#fcc" d="m74.8 143.2 2.9 3-3-3zm135.8 0 2.9 3-3-3z"/>
|
<path fill="#fcc" d="m74.8 143.2 2.9 3zm135.8 0 2.9 3z"/>
|
||||||
<path fill="#9cf" d="m222.3 143.2 3 3-3-3z"/>
|
<path fill="#9cf" d="m222.3 143.2 3 3z"/>
|
||||||
<path fill="#6cc" d="m225.3 143.2 3 3-3-3z"/>
|
<path fill="#6cc" d="m225.3 143.2 3 3z"/>
|
||||||
<path fill="#69c" d="m68.8 146.2 3 2.9-3-3z"/>
|
<path fill="#69c" d="m68.8 146.2 3 2.9z"/>
|
||||||
<path fill="#9cf" d="m71.8 146.2 3 2.9-3-3z"/>
|
<path fill="#9cf" d="m71.8 146.2 3 2.9z"/>
|
||||||
<path fill="#fcc" d="m86.6 146.2 3 2.9-3-3z"/>
|
<path fill="#fcc" d="m86.6 146.2 3 2.9z"/>
|
||||||
<path fill="#c33" d="m91.5 147.1 2 1-2-1m103.3 0 2 1-2-1z"/>
|
<path fill="#c33" d="m91.5 147.1 2 1zm103.3 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m198.7 146.2 3 2.9-3-3z"/>
|
<path fill="#fcc" d="m198.7 146.2 3 2.9z"/>
|
||||||
<path fill="#9cf" d="m213.5 146.2 3 2.9-3-3z"/>
|
<path fill="#9cf" d="m213.5 146.2 3 2.9z"/>
|
||||||
<path fill="#69c" d="m216.4 146.2 3 2.9-3-3m-138.7 3 3 3-3-3z"/>
|
<path fill="#69c" d="m216.4 146.2 3 2.9zm-138.7 3 3 3z"/>
|
||||||
<path fill="#9cc" d="m80.7 149.1 3 3-3-3z"/>
|
<path fill="#9cc" d="m80.7 149.1 3 3z"/>
|
||||||
<path fill="#cff" d="m83.6 149.1 3 3-3-3z"/>
|
<path fill="#cff" d="m83.6 149.1 3 3z"/>
|
||||||
<path fill="#fcc" d="m95.4 149.1 3 3-3-3z"/>
|
<path fill="#fcc" d="m95.4 149.1 3 3z"/>
|
||||||
<path fill="#c33" d="m100.3 150 2 1-2-1m85.6 0 2 1-2-1z"/>
|
<path fill="#c33" d="m100.3 150 2 1zm85.6 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m189.9 149.1 3 3-3-3z"/>
|
<path fill="#fcc" d="m189.9 149.1 3 3z"/>
|
||||||
<path fill="#cff" d="m201.7 149.1 3 3-3-3z"/>
|
<path fill="#cff" d="m201.7 149.1 3 3z"/>
|
||||||
<path fill="#9cc" d="m204.6 149.1 3 3-3-3z"/>
|
<path fill="#9cc" d="m204.6 149.1 3 3z"/>
|
||||||
<path fill="#69c" d="m207.6 149.1 3 3-3-3m-121 3 2.9 2.9-3-3z"/>
|
<path fill="#69c" d="m207.6 149.1 3 3zm-121 3 2.9 2.9z"/>
|
||||||
<path fill="#9cc" d="m89.5 152 3 3-3-3z"/>
|
<path fill="#9cc" d="m89.5 152 3 3z"/>
|
||||||
<path fill="#cff" d="m92.5 152 3 3-3-3z"/>
|
<path fill="#cff" d="m92.5 152 3 3z"/>
|
||||||
<path fill="#fcc" d="m104.3 152 3 3-3-3z"/>
|
<path fill="#fcc" d="m104.3 152 3 3z"/>
|
||||||
<path fill="#c33" d="m109.2 153 2 1-2-1m67.9 0 2 1-2-1z"/>
|
<path fill="#c33" d="m109.2 153 2 1zm67.9 0 2 1z"/>
|
||||||
<path fill="#fcc" d="m181 152 3 3-3-3z"/>
|
<path fill="#fcc" d="m181 152 3 3z"/>
|
||||||
<path fill="#cff" d="m192.8 152 3 3-3-3z"/>
|
<path fill="#cff" d="m192.8 152 3 3z"/>
|
||||||
<path fill="#9cc" d="m195.8 152 3 3-3-3z"/>
|
<path fill="#9cc" d="m195.8 152 3 3z"/>
|
||||||
<path fill="#69c" d="m198.7 152 3 3-3-3z"/>
|
<path fill="#69c" d="m198.7 152 3 3z"/>
|
||||||
<path fill="#9cc" d="m98.4 155 3 3-3-3z"/>
|
<path fill="#9cc" d="m98.4 155 3 3z"/>
|
||||||
<path fill="#ccf" d="m101.3 155 3 3-3-3z"/>
|
<path fill="#ccf" d="m101.3 155 3 3z"/>
|
||||||
<path fill="#fcc" d="m113.1 155 3 3-3-3z"/>
|
<path fill="#fcc" d="m113.1 155 3 3z"/>
|
||||||
<path fill="#c33" d="m116 155 3 3-3-3m53.2 0 3 3-3-3z"/>
|
<path fill="#c33" d="m116 155 3 3zm53.2 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m172.2 155 3 3-3-3z"/>
|
<path fill="#fcc" d="m172.2 155 3 3z"/>
|
||||||
<path fill="#ccf" d="m184 155 3 3-3-3z"/>
|
<path fill="#ccf" d="m184 155 3 3z"/>
|
||||||
<path fill="#9cc" d="m187 155 2.9 3-3-3m-79.7 3 3 3-3-3z"/>
|
<path fill="#9cc" d="m187 155 2.9 3zm-79.7 3 3 3z"/>
|
||||||
<path fill="#ccf" d="m110.2 158 3 3-3-3m65 0 2.9 3-3-3z"/>
|
<path fill="#ccf" d="m110.2 158 3 3zm65 0 2.9 3z"/>
|
||||||
<path fill="#9cc" d="m178 158 3 3-3-3m-62 3 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m178 158 3 3zm-62 3 3 2.9z"/>
|
||||||
<path fill="#c33" d="m122 161 3 2.9-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#c33" d="m122 161 3 2.9zm41.3 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m169.2 161 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m169.2 161 3 2.9z"/>
|
||||||
<path fill="#fcc" d="m122 163.9 3 3-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m122 163.9 3 3zm41.3 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m119 166.8 3 3-3-3z"/>
|
<path fill="#ccf" d="m119 166.8 3 3z"/>
|
||||||
<path fill="#c33" d="m126 168.8.9 2-1-2m35.4 0 1 2-1-2z"/>
|
<path fill="#c33" d="m126 168.8.9 2zm35.4 0 1 2z"/>
|
||||||
<path fill="#ccf" d="m166.3 166.8 3 3-3-3z"/>
|
<path fill="#ccf" d="m166.3 166.8 3 3z"/>
|
||||||
<path fill="#9cc" d="m119 169.8 3 3-3-3m47.3 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m119 169.8 3 3zm47.3 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m125 172.7 2.9 3-3-3m35.5 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m125 172.7 2.9 3zm35.5 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m122 175.7 3 3-3-3z"/>
|
<path fill="#ccf" d="m122 175.7 3 3z"/>
|
||||||
<path fill="#c33" d="m128.9 177.6 1 2-1-2m29.5 0 1 2-1-2z"/>
|
<path fill="#c33" d="m128.9 177.6 1 2zm29.5 0 1 2z"/>
|
||||||
<path fill="#ccf" d="m163.3 175.7 3 3-3-3z"/>
|
<path fill="#ccf" d="m163.3 175.7 3 3z"/>
|
||||||
<path fill="#9cc" d="m122 178.6 3 3-3-3m41.3 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m122 178.6 3 3zm41.3 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m127.9 181.6 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m127.9 181.6 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#cff" d="m125 184.5 2.9 3-3-3z"/>
|
<path fill="#cff" d="m125 184.5 2.9 3z"/>
|
||||||
<path fill="#c33" d="m131.8 186.5 1 2-1-2m23.6 0 1 2-1-2z"/>
|
<path fill="#c33" d="m131.8 186.5 1 2zm23.6 0 1 2z"/>
|
||||||
<path fill="#cff" d="m160.4 184.5 3 3-3-3z"/>
|
<path fill="#cff" d="m160.4 184.5 3 3z"/>
|
||||||
<path fill="#9cc" d="m125 187.5 2.9 3-3-3m35.5 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m125 187.5 2.9 3zm35.5 0 3 3z"/>
|
||||||
<path fill="#69c" d="m125 190.4 2.9 3-3-3z"/>
|
<path fill="#69c" d="m125 190.4 2.9 3z"/>
|
||||||
<path fill="#fcc" d="m130.8 190.4 3 3-3-3m23.7 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m130.8 190.4 3 3zm23.7 0 3 3z"/>
|
||||||
<path fill="#69c" d="m160.4 190.4 3 3-3-3z"/>
|
<path fill="#69c" d="m160.4 190.4 3 3z"/>
|
||||||
<path fill="#cff" d="m127.9 193.4 3 3-3-3zm29.5 0 3 3-3-3z"/>
|
<path fill="#cff" d="m127.9 193.4 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m127.9 196.3 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#9cc" d="m127.9 196.3 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#69c" d="m127.9 199.3 3 3-3-3m29.5 0 3 3-3-3z"/>
|
<path fill="#69c" d="m127.9 199.3 3 3zm29.5 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m133.8 202.2 3 3-3-3m17.7 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m133.8 202.2 3 3zm17.7 0 3 3z"/>
|
||||||
<path fill="#9cf" d="m130.8 205.2 3 3-3-3z"/>
|
<path fill="#9cf" d="m130.8 205.2 3 3z"/>
|
||||||
<path fill="#c33" d="m137.7 207.2 1 2-1-2m11.8 0 1 2-1-2z"/>
|
<path fill="#c33" d="m137.7 207.2 1 2zm11.8 0 1 2z"/>
|
||||||
<path fill="#9cf" d="m154.5 205.2 3 3-3-3z"/>
|
<path fill="#9cf" d="m154.5 205.2 3 3z"/>
|
||||||
<path fill="#69c" d="m130.8 208.2 3 2.9-3-3m23.7 0 3 3-3-3z"/>
|
<path fill="#69c" d="m130.8 208.2 3 2.9zm23.7 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m136.7 211.1 3 3-3-3m11.9 0 2.9 3-3-3z"/>
|
<path fill="#fcc" d="m136.7 211.1 3 3zm11.9 0 2.9 3z"/>
|
||||||
<path fill="#9cf" d="m133.8 214 3 3-3-3zm17.7 0 3 3-3-3z"/>
|
<path fill="#9cf" d="m133.8 214 3 3zm17.7 0 3 3z"/>
|
||||||
<path fill="#6cc" d="m133.8 217 3 3-3-3m17.7 0 3 3-3-3z"/>
|
<path fill="#6cc" d="m133.8 217 3 3zm17.7 0 3 3z"/>
|
||||||
<path fill="#fcc" d="m139.7 220 3 3-3-3m5.9 0 3 3-3-3z"/>
|
<path fill="#fcc" d="m139.7 220 3 3zm5.9 0 3 3z"/>
|
||||||
<path fill="#ccf" d="m136.7 222.9 3 3-3-3m11.9 0 2.9 3-3-3z"/>
|
<path fill="#ccf" d="m136.7 222.9 3 3zm11.9 0 2.9 3z"/>
|
||||||
<path fill="#6cc" d="m136.7 225.9 3 3-3-3z"/>
|
<path fill="#6cc" d="m136.7 225.9 3 3z"/>
|
||||||
<path fill="#c66" d="m142.7 225.9 2.9 3-3-3z"/>
|
<path fill="#c66" d="m142.7 225.9 2.9 3z"/>
|
||||||
<path fill="#6cc" d="m148.6 225.9 2.9 3-3-3z"/>
|
<path fill="#6cc" d="m148.6 225.9 2.9 3z"/>
|
||||||
<path fill="#ccf" d="m139.7 231.8 3 3-3-3m5.9 0 3 3-3-3z"/>
|
<path fill="#ccf" d="m139.7 231.8 3 3zm5.9 0 3 3z"/>
|
||||||
<path fill="#9cc" d="m139.7 234.7 3 3-3-3m5.9 0 3 3-3-3m-3 6 3 2.9-3-3z"/>
|
<path fill="#9cc" d="m139.7 234.7 3 3zm5.9 0 3 3zm-3 6 3 2.9z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 8.8 KiB |