on xenial help sign in
Updated the visuals of the SwipeToAct-widget for incoming-call snap-decision notifications according to new design-spec.

Approved by: Daniel d'Andrada

commitf74aa057b10573755d23d218509a16f6f8e7cf33 authorMirco Müller <mirco.mueller@canonical.com> dateWed 18 Mar 2015, 10:18 (12 years ago) parent28b1389dc39ffd
2 files changed+328−247
qml/Notifications/SwipeToAct.qml+178−247 qml/Notifications/grip-large.svg+150
qml/Notifications/SwipeToAct.qml+178−247
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 20014-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -16,12 +16,10 @@
1616
1717import QtQuick 2.3
1818import Ubuntu.Components 1.1
19−import QtGraphicalEffects 1.0
2019
2120Item {
2221 id: swipeToAct
2322
24− width: parent.width
2523 height: childrenRect.height
2624
2725 signal leftTriggered()
@@ -29,280 +27,213 @@ Item {
2927
3028 property string leftIconName
3129 property string rightIconName
32− readonly property double sliderHeight: units.gu(6)
33− readonly property double gap: units.gu(1)
34− readonly property double halfWay: mouseArea.drag.maximumX / 2
3530
36− Rectangle {
37− id: gradient
38− width: parent.width * 5
39− height: sliderHeight
40− visible: false
41− LinearGradient {
42− anchors.fill: parent
43− start: Qt.point(parent.x, parent.y)
44− end: Qt.point(parent.width, parent.y)
45− gradient: Gradient {
46− GradientStop { position: 0.0; color: UbuntuColors.red }
47− GradientStop { position: 0.2; color: UbuntuColors.red }
48− GradientStop { position: 0.4; color: "#dddddd" }
49− GradientStop { position: 0.6; color: "#dddddd" }
50− GradientStop { position: 0.8; color: UbuntuColors.green }
51− GradientStop { position: 1.0; color: UbuntuColors.green }
52− }
31+ QtObject {
32+ id: priv
33+
34+ property double opacityDelta
35+ readonly property double sliderHeight: units.gu(8)
36+ readonly property double gap: units.gu(1)
37+ readonly property color sliderMainColor: "#b2b2b2"
38+ readonly property color sliderBGColor: "#f4f4f4"
39+ readonly property double halfWay: mouseArea.drag.maximumX / 2
40+
41+ UbuntuNumberAnimation on opacityDelta {
42+ from: 0
43+ to: .5
44+ loops: Animation.Infinite
45+ duration: UbuntuAnimation.SleepyDuration
46+ easing.type: Easing.Linear
5347 }
54− }
5548
56− ShaderEffectSource {
57− id: effectSourceGradient
58− sourceItem: gradient
59− width: gradient.width
60− height: gradient.height
61− sourceRect: Qt.rect(0.4 * gradient.width * (slider.x / halfWay), 0, mask.width, mask.height)
62− visible: false
63− hideSource: true
49+ // linearly interpolate between start- and end-color
50+ // with a normalized weight-factor
51+ // 0.0 meaning just the start-color being taken into
52+ // account and 1.0 only taking the end-color into
53+ // account
54+ function interpolate(start, end, factor) {
55+ var rdiff = start.r > end.r ? end.r - start.r : end.r - start.r
56+ var gdiff = start.g > end.g ? end.g - start.g : end.g - start.g
57+ var bdiff = start.b > end.b ? end.b - start.b : end.b - start.b
58+ var adiff = start.a > end.a ? end.a - start.a : end.a - start.a
59+ var r = start.r + factor * rdiff
60+ var g = start.g + factor * gdiff
61+ var b = start.b + factor * bdiff
62+ var a = start.a + factor * adiff
63+ return Qt.rgba(r,g,b,a)
64+ }
6465 }
6566
6667 UbuntuShape {
67− id: mask
68− color: "black"
68+ id: row
6969 width: parent.width
70− height: sliderHeight
70+ height: priv.sliderHeight
71+ color: priv.sliderBGColor
7172 borderSource: "none"
72− visible: false
73− }
7473
75− ShaderEffectSource {
76− id: effectSourceMask
77− sourceItem: mask
78− width: mask.width
79− height: mask.height
80− visible: false
81− hideSource: true
82− }
83−
84− ShaderEffect {
85− width: parent.width
86− height: sliderHeight
87− property variant mask: effectSourceMask
88− property variant gradient: effectSourceGradient
89− vertexShader: "
90− uniform highp mat4 qt_Matrix;
91− attribute highp vec4 qt_Vertex;
92− attribute highp vec2 qt_MultiTexCoord0;
93− varying highp vec2 coord;
94− void main() {
95− coord = qt_MultiTexCoord0;
96− gl_Position = qt_Matrix * qt_Vertex;
97− }"
98− fragmentShader: "
99− varying highp vec2 coord;
100− uniform sampler2D mask;
101− uniform sampler2D gradient;
102− void main() {
103− lowp vec4 texMask = texture2D(mask, coord);
104− lowp vec4 texGradient = texture2D(gradient, coord);
105− gl_FragColor = texGradient.rgba * texMask.a ;
106− }"
74+ UbuntuShape {
75+ id: leftShape
76+ anchors.top: parent.top
77+ anchors.left: parent.left
78+ anchors.margins: priv.gap
79+ color: UbuntuColors.red
80+ borderSource: "none"
81+
82+ state: "normal"
83+ height: units.gu(6)
84+ width: units.gu(6)
85+ radius: "medium"
86+ opacity: slider.x <= priv.halfWay ? 1.0 : 1.0 - ((slider.x - priv.halfWay) / priv.halfWay)
87+
88+ Icon {
89+ anchors.centerIn: parent
90+ width: units.gu(3.5)
91+ height: units.gu(3.5)
92+ name: leftIconName
93+ color: "white"
94+ }
95+ }
10796
10897 Row {
109− id: row
110− anchors.fill: parent
111− spacing: gap
112− anchors.margins: gap
113−
114− UbuntuShape {
115− id: leftShape
116− states: [
117− State {
118− name: "normal"
119− PropertyChanges {
120− target: leftShape
121− color: UbuntuColors.red
122− }
123− PropertyChanges {
124− target: innerLeftShape
125− color: UbuntuColors.red
126− visible: false
127− }
128− },
129− State {
130− name: "selected"
131− PropertyChanges {
132− target: leftShape
133− color: "white"
134− }
135− PropertyChanges {
136− target: innerLeftShape
137− color: UbuntuColors.red
138− visible: true
139− }
140− }
141− ]
142− state: "normal"
143− height: units.gu(4)
144− width: units.gu(7)
145− borderSource: "none"
146− opacity: slider.x <= halfWay ? 1.0 : 1.0 - ((slider.x - halfWay) / halfWay)
147− UbuntuShape {
148− id: innerLeftShape
149− anchors.centerIn: parent
150− borderSource: "none"
151− width: parent.width - units.gu(.5)
152− height: parent.height - units.gu(.5)
153− }
154− Icon {
155− anchors.centerIn: parent
156− width: units.gu(2)
157− height: units.gu(2)
158− name: leftIconName
159− color: "white"
160− }
98+ anchors.verticalCenter: parent.verticalCenter
99+ anchors.right: slider.left
100+ anchors.rightMargin: units.gu(1.5)
101+ spacing: -units.gu(1)
102+ visible: slider.x === priv.halfWay
103+ Icon {
104+ name: "back"
105+ height: units.gu(2.5)
106+ color: priv.sliderMainColor
107+ opacity: .5 + priv.opacityDelta
161108 }
162−
163− Rectangle {
164− id: leftSpacer
165− width: (row.width - (leftShape.width + slider.width + rightShape.width + 4 * row.spacing)) / 2
166− height: units.gu(4)
167− opacity: 0
109+ Icon {
110+ name: "back"
111+ height: units.gu(2.5)
112+ color: priv.sliderMainColor
113+ opacity: 1 - priv.opacityDelta
168114 }
115+ }
169116
170− UbuntuShape {
171− id: slider
172− objectName: "slider"
117+ UbuntuShape {
118+ id: slider
119+ objectName: "slider"
120+ anchors.top: parent.top
121+ anchors.margins: priv.gap
122+ x: priv.halfWay
173123
174− Behavior on x {
175− UbuntuNumberAnimation {
176− duration: UbuntuAnimation.FastDuration
177− easing.type: Easing.OutBounce
178− }
179− }
124+ Component.onCompleted: {
125+ xBehavior.enabled = true
126+ }
180127
181− Behavior on opacity {
182− UbuntuNumberAnimation {
183− duration: UbuntuAnimation.FastDuration
184− }
128+ Behavior on x {
129+ id: xBehavior
130+ enabled: false
131+ UbuntuNumberAnimation {
132+ duration: UbuntuAnimation.FastDuration
133+ easing.type: Easing.OutBounce
185134 }
135+ }
186136
187− onOpacityChanged: {
188− if (opacity === 0) {
189− if (rightShape.state === "selected") {
190− rightTriggered()
191− }
192− if (leftShape.state === "selected") {
193− leftTriggered()
194− }
195− }
137+ Behavior on opacity {
138+ UbuntuNumberAnimation {
139+ duration: UbuntuAnimation.FastDuration
196140 }
141+ }
197142
198− z: 1
199− color: "white"
200− height: units.gu(4)
201− width: units.gu(7)
202− borderSource: "none"
203− Row {
204− anchors.fill: parent
205− spacing: 2 * gap
206− anchors.leftMargin: units.gu(.5)
207− anchors.rightMargin: units.gu(.5)
208− Icon {
209− anchors.verticalCenter: parent.verticalCenter
210− name: "back"
211− width: units.gu(2)
212− height: units.gu(2)
213− }
214− Icon {
215− anchors.verticalCenter: parent.verticalCenter
216− name: "next"
217− width: units.gu(2)
218− height: units.gu(2)
219− }
143+ onXChanged: {
144+ var factor
145+ if (slider.x <= priv.gap + leftShape.width)
146+ {
147+ factor = (slider.x - priv.gap) / leftShape.width
148+ slider.color = priv.interpolate(leftShape.color, priv.sliderMainColor, factor)
149+ } else if (slider.x >= rightShape.x - slider.width) {
150+ factor = (slider.x - rightShape.x + rightShape.width) / rightShape.width
151+ slider.color = priv.interpolate(priv.sliderMainColor, rightShape.color, factor)
152+ } else {
153+ slider.color = priv.sliderMainColor
220154 }
221155 }
222156
223− Rectangle {
224− id: rightSpacer
225− width: leftSpacer.width
226− height: units.gu(4)
227− opacity: 0
157+ z: 1
158+ color: priv.sliderMainColor
159+ height: units.gu(6)
160+ width: units.gu(6)
161+ borderSource: "none"
162+ radius: "medium"
163+ Icon {
164+ anchors.fill: parent
165+ anchors.margins: units.gu(1.5)
166+ source: "grip-large.svg"
167+ color: "white"
228168 }
169+ }
170+ Row {
171+ anchors.verticalCenter: parent.verticalCenter
172+ anchors.left: slider.right
173+ anchors.leftMargin: units.gu(1.5)
174+ spacing: -units.gu(1)
175+ visible: slider.x === priv.halfWay
176+ Icon {
177+ name: "next"
178+ height: units.gu(2.5)
179+ color: priv.sliderMainColor
180+ opacity: 1 - priv.opacityDelta
181+ }
182+ Icon {
183+ name: "next"
184+ height: units.gu(2.5)
185+ color: priv.sliderMainColor
186+ opacity: 0.5 + priv.opacityDelta
187+ }
188+ }
229189
230− UbuntuShape {
231− id: rightShape
232− states: [
233− State {
234− name: "normal"
235− PropertyChanges {
236− target: rightShape
237− color: UbuntuColors.green
238− }
239− PropertyChanges {
240− target: innerRightShape
241− color: UbuntuColors.green
242− visible: false
243− }
244− },
245− State {
246− name: "selected"
247− PropertyChanges {
248− target: rightShape
249− color: "white"
250− }
251− PropertyChanges {
252− target: innerRightShape
253− color: UbuntuColors.green
254− visible: true
255− }
256− }
257− ]
258− state: "normal"
259− height: units.gu(4)
260− width: units.gu(7)
261− borderSource: "none"
262− opacity: slider.x >= halfWay ? 1.0 : slider.x / halfWay
263− UbuntuShape {
264− id: innerRightShape
265− anchors.centerIn: parent
266− borderSource: "none"
267− width: parent.width - units.gu(.5)
268− height: parent.height - units.gu(.5)
269− }
270− Icon {
271− anchors.centerIn: parent
272− width: units.gu(2)
273− height: units.gu(2)
274− name: rightIconName
275− color: "white"
276− }
190+ UbuntuShape {
191+ id: rightShape
192+ anchors.top: parent.top
193+ anchors.right: parent.right
194+ anchors.margins: priv.gap
195+ color: UbuntuColors.green
196+ borderSource: "none"
197+
198+ state: "normal"
199+ height: units.gu(6)
200+ width: units.gu(6)
201+ radius: "medium"
202+ opacity: slider.x >= priv.halfWay ? 1.0 : slider.x / priv.halfWay
203+
204+ Icon {
205+ anchors.centerIn: parent
206+ width: units.gu(3.5)
207+ height: units.gu(3.5)
208+ name: rightIconName
209+ color: "white"
277210 }
278211 }
212+ }
279213
280− MouseArea {
281− id: mouseArea
282− objectName: "swipeMouseArea"
214+ MouseArea {
215+ id: mouseArea
216+ objectName: "swipeMouseArea"
283217
284− anchors.fill: row
285− drag.target: slider
286− drag.axis: Drag.XAxis
287− drag.minimumX: 0
288− drag.maximumX: row.width - slider.width
218+ anchors.fill: row
219+ drag.target: slider
220+ drag.axis: Drag.XAxis
221+ drag.minimumX: priv.gap
222+ drag.maximumX: row.width - slider.width - priv.gap
289223
290− onReleased: {
291− if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
292− slider.x = halfWay
293− }
294− if (slider.x === drag.minimumX) {
295− slider.x = drag.minimumX
296− slider.opacity = 0
297− enabled = false
298− leftShape.state = "selected"
299− }
300− if (slider.x === drag.maximumX) {
301− slider.x = drag.maximumX
302− slider.opacity = 0
303− enabled = false
304− rightShape.state = "selected"
305− }
224+ onReleased: {
225+ if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
226+ slider.x = priv.halfWay
227+ }
228+ if (slider.x === drag.minimumX) {
229+ slider.x = drag.minimumX
230+ enabled = false
231+ leftTriggered()
232+ }
233+ if (slider.x === drag.maximumX) {
234+ slider.x = drag.maximumX
235+ enabled = false
236+ rightTriggered()
306237 }
307238 }
308239 }
qml/Notifications/grip-large.svgnew file+150
@@ -0,0 +1,150 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+
4+<svg
5+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6+ xmlns:cc="http://creativecommons.org/ns#"
7+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8+ xmlns:svg="http://www.w3.org/2000/svg"
9+ xmlns="http://www.w3.org/2000/svg"
10+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12+ width="90"
13+ height="90"
14+ id="svg4874"
15+ version="1.1"
16+ inkscape:version="0.91+devel r"
17+ viewBox="0 0 90 90.000001"
18+ sodipodi:docname="grip-large01.svg">
19+ <defs
20+ id="defs4876" />
21+ <sodipodi:namedview
22+ id="base"
23+ pagecolor="#ffffff"
24+ bordercolor="#666666"
25+ borderopacity="1.0"
26+ inkscape:pageopacity="0.0"
27+ inkscape:pageshadow="2"
28+ inkscape:zoom="7.9580786"
29+ inkscape:cx="13.632541"
30+ inkscape:cy="49.591116"
31+ inkscape:document-units="px"
32+ inkscape:current-layer="g1708"
33+ showgrid="true"
34+ showborder="true"
35+ fit-margin-top="0"
36+ fit-margin-left="0"
37+ fit-margin-right="0"
38+ fit-margin-bottom="0"
39+ inkscape:snap-bbox="true"
40+ inkscape:bbox-paths="true"
41+ inkscape:bbox-nodes="true"
42+ inkscape:snap-bbox-edge-midpoints="true"
43+ inkscape:snap-bbox-midpoints="true"
44+ inkscape:object-paths="true"
45+ inkscape:snap-intersection-paths="true"
46+ inkscape:object-nodes="true"
47+ inkscape:snap-smooth-nodes="true"
48+ inkscape:snap-midpoints="true"
49+ inkscape:snap-object-midpoints="true"
50+ inkscape:snap-center="true"
51+ showguides="true"
52+ inkscape:guide-bbox="true">
53+ <inkscape:grid
54+ type="xygrid"
55+ id="grid5451"
56+ empspacing="6" />
57+ <sodipodi:guide
58+ orientation="1,0"
59+ position="6,77"
60+ id="guide4063" />
61+ <sodipodi:guide
62+ orientation="1,0"
63+ position="3,78"
64+ id="guide4065" />
65+ <sodipodi:guide
66+ orientation="0,1"
67+ position="55,84"
68+ id="guide4067" />
69+ <sodipodi:guide
70+ orientation="0,1"
71+ position="53,87"
72+ id="guide4069" />
73+ <sodipodi:guide
74+ orientation="0,1"
75+ position="20,3"
76+ id="guide4071" />
77+ <sodipodi:guide
78+ orientation="0,1"
79+ position="20,6"
80+ id="guide4073" />
81+ <sodipodi:guide
82+ orientation="1,0"
83+ position="87,7"
84+ id="guide4075" />
85+ <sodipodi:guide
86+ orientation="1,0"
87+ position="84,7"
88+ id="guide4077" />
89+ <sodipodi:guide
90+ orientation="0,1"
91+ position="58,81"
92+ id="guide4074" />
93+ <sodipodi:guide
94+ orientation="1,0"
95+ position="9,74"
96+ id="guide4076" />
97+ <sodipodi:guide
98+ orientation="0,1"
99+ position="21,9"
100+ id="guide4078" />
101+ <sodipodi:guide
102+ orientation="1,0"
103+ position="81,4"
104+ id="guide4080" />
105+ </sodipodi:namedview>
106+ <metadata
107+ id="metadata4879">
108+ <rdf:RDF>
109+ <cc:Work
110+ rdf:about="">
111+ <dc:format>image/svg+xml</dc:format>
112+ <dc:type
113+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
114+ <dc:title></dc:title>
115+ </cc:Work>
116+ </rdf:RDF>
117+ </metadata>
118+ <g
119+ inkscape:label="Layer 1"
120+ inkscape:groupmode="layer"
121+ id="layer1"
122+ transform="translate(67.857146,-84.50504)">
123+ <g
124+ transform="matrix(0,-1,-1,0,373.50506,516.50504)"
125+ id="g4845"
126+ style="display:inline">
127+ <g
128+ inkscape:label="Layer 1"
129+ id="g1708"
130+ transform="matrix(0,-1,-1,0,1394.3622,441.36221)"
131+ inkscape:export-filename="add01.png"
132+ inkscape:export-xdpi="90"
133+ inkscape:export-ydpi="90">
134+ <rect
135+ style="color:#000000;fill:none;stroke:none;stroke-width:7.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
136+ id="rect1710"
137+ width="90"
138+ height="90"
139+ x="0"
140+ y="962.36218" />
141+ <path
142+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
143+ d="m 9.000004,971.3622 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m -72,16 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.79086 -4,4 0,2.20914 1.790861,4 4,4 2.209139,0 4,-1.79086 4,-4 0,-2.20914 -1.790861,-4 -4,-4 z m -72,16 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m -72,16 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m -72,16 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 18.199219,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z m 17.800781,0 c -2.209139,0 -4,1.7909 -4,4 0,2.2091 1.790861,4 4,4 2.209139,0 4,-1.7909 4,-4 0,-2.2091 -1.790861,-4 -4,-4 z"
144+ id="path4169"
145+ inkscape:connector-curvature="0"
146+ sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" />
147+ </g>
148+ </g>
149+ </g>
150+</svg>