personal space feature

This commit is contained in:
Brad Hefta-Gaub 2016-11-19 15:05:53 -08:00
parent e9563ef9af
commit fe709f51de
20 changed files with 557 additions and 21 deletions

View file

@ -15,7 +15,6 @@
// this should send a signal every 10ms, with pretty good precision. Hardcoding
// to 10ms since that's what you'd want for audio.
void AvatarAudioTimer::start() {
qDebug() << __FUNCTION__;
auto startTime = usecTimestampNow();
quint64 frameCounter = 0;
const int TARGET_INTERVAL_USEC = 10000; // 10ms

View file

@ -95,7 +95,7 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket");
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket");
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);
}
@ -393,16 +393,26 @@ bool AudioMixer::prepareMixForListeningNode(Node* node) {
&& !node->isIgnoringNodeWithID(otherNode->getUUID()) && !otherNode->isIgnoringNodeWithID(node->getUUID())) {
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
// enumerate the ARBs attached to the otherNode and add all that should be added to mix
auto streamsCopy = otherNodeClientData->getAudioStreams();
// check to see if we're ignoring in radius
bool insideIgnoreRadius = false;
if (node->isIgnoreRadiusEnabled() || otherNode->isIgnoreRadiusEnabled()) {
AudioMixerClientData* otherData = reinterpret_cast<AudioMixerClientData*>(otherNode->getLinkedData());
AudioMixerClientData* nodeData = reinterpret_cast<AudioMixerClientData*>(node->getLinkedData());
float ignoreRadius = glm::min(node->getIgnoreRadius(), otherNode->getIgnoreRadius());
if (glm::distance(nodeData->getPosition(), otherData->getPosition()) < ignoreRadius) {
insideIgnoreRadius = true;
}
}
for (auto& streamPair : streamsCopy) {
auto otherNodeStream = streamPair.second;
if (*otherNode != *node || otherNodeStream->shouldLoopbackForNode()) {
addStreamToMixForListeningNodeWithStream(*listenerNodeData, *otherNodeStream, otherNode->getUUID(),
*nodeAudioStream);
if (!insideIgnoreRadius) {
// enumerate the ARBs attached to the otherNode and add all that should be added to mix
auto streamsCopy = otherNodeClientData->getAudioStreams();
for (auto& streamPair : streamsCopy) {
auto otherNodeStream = streamPair.second;
if (*otherNode != *node || otherNodeStream->shouldLoopbackForNode()) {
addStreamToMixForListeningNodeWithStream(*listenerNodeData, *otherNodeStream, otherNode->getUUID(),
*nodeAudioStream);
}
}
}
}
@ -634,11 +644,14 @@ void AudioMixer::handleKillAvatarPacket(QSharedPointer<ReceivedMessage> packet,
}
}
void AudioMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseIgnoreRequestMessage(packet);
}
void AudioMixer::handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseIgnoreRadiusRequestMessage(packet);
}
void AudioMixer::removeHRTFsForFinishedInjector(const QUuid& streamID) {
auto injectorClientData = qobject_cast<AudioMixerClientData*>(sender());
if (injectorClientData) {

View file

@ -48,6 +48,7 @@ private slots:
void handleNegotiateAudioFormat(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void handleNodeKilled(SharedNodePointer killedNode);
void handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
void handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
void handleKillAvatarPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
void handleNodeMuteRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);

View file

@ -365,10 +365,6 @@ QJsonObject AudioMixerClientData::getAudioStreamStats() {
}
void AudioMixerClientData::handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec) {
qDebug() << __FUNCTION__ <<
"sendingNode:" << *node <<
"currentCodec:" << currentCodec <<
"receivedCodec:" << recievedCodec;
sendSelectAudioFormat(node, currentCodec);
}

View file

@ -89,6 +89,7 @@ public:
bool shouldMuteClient() { return _shouldMuteClient; }
void setShouldMuteClient(bool shouldMuteClient) { _shouldMuteClient = shouldMuteClient; }
glm::vec3 getPosition() { return getAvatarAudioStream() ? getAvatarAudioStream()->getPosition() : glm::vec3(0); }
signals:
void injectorStreamFinished(const QUuid& streamIdentifier);

View file

@ -46,6 +46,7 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket");
auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &AvatarMixer::handlePacketVersionMismatch);
@ -237,6 +238,20 @@ void AvatarMixer::broadcastAvatarData() {
|| otherNode->isIgnoringNodeWithID(node->getUUID())) {
return false;
} else {
AvatarMixerClientData* otherData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
AvatarMixerClientData* nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData());
// check to see if we're ignoring in radius
if (node->isIgnoreRadiusEnabled() || otherNode->isIgnoreRadiusEnabled()) {
float ignoreRadius = glm::min(node->getIgnoreRadius(), otherNode->getIgnoreRadius());
if (glm::distance(nodeData->getPosition(), otherData->getPosition()) < ignoreRadius) {
nodeData->ignoreOther(node, otherNode);
otherData->ignoreOther(otherNode, node);
return false;
}
}
// not close enough to ignore
nodeData->removeFromRadiusIgnoringSet(otherNode->getUUID());
otherData->removeFromRadiusIgnoringSet(node->getUUID());
return true;
}
},
@ -442,6 +457,10 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage>
senderNode->parseIgnoreRequestMessage(message);
}
void AvatarMixer::handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
sendingNode->parseIgnoreRadiusRequestMessage(packet);
}
void AvatarMixer::sendStatsPacket() {
QJsonObject statsObject;
statsObject["average_listeners_last_second"] = (float) _sumListeners / (float) _numStatFrames;

View file

@ -38,6 +38,7 @@ private slots:
void handleAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void handleKillAvatarPacket(QSharedPointer<ReceivedMessage> message);
void handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void handleRadiusIgnoreRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
void domainSettingsRequestComplete();
void handlePacketVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID);

View file

@ -11,6 +11,9 @@
#include <udt/PacketHeaders.h>
#include <DependencyManager.h>
#include <NodeList.h>
#include "AvatarMixerClientData.h"
int AvatarMixerClientData::parseData(ReceivedMessage& message) {
@ -39,6 +42,16 @@ uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& node
}
}
void AvatarMixerClientData::ignoreOther(SharedNodePointer self, SharedNodePointer other) {
if (!isRadiusIgnoring(other->getUUID())) {
addToRadiusIgnoringSet(other->getUUID());
auto killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID);
killPacket->write(other->getUUID().toRfc4122());
DependencyManager::get<NodeList>()->sendUnreliablePacket(*killPacket, *self);
_hasReceivedFirstPacketsFrom.erase(other->getUUID());
}
}
void AvatarMixerClientData::loadJSONStats(QJsonObject& jsonObject) const {
jsonObject["display_name"] = _avatar->getDisplayName();
jsonObject["full_rate_distance"] = _fullRateDistance;

View file

@ -79,6 +79,13 @@ public:
{ return _avgOtherAvatarDataRate.getAverageSampleValuePerSecond() / (float) BYTES_PER_KILOBIT; }
void loadJSONStats(QJsonObject& jsonObject) const;
glm::vec3 getPosition() { return _avatar ? _avatar->getPosition() : glm::vec3(0); }
bool isRadiusIgnoring(const QUuid& other) { return _radiusIgnoredOthers.find(other) != _radiusIgnoredOthers.end(); }
void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); }
void removeFromRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.erase(other); }
void ignoreOther(SharedNodePointer self, SharedNodePointer other);
private:
AvatarSharedPointer _avatar { new AvatarData() };
@ -99,6 +106,7 @@ private:
int _numOutOfOrderSends = 0;
SimpleMovingAverage _avgOtherAvatarDataRate;
std::unordered_set<QUuid> _radiusIgnoredOthers;
};
#endif // hifi_AvatarMixerClientData_h

