grunt-svgmin - how to remove fill="none" - svg

I am trying to configure grunt-svgmin to remove the fill="none" attribute that is automatically added to transparent SVGs when exported from Adobe Illustrator.
I currently have the below configuration:
svgmin: {
options: {
plugins: [
{
removeViewBox: false
},
{
removeUselessStrokeAndFill: {
removeNone: true
}
},
{
removeEmptyAttrs: true
},
{
removeTitle: true
},
{
removeAttrs: {
attrs: ['xmlns', 'id', 'data-name']
}
}
]
},
dist: {
files: [{
expand: true,
cwd: 'static/images/svgs/',
src: ['**/*.svg'],
dest: 'static/images/svgs/'
}]
}
}
I was under the impression that the removeUselessStrokeAndFill plugin with the option of removeNone would be what I needed to have in order to remove fill="none" but it isn't working.
Does anyone have any suggestions / advice on what I need to do to get this working?
Thanks,
Jess

fill="none" is not useless for two reasons:
The default for fill is black.
It is an inheritable property, so if for example you had this fragment
<g fill="none">
<rect width="100" height="100" />
<circle r="50" fill="red" />
</g>
the rect would get a transparent fill, while the circle would be rendered red.
The option you quote has another function: if a grafical element has neither a visible stroke nor a visible fill, the whole element is deleted.

Related

Changing single contour svg image fill color in QML

I have made a single contour .svg cursor (basically a triangle curved at the bottom) without any fill, and I want to be able to change its fill color. I can't just make few different svgs for this, due to fill color being picked by user.
QtGraphicalEffects library is not supported since Qt6, so all I could find on this topic was of little use. The solution for this might be to just drop my svg over a colored rectangle, but then I'll have to mask out the area outside of my cursor to make it transparent(or vice-versa), and I'm not sure if it's even possible. I also found some shader-based solutions but none of then seem to work for my case (might just be me being new to QML)
SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #414141;
stroke-width: 44px;
fill-rule: evenodd;
}
</style>
</defs>
<path id="Pointer_1" data-name="Pointer 1" class="cls-1" d="M300.291,48.248L556.347,560.4s-127.234-47.825-255.133-47.825c-128.157,0-256.979,47.825-256.979,47.825Z"/>
</svg>
[MULTIPLE EDITS]
Firstly, the latest builds of Qt6 do support QtGraphicalEffects via Qt5Compat.GraphicalEffects. https://doc.qt.io/qt-6/qtgraphicaleffects5-
The approach I prefer to use is to leverage the fact that most components have an icon property which has a built-in mechanism for recoloring an SVG. You set the following properties:
icon.source
icon.width
icon.height
icon.color
By creating two SVGs we can use the above approach to control the fill and stroke independently.
The typical component I use is Button, but, I strip off the default Button UI/UX and just leverage from the icon property as follows:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
SplitView {
anchors.fill: parent
orientation: Qt.Horizontal
Item {
SplitView.preferredWidth: parent.width / 2
SplitView.fillHeight: true
Item {
anchors.centerIn: parent
width: parent.width * 8 / 10
height: parent.height * 8 / 10
Button {
anchors.centerIn: parent
visible: fillCombo.currentText !== 'none'
background: Item { }
icon.source: "shape-fill.svg"
icon.width: Math.min(parent.width, parent.height)
icon.height: icon.width
icon.color: fillCombo.currentText
}
Button {
anchors.centerIn: parent
visible: strokeCombo.currentText !== 'none'
background: Item { }
icon.source: "shape-outline.svg"
icon.width: Math.min(parent.width, parent.height)
icon.height: icon.width
icon.color: strokeCombo.currentText
}
}
}
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
ColumnLayout {
anchors.centerIn: parent
Label {
text: qsTr("Stroke")
}
ComboBox {
id: strokeCombo
model: [ "lightsteelblue", "red", "orange", "yellow", "green", "blue" ]
}
Label {
Layout.topMargin: 20
text: qsTr("Fill")
}
ComboBox {
id: fillCombo
model: [ "none", "red", "orange", "yellow", "green", "blue" ]
}
}
}
}
}
// shape-outline.svg
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<path stroke="red" stroke-width="44" fill="none" d="M300.291,48.248L556.347,560.4s-127.234-47.825-255.133-47.825c-128.157,0-256.979,47.825-256.979,47.825Z"/>
</svg>
// shape-fill.svg
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<path stroke="none" fill="black" d="M300.291,48.248L556.347,560.4s-127.234-47.825-255.133-47.825c-128.157,0-256.979,47.825-256.979,47.825Z"/>
</svg>
You can Try it Online!
Alternatively, another approach is you can build your SVG as a data uri by adding a "data:image/svg+xml," prefix to your SVG string. Because you're using a data uri, you can make a function that generates the SVG based on use input:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
SplitView {
anchors.fill: parent
orientation: Qt.Horizontal
Item {
SplitView.preferredWidth: parent.width / 2
SplitView.fillHeight: true
Image {
anchors.centerIn: parent
width: parent.width * 8 / 10
height: parent.height * 8 / 10
source: todatauri(getsvg(strokeCombo.currentText, fillCombo.currentText))
fillMode: Image.PreserveAspectFit
}
}
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
ColumnLayout {
anchors.centerIn: parent
Label {
text: qsTr("Stroke")
}
ComboBox {
id: strokeCombo
model: [ "black", "red", "orange", "yellow", "green", "blue" ]
}
Label {
Layout.topMargin: 20
text: qsTr("Fill")
}
ComboBox {
id: fillCombo
model: [ "none", "red", "orange", "yellow", "green", "blue" ]
}
}
}
}
function todatauri(svg) {
return "data:image/svg+xml," + svg;
}
function getsvg(stroke, fill) {
return `<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #414141;
stroke-width: 44px;
fill-rule: evenodd;
}
</style>
</defs>
<path id="Pointer_1" data-name="Pointer 1" class="cls-1" stroke="${stroke}" stroke-width="44" fill="${fill}" d="M300.291,48.248L556.347,560.4s-127.234-47.825-255.133-47.825c-128.157,0-256.979,47.825-256.979,47.825Z"/>
</svg>
`;
}
}
You can Try it Online!

D3 and React Hooks: Move element along an arc

