Merge branch 'main' into fixQTMissingIcon

This commit is contained in:
Jason Beck 2024-03-15 17:24:37 -05:00 committed by GitHub
commit c77967292d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 231 additions and 52 deletions

View File

@ -115,37 +115,81 @@ jobs:
echo "When CI is done, the above patch will be uploaded as 'code-style.diff' to https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/ ."
exit 1
sanitizer-tests:
runs-on: ubuntu-22.04
# sanitizer-tests-ubuntu:
# runs-on: ubuntu-22.04
# needs: [ what-to-make ]
# if: ${{ needs.what-to-make.outputs.make-tests == 'true' }}
# env:
# NODE_PATH: /usr/lib/nodejs:/usr/share/nodejs
# steps:
# - name: Show Configuration
# run: |
# echo '${{ toJSON(needs) }}'
# echo '${{ toJSON(runner) }}'
# cat /etc/os-release
# - name: Get Dependencies
# run: |
# set -ex
# sudo apt-get update
# sudo apt-get install -y --no-install-recommends \
# ca-certificates \
# clang \
# cmake \
# gettext \
# libcurl4-openssl-dev \
# libdeflate-dev \
# libevent-dev \
# libfmt-dev \
# libminiupnpc-dev \
# libnatpmp-dev \
# libpsl-dev \
# libssl-dev \
# ninja-build \
# npm
# - name: Get Source
# uses: actions/checkout@v4
# with:
# submodules: recursive
# path: src
# - name: Configure
# run: |
# cmake \
# -S src \
# -B obj \
# -G Ninja \
# -DCMAKE_BUILD_TYPE=Debug \
# -DCMAKE_CXX_COMPILER='clang++' \
# -DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \
# -DCMAKE_C_COMPILER='clang' \
# -DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \
# -DCMAKE_INSTALL_PREFIX=pfx \
# -DENABLE_CLI=OFF \
# -DENABLE_DAEMON=OFF \
# -DENABLE_GTK=OFF \
# -DENABLE_MAC=OFF \
# -DENABLE_QT=OFF \
# -DENABLE_TESTS=ON \
# -DENABLE_UTILS=ON \
# -DREBUILD_WEB=OFF \
# -DRUN_CLANG_TIDY=OFF
# - name: Make
# run: cmake --build obj --config Debug --target libtransmission-test transmission-show
# - name: Test with sanitizers
# run: cmake -E chdir obj ctest -j $(nproc) --build-config Debug --output-on-failure
sanitizer-tests-macos:
runs-on: macos-14
needs: [ what-to-make ]
if: ${{ needs.what-to-make.outputs.make-tests == 'true' }}
env:
NODE_PATH: /usr/lib/nodejs:/usr/share/nodejs
steps:
- name: Show Configuration
run: |
echo '${{ toJSON(needs) }}'
echo '${{ toJSON(runner) }}'
cat /etc/os-release
sw_vers
- name: Get Dependencies
run: |
set -ex
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates \
clang \
cmake \
gettext \
libcurl4-openssl-dev \
libdeflate-dev \
libevent-dev \
libfmt-dev \
libminiupnpc-dev \
libnatpmp-dev \
libpsl-dev \
libssl-dev \
ninja-build \
npm
brew install cmake gettext libdeflate libevent libpsl miniupnpc ninja node pkg-config
- name: Get Source
uses: actions/checkout@v4
with:
@ -158,10 +202,8 @@ jobs:
-B obj \
-G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_COMPILER='clang++' \
-DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \
-DCMAKE_C_COMPILER='clang' \
-DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \
-DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,undefined' \
-DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,undefined' \
-DCMAKE_INSTALL_PREFIX=pfx \
-DENABLE_CLI=OFF \
-DENABLE_DAEMON=OFF \

View File

@ -11,7 +11,6 @@ Contributor Team
Dmitry Serov (@DevilDimon) (macOS client)
Dzmitry Neviadomski (@nevack) (macOS client)
FX Coudert (@fxcoudert) (macOS client)
Gary Elshaw (@GaryElshaw)
John Clay (@JohnClay)
SweetP Pro (@sweetppro) (macOS client)
Yat Ho (@tearfur) (libtransmission)

View File

@ -632,7 +632,6 @@ else()
-Wextra
-Wcast-align
-Wduplicated-cond
-Wexit-time-destructors
-Wextra-semi
-Wextra-semi-stmt
-Wextra-tokens

View File