View file

@ -32,7 +32,7 @@
void setupPreferences() {
auto preferences = DependencyManager::get<Preferences>();
auto nodeList = DependencyManager::get<NodeList>();
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
static const QString AVATAR_BASICS { "Avatar Basics" };
{
@ -68,6 +68,18 @@ void setupPreferences() {
auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); };
preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when moving", getter, setter));
}
{
auto getter = [=]()->float { return nodeList->getIgnoreRadius(); };
auto setter = [=](float value) {
nodeList->ignoreNodesInRadius(value, nodeList->getIgnoreRadiusEnabled());
};
auto preference = new SpinnerPreference(AVATAR_BASICS, "Personal space bubble radius (default is 1m)", getter, setter);
preference->setMin(0.01f);
preference->setMax(99.9f);
preference->setDecimals(2);
preference->setStep(0.25);
preferences->addPreference(preference);
}
// UI
{

View file

@ -64,6 +64,7 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
{
// Update socket's object name
setType(_type);
_ignoreRadiusEnabled = false;
}
void Node::setType(char type) {
@ -101,6 +102,15 @@ void Node::addIgnoredNode(const QUuid& otherNodeID) {
}
}
void Node::parseIgnoreRadiusRequestMessage(QSharedPointer<ReceivedMessage> message) {
bool enabled;
float radius;
message->readPrimitive(&enabled);
message->readPrimitive(&radius);
_ignoreRadiusEnabled = enabled;
_ignoreRadius = radius;
}
QDataStream& operator<<(QDataStream& out, const Node& node) {
out << node._type;
out << node._uuid;

View file

@ -74,10 +74,14 @@ public:
void parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message);
void addIgnoredNode(const QUuid& otherNodeID);
bool isIgnoringNodeWithID(const QUuid& nodeID) const { return _ignoredNodeIDSet.find(nodeID) != _ignoredNodeIDSet.cend(); }
void parseIgnoreRadiusRequestMessage(QSharedPointer<ReceivedMessage> message);
friend QDataStream& operator<<(QDataStream& out, const Node& node);
friend QDataStream& operator>>(QDataStream& in, Node& node);
bool isIgnoreRadiusEnabled() const { return _ignoreRadiusEnabled; }
float getIgnoreRadius() { return _ignoreRadiusEnabled ? _ignoreRadius.load() : std::numeric_limits<float>::max(); }
private:
// privatize copy and assignment operator to disallow Node copying
Node(const Node &otherNode);
@ -94,6 +98,9 @@ private:
MovingPercentile _clockSkewMovingPercentile;
NodePermissions _permissions;
tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDSet;
std::atomic_bool _ignoreRadiusEnabled;
std::atomic<float> _ignoreRadius { 0.0f };
};
Q_DECLARE_METATYPE(Node*)

View file

@ -750,9 +750,26 @@ bool NodeList::sockAddrBelongsToDomainOrNode(const HifiSockAddr& sockAddr) {
return _domainHandler.getSockAddr() == sockAddr || LimitedNodeList::sockAddrBelongsToNode(sockAddr);
}
void NodeList::ignoreNodesInRadius(float radiusToIgnore, bool enabled) {
_ignoreRadiusEnabled.set(enabled);
_ignoreRadius.set(radiusToIgnore);
eachMatchingNode([](const SharedNodePointer& node)->bool {
return (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer);
}, [this](const SharedNodePointer& destinationNode) {
sendIgnoreRadiusStateToNode(destinationNode);
});
}
void NodeList::sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationNode) {
auto ignorePacket = NLPacket::create(PacketType::RadiusIgnoreRequest, sizeof(bool) + sizeof(float), true);
ignorePacket->writePrimitive(_ignoreRadiusEnabled.get());
ignorePacket->writePrimitive(_ignoreRadius.get());
sendPacket(std::move(ignorePacket), *destinationNode);
}
void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) {
// enumerate the nodes to send a reliable ignore packet to each that can leverage it
if (!nodeID.isNull() && _sessionUUID != nodeID) {
eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool {
if (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer) {
@ -811,6 +828,9 @@ void NodeList::maybeSendIgnoreSetToNode(SharedNodePointer newNode) {
// send this NLPacketList to the new node
sendPacketList(std::move(ignorePacketList), *newNode);
}
// also send them the current ignore radius state.
sendIgnoreRadiusStateToNode(newNode);
}
}

View file

@ -30,6 +30,7 @@
#include <QtNetwork/QUdpSocket>
#include <DependencyManager.h>
#include <SettingHandle.h>
#include "DomainHandler.h"
#include "LimitedNodeList.h"
@ -70,6 +71,12 @@ public:
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
void ignoreNodesInRadius(float radiusToIgnore, bool enabled = true);
float getIgnoreRadius() const { return _ignoreRadius.get(); }
bool getIgnoreRadiusEnabled() const { return _ignoreRadiusEnabled.get(); }
void toggleIgnoreRadius() { ignoreNodesInRadius(getIgnoreRadius(), !getIgnoreRadiusEnabled()); }
void enableIgnoreRadius() { ignoreNodesInRadius(getIgnoreRadius(), true); }
void disableIgnoreRadius() { ignoreNodesInRadius(getIgnoreRadius(), false); }
void ignoreNodeBySessionID(const QUuid& nodeID);
bool isIgnoringNode(const QUuid& nodeID) const;
@ -101,7 +108,7 @@ signals:
void limitOfSilentDomainCheckInsReached();
void receivedDomainServerList();
void ignoredNode(const QUuid& nodeID);
private slots:
void stopKeepalivePingTimer();
void sendPendingDSPathQuery();
@ -146,6 +153,10 @@ private:
mutable QReadWriteLock _ignoredSetLock;
tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDs;
void sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationNode);
Setting::Handle<bool> _ignoreRadiusEnabled { "IgnoreRadiusEnabled", false };
Setting::Handle<float> _ignoreRadius { "IgnoreRadius", 1.0f };
#if (PR_BUILD || DEV_BUILD)
bool _shouldSendNewerVersion { false };
#endif

View file

@ -100,7 +100,8 @@ public:
MoreEntityShapes,
NodeKickRequest,
NodeMuteRequest,
LAST_PACKET_TYPE = NodeMuteRequest
RadiusIgnoreRequest,
LAST_PACKET_TYPE = RadiusIgnoreRequest
};
};

View file