I am creating a gauge with a small marker which is a triangle, I already have it working here: https://codesandbox.io/s/blazing-sun-teo9oe?file=/src/Gauge.tsx
Except for the marker transition, I need it to move along the gauge arc, so when the component prop changes from 40 to 80 for example, the marker will move from 40 to 80, right now it always starts at 50 or the middle of the arc and then moves to the final value.
Feel free to change the Gauge prop value in the index.tsx file to see the problem. Transition duration is 10 seconds to see the problem easier.
D3 and React = 300 kB (minified!)
You can do it in native JavaScript:
customElements.define("svg-gauge", class extends HTMLElement {
connectedCallback() {
let arc = "m20 45a35 35 0 1170 0";
let col = this.getAttribute("color")||"green";
this.innerHTML =
`<input type="range" min="0" max="100" step="5" value="0"`+ // delete 2 lines
` oninput="this.parentNode.percent=this.value" /><br>`+ // just for demo
`<svg viewbox="0 0 100 100">
<path d="${arc}" stroke="grey" stroke-width="6" fill="none"
stroke-linecap="round"></path>
<path id="P" d="${arc}" stroke="${col}" stroke-width="8" pathLength="100"
fill="none" stroke-linecap="round" stroke-dasharray="75 35"></path>
<circle cx="0" cy="0" fill="#fff" r="4" stroke="${col}" stroke-width="3">
<animateMotion dur="0.5s" keyPoints="0;0.75"
fill="freeze" keyTimes="0;1" calcMode="linear" path="${arc}">
</animateMotion></circle>
<text x="55%" y="40%" text-anchor="middle"/>
</svg>`;
this.style.display='inline-block';
this.percent = this.getAttribute("value") || "50";
}
set percent(val = 0) {
this.setAttribute("value", val);
let dash = val + " " + (105 - val);
this.querySelector("#P").setAttribute('stroke-dasharray', dash);
this.querySelector("animateMotion").setAttribute('keyPoints', '0;'+val/100);
this.querySelector("text").innerHTML =`${val} %`;
this.querySelector("animateMotion").beginElement();
this.querySelector("input").value = val;
}
})
svg-gauge { width:180px }
<h3>Drag sliders:</h3>
<svg-gauge value="35" color="red"></svg-gauge>
<svg-gauge value="50" color="hotpink"></svg-gauge>
<svg-gauge value="75" color="blue"></svg-gauge>

How to ensure that every path or group in an illustrator SVG has its own class name?