@ -452,6 +452,7 @@
ED8A16402735A8AA000D61F9 /* peer-mgr-active-requests.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */; };
ED8A16412735A8AA000D61F9 /* peer-mgr-wishlist.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */; };
ED8A16422735A8AA000D61F9 /* peer-mgr-wishlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */; };
ED9862972B979AA2002F3035 /* Utils.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED9862962B979AA2002F3035 /* Utils.mm */; };
EDBAAC8C29E486BC00D9495F /* global-ip-cache.h in Headers */ = {isa = PBXBuildFile; fileRef = EDBAAC8B29E486BC00D9495F /* global-ip-cache.h */; };
EDBAAC8E29E486C200D9495F /* global-ip-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = EDBAAC8D29E486C200D9495F /* global-ip-cache.cc */; };
EDBDFA9E25AFCCA60093D9C1 /* evutil_time.c in Sources */ = {isa = PBXBuildFile; fileRef = EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */; };
@ -1366,6 +1367,8 @@
ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-active-requests.cc"; sourceTree = "<group>"; };
ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "peer-mgr-wishlist.h"; sourceTree = "<group>"; };
ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-wishlist.cc"; sourceTree = "<group>"; };
ED9862952B979AA2002F3035 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
ED9862962B979AA2002F3035 /* Utils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Utils.mm; sourceTree = "<group>"; };
EDBAAC8B29E486BC00D9495F /* global-ip-cache.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "global-ip-cache.h"; sourceTree = "<group>"; };
EDBAAC8D29E486C200D9495F /* global-ip-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "global-ip-cache.cc"; sourceTree = "<group>"; };
EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = evutil_time.c; sourceTree = "<group>"; };
@ -1664,6 +1667,8 @@
A222EA7A0E6C32C4009FB003 /* BlocklistScheduler.mm */,
ED86936D2ADAE34D00342B1A /* DefaultAppHelper.h */,
ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */,
ED9862952B979AA2002F3035 /* Utils.h */,
ED9862962B979AA2002F3035 /* Utils.mm */,
A2AB883916A399A6008FAD50 /* VDKQueue */,
);
name = Sources;
@ -3274,6 +3279,7 @@
A209EB9D1142E59A002B02D1 /* InfoPeersViewController.mm in Sources */,
A209EBCE1142F2B4002B02D1 /* InfoFileViewController.mm in Sources */,
A209EBF91142FEEE002B02D1 /* InfoOptionsViewController.mm in Sources */,
ED9862972B979AA2002F3035 /* Utils.mm in Sources */,
A21F15AC11729A8B00CF5A9C /* AddMagnetWindowController.mm in Sources */,
A2661D6112D0E8D9004F69D5 /* FilterBarView.mm in Sources */,
A2F7CF5F13035FFD0016FF10 /* URLSheetWindowController.mm in Sources */,
@ -3930,6 +3936,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LIBRARY = "libc++";
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"third-party/dht",
@ -4184,6 +4191,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LIBRARY = "libc++";
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"third-party/dht",
@ -4359,6 +4367,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_STRICT_PROTOTYPES = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GENERATE_MASTER_OBJECT_FILE = YES;
PRODUCT_NAME = dht;
@ -4369,6 +4378,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_STRICT_PROTOTYPES = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GENERATE_MASTER_OBJECT_FILE = YES;
PRODUCT_NAME = dht;
@ -4379,6 +4389,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_STRICT_PROTOTYPES = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GENERATE_MASTER_OBJECT_FILE = YES;
PRODUCT_NAME = dht;
@ -4513,6 +4524,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LIBRARY = "libc++";
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"third-party/dht",

View File