@ -38,3 +38,27 @@ bool UsersScriptingInterface::getCanKick() {
// ask the NodeList to return our ability to kick
return DependencyManager::get<NodeList>()->getThisNodeCanKick();
}
void UsersScriptingInterface::toggleIgnoreRadius() {
DependencyManager::get<NodeList>()->toggleIgnoreRadius();
}
void UsersScriptingInterface::enableIgnoreRadius() {
DependencyManager::get<NodeList>()->enableIgnoreRadius();
}
void UsersScriptingInterface::disableIgnoreRadius() {
DependencyManager::get<NodeList>()->disableIgnoreRadius();
}
void UsersScriptingInterface::setIgnoreRadius(float radius, bool enabled) {
DependencyManager::get<NodeList>()->ignoreNodesInRadius(radius, enabled);
}
float UsersScriptingInterface::getIgnoreRadius() {
return DependencyManager::get<NodeList>()->getIgnoreRadius();
}
bool UsersScriptingInterface::getIgnoreRadiusEnabled() {
return DependencyManager::get<NodeList>()->getIgnoreRadiusEnabled();
}

View file

@ -16,6 +16,9 @@
#include <DependencyManager.h>
/**jsdoc
* @namespace Users
*/
class UsersScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@ -26,12 +29,75 @@ public:
UsersScriptingInterface();
public slots:
/**jsdoc
* Ignore another user.
* @function Users.ignore
* @param {nodeID} nodeID The node or session ID of the user you want to ignore.
*/
void ignore(const QUuid& nodeID);
/**jsdoc
* Kick another user.
* @function Users.kick
* @param {nodeID} nodeID The node or session ID of the user you want to kick.
*/
void kick(const QUuid& nodeID);
/**jsdoc
* Mute another user.
* @function Users.mute
* @param {nodeID} nodeID The node or session ID of the user you want to mute.
*/
void mute(const QUuid& nodeID);
/**jsdoc
* Returns `true` if the DomainServer will allow this Node/Avatar to make kick
* @function Users.getCanKick
* @return {bool} `true` if the client can kick other users, `false` if not.
*/
bool getCanKick();
/**jsdoc
* Toggle the state of the ignore in radius feature
* @function Users.toggleIgnoreRadius
*/
void toggleIgnoreRadius();
/**jsdoc
* Enables the ignore radius feature.
* @function Users.enableIgnoreRadius
*/
void enableIgnoreRadius();
/**jsdoc
* Disables the ignore radius feature.
* @function Users.disableIgnoreRadius
*/
void disableIgnoreRadius();
/**jsdoc
* sets the parameters for the ignore radius feature.
* @function Users.setIgnoreRadius
* @param {number} radius The radius for the auto ignore in radius feature
* @param {bool} [enabled=true] Whether the ignore in radius feature should be enabled
*/
void setIgnoreRadius(float radius, bool enabled = true);
/**jsdoc
* Returns the effective radius of the ingore radius feature if it is enabled.
* @function Users.getIgnoreRadius
* @return {number} radius of the ignore feature
*/
float getIgnoreRadius();
/**jsdoc
* Returns `true` if the ignore in radius feature is enabled
* @function Users.getIgnoreRadiusEnabled
* @return {bool} `true` if the ignore in radius feature is enabled, `false` if not.
*/
bool getIgnoreRadiusEnabled();
signals:
void canKickChanged(bool canKick);
};

View file

@ -33,7 +33,8 @@ var DEFAULT_SCRIPTS = [
"system/dialTone.js",
"system/firstPersonHMD.js",
"system/snapshot.js",
"system/help.js"
"system/help.js",
"system/bubble.js"
];
// add a menu item for debugging

View file