I am trying to create the floor plans of an apartment building as a SVG using Illustrator. The end goal is to use it on a website with a table next to it, where each row has some details about the individual apartments and when hovering over the row, the respective apartment in the SVG graphic highlights with changing its fill to a specific color. (an example would be this: https://the-jay.ch/wohnungen when you scroll down to 'wohnungsangebot')
I am fine with the coding part about the animation but one thing I struggle in illustrator, is to assign my own classes to the paths or groups of the floor plans I am designing. From my own research it is not possible in Illustrator to add my own classes.
The issue I have is that all apartments will have the same styling in terms of fill and stroke. Because of that reason, they all get assigned the same class. This is an issue for the jquery part later, because I will need to select each apartment individually to create the hover animation.
Of course I could add my own classes later on when I exported the SVG but that would also mean that I would have to re-add these classes every time when I need to make a change to the SVG graphic.
So my question is: is there a way to determine that each group or path in illustrator gets their own individual classes?
I know that by naming the layers, I can assign IDs but this doesn't help much because the styling is stored in the class that illustrator assigns and additionally, some of my 'apartments' are built out of multiple paths that would all get their own ID as an ID needs to be unique. But I need to target with my jquery the entire apartment not just one part of the apartment
To some extend you might define class names by using named graphic styles.
But this might not be extremely feasible.
As a workaround you could write some helperfunction in js, that will add classnames according to your AI object IDS.
Example of a naming scheme for AI layers:
In the above example I'm using double hyphens to seperate multiple id substrings.
Auto Class name function:
function setAutoClassNames(svg){
const elements = svg.querySelectorAll('[id]');
if(elements.length){
elements.forEach(function(el,i){
let id = el.id;
let idArr = id.split('--');
let firstID = idArr[0];
let idPrefix = firstID.replace(/[0-9]/g, '');
//optional: add classnames for certain types
if(idPrefix==='a'){
idArr.push('appartment');
}
//add classname prefix for elements of same type e.g floors, appartments
el.classList.add(idPrefix);
el.classList.add(firstID);
if(idArr.length>1){
let newClassNames = idArr.join(' ');
el.classList.add(...idArr);
}
})
}
}
<g id="floor2--floor-special">
will become
<g id="floor2--floor-special" class="floor floor2 floor-special">
All floor layers will both have a generic .floor and a unique .floorX class. (Same principle for appartments).
Example usage
const svg = document.querySelector('svg');
setAutoClassNames(svg);
function setAutoClassNames(svg) {
const elements = svg.querySelectorAll('[id]');
if (elements.length) {
elements.forEach(function(el, i) {
let id = el.id;
let idArr = id.split('--');
let firstID = idArr[0];
let idPrefix = firstID.replace(/[0-9]/g, '');
//optional: add classnames for certain types
if (idPrefix === 'a') {
idArr.push('appartment');
}
//add classname prefix for elements of same type e.g floors, appartments
el.classList.add(idPrefix);
el.classList.add(firstID);
if (idArr.length > 1) {
let newClassNames = idArr.join(' ');
el.classList.add(...idArr);
}
})
}
}
/**
* usage example
*/
// remove svg stylesheet to use own rules
const svgCss = svg.querySelector('style');
svgCss.remove();
//example show current selection
const pInfo = document.querySelector('.p-info');
let appartments = svg.querySelectorAll('.a');
appartments.forEach(function(appartment, i) {
appartment.addEventListener('click', function(e) {
let currentA = e.currentTarget;
let floor = currentA.closest('.floor');
// get floor/appartment number by id
let appNum = appartment.id.replaceAll('a', '');
let floorNum = floor.id.replaceAll('floor', '');
currentA.classList.toggle('a-active');
pInfo.innerHTML = `<span class="span-app">Appartment: ${appNum}</span>; <span class="span-floor">Floor: ${floorNum}</span>`;
});
});
.st0 {
fill: #FFFFFF;
stroke: #000000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-miterlimit: 10;
}
.st1 {
fill: #FFFFFF;
}
.a-active {
fill: red!important;
}
.h-active {
fill: green!important;
}
.open {
fill: green;
}
<svg version="1.1" id="SvgjsSvg1006" xmlns:svgjs="http://svgjs.com/svgjs" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="404.5px" height="125.9px" viewBox="219.7 278.3 404.5 125.9" style="enable-background:new 219.7 278.3 404.5 125.9;"
xml:space="preserve">
<style type="text/css">
<![CDATA[
.st0{fill:#FFFFFF;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st1{fill:#FFFFFF;}
]]>
</style>
<g id="floor2--floor-special" transform="matrix(1,0,0,1,0,0)">
<polygon id="open21" class="st1" points="575.8,326.6 552,318.4 546.5,325.4 495.4,307.9 494.4,309.1 493,308.7 492.9,308.6
492.1,308.4 491.4,308.1 490.6,307.9 489.8,307.7 489,307.4 488.2,307.2 487.5,307 486.6,306.8 485.8,306.6 485,306.4 484.2,306.2
483.4,306 482.6,305.8 481.8,305.7 481,305.5 480.1,305.3 479.3,305.1 478.5,305 477.7,304.8 476.8,304.7 476,304.6 475.7,304.5
474.9,304.4 473.2,304.1 471.5,303.9 469.8,303.7 468.1,303.5 466.8,303.4 466.7,298 465.8,298 464,297.9 462.3,297.8 460.5,297.7
458.7,297.7 456.9,297.7 455.1,297.7 453.4,297.7 451.6,297.8 449.8,297.8 448,297.9 446.2,298 444.8,298.2 444.8,302.6 444,302.7
442.2,302.9 440.6,303.1 438.8,303.4 437.2,303.6 435.5,303.9 433.8,304.2 432.1,304.6 430.5,304.9 428.9,305.2 427.4,305.6
425.7,306 424.1,306.5 422.6,306.9 421,307.4 419.5,307.9 417.9,308.4 416.7,308.9 415.4,309.3 413.8,307.4 313.1,343.6
308.8,338.3 271.1,351.8 275.5,357.2 251.1,366 230.6,373.4 230.6,382.4 234.3,387 234.3,377.9 254.9,370.5 254.9,370.5
285.3,359.6 287,361.5 287.5,361.3 306.3,354.6 304.7,352.6 316.9,348.2 316.9,348.2 326.6,344.7 326.6,344.7 417.6,311.9
430.9,328.4 431.6,329.2 432.6,330.4 432.6,336.8 432.8,336.7 434,336.3 435.2,335.9 436.4,335.5 437.6,335.2 438.9,334.9
440.2,334.6 441.5,334.3 442.8,334 444.1,333.8 445.4,333.6 446.7,333.4 448,333.3 449.4,333.1 450.7,333 452.1,332.9 453.4,332.9
454.7,332.8 456.1,332.8 457.4,332.8 458.8,332.8 460.2,332.9 461.5,332.9 462.8,333 464.2,333.2 465.5,333.3 466.8,333.5
468.2,333.7 469.4,333.9 470.7,334.1 472,334.4 473.3,334.7 474.6,335 475.3,335.2 475.3,333.8 475.9,333.1 477.1,331.5
478.4,329.9 479.5,328.3 480.1,327.5 491.9,312.5 546.7,331.3 546.3,331.9 559.2,336.3 565.9,327.7 565.9,327.7 570,329.1
573.8,330.4 573.8,330.4 577.6,331.8 580.4,328.2 "/>
<polygon id="a201" class="st1" points="417.6,311.9 394.4,320.3 409.4,338.7 409.4,347.8 432.6,339.5 432.6,330.4 "/>
<polygon id="a202" class="st1" points="394.4,320.3 378.9,325.9 393.9,344.3 393.9,353.4 409.4,347.8 409.4,338.7 "/>
<polygon id="a203" class="st1" points="378.9,325.9 363.4,331.5 378.4,349.9 378.4,359 393.9,353.4 393.9,344.3 "/>
<polygon id="a204" class="st1" points="363.4,331.5 347.9,337 362.9,355.5 362.9,364.6 378.4,359 378.4,349.9 "/>
<polygon id="a205" class="st1" points="347.9,337 332.3,342.6 347.3,361.1 347.3,370.2 362.9,364.6 362.9,355.5 "/>
<polygon id="a206" class="st1" points="332.3,342.6 326.6,344.7 326.6,344.7 316.9,348.2 331.9,366.7 331.9,375.7 347.3,370.2
347.3,361.1 "/>
<polygon id="a207" class="st1" points="316.9,348.2 304.7,352.6 306.3,354.6 287.5,361.3 300.8,377.8 300.8,386.9 331.9,375.7
331.9,366.7 "/>
<polygon id="a208" class="st1" points="290.3,364.7 287.5,361.3 287,361.5 285.3,359.6 270.3,364.9 285.3,383.4 285.3,392.5
300.8,386.9 300.8,377.8 "/>
<polygon id="a209" class="st1" points="270.3,364.9 254.9,370.5 269.9,389 269.9,398 285.3,392.5 285.3,383.4 "/>
<polygon id="a210" class="st1" points="254.9,370.5 234.3,377.9 234.3,387 239,392.8 243.7,391.1 254,403.8 269.9,398 269.9,389
"/>
<polygon id="a211" class="st1" points="236.1,347.6 220.3,353.3 220.3,362.3 225.9,369.2 225.9,376.6 230.6,382.4 230.6,373.4
251.1,366 "/>
<polyline id="a212" class="st1" points="236.1,347.6 251.7,342 266.6,360.4 251.1,366 236.1,347.6 "/>
<polyline id="a213" class="st1" points="251.7,342 298.2,325.2 308.8,338.3 271.1,351.8 275.5,357.2 266.6,360.4 251.7,342 "/>
<polyline id="a214" class="st1" points="313.7,319.6 328.7,338.1 313.1,343.6 308.8,338.3 298.2,325.2 313.7,319.6 "/>
<polyline id="a215" class="st1" points="329.2,314 344.2,332.5 328.7,338.1 313.7,319.6 329.2,314 "/>
<polyline id="a216" class="st1" points="329.2,314 344.7,308.5 359.6,326.9 344.2,332.5 329.2,314 "/>
<polyline id="a217" class="st1" points="344.7,308.5 360.2,302.9 375.2,321.3 359.6,326.9 344.7,308.5 "/>
<polyline id="a218" class="st1" points="375.7,297.3 390.7,315.7 375.2,321.3 360.2,302.9 375.7,297.3 "/>
<polyline id="a219" class="st1" points="375.7,297.3 398.9,288.9 413.8,307.4 390.7,315.7 375.7,297.3 "/>
<polyline id="a220" class="st1" points="398.9,288.9 399.2,288.8 401.1,288.2 402.9,287.5 404.7,286.9 406.6,286.3 408.4,285.8
410.4,285.2 412.2,284.7 414.1,284.2 416.1,283.7 418,283.2 420,282.8 421.9,282.4 423.9,282 425.9,281.7 427.9,281.3 429.9,281
431.9,280.7 433.9,280.4 435.9,280.2 438,279.9 440,279.7 441,279.7 445.2,298.1 444.8,298.2 444.8,302.6 444,302.7 442.3,302.9
440.6,303.1 438.9,303.4 437.2,303.6 435.5,303.9 433.9,304.2 432.2,304.5 430.6,304.9 428.9,305.2 427.4,305.6 425.7,306
424.1,306.5 422.6,306.9 421,307.4 419.5,307.9 417.9,308.4 416.7,308.9 415.4,309.3 413.8,307.4 398.9,288.9 "/>
<polyline id="a221" class="st1" points="441,279.7 442.3,279.6 444.3,279.4 446.4,279.3 448.4,279.2 450.5,279.1 452.5,279
454.6,279 456.6,279 458.7,279 460.7,279 462.8,279.1 464.8,279.2 466.9,279.3 468.9,279.4 471,279.6 473,279.7 475,279.9
477.1,280.2 479.1,280.4 481.1,280.7 483.1,280.9 484.1,281.1 475.7,304.5 474.9,304.4 473.2,304.1 471.5,303.9 469.8,303.7
468.1,303.5 466.8,303.4 466.7,298 465.8,298 464,297.9 462.3,297.8 460.5,297.7 458.7,297.7 456.9,297.7 455.1,297.7 455.1,297.7
453.4,297.7 451.6,297.8 449.8,297.8 448,297.9 446.2,298 445.2,298.1 441,279.7 "/>
<polyline id="a222" class="st1" points="475.7,304.5 484.1,281.1 485.2,281.3 487.2,281.7 489.2,282 491.1,282.4 493.1,282.8
495,283.2 497,283.7 498.9,284.2 500.8,284.7 502.7,285.2 504.6,285.7 506.5,286.3 508.3,286.9 510.1,287.5 511.1,287.8
519.4,290.7 503.8,310.7 495.4,307.9 494.4,309.1 493.7,308.9 492.1,308.4 490.6,307.9 489,307.4 487.4,307 485.8,306.6
484.2,306.2 482.6,305.8 480.9,305.5 479.3,305.1 477.6,304.8 476,304.6 475.7,304.5 "/>
<polyline id="a223" class="st1" points="519.4,290.7 535,296.1 519.5,316.1 503.8,310.7 519.4,290.7 "/>
<polyline id="a224" class="st1" points="535,296.1 550.8,301.4 535.2,321.5 519.5,316.1 535,296.1 "/>
<polyline id="a225" class="st1" points="550.8,301.4 586,313.6 575.8,326.6 552,318.4 546.5,325.4 535.2,321.5 550.8,301.4 "/>
<polygon id="a226" class="st1" points="586,313.6 575.8,326.6 580.4,328.2 577.6,331.8 583,333.6 589.5,341.5 589.5,350.6
601.5,346.3 601.5,343.6 623.7,335.6 623.7,326.5 "/>
<polygon id="a227" class="st1" points="583,333.6 573.8,330.4 573.8,330.4 570,329.1 565.9,327.7 559.2,336.3 556.2,335.3
554.5,334.7 547.7,343.4 549,352.8 549,361.8 549.7,361.8 551.1,361.6 552.5,361.5 553.9,361.3 555.3,361.2 556.6,361 558,360.8
559.3,360.5 560.7,360.2 562,359.9 563.4,359.6 564.6,359.3 565.9,358.9 567.2,358.5 568.5,358.1 569.8,357.7 570.1,357.6
578.2,354.6 589.5,350.6 589.5,341.5 "/>
<polygon id="a228" class="st1" points="554.5,334.7 546.3,331.9 546.7,331.3 531.6,326.1 515,347.5 515,356.6 518.9,357.9
519.5,358.1 520.8,358.5 522,358.9 523.3,359.2 524.6,359.6 525.9,359.9 527.2,360.2 528.5,360.5 529.9,360.7 531.2,361
532.6,361.2 533.9,361.3 535.3,361.5 536.7,361.6 538.1,361.8 539.4,361.8 540.8,361.9 542.2,362 543.6,362 545,362 546.4,361.9
547.7,361.9 549,361.8 549,352.8 547.7,343.4 "/>
<polygon id="a229" class="st1" points="515.9,320.7 499.3,342.1 499.3,351.1 515,356.6 515,347.5 531.6,326.1 "/>
<polygon id="a230--specialClass" class="st1" points="491.9,312.5 475.3,333.8 475.3,342.9 499.3,351.1 499.3,342.1 515.9,320.7
"/>
<path id="OG2" class="st0" d="M623.8,326.5L623.8,326.5L623.8,326.5C623.8,326.5,623.7,326.5,623.8,326.5
C623.7,326.5,623.7,326.5,623.8,326.5C623.7,326.5,623.7,326.5,623.8,326.5C623.7,326.5,623.7,326.5,623.8,326.5L623.8,326.5
l-37.8-13l-35.2-12.1l-15.7-5.4l-15.7-5.4l-8.3-2.9l-0.9-0.3l0,0l0,0l-1.8-0.6l0,0l0,0l-1.9-0.6l0,0l0,0l-1.9-0.6l0,0l0,0l-1.9-0.5
l0,0l0,0l-1.9-0.5l0,0l0,0l-1.9-0.5l0,0l0,0l-1.9-0.5l0,0l0,0l-1.9-0.4l0,0l0,0l-2-0.4l0,0l0,0l-2-0.4l0,0l0,0l-2-0.4l0,0l0,0
l-2-0.4l0,0l0,0l-2-0.3l0,0l0,0l-1.1-0.2l-1-0.1l0,0l0,0l-2-0.3l0,0l0,0l-2-0.3l0,0l0,0l-2-0.2l0,0l0,0l-2-0.2l0,0l0,0l-2-0.2l0,0
l0,0l-2.1-0.2l0,0l0,0l-2.1-0.1l0,0l0,0l-2.1-0.1l0,0l0,0l-2.1-0.1l0,0l0,0l-2.1-0.1l0,0l0,0l-2.1,0l0,0l0,0l-2.1,0l0,0h-2.1l0,0
l0,0h-2.1l0,0l-2.1,0l0,0l-2.1,0l0,0l0,0l-2.1,0.1l0,0l0,0l-2.1,0.1l0,0l0,0l-2.1,0.1l0,0l0,0l-2.1,0.1l0,0l0,0l-1.2,0.1l-1,0.1
l0,0l0,0l-2,0.2l0,0l0,0l-2,0.2l0,0l0,0l-2,0.2l0,0l0,0l-2,0.3l0,0l0,0l-2,0.3l0,0l0,0l-2,0.3l0,0l0,0l-2,0.3l0,0l0,0l-2,0.4l0,0
l0,0l-2,0.4l0,0l0,0l-2,0.4l0,0l0,0l-2,0.4l0,0l0,0l-2,0.5l0,0l0,0l-1.9,0.5l0,0l0,0l-1.9,0.5l0,0l0,0l-1.9,0.5l0,0l0,0l-1.9,0.5
l0,0l0,0l-1.9,0.6l0,0l0,0l-1.9,0.6l0,0l0,0l-1.8,0.6l0,0l0,0l-1.8,0.6l0,0l0,0l-1.8,0.7l0,0l0,0l-0.4,0.1l0,0l-23.2,8.3l-15.5,5.6
l-15.5,5.6l-15.5,5.6l-15.5,5.6l-15.5,5.6L251.6,342l-15.5,5.6l-15.9,5.7l0,0l0,0l0,0l0,0l0,0l0,0l0,0v9.1l0,0l0,0l5.6,6.9v7.4l0,0
l0,0l4.7,5.8l0,0l3.7,4.5l0,0l4.7,5.8l0,0h0l0,0l4.6-1.7l10.2,12.6l0,0h0l0,0l15.9-5.7l15.5-5.6l15.5-5.6l31-11.2l15.5-5.6
l15.5-5.6l15.5-5.6l15.5-5.6l15.5-5.6l23.2-8.3l0,0l0,0l0,0l0,0v-2.6l0.1,0l0,0l1.2-0.4l0,0l1.2-0.4l0,0l1.2-0.4l0,0l1.2-0.3l0,0
l1.2-0.3l0,0l1.3-0.3l0,0l1.3-0.3l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.1l0,0l1.3-0.1l0,0l1.3-0.1l0,0l1.3-0.1
l0,0l1.3,0l0,0l1.3,0l0,0h1.3h1.3l0,0l1.3,0l0,0l1.3,0l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.2
l0,0l1.3,0.2l0,0l1.3,0.2l0,0l1.3,0.2l0,0l1.3,0.3l0,0l1.2,0.3l0.6,0.1v7.7l0,0l0,0l0,0l0,0l24,8.3l15.7,5.4l3.9,1.3l0,0l0.6,0.2
l0,0l0,0l1.2,0.4l0,0l0,0l1.2,0.4l0,0l0,0l1.3,0.4l0,0l0,0l1.3,0.3l0,0l0,0l1.3,0.3l0,0l0,0l1.3,0.3l0,0l0,0l1.3,0.3l0,0l0,0
l1.3,0.2l0,0l1.3,0.2l0,0l0,0l1.3,0.2l0,0l0,0l1.3,0.2l0,0l1.4,0.1l0,0l0,0l1.4,0.1l0,0l1.4,0.1l0,0l1.4,0.1l0,0l0,0l1.4,0l0,0
l1.4,0l0,0h1.4l0,0l0,0h1.4l0,0l1.4,0l0,0l1.4,0l0,0l1.2,0l0,0l0.7,0l0,0l0,0l1.4-0.1l0,0l1.4-0.1l0,0l0,0l1.4-0.1l0,0l1.4-0.2l0,0
l0,0l1.4-0.2l0,0l1.3-0.2l0,0l0,0l1.3-0.2l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.4l0,0
l0,0l1.3-0.4l0,0l0,0l1.2-0.4l0,0l0,0l1.2-0.4l0,0l0,0l0.3-0.1l0,0l8.1-2.9l11.3-4.1l12-4.3l0,0l0,0l0,0l0,0v-2.6l22.2-8l0,0l0,0
l0,0l0,0L623.8,326.5L623.8,326.5z M599.7,335.1L599.7,335.1L599.7,335.1L599.7,335.1L599.7,335.1
C599.7,335.2,599.7,335.2,599.7,335.1L599.7,335.1L599.7,335.1L599.7,335.1l1.6,2.1l-11.9,4.3l-6.4-7.9l0,0l0,0l-5.3-1.8l2.7-3.5
l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l-4.5-1.5l10.1-13l37.5,12.9L599.7,335.1z M578.2,354.6l-8.1,2.9l0,0l0,0l-0.3,0.1l0,0l-1.2,0.4
l0,0l-1.2,0.4l0,0l-1.3,0.4l0,0l-1.3,0.4l0,0l-1.3,0.3l-1.3,0.3l0,0l-1.3,0.3l0,0l-1.3,0.3l-1.3,0.2l0,0l-1.3,0.2l0,0l-1.4,0.2l0,0
l-1.4,0.2l0,0l-1.4,0.1l0,0l-1.4,0.1l0,0l-1.4,0.1l0,0l-0.6,0v-9l0.6,0l0,0l0,0l1.4-0.1l0,0l1.4-0.1l0,0l0,0l1.4-0.1l0,0l1.4-0.2
l0,0l0,0l1.4-0.2l0,0l0,0l1.3-0.2l0,0l0,0l1.3-0.2l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0l1.3-0.3l0,0l0,0
l1.3-0.4l0,0l0,0l1.3-0.4l0,0l0,0l1.2-0.4l0,0l0,0l1.2-0.4l0,0l0,0l0.3-0.1l0,0l8.1-2.9l11.2-4v9L578.2,354.6z M547.7,361.8
L547.7,361.8l-1.4,0l0,0l-1.4,0l0,0h-1.4h-1.4l0,0l-1.4,0l0,0l-1.4,0l0,0l-1.4-0.1l0,0l-1.4-0.1l0,0l-1.4-0.1l0,0l-1.3-0.1l0,0
l-1.3-0.2l0,0l-1.3-0.2l0,0l-1.3-0.2l0,0l-1.3-0.2l-1.3-0.3l0,0l-1.3-0.3l0,0l-1.3-0.3l-1.3-0.3l0,0l-1.3-0.4l0,0l-1.2-0.4l0,0
l-1.2-0.4l0,0l-0.6-0.2l0,0l0,0l-3.9-1.3v-9l3.8,1.3l0.6,0.2l0,0l0,0l1.2,0.4l0,0l0,0l1.2,0.4l0,0l0,0l1.3,0.4l0,0l0,0l1.3,0.3l0,0
l0,0l1.3,0.3l0,0l0,0l1.3,0.3l0,0l0,0l1.3,0.3l0,0l0,0l1.3,0.2l0,0l1.3,0.2l0,0l0,0l1.3,0.2l0,0l0,0l1.3,0.2l0,0l1.4,0.1l0,0l0,0
l1.4,0.1l0,0l1.4,0.1l0,0l1.4,0.1l0,0l0,0l1.4,0l0,0l1.4,0l0,0h1.4l0,0l0,0h1.4l0,0l1.4,0l0,0l1.4,0l0,0l1.2,0v9L547.7,361.8z
M479.5,327.3L479.5,327.3L479.5,327.3l-1.2-0.4l0,0l0,0l-1.2-0.4l0,0l0,0l-1.2-0.3l0,0l0,0l-1.2-0.3l0,0l0,0l-1.3-0.3l0,0l0,0
l-1.3-0.3l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.1l0,0l0,0l-1.3-0.1l0,0l0,0
l-1.3-0.1l0,0l0,0l-1.3-0.1l0,0l0,0l-1.3-0.1l0,0l0,0l-1.3,0l0,0l-1.3,0l0,0l0,0h-1.3l0,0l0,0h-1.3l0,0l0,0l-1.3,0l0,0l0,0l-1.3,0
l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.2l0,0l0,0l-1.3,0.2l0,0l0,0l-1.3,0.2l0,0
l0,0l-1.3,0.2l0,0l0,0l-1.3,0.3l0,0l0,0l-1.3,0.3l0,0l0,0l-1.2,0.3l0,0l0,0l-1.2,0.3l0,0l0,0l-1.2,0.4l0,0l0,0l-1.2,0.4l0,0l0,0
l-1.2,0.4l0,0l0,0l-1.2,0.4l0,0l0,0l-0.7,0.2l-13.3-16.3l0,0l0,0l0,0l0,0l-23.2,8.3l-15.5,5.6l-15.5,5.6l-15.5,5.6l-15.5,5.6
l-15.5,5.6l-12.2,4.4l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l1.6,1.9l-18.8,6.8l-0.5,0.2l-1.6-2l0,0l0,0l0,0l0,0l-15,5.4l-15.5,5.6l0,0
l-20.5,7.4l-3.6-4.5l20.4-7.4l15.5-5.6l8.8-3.2l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l-4.3-5.3l37.6-13.6l4.4,5.4h0l0,0l15.5-5.6
l85.1-30.6l1.5,1.9h0l0,0l1.3-0.5l0,0l1.1-0.4l0,0l1.5-0.5l0,0l1.5-0.5l0,0l1.6-0.5l0,0l1.6-0.5l0,0l1.6-0.4l0,0l1.6-0.4l1.6-0.4
l0,0l1.6-0.4l0,0l1.6-0.3l0,0h0.1l0,0l1.6-0.3l0,0l1.7-0.3l0,0l1.7-0.3l0,0l1.7-0.2l0,0l1.7-0.2l0,0l1.7-0.2l0,0l0,0l0,0l1.7-0.2
l0,0l0,0l0.9-0.1l0,0l0,0l0,0l0,0l0,0l0,0l0-4.4l0.3,0l1.1-0.1l0,0l0,0l1.8-0.1l0,0l0,0l0,0l1.8-0.1l0,0l1.8-0.1l0,0l1.8,0l0,0
l1.8,0l0,0h1.8h1.8l0,0l0,0l1.8,0l0,0l1.8,0l0,0l1.8,0.1l0,0l1.8,0.1l0,0l0,0l0,0l0.8,0l0.1,5.3l0,0l0,0l0,0l0,0l1.2,0.1l0,0
l1.7,0.2l0,0l1.7,0.2l0,0l1.7,0.2l0,0l1.7,0.2l0,0l0.9,0.1l0,0l0.2,0l0,0h0l0,0l1.6,0.3l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l1.6,0.3
l0,0l0.9,0.2l0.7,0.1l0,0h0l0,0l0,0h0l0,0l1.6,0.3l0,0l0,0l0,0l0,0l0.8,0.2l0.8,0.2l0,0l0,0h0h0l0,0l1.6,0.4l1.6,0.4l0,0l1.6,0.4
l0,0l1.6,0.5l0,0h0h0l0,0l1.5,0.5l0,0l0,0l0,0l0,0l0.8,0.3l1.5,0.5l0,0h0l1-1.3l8.4,2.9l42.7,14.7l0,0h0l5.4-7l23.8,8.2l4.5,1.5
l-2.7,3.4l-3.8-1.3l0,0L570,329l-4.1-1.4l0,0l0,0l0,0l0,0l-6.7,8.6l-3-1l-1.7-0.6l-8.1-2.8l0.4-0.5l0,0l0,0l0,0l0,0l0,0l0,0l0,0
l0,0l-15.1-5.2l-15.7-5.4l-24-8.3l0,0l0,0l0,0l0,0l-11.7,15.1L479.5,327.3z M230.6,365.9L230.6,365.9L230.6,365.9
C230.6,365.9,230.6,365.9,230.6,365.9C230.6,365.9,230.6,365.9,230.6,365.9C230.6,365.9,230.6,365.9,230.6,365.9L230.6,365.9
L230.6,365.9L230.6,365.9l-10.2-12.6l15.8-5.7l14.9,18.3l-20.4,7.4l-4.6-5.7L230.6,365.9z M399.2,288.8L399.2,288.8l1.8-0.7l0,0
l1.8-0.6l1.8-0.6l0,0l1.9-0.6l0,0l1.9-0.6l0,0l1.9-0.5l0,0l1.9-0.5l0,0l1.9-0.5l0,0l1.9-0.5l0,0l1.9-0.5l0,0l2-0.4l0,0l2-0.4l0,0
l2-0.4l0,0l2-0.4l0,0l2-0.3l0,0l2-0.3l0,0l2-0.3l0,0l2-0.3l0,0l2-0.2l0,0l2-0.2l0,0l2-0.2l0,0l1-0.1L445,298l-0.3,0l0,0l0,0l0,0
l0,0l0,0l0,4.4l-0.8,0.1l0,0l0,0l-1.7,0.2l0,0l0,0l-1.7,0.2l0,0l0,0l-1.7,0.2l0,0l0,0l-1.7,0.2l0,0l0,0l-1.7,0.3l0,0l0,0l-1.7,0.3
l0,0l0,0l-1.7,0.3l0,0l0,0l-1.6,0.3l0,0l0,0h0l0,0h0l0,0l0,0l-1.6,0.4l0,0l0,0l-1.6,0.4l0,0l0,0l-1.6,0.4l0,0l0,0l-1.6,0.4l0,0l0,0
l-1.6,0.5l0,0l0,0l-1.6,0.5l0,0l0,0l-1.6,0.5l0,0l0,0l-1.5,0.5l0,0l0,0l-1.5,0.5l0,0l0,0l-0.7,0.3l-1.5-1.9l0,0l-14.9-18.4
L399.2,288.8z M442.3,279.6L442.3,279.6l2.1-0.1l0,0l2.1-0.1l0,0l2.1-0.1l0,0l2.1-0.1l0,0l2.1,0l0,0l2.1,0l0,0h2.1h2.1l0,0l2.1,0
l0,0l2.1,0l0,0l2.1,0.1l0,0l2.1,0.1l0,0l2.1,0.1l0,0l2.1,0.1l0,0l2.1,0.2l0,0l2,0.2l0,0l2,0.2l0,0l2,0.2l0,0l2,0.3l0,0l2,0.3l0,0
l0.9,0.1l-8.3,23.3l-0.8-0.1l0,0l0,0l-1.7-0.2l0,0l0,0l-1.7-0.2l0,0l0,0l-1.7-0.2l0,0l0,0l-1.7-0.2l0,0l0,0l-1.2-0.1l-0.1-5.3l0,0
l0,0l0,0l0,0l-0.9,0l0,0l0,0l-1.8-0.1l0,0l0,0l0,0l0,0l-1.8-0.1l0,0l0,0l-1.8,0l0,0l0,0l-1.8,0l0,0h-1.8l0,0l0,0h-1.8l0,0l0,0l0,0
l-1.8,0l0,0l0,0l-1.8,0l0,0l0,0l0,0l0,0l-1.8,0.1l0,0l0,0l-1.8,0.1l0,0l0,0l-1.8,0.1l0,0l0,0l0,0l0,0l0,0l-1,0.1l-4.1-18.4
L442.3,279.6z M485.2,281.4L485.2,281.4l2,0.3l0,0l2,0.4l0,0l2,0.4l0,0l2,0.4l0,0l2,0.4l0,0l1.9,0.4l0,0l1.9,0.5l0,0l1.9,0.5l0,0
l1.9,0.5l0,0l1.9,0.5l0,0l1.9,0.6l0,0l1.9,0.6l0,0l1.8,0.6l0.9,0.3l8.2,2.8l-15.5,20l-8.4-2.9l0,0l0,0l0,0l0,0l-1,1.3l-0.7-0.2l0,0
l0,0l-0.7-0.2h0l0,0l0,0l-0.8-0.2l0,0l0,0h0l0,0h0l0,0l0,0l-1.5-0.5l0,0l0,0l0,0l0,0l0,0l-1.5-0.4l0,0h0l0,0l0,0h0l0,0l-1.5-0.4
l0,0l0,0h0h0l0,0l0,0l0,0l-1.5-0.4l0,0l0,0l0,0h0l0,0l0,0l-1.6-0.4l0,0l0,0l-0.7-0.2l-0.8-0.2l0,0l0,0h0l0,0l0,0h0l0,0l-1.6-0.3
l0,0l0,0l-0.7-0.1l-0.9-0.2l0,0l0,0h0l0,0l0,0l0,0l0,0l0,0l0,0l-1.6-0.3l0,0l0,0l0,0h0l0,0l0,0l-1.6-0.3l0,0l0,0l0,0l0,0h0l0,0l0,0
l-0.2,0l8.3-23.3L485.2,281.4z M552,318.3L552,318.3L552,318.3C551.9,318.3,551.9,318.3,552,318.3L552,318.3l-5.5,7l-11.2-3.9
l15.5-20l35.1,12.1l-10.1,13L552,318.3z M535.1,321.5l-15.6-5.4l15.5-20l15.6,5.4L535.1,321.5z M519.5,316l-15.6-5.4l15.5-20
l15.6,5.4L519.5,316z M398.9,289l14.9,18.3l-23.1,8.3l-14.9-18.3L398.9,289z M375.7,297.4l14.9,18.3l-15.4,5.6l-14.9-18.3
L375.7,297.4z M360.2,302.9l14.9,18.3l-15.4,5.6l-14.9-18.3L360.2,302.9z M344.7,308.5l14.9,18.3l-15.4,5.6l-14.9-18.3L344.7,308.5
z M329.1,314.1l14.9,18.3l-15.4,5.6l-14.9-18.3L329.1,314.1z M313.7,319.7l14.9,18.3l-15.4,5.6l-4.4-5.4l-10.5-13L313.7,319.7z
M298.2,325.3l10.5,12.9l-37.6,13.6l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l4.3,5.3l-8.7,3.1l-14.9-18.3L298.2,325.3z M251.7,342
l14.9,18.3l-15.4,5.6l-14.9-18.3L251.7,342z M225.9,367.8l4.6,5.7v8.9l-4.6-5.7V367.8z M230.7,373.6l3.6,4.4v8.9l-3.6-4.4V373.6z
M331.9,366.6L317,348.2l15.4-5.6l14.9,18.3L331.9,366.6z M347.4,361l-14.9-18.3l15.4-5.6l14.9,18.3L347.4,361z M362.9,355.4
L348,337.1l15.4-5.6l14.9,18.3L362.9,355.4z M378.4,349.9l-14.9-18.3l15.4-5.6l14.9,18.3L378.4,349.9z M393.9,344.2L379,325.9
l15.4-5.6l14.9,18.3L393.9,344.2z M316.8,348.3l14.9,18.3l-30.9,11.1l-10.6-13l-2.7-3.4l18.8-6.8l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0
l-1.6-1.9L316.8,348.3z M286.9,361.6C286.9,361.6,286.9,361.6,286.9,361.6C287,361.6,287,361.6,286.9,361.6l0.5-0.2l2.7,3.4
l10.5,13l-15.4,5.6l-14.9-18.3l14.8-5.4L286.9,361.6z M254,394.6L243.8,382l0,0l0,0l0,0l0,0l0,0l0,0l0,0l-4.6,1.7l-4.6-5.7
l20.4-7.3l14.9,18.3L254,394.6z M269.9,388.9L255,370.6l15.4-5.6l14.9,18.3L269.9,388.9z M234.4,378.1l4.6,5.7v8.9l-4.6-5.7V378.1z
M239.1,383.8l4.5-1.6v9l-4.5,1.6V383.8z M243.8,382.2l10.2,12.5v8.9l-10.2-12.5V382.2z M254.1,394.7l15.8-5.7v8.9l-15.8,5.7V394.7
z M269.9,389l15.4-5.6v9l-15.4,5.6V389z M285.4,383.4l15.4-5.6v9l-15.4,5.6V383.4z M300.9,377.9l30.9-11.1v9l-30.9,11.1V377.9z
M331.9,366.7l15.4-5.6v9l-15.4,5.6V366.7L331.9,366.7z M347.4,361.1l15.4-5.6v9l-15.4,5.6V361.1L347.4,361.1z M362.9,355.6
l15.4-5.6v9l-15.4,5.6V355.6z M378.4,349.9l15.4-5.6v9l-15.4,5.6V349.9L378.4,349.9z M393.9,344.3l15.4-5.6v9l-15.4,5.6V344.3z
M409.4,338.8l23.1-8.3v9l-23.1,8.3V338.8z M409.4,338.6l-14.9-18.3l23.1-8.3l13.3,16.3l1.6,2L409.4,338.6z M583,333.6l6.4,7.9
l-11.2,4l-8.1,2.9l0,0l-0.3,0.1l0,0l-1.2,0.4l0,0l-1.2,0.4l0,0l-1.3,0.4l0,0l-1.3,0.4l0,0l-1.3,0.3l-1.3,0.3l0,0l-1.3,0.3l0,0
l-1.3,0.3l-1.3,0.2l0,0l-1.3,0.2l0,0l-1.4,0.2l0,0l-1.4,0.2l0,0l-1.4,0.1l0,0l-1.4,0.1l0,0l-1.4,0.1l0,0l-0.6,0l-1.2-9.2l6.7-8.7
l1.7,0.6l3,1.1l0,0h0l6.7-8.6l7.8,2.7l0,0l3.9,1.3L583,333.6z M547.7,352.8L547.7,352.8l-1.4,0l0,0l-1.4,0l0,0h-1.4h-1.4l0,0
l-1.4,0l0,0l-1.4,0l0,0l-1.4-0.1l0,0l-1.4-0.1l0,0l-1.4-0.1l0,0l-1.3-0.1l0,0l-1.3-0.2l0,0l-1.3-0.2l0,0l-1.3-0.2l0,0l-1.3-0.2
l-1.3-0.3l0,0l-1.3-0.3l0,0l-1.3-0.3l-1.3-0.3l0,0l-1.3-0.4l0,0l-1.2-0.4l0,0l-1.2-0.4l0,0l-0.6-0.2l-3.8-1.3l16.5-21.3l15,5.2
l-0.4,0.5l0,0l0,0l0,0l0,0l0,0l0,0l0,0l0,0l8.1,2.8l-6.7,8.7l0,0l0,0l0,0l0,0l1.2,9.2L547.7,352.8z M531.5,326.1l-16.5,21.3
l-15.6-5.4l16.5-21.3L531.5,326.1z M480.2,327.6l11.7-15.1l23.9,8.2L499.3,342l-23.9-8.2L480.2,327.6z M475.3,333.9l23.9,8.2v9
l-23.9-8.2V333.9z M499.4,342.2l15.6,5.4v9l-15.6-5.4V342.2z M589.5,341.6l11.9-4.3v9l-11.9,4.3V341.6z M220.3,362.3v-8.9
l10.1,12.5l-4.6,1.7l0,0l0,0l0,0l0,0l0,0l0,0l0,0v1.4L220.3,362.3z M474.6,334.9L474.6,334.9L474.6,334.9l-1.3-0.3l0,0l0,0
l-1.3-0.3l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.2l0,0l0,0l-1.3-0.1l0,0l0,0l-1.3-0.1l0,0l0,0
l-1.3-0.1l0,0l-1.3-0.1l0,0l0,0l-1.3-0.1l0,0l0,0l-1.3,0l0,0l-1.3,0l0,0h-1.3l0,0l0,0h-1.3l0,0l0,0l-1.3,0l0,0l0,0l-1.3,0l0,0l0,0
l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.1l0,0l0,0l-1.3,0.2l0,0l0,0l-1.3,0.2l0,0l0,0l-1.3,0.2l0,0l0,0
l-1.3,0.2l0,0l0,0l-1.3,0.3l0,0l0,0l-1.3,0.3l0,0l0,0l-1.2,0.3l0,0l0,0l-1.2,0.3l0,0l0,0l-1.2,0.4l0,0l0,0l-1.2,0.4l0,0l0,0
l-1.2,0.4l0,0l0,0l-0.1,0v-6.3l0,0l0,0l0,0l0,0l-1.6-2l0.6-0.2l0,0l1.2-0.4l0,0l1.2-0.4l0,0l1.2-0.4l0,0l1.2-0.4l0,0l1.2-0.3l0,0
l1.2-0.3l0,0l1.3-0.3l0,0l1.3-0.3l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.2l0,0l1.3-0.1l0,0l1.3-0.1l0,0l1.3-0.1l0,0l1.3-0.1
l0,0l1.3,0l0,0l1.3,0l0,0h1.3h1.3l0,0l1.3,0l0,0l1.3,0l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.1l0,0l1.3,0.2
l0,0l1.3,0.2l0,0l1.3,0.2l0,0l1.3,0.2l0,0l1.3,0.3l0,0l1.2,0.3l1.2,0.3l0,0l1.2,0.3l0,0l1.2,0.4l0,0l1.2,0.4l0,0l0.5,0.2l-4.8,6.2
l0,0l0,0l0,0l0,0v1.2L474.6,334.9z M601.5,337.2L601.5,337.2L601.5,337.2C601.5,337.2,601.5,337.2,601.5,337.2l-1.6-2l23.8-8.6v9
l-22.1,7.9V337.2L601.5,337.2z"/>
</g>
</svg>
Since AI won't strip ids when resaving the svg you can retain all class names.
However, you need to find a proper naming scheme to get the desired selectors.

How to import a local SVG file in React?

I am trying to import a local SVG file in React but I keep coming across this error:
My code looks like this:
import React from "react";
import styled from "styled-components";
import { ReactComponent as Logo } from "./images/logo.svg";
const MainImage = styled.div`
height: 400px;
width: 100%;
background: #026857;
`;
const Home = () => {
return (
<div className="home">
<MainImage>
<Logo />
</MainImage>
</div>
);
};
export default Home;
I have tried many solutions offered by others such as importing default as Logo, creating an image prop to contain the local svg (<img src={'./images/logo.svg'}/> ) but none have given me any success so far. I believe I may have to add something to my Webpack config file but I'm not sure what it is and where I should put it, as the config file is nearly 800 lines of code.
Also, I am using SVG files from https://undraw.co/ if the information helps, it seems their illustrations have many tags in them which I have not seen in simple SVG icons.
<svg
id="f6dc6f51-58d1-4328-a543-5a2c5176acea"
dataName="Layer 1"
xmlns="http://www.w3.org/2000/svg"
width="922.18516"
height="747.35665"
viewBox="0 0 922.18516 747.35665"
>
<path
d="M420.91148,313.56734c-2.67984,100.75634,131.62869,203.61052,299.27661,203.61052S1154.817,318.5411,1028.01831,313.56734c-244.32514-9.5838-328.052-110.77046-303.55341-182.5C768.33985,2.60566,426.18809,115.17786,420.91148,313.56734Z"
transform="translate(-138.90742 -76.32167)"
fill="#3f3d56"
/>
<polygon
points="505.004 157.445 502.96 156.144 504.261 154.1 503.703 153.746 502.403 155.79 500.359 154.489 500.004 155.046 502.048 156.347 500.747 158.391 501.305 158.746 502.605 156.702 504.649 158.002 505.004 157.445"
fill="#fcce33"
/>
<polygon
points="657.004 305.445 654.96 304.144 656.261 302.1 655.703 301.746 654.403 303.79 652.359 302.489 652.004 303.046 654.048 304.347 652.747 306.391 653.305 306.746 654.605 304.702 656.649 306.002 657.004 305.445"
fill="#fcce33"
/>
...
assuming you are using Webpack 5, you need to configure your webpack loader to something like this using asset modules:
module: {
rules: [
{
test: /\.svg$/i,
type: 'asset/resource',
},
...
]
}
if you are using webpack 4, you can use file-loader instead of asset/resource:
module: {
rules: [
{
test: /\.svg$/i,
use: [
{
loader: 'file-loader',
},
],
},
...
]
}
then you can import your svg file like this:
import Logo from "./images/logo.svg";
//...
return <img src={Logo} />
I usually always convert each SVG into its own component like so
import * as React from "react";
const ArrowDownSVG = (props: React.SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
strokeWidth={2}
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
viewBox="0 0 24 24"
{...props}
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M6 9l6 6 6-6" />
</svg>
);
export default ArrowDownSVG;
Has worked for me in the past year or so
By leaving out the type for the props, you can use this in plain JS as well

Aligning text around center in pie chart using svg circle and text

I've created a pie chart using react and svg circles. Now I want to position the text labels so that the text starts close to the middle of the circle and continue outwards, wheel of fortune style.
This is my code, rendering the svgs. In chrome dev tools I tried to apply tranform: rotate(45deg); and adjusting the number but the text keeps flyying away outside the circle.
<svg viewBox="0 0 32 32">
{elements.map((element, index) => (
<g>
<circle
key={_id}
r={16 / 1.0053}
cx={'50%'}
cy={'50%'}
style={{
strokeDasharray: `${percentage}, 100.53`,
strokeDashoffset: -offset,
stroke: segmentColor,
}}
textAnchor="middle"
></circle>
<text
textAnchor="middle"
x={'50%'}
y={'50%'}
fontFamily={'sans-serif'}
fontSize={'20px'}
fill="black"
textAnchor="start"
>
{title}
</text>
</g>
))}
</svg>
```
The issue is that rotation is about the origin, which is the top left of your image. The easiest way around this is to change the viewBox so the origin is in the center of your SVG: viewBox="-16 -16 32 32".
Then you calculate the angle based on the offset and the percentage.
I assume you have some elements like this:
const elements = [
{ percentage: 15, offset: 0, title: 'title', segmentColor: 'red' },
{ percentage: 40, offset: 15, title: 'another title', segmentColor: 'blue' },
{ percentage: 25, offset: 55, title: 'and another', segmentColor: 'green' },
{ percentage: 20, offset: 80, title: 'yet another', segmentColor: 'black' },
];
So something like this would work:
<svg viewBox="-16 -16 32 32">
{elements.map((element, index) => {
const angle = (element.offset + element.percentage / 2) * 360 / 100;
return <g key={index}>
<circle
r={15.5}
style={{
fill: 'none',
strokeDasharray: `${element.percentage}, 100.53`,
strokeDashoffset: -element.offset,
stroke: element.segmentColor,
}}
textAnchor="middle"
></circle>
<text
x="10%"
transform={`rotate(${angle})`}
fontFamily={'sans-serif'}
fontSize={'2px'}
fill="black"
textAnchor="start"
alignmentBaseline="middle"
>
{element.title}
</text>
</g>
})}
</svg>
Now the x value on the text determined how from the center the text starts.

Resources