@ -44,7 +44,7 @@ public:
return iter != std::end(icons_) ? &iter->second : nullptr;
}
void load(
void load( //
std::string_view url_in,
IconFunc callback = [](Icon const&) { /*default callback is a no-op */ })
{

View File

@ -5,6 +5,7 @@
#import "BadgeView.h"
#import "NSStringAdditions.h"
#import "NSImageAdditions.h"
#import "Utils.h"
static CGFloat const kBetweenPadding = 2.0;
static NSImage* kWhiteUpArrow = [[NSImage imageNamed:@"UpArrowTemplate"] imageWithColor:NSColor.whiteColor];
@ -61,7 +62,7 @@ typedef NS_ENUM(NSInteger, ArrowDirection) {
- (BOOL)setRatesWithDownload:(CGFloat)downloadRate upload:(CGFloat)uploadRate
{
//only needs update if the badges were displayed or are displayed now
if (self.fDownloadRate == downloadRate && self.fUploadRate == uploadRate)
if (isSpeedEqual(self.fDownloadRate, downloadRate) && isSpeedEqual(self.fUploadRate, uploadRate))
{
return NO;
}

View File

@ -191,6 +191,8 @@ target_sources(${TR_NAME}-mac
TrackerTableView.mm
URLSheetWindowController.h
URLSheetWindowController.mm
Utils.h
Utils.mm
WebSeedTableView.h
WebSeedTableView.mm)

View File

@ -5,6 +5,7 @@
#import "InfoOptionsViewController.h"
#import "NSStringAdditions.h"
#import "Torrent.h"
#import "Utils.h"
typedef NS_ENUM(NSInteger, OptionPopupType) {
OptionPopupTypeGlobal = 0,
@ -295,7 +296,7 @@ static CGFloat const kStackViewSpacing = 8.0;
checkRatio = kInvalidValue;
}
if (!multipleRatioLimits && ratioLimit != torrent.ratioLimit)
if (!multipleRatioLimits && isRatioEqual(ratioLimit, torrent.ratioLimit))
{
multipleRatioLimits = YES;
}

View File

@ -351,9 +351,9 @@ typedef NS_ENUM(NSUInteger, TabTag) {
viewRect = [self.fOptionsViewController viewRect];
}
CGFloat const difference = NSHeight(viewRect) - oldHeight;
windowRect.origin.y -= difference;
windowRect.size.height += difference;
CGFloat const viewHeightDifference = NSHeight(viewRect) - oldHeight;
windowRect.origin.y -= viewHeightDifference;
windowRect.size.height += viewHeightDifference;
windowRect.size.width = MAX(NSWidth(windowRect), minWindowWidth);
if ([self.fViewController respondsToSelector:@selector(saveViewSize)]) //a little bit hacky, but avoids requiring an extra method
@ -363,11 +363,11 @@ typedef NS_ENUM(NSUInteger, TabTag) {
CGFloat const screenHeight = NSHeight(window.screen.visibleFrame);
if (NSHeight(windowRect) > screenHeight)
{
CGFloat const difference = screenHeight - NSHeight(windowRect);
windowRect.origin.y -= difference;
windowRect.size.height += difference;
CGFloat const windowHeightDifference = screenHeight - NSHeight(windowRect);
windowRect.origin.y -= windowHeightDifference;
windowRect.size.height += windowHeightDifference;
viewRect.size.height += difference;
viewRect.size.height += windowHeightDifference;
}
}

View File

@ -72,7 +72,7 @@ static NSTimeInterval const kCheckFireInterval = 3.0;
timeoutInterval:15.0];
_fTask = [_fSession dataTaskWithRequest:portProbeRequest
completionHandler:^(NSData* _Nullable data, NSURLResponse* _Nullable response, NSError* _Nullable error) {
completionHandler:^(NSData* _Nullable data, NSURLResponse* _Nullable, NSError* _Nullable error) {
if (error)
{
NSLog(@"Unable to get port status: connection failed (%@)", error.localizedDescription);

View File

@ -4,6 +4,7 @@
#import "StatusBarController.h"
#import "NSStringAdditions.h"
#import "Utils.h"
typedef NSString* StatusRatioType NS_TYPED_EXTENSIBLE_ENUM;
@ -77,13 +78,13 @@ typedef NS_ENUM(NSUInteger, StatusTag) {
- (void)updateWithDownload:(CGFloat)dlRate upload:(CGFloat)ulRate
{
//set rates
if (dlRate != self.fPreviousDownloadRate)
if (!isSpeedEqual(self.fPreviousDownloadRate, dlRate))
{
self.fTotalDLField.stringValue = [NSString stringForSpeed:dlRate];
self.fPreviousDownloadRate = dlRate;
}
if (ulRate != self.fPreviousUploadRate)
if (!isSpeedEqual(self.fPreviousUploadRate, ulRate))
{
self.fTotalULField.stringValue = [NSString stringForSpeed:ulRate];
self.fPreviousUploadRate = ulRate;

View File

@ -125,7 +125,7 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175;
NSIndexSet* fullIndexSet = [NSIndexSet indexSetWithIndexesInRange:fullRange];
NSMutableIndexSet* visibleIndexSet = [[NSMutableIndexSet alloc] init];
[fullIndexSet enumerateIndexesUsingBlock:^(NSUInteger row, BOOL* stop) {
[fullIndexSet enumerateIndexesUsingBlock:^(NSUInteger row, BOOL*) {
id rowView = [self rowViewAtRow:row makeIfNecessary:NO];
if ([rowView isGroupRowStyle])
{
@ -151,7 +151,7 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175;
//redraw fControlButton
BOOL minimal = [self.fDefaults boolForKey:@"SmallView"];
[rowIndexes enumerateIndexesUsingBlock:^(NSUInteger row, BOOL* stop) {
[rowIndexes enumerateIndexesUsingBlock:^(NSUInteger row, BOOL*) {
id rowView = [self rowViewAtRow:row makeIfNecessary:NO];
if (![rowView isGroupRowStyle])
{

8
macosx/Utils.h Normal file
View File

@ -0,0 +1,8 @@
// This file Copyright © Transmission authors and contributors.
// It may be used under the MIT (SPDX: MIT) license.
// License text can be found in the licenses/ folder.
#import <CoreFoundation/CoreFoundation.h>
bool isSpeedEqual(CGFloat old_speed, CGFloat new_speed);
bool isRatioEqual(CGFloat old_ratio, CGFloat new_ratio);

19
macosx/Utils.mm Normal file
View File

@ -0,0 +1,19 @@
// This file Copyright © Transmission authors and contributors.
// It may be used under the MIT (SPDX: MIT) license.
// License text can be found in the licenses/ folder.
#include <cmath>
#import "Utils.h"
bool isSpeedEqual(CGFloat old_speed, CGFloat new_speed)
{
static CGFloat constexpr kSpeedCompareEps = 0.1 / 2;
return std::abs(new_speed - old_speed) < kSpeedCompareEps;
}
bool isRatioEqual(CGFloat old_ratio, CGFloat new_ratio)
{
static CGFloat constexpr kRatioCompareEps = 0.01 / 2;
return std::abs(new_ratio - old_ratio) < kRatioCompareEps;
}

View File

@ -130,8 +130,7 @@ void RpcClient::sendNetworkRequest(TrVariantPtr req, QFutureInterface<RpcRespons
if (verbose_)
{
qInfo() << "sending"
<< "POST" << qPrintable(url_.path());
qInfo() << "sending POST " << qPrintable(url_.path());
for (QByteArray const& b : request_->rawHeaderList())
{

View File

@ -63,7 +63,7 @@ namespace libtransmission::test
bool waitFor(struct event_base* event_base, std::chrono::milliseconds msec)
{
return waitFor(
return waitFor( //
event_base,
[]() { return false; },
msec);
@ -596,7 +596,7 @@ TEST_F(DhtTest, usesBootstrapFile)
// Confirm that BootstrapNodeName gets pinged first.
auto const expected = getSockaddr(BootstrapNodeName, BootstrapNodePort);
auto& pinged = mediator.mock_dht_.pinged_;
waitFor(
waitFor( //
event_base_,
[&pinged]() { return !std::empty(pinged); },
5s);

View File

@ -42,7 +42,7 @@ protected:
void sleepMsec(std::chrono::milliseconds msec)
{
EXPECT_FALSE(waitFor(
EXPECT_FALSE(waitFor( //
evbase_.get(),
[]() { return false; },
msec));

View File

@ -1 +1,39 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#800" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg1"
width="60"
height="60"
viewBox="0 0 60 60"
sodipodi:docname="pause.png"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g1">
<image
width="60"
height="60"
preserveAspectRatio="none"
style="image-rendering:optimizeQuality"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABGdBTUEAALGPC/xhBQAAACBjSFJN&#10;AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUGVYSWZNTQAqAAAACAACARIA&#10;AwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAA8oAMABAAA&#10;AAEAAAA8AAAAAJkCx0IAAAIwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHht&#10;bG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6&#10;UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5z&#10;IyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5z&#10;OmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0&#10;aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVs&#10;WURpbWVuc2lvbj42MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVs&#10;WERpbWVuc2lvbj42MDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9y&#10;U3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90&#10;aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8&#10;L3g6eG1wbWV0YT4KQTteaQAABE5JREFUaAXlW09IFFEcfquZlFkdtjrkQmm1omBsURRIUnYOCmoL&#10;OkRERAQSRJIRIkhECxUSRNChWiJq65aHDtUeCpNy0S7ZoXIjFqXCba02JbPvm3VkWWdy58/uzux8&#10;8Plm35/f+33z3rx585vRJXKLZTDvA2unuRxp5TT/IB2b5iek78BBMAImQdugEZ5eAgfAv+CURv5G&#10;/WfgWbAGtCTc8Ooc+B7UKnCu+s9h8xBYBhYcnKIB8Ac4l+NGy6Po4zg4H8w7StDjCTAOGhWitT2v&#10;82Ywb1iHnl6BWh01u/5t+MAFMKfYD+sJ0Gzn9drjyr4+V4rPW0ho+gn6Bb92mSm6FMZuWFSsLJz3&#10;9MNmiHbByC2Li5VFMzUs+qKNxFIwR1r39D5iM7HySPOabgA1gQ3YUDZit5Sr96JsFZejIm/udhOZ&#10;6e/NbAW3F4FYWfz2uUSvQQU+rcgN7J6+hZb/7r3vFJFYebCOQZMi1iKXy7pcsVjSj9A0T1Y8c4CM&#10;0yB3VbrhdrtFW1ub8Hq9orQ0ZSqZTIpwOCy6urrE1BTP4WxUVFSI1tZW4fP5RFlZ6rF3YmJC9Pb2&#10;ikAgIHhsAKvQ9gAYTLexED8YbjE0qsFgEJqU4ff7VW13dnYqN0JuS0uLajsN/oZRVwKfa4k9YNb3&#10;LamFwp/6+nqF3FSW3rK6ujpVmxoKtqHuataXBfs1NFat6nJx660MvWUlJbKLynazzKVj+1iX1ngd&#10;N/FHkaOZ+ih4M5jzyAE7KzAa0X85BW8psCP56n4BOmqgYAbJnYJaCvY6RS10SoI9DhJcxRF2woIl&#10;j+lipwmupGDSKZC2MdxDOwVjHF3HCR52yvBC5zBHmAE7p2DQaYLfUfBrhwwvw1f9FPwCHHeAaL7T&#10;llZpfjHT4wDBT6iRI0w8SCXW+4uwlllOPaQhWfBdHBsKDdLY0NAQE0XoLYtGo4r2NGa+Qf1+tpHD&#10;spzW/HTAUMSsr69PVFdXC8ah4vG4GB0dFbFYTIRCISncOjk5yT5nIRKJCI/HI4VoE4mE1G5kZER0&#10;d3eLjo4OMT5ueIm5gE5fZna8CRlmhEStZuMbdM1EZOUpTfFcxR7zoMhwBXr4HZkiOMqcd1YbJb3+&#10;cNu8RFFpWua1IhJ8ME2X6uFSlPDM6D2rVmn3VFWhQsFO5Nl5an+B/1UKumZuS5llH5DBW1ZTZoEN&#10;fnOG7QUjWn3lCh4CrTJFs/XjlFah6fXL8YN70Gw7K3S9QLrzeo8ZxrWD6MvwU/31pUb1/DDkPljo&#10;EVTr/4xGPVlV5zXdDlpp9f4Of7hA5RQ7YD0Gqp3tfOUzUlOTU6VpxrlduwoWYrT5gfpJUH7Sw2H+&#10;sAFdPQLzMap8RrwOrgQLDv4zFoMIfK42W/xX2OQKrLhzQn5BwX34UZCPmT9BveK5NbwH7gZ5hzAN&#10;pt23FDyio1vBjWDtNFcg5X2d5PXP1zy8Jj+DfCFA9oADIE+W6fgHx/XhAwJBPHEAAAAASUVORK5C&#10;YII=&#10;"
id="image1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 3.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -1 +1,39 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#080" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg1"
width="60"
height="60"
viewBox="0 0 60 60"
sodipodi:docname="play.png"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g1">
<image
width="60"
height="60"
preserveAspectRatio="none"
style="image-rendering:optimizeQuality"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABGdBTUEAALGPC/xhBQAAACBjSFJN&#10;AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUGVYSWZNTQAqAAAACAACARIA&#10;AwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAA8oAMABAAA&#10;AAEAAAA8AAAAAJkCx0IAAAIwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHht&#10;bG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6&#10;UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5z&#10;IyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5z&#10;OmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0&#10;aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVs&#10;WURpbWVuc2lvbj42MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVs&#10;WERpbWVuc2lvbj42MDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9y&#10;U3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90&#10;aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8&#10;L3g6eG1wbWV0YT4KQTteaQAABRFJREFUaAXdWl9IJVUc/u21vBZuZag9uEKypeuDm1uGFYJYgiCi&#10;9FAm+BChEZVaEElK7JMhLhRIEGFCBRrqi2CgBZYPkQ/Gwiq4N8SiTFmwsFq1smz6vovnMl3v9c6f&#10;M/fO+IOPc2bmnO/8vjkzc37nnDkj3loB6C8BF45QiPTsEf5BevMIPyL9FogAV4E/gMBYDTx9G7gG&#10;/AsYNvEnyn8J9APnAV9aPrx6E1gH7ApMVf4rcD4L3Apk3PiIXgF2gVSOu73+A9p4EcgG0m4htPgy&#10;8CvgVojd+nzPnwDSZqVoaQmw66ju8h/DB34APbVnwP47oNt5p3z8sj/gleK3fCTUfIP24VezTtFZ&#10;IPvAp2KVcI7pz+kQfQYkH/lcrBLN1LXooQCJpWD2tOPHuyNgYlVP852+CNgyVmBFRRK0lF/vXKuK&#10;wyjIwT1oIuP9/dCq4MunQKwSX5dK9H0owNmKqhD09Dq0nBh7j50isaqzXoCmhHY/zvKzrgqelvR7&#10;aLpFKeasR9nryDCqcm01NTWyubkpu7u7Mjw8LHl5ea45XRDci7pt8fVvxwkut2jp1ampKcNs29vb&#10;RkdHhxEKhbTwO/BzAXX+Z+040ubMzMyMWW8sv7S0ZFRXV2trx4bPXGoqoWL1SLfywGurqqqSxcVF&#10;GR0dlcLCQq+bM/NzTvC0OsEXWuscN1kPx7oamZ2dHaO7u9vIyspKV49/rgQ/hozWRq0IVuKXl5eN&#10;2tpare0n0cNQOcxH+hEgY1ZRUSELCwsyPj4uRUVFXvpxG8gvUjAXyTNubW1tEolEpLe3V7KzTwyO&#10;3Ph6gYLL3DDorJubmyuDg4OysrIiDQ0NOqkVV1RwsTryS1paWipzc3MyPT0tJSXR0USXa+fYw54v&#10;dTr1tqWlRVZXV6Wvr88pRXy9O3wtmN7m5OTIwMCANDU1xTvv5PgsBRO+t/x8bl+5thDFMob2tc3P&#10;z8vk5KQOH2/6WvDW1pa0t7dLfX297O8zbnBtUcE3XNNoJjg4OJChoSEpKyuTsTGuSWizG4yjuWBX&#10;rY3SJdHs7Kz09PTI2tqaS6aE1SN8pCk447a+vi7Nzc3S2NjolVhq5PKt1ANag3c7k4e9vT2jv7/f&#10;CIfDWn1IoOlvnIvGHAyqta5UWhU8MTFhFBcXey1U8X8NndExmH/MLPIgXcZYua6uTlpbW2VjYyNd&#10;zc6bG3oJB+pOuE6T9TAn/V1dXemc9Ju1VJoF342Dv3SJRtCv5vfR9PDw0BgZGTEKCgrMDqQzz1+o&#10;jtkUzmhxorOzMyYYa1gG1rK08Lrw75VjanHiYReExwSVl5cblZWVx87rbMMi1y8ol3Qncc4iiR+E&#10;WPWBP8wlNfbyIWCVzO/lGDbfmVTt0YX3TpFgbjCktLtQgnfG772Xyr8vUio1FWC4GeRHexv+nzPp&#10;iWWT7RZ+hxK8VhsrGZwMe/4p4KpdlzmT0jY2gyvVI6jr+mt2hZrL8wcXxqC6nPGa54rZead5TqmC&#10;IPod+MldQi3GvQ+uonndQ07539CiMo6E7/RlwE9f79/gDz9QntrjYN8CnPaGrnrfwIfznio1kTNc&#10;exfIRG9z8/5VINmQikve2YOg/hTQ1Wsn8XC+/j7g6SYy+C3ZJZT6BOBy0UlOO7n2Mzj5BU4YOeF8&#10;Ro1x+PPAZ8Ae4EQg6zA0nACeBDhCaDNt41YCj+joo8BDAP8yIO4BOK4TfP+5r8V38ieA6+MEFxSv&#10;ARSu3f4DFAR8/czUm8MAAAAASUVORK5CYII=&#10;"
id="image1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 44 KiB