@ -0,0 +1,275 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 200.1" style="enable-background:new 0 0 50 200.1;" xml:space="preserve">
<style type="text/css">
.st0{fill:#414042;}
.st1{fill:#FFFFFF;}
.st2{fill:#1E1E1E;}
.st3{fill:#333333;}
</style>
<g id="Layer_2">
<g>
<g>
<path class="st0" d="M50.1,146.1c0,2.2-1.8,4-4,4h-42c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V146.1z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M50,196.1c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V196.1z"/>
</g>
</g>
<g>
<g>
<path class="st1" d="M50,46c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V46z"/>
</g>
</g>
<g>
<path class="st2" d="M50,96.1c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V96.1z"/>
</g>
</g>
<g id="Layer_3">
</g>
<g>
<path class="st3" d="M24.3,19.6c-0.5,0.5-0.9,1-1.3,1.5c-0.1,0.1-0.1,0.3-0.1,0.4c0,1,0,2,0.1,3c0,0.4-0.2,0.7-0.7,0.8
c-0.4,0-0.8-0.2-0.8-0.7c-0.1-1.3-0.1-2.5-0.2-3.8c0-0.2,0.1-0.4,0.2-0.6c0.7-0.9,1.4-1.7,2-2.6c0.3-0.4,1-0.9,1.5-0.9
c0.2,0,0.6,0,0.8,0c0.5,0,0.8,0.1,1.1,0.6c0.5,0.7,0.9,1.4,1.4,2.1c0.4,0.7,0.8,1,1.7,1.2c0.6,0.1,1.3,0.3,1.9,0.5
c0.2,0,0.3,0.1,0.5,0.2c0.3,0.2,0.4,0.5,0.3,0.8c-0.1,0.3-0.3,0.4-0.6,0.4c-0.2,0-0.5,0-0.7-0.1c-0.8-0.2-1.6-0.4-2.4-0.6
c-0.5-0.1-0.8-0.4-1.2-0.7c-0.2-0.2-0.3-0.3-0.5-0.5c0,0.2,0,0.3,0,0.4c0,0.7,0,1.4-0.1,2.1c0,0.2-0.2,6.4-0.3,8.9
c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.4-0.4,0.6-0.9,0.6c-0.4,0-0.8-0.3-0.9-0.7c-0.1-0.3-0.1-0.6-0.1-1c0-2.7-0.4-6.5-0.5-7
c0-0.5-0.1-0.6-0.1-1.2c-0.1-0.3-0.1-0.5-0.1-0.7C24.2,21.8,24.3,20.8,24.3,19.6z"/>
<path class="st3" d="M27.1,14.7c0,0.7-0.6,1.3-1.4,1.3l-0.3,0c-0.7,0-1.3-0.6-1.3-1.4l0-1.3c0-0.7,0.6-1.3,1.4-1.3l0.3,0
c0.7,0,1.3,0.6,1.3,1.4L27.1,14.7z"/>
</g>
<path class="st3" d="M22,31.5L22,31.5L22,31.5c-0.1,0-0.2,0-0.4-0.1c-2.2-0.7-4.2-2.1-5.7-3.9c-0.5-0.5-0.4-1.4,0.2-1.8
c0.2-0.2,0.5-0.3,0.9-0.3c0.4,0,0.7,0.2,1,0.5c0.6,0.7,1.3,1.4,2.1,1.9c0.8,0.5,1.6,0.9,2.5,1.2l0,0c0.3,0.1,0.6,0.3,0.7,0.6
c0.2,0.3,0.2,0.7,0.1,1c-0.1,0.3-0.3,0.5-0.5,0.7C22.5,31.5,22.2,31.6,22,31.5z"/>
<path class="st3" d="M29.5,31.3c-0.5,0-1-0.3-1.2-0.8c-0.1-0.3-0.1-0.7,0-1s0.4-0.6,0.7-0.7c0.8-0.3,1.5-0.7,2.1-1.2
c0.8-0.6,1.6-1.4,2.2-2.2l0,0c0.2-0.3,0.7-0.5,1.1-0.5c0.3,0,0.5,0.1,0.7,0.2c0.3,0.2,0.5,0.5,0.5,0.8c0.1,0.3,0,0.7-0.2,1
c-0.8,1.1-1.7,2-2.8,2.8c-0.8,0.6-1.7,1.1-2.7,1.5C29.9,31.3,29.7,31.3,29.5,31.3z"/>
<path class="st3" d="M14.9,24.7c-0.3,0-0.5-0.1-0.7-0.2c-0.2-0.2-0.4-0.4-0.5-0.6c-0.2-0.7,0.1-1.4,0.8-1.7c0.2-0.1,0.3-0.1,0.5-0.1
c0.3,0,0.5,0.1,0.7,0.2c0.2,0.2,0.4,0.4,0.5,0.6c0.1,0.3,0.1,0.7,0,1c-0.1,0.3-0.4,0.5-0.7,0.7C15.2,24.7,15,24.7,14.9,24.7z"/>
<path class="st3" d="M36.1,24L36.1,24L36.1,24c-0.1,0-0.2,0-0.3-0.1c-0.3-0.1-0.6-0.3-0.8-0.6c-0.2-0.3-0.2-0.6-0.1-1
c0.2-0.6,0.7-0.9,1.3-0.9c0.1,0,0.2,0,0.3,0.1c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1C37.2,23.6,36.7,24,36.1,24z"/>
<path class="st3" d="M14.2,21c-0.3,0-0.7-0.1-0.9-0.4c-0.2-0.2-0.4-0.6-0.4-0.9c0-0.1,0-0.2,0-0.4c0.1-2.2,0.7-4.4,1.9-6.3
c0.1-0.2,0.3-0.4,0.5-0.5c0.2-0.1,0.4-0.2,0.6-0.1c0.2,0,0.5,0.1,0.6,0.2c0.6,0.4,0.8,1.2,0.4,1.8c-0.9,1.5-1.5,3.2-1.5,5
c0,0.1,0,0.2,0,0.3c0,0.3-0.1,0.7-0.4,0.9C14.9,20.8,14.6,21,14.2,21C14.2,21,14.2,21,14.2,21z"/>
<path class="st3" d="M36.5,20.2c-0.3,0-0.6-0.1-0.9-0.4c-0.2-0.2-0.4-0.5-0.4-0.8c-0.1-0.9-0.2-1.8-0.6-2.7
c-0.3-0.9-0.8-1.7-1.3-2.5l0,0c-0.2-0.3-0.3-0.6-0.2-1c0.1-0.3,0.2-0.6,0.5-0.8c0.2-0.2,0.5-0.3,0.8-0.2c0.4,0,0.8,0.2,1,0.5
c0,0,0,0,0,0l0,0c1.4,1.9,2.2,4.2,2.4,6.5c0,0.3-0.1,0.7-0.3,0.9c-0.2,0.3-0.5,0.4-0.9,0.4C36.6,20.2,36.6,20.2,36.5,20.2z"/>
<path class="st3" d="M18.5,12.1c-0.4,0-0.7-0.2-1-0.5c-0.2-0.3-0.3-0.6-0.3-1c0-0.3,0.2-0.6,0.5-0.9c0.2-0.2,0.5-0.3,0.8-0.3
c0.4,0,0.7,0.2,1,0.5c0.2,0.3,0.3,0.6,0.3,1c0,0.3-0.2,0.6-0.5,0.9C19.1,12,18.8,12.1,18.5,12.1z"/>
<path class="st3" d="M31.6,11.7c-0.2,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.5-0.5-0.8c-0.1-0.3,0-0.7,0.2-1c0.2-0.4,0.7-0.6,1.1-0.6
c0.2,0,0.5,0.1,0.7,0.2c0.6,0.4,0.7,1.2,0.3,1.8C32.5,11.5,32.1,11.7,31.6,11.7z"/>
<path class="st3" d="M21.9,10.3c-0.5,0-1-0.4-1.2-0.9c-0.1-0.3-0.1-0.7,0.1-1c0.2-0.3,0.4-0.5,0.7-0.6c1.4-0.4,2.8-0.7,4.2-0.6
c0.9,0,1.8,0.1,2.7,0.4c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1c-0.1,0.3-0.2,0.5-0.5,0.7c-0.3,0.2-0.7,0.3-1.1,0.2
c-0.7-0.2-1.4-0.3-2.2-0.3c-1.1,0-2.3,0.1-3.3,0.5C22.2,10.3,22,10.3,21.9,10.3z"/>
<g>
<path class="st3" d="M13.8,40.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1H8.6v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C13.7,40.1,13.8,40.4,13.8,40.8z M9.9,37.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H9.9z M12.5,40.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1H9.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S12.5,40.7,12.5,40.6z"/>
<path class="st3" d="M17.7,41.4c0.3,0,0.5-0.1,0.7-0.2s0.4-0.3,0.5-0.5c0.1-0.2,0.2-0.4,0.3-0.7s0.1-0.5,0.1-0.8v-3.3h1.2v3.3
c0,0.4-0.1,0.8-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1c-0.2,0.3-0.5,0.5-0.9,0.7c-0.4,0.2-0.8,0.3-1.3,0.3c-0.5,0-0.9-0.1-1.3-0.3
c-0.4-0.2-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3h1.2v3.3c0,0.3,0,0.5,0.1,0.8
c0.1,0.2,0.1,0.5,0.3,0.7s0.3,0.3,0.5,0.5S17.4,41.4,17.7,41.4z"/>
<path class="st3" d="M27.1,40.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C27,40.1,27.1,40.4,27.1,40.8z M23.2,37.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H23.2z M25.8,40.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7H25c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S25.8,40.7,25.8,40.6z"/>
<path class="st3" d="M33.4,40.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C33.3,40.1,33.4,40.4,33.4,40.8z M29.5,37.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H29.5z M32.2,40.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S32.2,40.7,32.2,40.6z"/>
<path class="st3" d="M34.6,42.5v-6.4h1.2v5.3h3.3v1.1H34.6z"/>
<path class="st3" d="M44.6,41.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H44.6z"/>
</g>
<g>
<path class="st1" d="M24.3,69.6c-0.5,0.5-0.9,1-1.3,1.5c-0.1,0.1-0.1,0.3-0.1,0.4c0,1,0,2,0.1,3c0,0.4-0.2,0.7-0.7,0.8
c-0.4,0-0.8-0.2-0.8-0.7c-0.1-1.3-0.1-2.5-0.2-3.8c0-0.2,0.1-0.4,0.2-0.6c0.7-0.9,1.4-1.7,2-2.6c0.3-0.4,1-0.9,1.5-0.9
c0.2,0,0.6,0,0.8,0c0.5,0,0.8,0.1,1.1,0.6c0.5,0.7,0.9,1.4,1.4,2.1c0.4,0.7,0.8,1,1.7,1.2c0.6,0.1,1.3,0.3,1.9,0.5
c0.2,0,0.3,0.1,0.5,0.2c0.3,0.2,0.4,0.5,0.3,0.8c-0.1,0.3-0.3,0.4-0.6,0.4c-0.2,0-0.5,0-0.7-0.1c-0.8-0.2-1.6-0.4-2.4-0.6
c-0.5-0.1-0.8-0.4-1.2-0.7c-0.2-0.2-0.3-0.3-0.5-0.5c0,0.2,0,0.3,0,0.4c0,0.7,0,1.4-0.1,2.1c0,0.2-0.2,6.4-0.3,8.9
c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.4-0.4,0.6-0.9,0.6c-0.4,0-0.8-0.3-0.9-0.7c-0.1-0.3-0.1-0.6-0.1-1c0-2.7-0.4-6.5-0.5-7
c0-0.5-0.1-0.6-0.1-1.2c-0.1-0.3-0.1-0.5-0.1-0.7C24.2,71.8,24.3,70.8,24.3,69.6z"/>
<path class="st1" d="M27.1,64.7c0,0.7-0.6,1.3-1.4,1.3l-0.3,0c-0.7,0-1.3-0.6-1.3-1.4l0-1.3c0-0.7,0.6-1.3,1.4-1.3l0.3,0
c0.7,0,1.3,0.6,1.3,1.4L27.1,64.7z"/>
</g>
<path class="st1" d="M22,81.5L22,81.5L22,81.5c-0.1,0-0.2,0-0.4-0.1c-2.2-0.7-4.2-2.1-5.7-3.9c-0.5-0.5-0.4-1.4,0.2-1.8
c0.2-0.2,0.5-0.3,0.9-0.3c0.4,0,0.7,0.2,1,0.5c0.6,0.7,1.3,1.4,2.1,1.9c0.8,0.5,1.6,0.9,2.5,1.2l0,0c0.3,0.1,0.6,0.3,0.7,0.6
c0.2,0.3,0.2,0.7,0.1,1c-0.1,0.3-0.3,0.5-0.5,0.7C22.5,81.5,22.2,81.6,22,81.5z"/>
<path class="st1" d="M29.5,81.3c-0.5,0-1-0.3-1.2-0.8c-0.1-0.3-0.1-0.7,0-1s0.4-0.6,0.7-0.7c0.8-0.3,1.5-0.7,2.1-1.2
c0.8-0.6,1.6-1.4,2.2-2.2l0,0c0.2-0.3,0.7-0.5,1.1-0.5c0.3,0,0.5,0.1,0.7,0.2c0.3,0.2,0.5,0.5,0.5,0.8c0.1,0.3,0,0.7-0.2,1
c-0.8,1.1-1.7,2-2.8,2.8c-0.8,0.6-1.7,1.1-2.7,1.5C29.9,81.3,29.7,81.3,29.5,81.3z"/>
<path class="st1" d="M14.9,74.7c-0.3,0-0.5-0.1-0.7-0.2c-0.2-0.2-0.4-0.4-0.5-0.6c-0.2-0.7,0.1-1.4,0.8-1.7c0.2-0.1,0.3-0.1,0.5-0.1
c0.3,0,0.5,0.1,0.7,0.2c0.2,0.2,0.4,0.4,0.5,0.6c0.1,0.3,0.1,0.7,0,1c-0.1,0.3-0.4,0.5-0.7,0.7C15.2,74.7,15,74.7,14.9,74.7z"/>
<path class="st1" d="M36.1,74L36.1,74L36.1,74c-0.1,0-0.2,0-0.3-0.1c-0.3-0.1-0.6-0.3-0.8-0.6c-0.2-0.3-0.2-0.6-0.1-1
c0.2-0.6,0.7-0.9,1.3-0.9c0.1,0,0.2,0,0.3,0.1c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1C37.2,73.6,36.7,74,36.1,74z"/>
<path class="st1" d="M14.2,71c-0.3,0-0.7-0.1-0.9-0.4c-0.2-0.2-0.4-0.6-0.4-0.9c0-0.1,0-0.2,0-0.4c0.1-2.2,0.7-4.4,1.9-6.3
c0.1-0.2,0.3-0.4,0.5-0.5c0.2-0.1,0.4-0.2,0.6-0.1c0.2,0,0.5,0.1,0.6,0.2c0.6,0.4,0.8,1.2,0.4,1.8c-0.9,1.5-1.5,3.2-1.5,5
c0,0.1,0,0.2,0,0.3c0,0.3-0.1,0.7-0.4,0.9C14.9,70.8,14.6,71,14.2,71C14.2,71,14.2,71,14.2,71z"/>
<path class="st1" d="M36.5,70.2c-0.3,0-0.6-0.1-0.9-0.4c-0.2-0.2-0.4-0.5-0.4-0.8c-0.1-0.9-0.2-1.8-0.6-2.7
c-0.3-0.9-0.8-1.7-1.3-2.5l0,0c-0.2-0.3-0.3-0.6-0.2-1c0.1-0.3,0.2-0.6,0.5-0.8c0.2-0.2,0.5-0.3,0.8-0.2c0.4,0,0.8,0.2,1,0.5
c0,0,0,0,0,0l0,0c1.4,1.9,2.2,4.2,2.4,6.5c0,0.3-0.1,0.7-0.3,0.9c-0.2,0.3-0.5,0.4-0.9,0.4C36.6,70.2,36.6,70.2,36.5,70.2z"/>
<path class="st1" d="M18.5,62.1c-0.4,0-0.7-0.2-1-0.5c-0.2-0.3-0.3-0.6-0.3-1c0-0.3,0.2-0.6,0.5-0.9c0.2-0.2,0.5-0.3,0.8-0.3
c0.4,0,0.7,0.2,1,0.5c0.2,0.3,0.3,0.6,0.3,1c0,0.3-0.2,0.6-0.5,0.9C19.1,62,18.8,62.1,18.5,62.1z"/>
<path class="st1" d="M31.6,61.7c-0.2,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.5-0.5-0.8s0-0.7,0.2-1c0.2-0.4,0.7-0.6,1.1-0.6
c0.2,0,0.5,0.1,0.7,0.2c0.6,0.4,0.7,1.2,0.3,1.8C32.5,61.5,32.1,61.7,31.6,61.7z"/>
<path class="st1" d="M21.9,60.3c-0.5,0-1-0.4-1.2-0.9c-0.1-0.3-0.1-0.7,0.1-1c0.2-0.3,0.4-0.5,0.7-0.6c1.4-0.4,2.8-0.7,4.2-0.6
c0.9,0,1.8,0.1,2.7,0.4c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1c-0.1,0.3-0.2,0.5-0.5,0.7c-0.3,0.2-0.7,0.3-1.1,0.2
c-0.7-0.2-1.4-0.3-2.2-0.3c-1.1,0-2.3,0.1-3.3,0.5C22.2,60.3,22,60.3,21.9,60.3z"/>
<g>
<path class="st1" d="M13.8,90.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1H8.6v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C13.7,90.1,13.8,90.4,13.8,90.8z M9.9,87.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H9.9z M12.5,90.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1H9.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S12.5,90.7,12.5,90.6z"/>
<path class="st1" d="M17.7,91.4c0.3,0,0.5-0.1,0.7-0.2s0.4-0.3,0.5-0.5c0.1-0.2,0.2-0.4,0.3-0.7s0.1-0.5,0.1-0.8v-3.3h1.2v3.3
c0,0.4-0.1,0.8-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1c-0.2,0.3-0.5,0.5-0.9,0.7c-0.4,0.2-0.8,0.3-1.3,0.3c-0.5,0-0.9-0.1-1.3-0.3
c-0.4-0.2-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3h1.2v3.3c0,0.3,0,0.5,0.1,0.8
c0.1,0.2,0.1,0.5,0.3,0.7s0.3,0.3,0.5,0.5S17.4,91.4,17.7,91.4z"/>
<path class="st1" d="M27.1,90.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C27,90.1,27.1,90.4,27.1,90.8z M23.2,87.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H23.2z M25.8,90.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7H25c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S25.8,90.7,25.8,90.6z"/>
<path class="st1" d="M33.4,90.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C33.3,90.1,33.4,90.4,33.4,90.8z M29.5,87.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H29.5z M32.2,90.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S32.2,90.7,32.2,90.6z"/>
<path class="st1" d="M34.6,92.5v-6.4h1.2v5.3h3.3v1.1H34.6z"/>
<path class="st1" d="M44.6,91.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H44.6z"/>
</g>
<g>
<path class="st1" d="M24.3,119.6c-0.5,0.5-0.9,1-1.3,1.5c-0.1,0.1-0.1,0.3-0.1,0.4c0,1,0,2,0.1,3c0,0.4-0.2,0.7-0.7,0.8
c-0.4,0-0.8-0.2-0.8-0.7c-0.1-1.3-0.1-2.5-0.2-3.8c0-0.2,0.1-0.4,0.2-0.6c0.7-0.9,1.4-1.7,2-2.6c0.3-0.4,1-0.9,1.5-0.9
c0.2,0,0.6,0,0.8,0c0.5,0,0.8,0.1,1.1,0.6c0.5,0.7,0.9,1.4,1.4,2.1c0.4,0.7,0.8,1,1.7,1.2c0.6,0.1,1.3,0.3,1.9,0.5
c0.2,0,0.3,0.1,0.5,0.2c0.3,0.2,0.4,0.5,0.3,0.8c-0.1,0.3-0.3,0.4-0.6,0.4c-0.2,0-0.5,0-0.7-0.1c-0.8-0.2-1.6-0.4-2.4-0.6
c-0.5-0.1-0.8-0.4-1.2-0.7c-0.2-0.2-0.3-0.3-0.5-0.5c0,0.2,0,0.3,0,0.4c0,0.7,0,1.4-0.1,2.1c0,0.2-0.2,6.4-0.3,8.9
c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.4-0.4,0.6-0.9,0.6c-0.4,0-0.8-0.3-0.9-0.7c-0.1-0.3-0.1-0.6-0.1-1c0-2.7-0.4-6.5-0.5-7
c0-0.5-0.1-0.6-0.1-1.2c-0.1-0.3-0.1-0.5-0.1-0.7C24.2,121.8,24.3,120.8,24.3,119.6z"/>
<path class="st1" d="M27.1,114.7c0,0.7-0.6,1.3-1.4,1.3l-0.3,0c-0.7,0-1.3-0.6-1.3-1.4l0-1.3c0-0.7,0.6-1.3,1.4-1.3l0.3,0
c0.7,0,1.3,0.6,1.3,1.4L27.1,114.7z"/>
</g>
<path class="st1" d="M22,131.5L22,131.5L22,131.5c-0.1,0-0.2,0-0.4-0.1c-2.2-0.7-4.2-2.1-5.7-3.9c-0.5-0.5-0.4-1.4,0.2-1.8
c0.2-0.2,0.5-0.3,0.9-0.3c0.4,0,0.7,0.2,1,0.5c0.6,0.7,1.3,1.4,2.1,1.9c0.8,0.5,1.6,0.9,2.5,1.2l0,0c0.3,0.1,0.6,0.3,0.7,0.6
c0.2,0.3,0.2,0.7,0.1,1c-0.1,0.3-0.3,0.5-0.5,0.7C22.5,131.5,22.2,131.6,22,131.5z"/>
<path class="st1" d="M29.5,131.3c-0.5,0-1-0.3-1.2-0.8c-0.1-0.3-0.1-0.7,0-1c0.1-0.3,0.4-0.6,0.7-0.7c0.8-0.3,1.5-0.7,2.1-1.2
c0.8-0.6,1.6-1.4,2.2-2.2l0,0c0.2-0.3,0.7-0.5,1.1-0.5c0.3,0,0.5,0.1,0.7,0.2c0.3,0.2,0.5,0.5,0.5,0.8c0.1,0.3,0,0.7-0.2,1
c-0.8,1.1-1.7,2-2.8,2.8c-0.8,0.6-1.7,1.1-2.7,1.5C29.9,131.3,29.7,131.3,29.5,131.3z"/>
<path class="st1" d="M14.9,124.7c-0.3,0-0.5-0.1-0.7-0.2c-0.2-0.2-0.4-0.4-0.5-0.6c-0.2-0.7,0.1-1.4,0.8-1.7
c0.2-0.1,0.3-0.1,0.5-0.1c0.3,0,0.5,0.1,0.7,0.2c0.2,0.2,0.4,0.4,0.5,0.6c0.1,0.3,0.1,0.7,0,1c-0.1,0.3-0.4,0.5-0.7,0.7
C15.2,124.7,15,124.7,14.9,124.7z"/>
<path class="st1" d="M36.1,124L36.1,124L36.1,124c-0.1,0-0.2,0-0.3-0.1c-0.3-0.1-0.6-0.3-0.8-0.6c-0.2-0.3-0.2-0.6-0.1-1
c0.2-0.6,0.7-0.9,1.3-0.9c0.1,0,0.2,0,0.3,0.1c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1C37.2,123.6,36.7,124,36.1,124z"/>
<path class="st1" d="M14.2,121c-0.3,0-0.7-0.1-0.9-0.4c-0.2-0.2-0.4-0.6-0.4-0.9c0-0.1,0-0.2,0-0.4c0.1-2.2,0.7-4.4,1.9-6.3
c0.1-0.2,0.3-0.4,0.5-0.5c0.2-0.1,0.4-0.2,0.6-0.1c0.2,0,0.5,0.1,0.6,0.2c0.6,0.4,0.8,1.2,0.4,1.8c-0.9,1.5-1.5,3.2-1.5,5
c0,0.1,0,0.2,0,0.3c0,0.3-0.1,0.7-0.4,0.9C14.9,120.8,14.6,121,14.2,121C14.2,121,14.2,121,14.2,121z"/>
<path class="st1" d="M36.5,120.2c-0.3,0-0.6-0.1-0.9-0.4c-0.2-0.2-0.4-0.5-0.4-0.8c-0.1-0.9-0.2-1.8-0.6-2.7
c-0.3-0.9-0.8-1.7-1.3-2.5l0,0c-0.2-0.3-0.3-0.6-0.2-1c0.1-0.3,0.2-0.6,0.5-0.8c0.2-0.2,0.5-0.3,0.8-0.2c0.4,0,0.8,0.2,1,0.5
c0,0,0,0,0,0l0,0c1.4,1.9,2.2,4.2,2.4,6.5c0,0.3-0.1,0.7-0.3,0.9c-0.2,0.3-0.5,0.4-0.9,0.4C36.6,120.2,36.6,120.2,36.5,120.2z"/>
<path class="st1" d="M18.5,112.1c-0.4,0-0.7-0.2-1-0.5c-0.2-0.3-0.3-0.6-0.3-1c0-0.3,0.2-0.6,0.5-0.9c0.2-0.2,0.5-0.3,0.8-0.3
c0.4,0,0.7,0.2,1,0.5c0.2,0.3,0.3,0.6,0.3,1c0,0.3-0.2,0.6-0.5,0.9C19.1,112,18.8,112.1,18.5,112.1z"/>
<path class="st1" d="M31.6,111.7c-0.2,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.5-0.5-0.8s0-0.7,0.2-1c0.2-0.4,0.7-0.6,1.1-0.6
c0.2,0,0.5,0.1,0.7,0.2c0.6,0.4,0.7,1.2,0.3,1.8C32.5,111.5,32.1,111.7,31.6,111.7z"/>
<path class="st1" d="M21.9,110.3c-0.5,0-1-0.4-1.2-0.9c-0.1-0.3-0.1-0.7,0.1-1c0.2-0.3,0.4-0.5,0.7-0.6c1.4-0.4,2.8-0.7,4.2-0.6
c0.9,0,1.8,0.1,2.7,0.4c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1c-0.1,0.3-0.2,0.5-0.5,0.7c-0.3,0.2-0.7,0.3-1.1,0.2
c-0.7-0.2-1.4-0.3-2.2-0.3c-1.1,0-2.3,0.1-3.3,0.5C22.2,110.3,22,110.3,21.9,110.3z"/>
<g>
<path class="st1" d="M13.8,140.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1H8.6v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C13.7,140.1,13.8,140.4,13.8,140.8z M9.9,137.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H9.9z M12.5,140.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1H9.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S12.5,140.7,12.5,140.6z"/>
<path class="st1" d="M17.7,141.4c0.3,0,0.5-0.1,0.7-0.2s0.4-0.3,0.5-0.5c0.1-0.2,0.2-0.4,0.3-0.7s0.1-0.5,0.1-0.8v-3.3h1.2v3.3
c0,0.4-0.1,0.8-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1c-0.2,0.3-0.5,0.5-0.9,0.7c-0.4,0.2-0.8,0.3-1.3,0.3c-0.5,0-0.9-0.1-1.3-0.3
c-0.4-0.2-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3h1.2v3.3c0,0.3,0,0.5,0.1,0.8
c0.1,0.2,0.1,0.5,0.3,0.7s0.3,0.3,0.5,0.5S17.4,141.4,17.7,141.4z"/>
<path class="st1" d="M27.1,140.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C27,140.1,27.1,140.4,27.1,140.8z M23.2,137.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H23.2z M25.8,140.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7H25c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S25.8,140.7,25.8,140.6z"/>
<path class="st1" d="M33.4,140.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C33.3,140.1,33.4,140.4,33.4,140.8z M29.5,137.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H29.5z M32.2,140.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S32.2,140.7,32.2,140.6z"/>
<path class="st1" d="M34.6,142.5v-6.4h1.2v5.3h3.3v1.1H34.6z"/>
<path class="st1" d="M44.6,141.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H44.6z"/>
</g>
<g>
<path class="st1" d="M24.3,169.6c-0.5,0.5-0.9,1-1.3,1.5c-0.1,0.1-0.1,0.3-0.1,0.4c0,1,0,2,0.1,3c0,0.4-0.2,0.7-0.7,0.8
c-0.4,0-0.8-0.2-0.8-0.7c-0.1-1.3-0.1-2.5-0.2-3.8c0-0.2,0.1-0.4,0.2-0.6c0.7-0.9,1.4-1.7,2-2.6c0.3-0.4,1-0.9,1.5-0.9
c0.2,0,0.6,0,0.8,0c0.5,0,0.8,0.1,1.1,0.6c0.5,0.7,0.9,1.4,1.4,2.1c0.4,0.7,0.8,1,1.7,1.2c0.6,0.1,1.3,0.3,1.9,0.5
c0.2,0,0.3,0.1,0.5,0.2c0.3,0.2,0.4,0.5,0.3,0.8c-0.1,0.3-0.3,0.4-0.6,0.4c-0.2,0-0.5,0-0.7-0.1c-0.8-0.2-1.6-0.4-2.4-0.6
c-0.5-0.1-0.8-0.4-1.2-0.7c-0.2-0.2-0.3-0.3-0.5-0.5c0,0.2,0,0.3,0,0.4c0,0.7,0,1.4-0.1,2.1c0,0.2-0.2,6.4-0.3,8.9
c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.4-0.4,0.6-0.9,0.6c-0.4,0-0.8-0.3-0.9-0.7c-0.1-0.3-0.1-0.6-0.1-1c0-2.7-0.4-6.5-0.5-7
c0-0.5-0.1-0.6-0.1-1.2c-0.1-0.3-0.1-0.5-0.1-0.7C24.2,171.8,24.3,170.8,24.3,169.6z"/>
<path class="st1" d="M27.1,164.7c0,0.7-0.6,1.3-1.4,1.3l-0.3,0c-0.7,0-1.3-0.6-1.3-1.4l0-1.3c0-0.7,0.6-1.3,1.4-1.3l0.3,0
c0.7,0,1.3,0.6,1.3,1.4L27.1,164.7z"/>
</g>
<path class="st1" d="M22,181.5L22,181.5L22,181.5c-0.1,0-0.2,0-0.4-0.1c-2.2-0.7-4.2-2.1-5.7-3.9c-0.5-0.5-0.4-1.4,0.2-1.8
c0.2-0.2,0.5-0.3,0.9-0.3c0.4,0,0.7,0.2,1,0.5c0.6,0.7,1.3,1.4,2.1,1.9c0.8,0.5,1.6,0.9,2.5,1.2l0,0c0.3,0.1,0.6,0.3,0.7,0.6
c0.2,0.3,0.2,0.7,0.1,1c-0.1,0.3-0.3,0.5-0.5,0.7C22.5,181.5,22.2,181.6,22,181.5z"/>
<path class="st1" d="M29.5,181.3c-0.5,0-1-0.3-1.2-0.8c-0.1-0.3-0.1-0.7,0-1c0.1-0.3,0.4-0.6,0.7-0.7c0.8-0.3,1.5-0.7,2.1-1.2
c0.8-0.6,1.6-1.4,2.2-2.2l0,0c0.2-0.3,0.7-0.5,1.1-0.5c0.3,0,0.5,0.1,0.7,0.2c0.3,0.2,0.5,0.5,0.5,0.8c0.1,0.3,0,0.7-0.2,1
c-0.8,1.1-1.7,2-2.8,2.8c-0.8,0.6-1.7,1.1-2.7,1.5C29.9,181.3,29.7,181.3,29.5,181.3z"/>
<path class="st1" d="M14.9,174.7c-0.3,0-0.5-0.1-0.7-0.2c-0.2-0.2-0.4-0.4-0.5-0.6c-0.2-0.7,0.1-1.4,0.8-1.7
c0.2-0.1,0.3-0.1,0.5-0.1c0.3,0,0.5,0.1,0.7,0.2c0.2,0.2,0.4,0.4,0.5,0.6c0.1,0.3,0.1,0.7,0,1c-0.1,0.3-0.4,0.5-0.7,0.7
C15.2,174.7,15,174.7,14.9,174.7z"/>
<path class="st1" d="M36.1,174L36.1,174L36.1,174c-0.1,0-0.2,0-0.3-0.1c-0.3-0.1-0.6-0.3-0.8-0.6c-0.2-0.3-0.2-0.6-0.1-1
c0.2-0.6,0.7-0.9,1.3-0.9c0.1,0,0.2,0,0.3,0.1c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1C37.2,173.6,36.7,174,36.1,174z"/>
<path class="st1" d="M14.2,171c-0.3,0-0.7-0.1-0.9-0.4c-0.2-0.2-0.4-0.6-0.4-0.9c0-0.1,0-0.2,0-0.4c0.1-2.2,0.7-4.4,1.9-6.3
c0.1-0.2,0.3-0.4,0.5-0.5c0.2-0.1,0.4-0.2,0.6-0.1c0.2,0,0.5,0.1,0.6,0.2c0.6,0.4,0.8,1.2,0.4,1.8c-0.9,1.5-1.5,3.2-1.5,5
c0,0.1,0,0.2,0,0.3c0,0.3-0.1,0.7-0.4,0.9C14.9,170.8,14.6,171,14.2,171C14.2,171,14.2,171,14.2,171z"/>
<path class="st1" d="M36.5,170.2c-0.3,0-0.6-0.1-0.9-0.4c-0.2-0.2-0.4-0.5-0.4-0.8c-0.1-0.9-0.2-1.8-0.6-2.7
c-0.3-0.9-0.8-1.7-1.3-2.5l0,0c-0.2-0.3-0.3-0.6-0.2-1c0.1-0.3,0.2-0.6,0.5-0.8c0.2-0.2,0.5-0.3,0.8-0.2c0.4,0,0.8,0.2,1,0.5
c0,0,0,0,0,0l0,0c1.4,1.9,2.2,4.2,2.4,6.5c0,0.3-0.1,0.7-0.3,0.9c-0.2,0.3-0.5,0.4-0.9,0.4C36.6,170.2,36.6,170.2,36.5,170.2z"/>
<path class="st1" d="M18.5,162.1c-0.4,0-0.7-0.2-1-0.5c-0.2-0.3-0.3-0.6-0.3-1c0-0.3,0.2-0.6,0.5-0.9c0.2-0.2,0.5-0.3,0.8-0.3
c0.4,0,0.7,0.2,1,0.5c0.2,0.3,0.3,0.6,0.3,1c0,0.3-0.2,0.6-0.5,0.9C19.1,162,18.8,162.1,18.5,162.1z"/>
<path class="st1" d="M31.6,161.7c-0.2,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.5-0.5-0.8s0-0.7,0.2-1c0.2-0.4,0.7-0.6,1.1-0.6
c0.2,0,0.5,0.1,0.7,0.2c0.6,0.4,0.7,1.2,0.3,1.8C32.5,161.5,32.1,161.7,31.6,161.7z"/>
<path class="st1" d="M21.9,160.3c-0.5,0-1-0.4-1.2-0.9c-0.1-0.3-0.1-0.7,0.1-1c0.2-0.3,0.4-0.5,0.7-0.6c1.4-0.4,2.8-0.7,4.2-0.6
c0.9,0,1.8,0.1,2.7,0.4c0.3,0.1,0.6,0.3,0.8,0.6c0.2,0.3,0.2,0.6,0.1,1c-0.1,0.3-0.2,0.5-0.5,0.7c-0.3,0.2-0.7,0.3-1.1,0.2
c-0.7-0.2-1.4-0.3-2.2-0.3c-1.1,0-2.3,0.1-3.3,0.5C22.2,160.3,22,160.3,21.9,160.3z"/>
<g>
<path class="st1" d="M13.8,190.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1H8.6v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C13.7,190.1,13.8,190.4,13.8,190.8z M9.9,187.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H9.9z M12.5,190.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1H9.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S12.5,190.7,12.5,190.6z"/>
<path class="st1" d="M17.7,191.4c0.3,0,0.5-0.1,0.7-0.2s0.4-0.3,0.5-0.5c0.1-0.2,0.2-0.4,0.3-0.7s0.1-0.5,0.1-0.8v-3.3h1.2v3.3
c0,0.4-0.1,0.8-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1c-0.2,0.3-0.5,0.5-0.9,0.7c-0.4,0.2-0.8,0.3-1.3,0.3c-0.5,0-0.9-0.1-1.3-0.3
c-0.4-0.2-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3h1.2v3.3c0,0.3,0,0.5,0.1,0.8
c0.1,0.2,0.1,0.5,0.3,0.7s0.3,0.3,0.5,0.5S17.4,191.4,17.7,191.4z"/>
<path class="st1" d="M27.1,190.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C27,190.1,27.1,190.4,27.1,190.8z M23.2,187.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H23.2z M25.8,190.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7H25c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S25.8,190.7,25.8,190.6z"/>
<path class="st1" d="M33.4,190.8c0,0.3-0.1,0.5-0.2,0.7c-0.1,0.2-0.3,0.4-0.4,0.5c-0.2,0.1-0.4,0.2-0.7,0.3
c-0.2,0.1-0.5,0.1-0.8,0.1h-3.1v-6.4h3.4c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.3,0.2,0.5,0.4s0.2,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6
c0,0.3-0.1,0.6-0.2,0.9c-0.2,0.3-0.4,0.5-0.7,0.6c0.4,0.1,0.7,0.3,0.9,0.6C33.3,190.1,33.4,190.4,33.4,190.8z M29.5,187.1v1.6h1.7
c0.2,0,0.4-0.1,0.5-0.2c0.1-0.1,0.2-0.3,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6c-0.1-0.1-0.3-0.2-0.5-0.2H29.5z M32.2,190.6
c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.1-0.2-0.2s-0.2-0.1-0.3-0.1h-1.9v1.7h1.8c0.1,0,0.2,0,0.3-0.1
c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.1-0.2,0.2-0.3S32.2,190.7,32.2,190.6z"/>
<path class="st1" d="M34.6,192.5v-6.4h1.2v5.3h3.3v1.1H34.6z"/>
<path class="st1" d="M44.6,191.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H44.6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

58
scripts/system/bubble.js Normal file
View file

@ -0,0 +1,58 @@
"use strict";
//
// bubble.js
// scripts/system/
//
// Created by Brad Hefta-Gaub on 11/18/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/* global Toolbars, Script, Users, Overlays, AvatarList, Controller, Camera, getControllerWorldLocation */
(function() { // BEGIN LOCAL_SCOPE
// grab the toolbar
var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system");
var ASSETS_PATH = Script.resolvePath("assets");
var TOOLS_PATH = Script.resolvePath("assets/images/tools/");
function buttonImageURL() {
return TOOLS_PATH + 'bubble.svg';
}
var bubbleActive = Users.getIgnoreRadiusEnabled();
// setup the mod button and add it to the toolbar
var button = toolbar.addButton({
objectName: 'bubble',
imageURL: buttonImageURL(),
visible: true,
buttonState: bubbleActive ? 0 : 1,
defaultState: bubbleActive ? 0 : 1,
hoverState: bubbleActive ? 2 : 3,
alpha: 0.9
});
// handle clicks on the toolbar button
function buttonClicked(){
Users.toggleIgnoreRadius();
bubbleActive = Users.getIgnoreRadiusEnabled();
button.writeProperty('buttonState', bubbleActive ? 0 : 1);
button.writeProperty('defaultState', bubbleActive ? 0 : 1);
button.writeProperty('hoverState', bubbleActive ? 2 : 3);
}
button.clicked.connect(buttonClicked);
// cleanup the toolbar button and overlays when script is stopped
Script.scriptEnding.connect(function() {
toolbar.removeButton('bubble');
});
}()); // END LOCAL_SCOPE