Adding root cause analysis to alarms

Change-Id: I736e7953fdf945c752db0f6465e3cda646d97604
This commit is contained in:
Alon Heller 2016-02-23 13:23:50 +02:00
parent 7b6e279c75
commit 82a7a14e1c
58 changed files with 12805 additions and 23 deletions

View File

@ -51,7 +51,7 @@ class Alarms(generic.View):
def get(self, request, vitrage_id):
"""Get a single entity's alarm with the vitrage id.
The following get alarma may be passed in the GET
The following get alarm may be passed in the GET
:param vitrage_id the id of the vitrage entity
@ -59,3 +59,21 @@ class Alarms(generic.View):
"""
return api.vitrage.alarms(request, vitrage_id)
@urls.register
class Rca(generic.View):
"""API for vitrage rca."""
url_regex = r'vitrage/rca/(?P<alarm_id>.+|default)/$'
@rest_utils.ajax()
def get(self, request, alarm_id):
"""Get rca graph for an alarm.
:param alarm_id the id of the alarm
The result is an rca graph.
"""
return api.vitrage.rca(request, alarm_id)

View File

@ -36,3 +36,7 @@ def topology(request):
def alarms(request, vitrage_id='all'):
return vitrageclient(request).alarms.list(vitrage_id=vitrage_id)
def rca(request, alarm_id):
return vitrageclient(request).rca.get(alarm_id=alarm_id)

View File

@ -15,7 +15,8 @@
var service = {
getTopology: getTopology,
getAlarms: getAlarms
getAlarms: getAlarms,
getRca: getRca
};
return service;
@ -39,6 +40,13 @@
});
}
function getRca(alarm_id) {
return apiService.get('/api/vitrage/rca/'+alarm_id)
.error(function () {
toastService.add('error', gettext('Unable to fetch the Vitrage RCA service.'));
});
}
}
}());

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFxAAABfAAAAZ3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABQEBAQAAAAAAAAAAAAAAAAAAAAUQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACmIl4A
AAAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//aAAgBAwIG
PwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_" display="inline">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_" display="inline">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_" display="inline">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_" display="inline">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFxAAABfAAAAZ3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABQEBAQAAAAAAAAAAAAAAAAAAAAUQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACmIl4A
AAAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//aAAgBAwIG
PwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFyAAABfQAAAZ7/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAAAAAAAAAAAAAAAAAAAAAwEBAQEAAAAAAAAAAAAAAAAAAAQGEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAoItQ
AAAAAAAB/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMC
Bj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_" display="inline">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_" display="inline">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_" display="inline">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_" display="inline">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFyAAABfQAAAZ7/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAAAAAAAAAAAAAAAAAAAAAwEBAQEAAAAAAAAAAAAAAAAAAAQGEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAoItQ
AAAAAAAB/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMC
Bj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFzAAABfgAAAZ//2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAAAAAAAAAAAAAAAAAAAABgEBAQEAAAAAAAAAAAAAAAAAAAUGEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAApRkK
IAAAAAAAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAED
AgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_" display="inline">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_" display="inline">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_" display="inline">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g display="none">
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_" display="inline">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1,161 @@
<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 33.9 33.9" enable-background="new 0 0 33.9 33.9" xml:space="preserve">
<g>
<g>
<defs>
<path id="SVGID_1_" d="M17,0c9.4,0,17,7.6,17,17c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17C0,7.6,7.6,0,17,0L17,0z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFzAAABfgAAAZ//2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAAAAAAAAAAAAAAAAAAAABgEBAQEAAAAAAAAAAAAAAAAAAAUGEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAApRkK
IAAAAAAAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAED
AgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_3_" d="M13.1,25.2c0-0.1,0-0.3,0.1-0.5c-2,0-4.1,0-4.1,0c-0.8,0-1.4-0.7-1.4-1.6c0-0.5,0.2-0.9,0.5-1.3
c0.1-0.1,0.6-0.8,1.1-1.4c1-1.4,1.8-2.4,2.1-2.8c0,0,0.1-0.2,0.1-0.7c0-0.4,0-0.9-0.1-1.5l-0.1-1.6c0,0,0,0,0,0s0,0,0,0l0-0.2
c0-3,2.8-5.7,5.8-5.7h0.6c3,0,5.6,2.6,5.6,5.6l0,0.2c0,0,0,0,0,0l-0.1,1.6c0,0.6-0.1,1.1-0.1,1.5c0,0.5,0,0.7,0.1,0.7
c0.3,0.4,1.1,1.4,2.1,2.8c0.4,0.6,1,1.3,1.1,1.4c0.3,0.3,0.5,0.8,0.5,1.3c0,0.9-0.6,1.6-1.4,1.6c0,0-2.4,0-4.6,0
c0.1,0.2,0.1,0.3,0.1,0.5c0,2.3-1.5,3.9-3.8,3.9C14.7,29.1,13.1,27.5,13.1,25.2 M11.4,17.6C11.4,17.6,11.4,17.6,11.4,17.6
C11.4,17.6,11.4,17.6,11.4,17.6 M23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6C23.2,17.6,23.2,17.6,23.2,17.6"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_4_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFwAAABewAAAZz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABfAAEBAAAAAAAAAAAAAAAAAAAABgEBAQAAAAAAAAAAAAAAAAAAAAIQAQEAAAAAAAAAAAAAAAAA
ADBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACVCgAA
AAAAAP/aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oACAEDAgY/
AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_5_" d="M25.4,23.7c-0.4,0-15.9,0-16.3,0c-0.4,0-0.6-0.7-0.2-1.2c0.4-0.4,2.7-3.7,3.2-4.2c0.5-0.5,0.3-2.1,0.2-4.5
c-0.1-2.5,2.3-4.8,4.8-4.8c0.2,0,0.4,0,0.6,0c2.5,0,4.7,2.3,4.6,4.8c-0.1,2.5-0.4,4,0.2,4.5c0.5,0.5,2.9,3.8,3.2,4.2
C26,23,25.9,23.7,25.4,23.7L25.4,23.7z M17,28.1c-1.6,0-3-0.9-3-2.9c0,0,1.4,0,1.4,0h3.1c0,0,1.3,0,1.3,0
C19.9,27.2,18.6,28.1,17,28.1L17,28.1z"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAFvAAABegAAAZv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABeAAEBAAAAAAAAAAAAAAAAAAAABgEBAAAAAAAAAAAAAAAAAAAAABABAQAAAAAAAAAAAAAAAAAA
MEARAQAAAAAAAAAAAAAAAAAAAEASAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAALwAAAAA
AAAH/9oACAECAAEFAB//2gAIAQMAAQUAH//aAAgBAQABBQCn/9oACAECAgY/AB//2gAIAQMCBj8A
H//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_7_" d="M11.8,9.6C12,9.5,12,9.5,12,9.5c0.3-0.1,0.3-0.5,0.2-0.7l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-1.3,1-2.2,2.5-2.2,4.3c0,1,0.3,2,0.9,2.8c0.2,0.2,0.2,0.2,0.2,0.2c0.2,0.2,0.6,0.3,0.9,0.1l0,0c0.3-0.2,0.3-0.5,0.1-0.7
c0,0,0,0-0.2-0.2C10.3,14.6,10,13.8,10,13C10,11.6,10.7,10.4,11.8,9.6L11.8,9.6z"/>
</defs>
<clipPath id="SVGID_8_">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_8_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF3AAABggAAAaP/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEAAAAAAAAAAAAAAAAAAAABEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAyYsS
6kuUColipLAAAAD/2gAIAQIAAQUAH//aAAgBAwABBQAf/9oACAEBAAEFAKf/2gAIAQICBj8AH//a
AAgBAwIGPwAf/9oACAEBAQY/AE//2Q==" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_9_" d="M10.4,7.7c0.2-0.2,0.2-0.2,0.2-0.2c0.3-0.2,0.4-0.5,0.2-0.8l0,0c-0.2-0.3-0.6-0.4-0.9-0.2c0,0,0,0-0.3,0.2
c-2,1.4-3.2,3.7-3.2,6.3c0,1.5,0.5,2.9,1.3,4.1c0.1,0.2,0.1,0.2,0.1,0.2c0.2,0.2,0.6,0.3,0.8,0.1l0,0C9,17.3,9.1,17,8.9,16.8
c0,0,0,0-0.1-0.2c-0.7-1-1.1-2.2-1.1-3.5C7.6,10.8,8.7,8.9,10.4,7.7L10.4,7.7z"/>
</defs>
<clipPath id="SVGID_10_">
<use xlink:href="#SVGID_9_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_10_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF/AAABigAAAav/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQYBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAAQAQIDBAEQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADKhpJrSUBKwaSa0lAQAAD/2gAIAQIAAQUAp//aAAgBAwABBQBFzH//2gAIAQEAAQUA0//aAAgB
AgIGPwAf/9oACAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_11_" d="M22.6,9.6c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.1-0.3-0.5-0.2-0.7l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c1.3,1,2.2,2.5,2.2,4.3c0,1-0.3,2-0.9,2.8c-0.2,0.2-0.2,0.2-0.2,0.2c-0.2,0.2-0.6,0.3-0.9,0.1l0,0
c-0.3-0.2-0.3-0.5-0.1-0.7c0,0,0,0,0.2-0.2c0.4-0.6,0.7-1.4,0.7-2.2C24.4,11.6,23.7,10.4,22.6,9.6L22.6,9.6z"/>
</defs>
<clipPath id="SVGID_12_">
<use xlink:href="#SVGID_11_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_12_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAGBAAABjAAAAa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABlAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEBAAAAAAAAAAAAAAAAAAABAhAAAQUAAAAAAAAAAAAA
AAAAIAAwQAEREQEAAAAAAAAAAAAAAAAAAABAEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEA
AADP60msoKBJrSTNZJLWSQCAAf/aAAgBAgABBQBn/9oACAEDAAEFAKDVof/aAAgBAQABBQCT/9oA
CAECAgY/AB//2gAIAQMCBj8AH//aAAgBAQEGPwBP/9k=" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
<g>
<defs>
<path id="SVGID_13_" d="M24.1,7.7c-0.2-0.2-0.2-0.2-0.2-0.2c-0.3-0.2-0.4-0.5-0.2-0.8l0,0c0.2-0.3,0.6-0.4,0.9-0.2
c0,0,0,0,0.3,0.2c2,1.4,3.2,3.7,3.2,6.3c0,1.5-0.5,2.9-1.3,4.1c-0.1,0.2-0.1,0.2-0.1,0.2c-0.2,0.2-0.6,0.3-0.8,0.1l0,0
c-0.3-0.2-0.4-0.5-0.2-0.7c0,0,0,0,0.1-0.2c0.7-1,1.1-2.2,1.1-3.5C26.8,10.8,25.7,8.9,24.1,7.7L24.1,7.7z"/>
</defs>
<clipPath id="SVGID_14_">
<use xlink:href="#SVGID_13_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_14_)">
<image overflow="visible" width="35" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAF2AAABgQAAAaL/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMAIwMBIgACEQEDEQH/
xABgAAEBAQAAAAAAAAAAAAAAAAAABQcBAQEAAAAAAAAAAAAAAAAAAAACEAEBAAAAAAAAAAAAAAAA
AAAwQBEBAAAAAAAAAAAAAAAAAAAAQBIBAAAAAAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAz8FY
KAkhNYKAkhIAH//aAAgBAgABBQAf/9oACAEDAAEFAB//2gAIAQEAAQUAp//aAAgBAgIGPwAf/9oA
CAEDAgY/AB//2gAIAQEBBj8AT//Z" transform="matrix(1 0 0 1 -0.6901 -0.4026)">
</image>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -4,31 +4,43 @@ angular
function hzAlarms() {
var directive = {
link: link,
templateUrl: STATIC_URL + 'dashboard/project/components/alarms/alarms.html',
restrict: 'E',
scope:{
selected:'='
scope: {
selected: '='
},
controller : AlarmsController,
controllerAs : 'alarmsCtrl'
controller: AlarmsController,
controllerAs: 'alarmsCtrl'
};
AlarmsController.$inject = ['$scope', 'vitrageTopologySrv'];
AlarmsController.$inject = ['$scope', '$modal', 'vitrageTopologySrv'];
return directive;
function link(scope, element, attrs) {
}
function AlarmsController($scope,vitrageTopologySrv){
function AlarmsController($scope, $modal, vitrageTopologySrv) {
var alarmsCtrl = this;
$scope.$watch('selected', function(newData,oldData) {
if (newData != oldData){
console.log('selected ',newData);
vitrageTopologySrv.getAlarms(newData.vitrage_id).then(function(result){
$scope.$watch('selected', function(newData, oldData) {
if (newData != oldData) {
console.log('selected ', newData);
vitrageTopologySrv.getAlarms(newData.vitrage_id).then(function(result) {
alarmsCtrl.computeAlarms = result.data;
});
}
});
alarmsCtrl.onAlarmClick = function(alarm) {
var modalOptions = {
animation: true,
templateUrl: STATIC_URL + 'dashboard/project/components/rca/rcaContainer.html',
controller: 'RcaContainerController',
windowClass: 'app-modal-window',
resolve: {alarm: function() {
return alarm;
}}
};
$modal.open(modalOptions);
}
}
}

View File

@ -2,7 +2,7 @@
<h1>{$ 'Alarms' | translate $}</h1>
<div class="panel panel-default alarm-list" >
<ul class="panel-body list-group" ng-repeat="alarm in alarmsCtrl.computeAlarms track by $index">
<li class="list-group-item">
<li class="list-group-item" ng-click="alarmsCtrl.onAlarmClick(alarm)">
<h4 class="list-group-item-heading">{$alarm.name$}</h4>
<p class="list-group-item-text">
{$alarm.update_timestamp | date:"h:mma"$} |

View File

@ -1,3 +1,18 @@
/* ------ GLOBAL ------ */
.app-modal-window .modal-dialog{
height: 90%;
width: 90%;
}
.app-modal-window .modal-content{
height: 100%;
width: 100%;
}
/* ------ GLOBAL ------ */
.vitrage-alarms {
.panel-body{
padding: 0;
@ -8,4 +23,8 @@
overflow-y: auto;
}
}
li {
cursor: pointer;
}
}

View File

@ -0,0 +1,33 @@
(function () {
'use strict';
angular
.module('horizon.dashboard.project.vitrage')
.controller('RcaContainerController', RcaContainerController);
RcaContainerController.$inject = ['alarm', '$scope', 'vitrageTopologySrv'];
function RcaContainerController(alarm, $scope, vitrageTopologySrv) {
var vm = this;
$scope.STATIC_URL = STATIC_URL;
vm.isLoading = true;
var getData = function() {
vm.isLoading = true;
vitrageTopologySrv.getRootCauseAnalysis(alarm.vitrage_id)
.then(
function success(result) {
console.log('RCA RESULT: ', result);
$scope.data = result.data;
},
function error(result) {
console.log('Error in RCA:', result);
}
)
};
getData();
}
})();

View File

@ -0,0 +1,3 @@
<div class="rca-container">
<hz-root-cause-analysis-graph data="data" selected="selected"></hz-root-cause-analysis-graph>
</div>

View File

@ -0,0 +1,4 @@
.rca-container {
height: 100%;
background: #CCCCCC;
}

View File

@ -0,0 +1,224 @@
angular
.module('horizon.dashboard.project.vitrage')
.directive('hzRootCauseAnalysisGraph', hzRootCauseAnalysisGraph);
hzRootCauseAnalysisGraph.$inject = ['$filter'];
function hzRootCauseAnalysisGraph($filter) {
var directive = {
link: link,
templateUrl: STATIC_URL + 'dashboard/project/components/rca/rootCauseAnalysisGraph.html',
restrict: 'E'
};
return directive;
function link(scope, element, attr, ctrl) {
scope.STATIC_URL = STATIC_URL;
var lastSelectedNode = {id:"",value:""};
function setSelected(u) {
if (lastSelectedNode.id != "" && lastSelectedNode.id != u){
lastSelectedNode.value.label = replaceAll(lastSelectedNode.value.label, "color: #ffffff", "color: #44575e;");
lastSelectedNode.value.label = replaceAll(lastSelectedNode.value.label, '#FFFFFF" class="fa fa-thumb-tack', '#44575e" class="fa fa-thumb-tack');
g.setNode(lastSelectedNode.id, {
labelType: "html",
label: lastSelectedNode.value.label,
rx: 26,
ry: 26,
padding: 0,
class: replaceAll(lastSelectedNode.value.class, " selectedNode","")
});
}
lastSelectedNode = {id:u, value:g._nodes[u]};
var temp = g._nodes[u];
temp.label = temp.label.replace("background: #ffffff;", "background: #000000");
temp.label = replaceAll(temp.label, "color: #44575e;", "color: #ffffff");
temp.label = replaceAll(temp.label, '#44575e" class="fa fa-thumb-tack', '#FFFFFF" class="fa fa-thumb-tack');
g.setNode(u, {
labelType: "html",
label: temp.label,
rx: 26,
ry: 26,
padding: 0,
class: temp.class + " selectedNode out"
});
scope.selected = getSelectedObject(u);
inner.call(render, g);
}
var replaceAll = function (str, strSearch, strReplaceWith) {
var strRes = str.replace(new RegExp(strSearch, "g"), strReplaceWith);
return strRes;
};
function getSelectedObject(alertId) {
for (var i=0; i < scope.data.nodes.length; i++) {
if (scope.data.nodes[i].id == alertId) {
return scope.data.nodes[i];
}
}
}
function cleanGraph() {
var nodes = g.nodes();
var edges = g.edges();
for (var i = 0; i < nodes.length; i++) {
g.removeNode(nodes[i]);
}
for (var j = 0; j < edges.length; j++) {
g.removeEdge(edges[j]);
}
}
function createGraph() {
draw(scope.data);
}
// Set up zoom support
var svg = d3.select("#root-cause-analysis-graph"),
inner = svg.select("g"),
zoom = d3.behavior.zoom().scaleExtent([0.1, 2]).on("zoom", function () {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
var render = new dagreD3.render();
// Left-to-right layout
var g = new dagreD3.graphlib.Graph();
g.setGraph({
nodesep: 70,
ranksep: 50,
rankdir: "UD",//UD up and down , RL right to left
marginx: 20,
marginy: 20
});
function draw(data) {
angular.forEach(data.nodes, function (key, value) {
var className = " clickable";
var alertName = key.name, // CPU load
alertCategory = key.category, // ALARM
alertInfo = key.info || '', // WARNING - 15min load 1.66 at 32 CPUs
alertResourceId = key.resource_id, // host-0
alertResourceName = key.resource_name, // host-0
alertResourceType = key.resource_type, // nova.host
alertSeverity = key.severity, //WARNING
alertState = key.state, //Active
alertTimeStamp = key.timestamp, //2015-12-01T12:46:41Z
alertType = key.type, //nagios
alertVitrageId = key.vitrage_id;
var html = '';
html += '<div style="padding: 10px; text-shadow: none; width: 378px; height: 115px; color: #44575e; clear:both"';
html+='>';
switch (alertState + '_' + alertSeverity) {
case 'ACTIVE_WARNING':
html += '<img src="/static/dashboard/project/assets/bell_orange_on.svg" style="width: 80px; height: 80px; padding-top: 10px;float: left;">';
break;
default:
html += '<img src="/static/dashboard/project/assets/bell_yellow_on.svg" style="width: 80px; height: 80px; padding-top: 10px;float: left;">';
break;
}
// TBD: When we get the relevant statuses
// case 'ACTIVE_HIGH': /static/dashboard/project/assets/bell_red_on.svg
// case 'Active_WARNING': /static/dashboard/project/assets/bell_orange_on.svg
// case 'ACTIVE_LOW': /static/dashboard/project/assets/bell_yellow_on.svg
// case 'INACTIVE_HIGH': /static/dashboard/project/assets/bell_red_off.svg
// case 'INACTIVE_MEDIUM': /static/dashboard/project/assets/bell_orange_off.svg
// case 'INACTIVE_LOW': /static/dashboard/project/assets/bell_yellow_off.svg
html += '<div style="height: 90px; width: 2px; background: #656a70; float: left; margin-top: 5px; margin-left: 10px;"></div>';
html += '<div>';
html += '<div style="line-height: 2em; padding-left: 10px">';
html += '<div style="font-weight: 600; font-size: 20px; color: #44575e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="'+alertName+'">' + alertName + '</div>';
html += '<div style="font-weight: 400; color: #44575e;">' + alertInfo + '</div>';
html += '<div style="font-weight: 400; color: #44575e;">' + alertTimeStamp + ' | ' + alertState + ' | ' + alertSeverity + '</div>';
html += '<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">';
html += '<span style="font-weight: 600; color: #44575e;">' + alertResourceType + ':</span>';
html += '<span style="font-weight: 400; padding-left: 5px; color: #44575e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis" title="' + alertResourceName + '">' + alertResourceName + '</span>';
html += '</div>';
html += '<div>';
html += '<span style="font-weight: 600; color: #44575e;">Type:</span>';
html += '<span style="font-weight: 400; padding-left: 5px; color: #44575e;">' + alertType + '</span>';
if (key.id == data.inspected_id) {
html+='<span style="float: right"><i title="Root cause analysis relative to this alert" style="font-size: 27px; color: #FFFFFF" class="fa fa-thumb-tack"></i></span>';
}
html += '</div>';
html += '</div></div></div>';
g.setNode(value, {
labelType: "html",
label: html,
rx: 26,
ry: 26,
padding: 0,
class: className
});
});
angular.forEach(data.links, function (key, value) {
g.setEdge(key.source, key.target, {
label: "",
width: 20
});
});
inner.call(render, g);
inner.selectAll(".clickable:not(.update)").
on("click", function(d) {
setSelected(d);
});
setSelected(data.inspected_id);
var verticesLength = data.nodes.length;
// Zoom and scale to fit
var zoomScale = zoom.scale();
var graphWidth = g.graph().width + 80;
var graphHeight = g.graph().height + 40;
var width = parseInt(svg.style("width").replace(/px/, ""));
var height = parseInt(svg.style("height").replace(/px/, ""));
zoomScale = Math.min(width / graphWidth, height / graphHeight)
if (verticesLength < 3) {
zoomScale /= 2;
}
else if (verticesLength < 5) {
zoomScale /= 1.5;
}
var translate = [(width / 2) - ((graphWidth * zoomScale) / 2), (height / 2) - ((graphHeight * zoomScale) / 2)];
zoom.translate(translate);
zoom.scale(zoomScale);
zoom.event(d3.select("#root-cause-analysis-graph svg"));
}
function centerGraph() {
cleanGraph();
draw(scope.data);
}
scope.$watch("data", function (newValue, oldValue) {
console.log('data watch');
if (scope.data) {
console.log('we have data:', scope.data);
createGraph();
}
});
scope.onCenterGraph = function() {
centerGraph();
}
}
}

View File

@ -0,0 +1,5 @@
<div class="root-cause-analysis-graph" id="root-cause-analysis-graph">
<svg>
<g class="diagram"></g>
</svg>
</div>

View File

@ -0,0 +1,67 @@
.root-cause-analysis-graph {
.clickable {
cursor: pointer;
}
.selectedNode rect{
fill: #4d545c !important;
color: #FFFFFF;
}
width: 100%;
height: 100%;
svg {
width: 100%;
height: 100%;
overflow: hidden;
}
text {
font-size: 14px;
}
.node rect {
width:400px;
stroke-width: 4px;
stroke: #bbb;
fill: #ffffff;
color: #455660;
}
.node g div span.consumers {
display: inline-block;
width: 280px;
}
.edgeLabel rect {
fill: none;
}
.edgeLabel div {
width: 50px;
color: #44575e;
}
.edgePath path {
stroke: #656a70;
stroke-width: 2.5px;
fill: #656a70;
}
/* Override path marker color */
#arrowhead {
fill: #656a70 !important;
}
.fa{
display: inline;
}
.center-button {
position: relative;
top: 9px;
left: 90%;
color: #FFFFFF;
background-color: #38424B;
}
}

View File

@ -8,7 +8,7 @@
</div>
<div class="panel-body">
<hz-information selected="computeCtrl.model.selected"></hz-information>
<hz-stacks></hz-stacks>
<!--<hz-stacks></hz-stacks>-->
<hz-alarms selected="computeCtrl.model.selected" ></hz-alarms>
</div>
</div>

View File

@ -1,5 +1,6 @@
<div class="vitrage-main" ng-controller="MainController as main">
<tabset>
<hz-compute></hz-compute>
<!--<tabset>
<tab>
<tab-heading>
<i class="fa fa-desktop"></i> {$ 'Compute' | translate $}
@ -25,5 +26,5 @@
<!--</tab-heading>-->
<!--<hz-network></hz-network>-->
<!--</tab>-->
</tabset>
<!--</tabset>-->
</div>

View File

@ -42,9 +42,24 @@
}
}
function getRootCauseAnalysis(alarm_id) {
if (vitrageAPI) {
return vitrageAPI.getRca(alarm_id)
.success(function(data) {
return data;
})
.error(function(err) {
console.error(err);
}
)
}
}
return {
getTopology: getTopology,
getAlarms: getAlarms
getAlarms: getAlarms,
getRootCauseAnalysis: getRootCauseAnalysis
}
}
})();

View File

@ -1,3 +1,8 @@
@import 'layout/main/compute/compute';
@import 'components/sunburst/sunburst';
@import 'components/alarms/alarms';
@import 'components/alarms/alarms.scss';
@import 'components/rca/rootCauseAnalysisGraph.scss';
@import 'components/rca/rcaContainer.scss';
@import 'components/alarms/alarms';
@import 'components/rca/rcaContainer';
@import 'components/rca/rootCauseAnalysisGraph';

View File

@ -0,0 +1,34 @@
{
"name": "d3",
"version": "3.4.12",
"main": "d3.js",
"scripts": [
"d3.js"
],
"ignore": [
".DS_Store",
".git",
".gitignore",
".npmignore",
".travis.yml",
"Makefile",
"bin",
"component.json",
"index.js",
"lib",
"node_modules",
"package.json",
"src",
"test"
],
"homepage": "https://github.com/mbostock/d3",
"_release": "3.4.12",
"_resolution": {
"type": "version",
"tag": "v3.4.12",
"commit": "269c727f88710ea86075b3ff6d396331cf8ede14"
},
"_source": "git://github.com/mbostock/d3.git",
"_target": "3.4.12",
"_originalSource": "d3"
}

View File

@ -0,0 +1,4 @@
bin
lib
src
test

View File

@ -0,0 +1,25 @@
# Contributing
If youre looking for ways to contribute, please [peruse open issues](https://github.com/mbostock/d3/issues?milestone=&page=1&state=open). The icebox is a good place to find ideas that are not currently in development. If you already have an idea, please check past issues to see whether your idea or a similar one was previously discussed.
Before submitting a pull request, consider implementing a live example first, say using [bl.ocks.org](http://bl.ocks.org). Real-world use cases go a long way to demonstrating the usefulness of a proposed feature. The more complex a features implementation, the more usefulness it should provide. Share your demo using the #d3js tag on Twitter or by sending it to the d3-js Google group.
If your proposed feature does not involve changing core functionality, consider submitting it instead as a [D3 plugin](https://github.com/d3/d3-plugins). New core features should be for general use, whereas plugins are suitable for more specialized use cases. When in doubt, its easier to start with a plugin before “graduating” to core.
To contribute new documentation or add examples to the gallery, just [edit the Wiki](https://github.com/mbostock/d3/wiki)!
## How to Submit a Pull Request
1. Click the “Fork” button to create your personal fork of the D3 repository.
2. After cloning your fork of the D3 repository in the terminal, run `npm install` to install D3s dependencies.
3. Create a new branch for your new feature. For example: `git checkout -b my-awesome-feature`. A dedicated branch for your pull request means you can develop multiple features at the same time, and ensures that your pull request is stable even if you later decide to develop an unrelated feature.
4. The `d3.js` and `d3.min.js` files are built from source files in the `src` directory. _Do not edit `d3.js` directly._ Instead, edit the source files, and then run `make` to build the generated files.
5. Use `make test` to run tests and verify your changes. If you are adding a new feature, you should add new tests! If you are changing existing functionality, make sure the existing tests run, or update them as appropriate.
6. Sign D3s [Individual Contributor License Agreement](https://docs.google.com/forms/d/1CzjdBKtDuA8WeuFJinadx956xLQ4Xriv7-oDvXnZMaI/viewform). Unless you are submitting a trivial patch (such as fixing a typo), this form is needed to verify that you are able to contribute.
7. Submit your pull request, and good luck!

View File

@ -0,0 +1,26 @@
Copyright (c) 2010-2014, Michael Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name Michael Bostock may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,9 @@
# Data-Driven Documents
<a href="http://d3js.org"><img src="http://d3js.org/logo.svg" align="left" hspace="10" vspace="6"></a>
**D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG and CSS. D3s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.
Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki)
For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostocks bl.ocks](http://bl.ocks.org/mbostock).

View File

@ -0,0 +1,24 @@
{
"name": "d3",
"version": "3.4.12",
"main": "d3.js",
"scripts": [
"d3.js"
],
"ignore": [
".DS_Store",
".git",
".gitignore",
".npmignore",
".travis.yml",
"Makefile",
"bin",
"component.json",
"index.js",
"lib",
"node_modules",
"package.json",
"src",
"test"
]
}

View File

@ -0,0 +1,19 @@
{
"name": "mbostock/d3",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": ["dom", "svg", "visualization", "js", "canvas"],
"homepage": "http://d3js.org/",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Mike Bostock",
"homepage": "http://bost.ocks.org/mike"
}
],
"support": {
"issues": "https://github.com/mbostock/d3/issues",
"wiki": "https://github.com/mbostock/d3/wiki",
"API": "https://github.com/mbostock/d3/wiki/API-Reference",
"source": "https://github.com/mbostock/d3"
}
}

9238
vitragedashboard/static/vendor/d3/d3.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
{
"name": "dagre-d3",
"version": "0.3.2",
"main": [
"dist/dagre-d3.core.js",
"dist/dagre-d3.core.min.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"browser.js",
"dist/dagre-d3.js",
"dist/dagre-d3.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"d3": "^3.3.8",
"dagre": "^0.6.1",
"graphlib": "^0.9.1",
"lodash": "^2.4.1"
},
"homepage": "https://github.com/cpettitt/dagre-d3",
"_release": "0.3.2",
"_resolution": {
"type": "version",
"tag": "v0.3.2",
"commit": "2fbf7d9e6982866663c9c60e37253fd94ac8a904"
},
"_source": "git://github.com/cpettitt/dagre-d3.git",
"_target": "0.3.2",
"_originalSource": "dagre-d3"
}

View File

@ -0,0 +1,19 @@
Copyright (c) 2013 Chris Pettitt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,29 @@
{
"name": "dagre-d3",
"version": "0.3.2",
"main": [
"dist/dagre-d3.core.js",
"dist/dagre-d3.core.min.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"browser.js",
"dist/dagre-d3.js",
"dist/dagre-d3.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"d3": "^3.3.8",
"dagre": "^0.6.1",
"graphlib": "^0.9.1",
"lodash": "^2.4.1"
}
}

View File

@ -0,0 +1,76 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Arrows</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<style id="css">
body {
font: 300 14px 'Helvetica Neue', Helvetica;
}
.node rect,
.node circle,
.node ellipse {
stroke: #333;
fill: #fff;
stroke-width: 1px;
}
.edgePath path {
stroke: #333;
fill: #333;
stroke-width: 1.5px;
}
</style>
<h1>Dagre D3 Demo: Arrows</h1>
<svg width=960 height=600><g/></svg>
<section>
<p>A sample that shows the different arrows available in dagre-d3.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
["normal", "vee"].forEach(function(arrowhead) {
g.setNode(arrowhead + "1", { label: " " });
g.setNode(arrowhead + "2", { label: " " });
g.setEdge(arrowhead + "1", arrowhead + "2", {
arrowhead: arrowhead,
label: arrowhead
});
});
var svg = d3.select("svg"),
inner = svg.select("g");
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Create the renderer
var render = new dagreD3.render();
// Run the renderer. This is what draws the final graph.
render(inner, g);
// Center the graph
var initialScale = 0.75;
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
.scale(initialScale)
.event(svg);
svg.attr('height', g.graph().height * initialScale + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,35 @@
body {
width: 960px;
margin: 0 auto;
color: #333;
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
}
h1 {
font-size: 3em;
font-weight: 300;
}
h2 {
font-size: 1.5em;
font-weight: 300;
}
section {
margin-bottom: 3em;
}
section p {
text-align: justify;
}
svg {
border: 1px solid #ccc;
overflow: hidden;
margin: 0 auto;
}
pre {
border: 1px solid #ccc;
}

View File

@ -0,0 +1,25 @@
var bodyElem = d3.select('body'),
jsElem = d3.select('#js'),
jsPanel = bodyElem.append('div').attr('id', 'jsPanel');
cssElem = d3.select('#css'),
cssPanel = bodyElem.append('div').attr('id', 'cssPanel');
function setupPanel(panel, elem, title) {
panel.append('h2').text(title);
return panel.append('pre').append('code').text(elem.html().trim());
}
var jsCode = setupPanel(jsPanel, jsElem, 'JavaScript');
var cssCode = setupPanel(cssPanel, cssElem, 'CSS');
var hljsRoot = 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1';
bodyElem.append('link')
.attr('rel', 'stylesheet')
.attr('href', hljsRoot + '/styles/xcode.min.css');
bodyElem.append('script')
.attr('src', hljsRoot + '/highlight.min.js')
.on('load', function() {
hljs.highlightBlock(jsCode.node());
hljs.highlightBlock(cssCode.node());
});

View File

@ -0,0 +1,99 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: DOM Example</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<h1>Dagre D3 Demo: DOM Example</h1>
<style id="css">
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
.node rect {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path {
stroke: #333;
stroke-width: 1.5px;
}
table {
border-spacing: 0;
}
table td {
padding: 7px;
}
table td:first-child {
background-color: #afa;
border-top: 1px solid #333;
border-left: 1px solid #333;
border-bottom: 1px solid #333;
border-radius: 5px 0 0 5px;
}
table td:last-child {
background-color: #faa;
border-top: 1px solid #333;
border-right: 1px solid #333;
border-bottom: 1px solid #333;
border-radius: 0 5px 5px 0;
}
</style>
<svg width=960 height=600></svg>
<section>
<p>A sample showing how to use DOM nodes in a graph. Note that IE does not
support this technique.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
g.setNode("root", {
label: function() {
var table = document.createElement("table"),
tr = d3.select(table).append("tr");
tr.append("td").text("A");
tr.append("td").text("B");
return table;
},
padding: 0,
rx: 5,
ry: 5
});
g.setNode("A", { label: "A", fill: "#afa" });
g.setNode("B", { label: "B", fill: "#faa" });
g.setEdge("root", "A", {});
g.setEdge("root", "B", {});
// Create the renderer
var render = new dagreD3.render();
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select('svg'),
svgGroup = svg.append('g');
// Run the renderer. This is what draws the final graph.
render(svgGroup, g);
// Center the graph
var xCenterOffset = (svg.attr('width') - g.graph().width) / 2;
svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 20)');
svg.attr('height', g.graph().height + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,285 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Renderer Demo</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<style>
body {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
background: #333;
}
@-webkit-keyframes flash {
0%, 50%, 100% {
opacity: 1;
}
25%, 75% {
opacity: 0.2;
}
}
@keyframes flash {
0%, 50%, 100% {
opacity: 1;
}
25%, 75% {
opacity: 0.2;
}
}
.warn {
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.live.map {
width: 100%;
height: 100%;
}
svg {
width: 100%;
height: 100%;
overflow: hidden;
}
.live.map text {
font-weight: 300;
font-size: 14px;
}
.live.map .node rect {
stroke-width: 1.5px;
stroke: #bbb;
fill: #666;
}
.live.map .status {
height: 100%;
width: 15px;
display: block;
float: left;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
margin-right: 4px;
}
.live.map .running .status {
background-color: #7f7;
}
.live.map .running.warn .status {
background-color: #ffed68;
}
.live.map .stopped .status {
background-color: #f77;
}
.live.map .warn .queue {
color: #f77;
}
.warn {
-webkit-animation-name: flash;
animation-name: flash;
}
.live.map .consumers {
margin-right: 2px;
}
.live.map .consumers,
.live.map .name {
margin-top: 4px;
}
.live.map .consumers:after {
content: "x";
}
.live.map .queue {
display: block;
float: left;
width: 130px;
height: 20px;
font-size: 12px;
margin-top: 2px;
}
.live.map .node g div {
width: 200px;
height: 40px;
color: #fff;
}
.live.map .node g div span.consumers {
display: inline-block;
width: 20px;
}
.live.map .edgeLabel text {
width: 50px;
fill: #fff;
}
.live.map .edgePath path {
stroke: #999;
stroke-width: 1.5px;
fill: #999;
}
</style>
<body>
<div class="live map">
<svg><g/></svg>
</div>
<script>
var workers = {
"identifier": {
"consumers": 2,
"count": 20
},
"lost-and-found": {
"consumers": 1,
"count": 1,
"inputQueue": "identifier",
"inputThroughput": 50
},
"monitor": {
"consumers": 1,
"count": 0,
"inputQueue": "identifier",
"inputThroughput": 50
},
"meta-enricher": {
"consumers": 4,
"count": 9900,
"inputQueue": "identifier",
"inputThroughput": 50
},
"geo-enricher": {
"consumers": 2,
"count": 1,
"inputQueue": "meta-enricher",
"inputThroughput": 50
},
"elasticsearch-writer": {
"consumers": 0,
"count": 9900,
"inputQueue": "geo-enricher",
"inputThroughput": 50
}
};
// Set up zoom support
var svg = d3.select("svg"),
inner = svg.select("g"),
zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
var render = new dagreD3.render();
// Left-to-right layout
var g = new dagreD3.graphlib.Graph();
g.setGraph({
nodesep: 70,
ranksep: 50,
rankdir: "LR",
marginx: 20,
marginy: 20
});
function draw(isUpdate) {
for (var id in workers) {
var worker = workers[id];
var className = worker.consumers ? "running" : "stopped";
if (worker.count > 10000) {
className += " warn";
}
var html = "<div>";
html += "<span class=status></span>";
html += "<span class=consumers>"+worker.consumers+"</span>";
html += "<span class=name>"+id+"</span>";
html += "<span class=queue><span class=counter>"+worker.count+"</span></span>";
html += "</div>";
g.setNode(id, {
labelType: "html",
label: html,
rx: 5,
ry: 5,
padding: 0,
class: className
});
if (worker.inputQueue) {
g.setEdge(worker.inputQueue, id, {
label: worker.inputThroughput + "/s",
width: 40
});
}
}
inner.call(render, g);
// Zoom and scale to fit
var zoomScale = zoom.scale();
var graphWidth = g.graph().width + 80;
var graphHeight = g.graph().height + 40;
var width = parseInt(svg.style("width").replace(/px/, ""));
var height = parseInt(svg.style("height").replace(/px/, ""));
zoomScale = Math.min(width / graphWidth, height / graphHeight);
var translate = [(width/2) - ((graphWidth*zoomScale)/2), (height/2) - ((graphHeight*zoomScale)/2)];
zoom.translate(translate);
zoom.scale(zoomScale);
zoom.event(isUpdate ? svg.transition().duration(500) : d3.select("svg"));
}
// Do some mock queue status updates
setInterval(function() {
var stoppedWorker1Count = workers["elasticsearch-writer"].count;
var stoppedWorker2Count = workers["meta-enricher"].count;
for (var id in workers) {
workers[id].count = Math.ceil(Math.random() * 3);
if (workers[id].inputThroughput) workers[id].inputThroughput = Math.ceil(Math.random() * 250);
}
workers["elasticsearch-writer"].count = stoppedWorker1Count + Math.ceil(Math.random() * 100);
workers["meta-enricher"].count = stoppedWorker2Count + Math.ceil(Math.random() * 100);
draw(true);
}, 1000);
// Do a mock change of worker configuration
setInterval(function() {
workers["elasticsearch-monitor"] = {
"consumers": 0,
"count": 0,
"inputQueue": "elasticsearch-writer",
"inputThroughput": 50
}
}, 5000);
draw();
</script>

View File

@ -0,0 +1,197 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Tooltip on Hover</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<!-- Pull in JQuery dependencies -->
<link rel="stylesheet" href="tipsy.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="tipsy.js"></script>
<h1>Dagre D3 Demo: Tooltip on Hover</h1>
<style id="css">
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
.node rect {
stroke: #333;
fill: #fff;
}
.edgePath path {
stroke: #333;
fill: #333;
stroke-width: 1.5px;
}
.node text {
pointer-events: none;
}
/* This styles the title of the tooltip */
.tipsy .name {
font-size: 1.5em;
font-weight: bold;
color: #60b1fc;
margin: 0;
}
/* This styles the body of the tooltip */
.tipsy .description {
font-size: 1.2em;
}
</style>
<svg width=960 height=600></svg>
<section>
<p>The TCP state diagram
(<a href="http://www.rfc-editor.org/rfc/rfc793.txt">source: RFC 793</a>) with
hover support. Uses <a href="http://bl.ocks.org/ilyabo/1373263">tipsy JS and CSS</a>
for the tooltip.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
// States and transitions from RFC 793
var states = {
CLOSED: {
description: "represents no connection state at all.",
style: "fill: #f77"
},
LISTEN: {
description: "represents waiting for a connection request from any " +
"remote TCP and port."
},
"SYN SENT": {
description: "represents waiting for a matching connection " +
"request after having sent a connection request."
},
"SYN RCVD": {
description: "represents waiting for a confirming connection " +
"request acknowledgment after having both received and sent a " +
"connection request."
},
ESTAB: {
description: "represents an open connection, data received " +
"can be delivered to the user. The normal state for the data " +
"transfer phase of the connection.",
style: "fill: #7f7"
},
"FINWAIT-1": {
description: "represents waiting for a connection termination " +
"request from the remote TCP, or an acknowledgment of the " +
"connection termination request previously sent."
},
"FINWAIT-2": {
description: "represents waiting for a connection termination " +
"request from the remote TCP."
},
"CLOSE WAIT": {
description: "represents waiting for a connection termination " +
"request from the local user."
},
CLOSING: {
description: "represents waiting for a connection termination " +
"request acknowledgment from the remote TCP."
},
"LAST-ACK": {
description: "represents waiting for an acknowledgment of the " +
"connection termination request previously sent to the remote " +
"TCP (which includes an acknowledgment of its connection " +
"termination request)."
},
"TIME WAIT": {
description: "represents waiting for enough time to pass to be " +
"sure the remote TCP received the acknowledgment of its " +
"connection termination request."
}
};
// Add states to the graph, set labels, and style
Object.keys(states).forEach(function(state) {
var value = states[state];
value.label = state;
value.rx = value.ry = 5;
g.setNode(state, value);
});
// Set up the edges
g.setEdge("CLOSED", "LISTEN", { label: "open" });
g.setEdge("LISTEN", "SYN RCVD", { label: "rcv SYN" });
g.setEdge("LISTEN", "SYN SENT", { label: "send" });
g.setEdge("LISTEN", "CLOSED", { label: "close" });
g.setEdge("SYN RCVD", "FINWAIT-1", { label: "close" });
g.setEdge("SYN RCVD", "ESTAB", { label: "rcv ACK of SYN" });
g.setEdge("SYN SENT", "SYN RCVD", { label: "rcv SYN" });
g.setEdge("SYN SENT", "ESTAB", { label: "rcv SYN, ACK" });
g.setEdge("SYN SENT", "CLOSED", { label: "close" });
g.setEdge("ESTAB", "FINWAIT-1", { label: "close" });
g.setEdge("ESTAB", "CLOSE WAIT", { label: "rcv FIN" });
g.setEdge("FINWAIT-1", "FINWAIT-2", { label: "rcv ACK of FIN" });
g.setEdge("FINWAIT-1", "CLOSING", { label: "rcv FIN" });
g.setEdge("CLOSE WAIT", "LAST-ACK", { label: "close" });
g.setEdge("FINWAIT-2", "TIME WAIT", { label: "rcv FIN" });
g.setEdge("CLOSING", "TIME WAIT", { label: "rcv ACK of FIN" });
g.setEdge("LAST-ACK", "CLOSED", { label: "rcv ACK of FIN" });
g.setEdge("TIME WAIT", "CLOSED", { label: "timeout=2MSL" });
// Create the renderer
var render = new dagreD3.render();
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
inner = svg.append("g");
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Simple function to style the tooltip for the given node.
var styleTooltip = function(name, description) {
return "<p class='name'>" + name + "</p><p class='description'>" + description + "</p>";
};
// Run the renderer. This is what draws the final graph.
render(inner, g);
inner.selectAll("g.node")
.attr("title", function(v) { return styleTooltip(v, g.node(v).description) })
.each(function(v) { $(this).tipsy({ gravity: "w", opacity: 1, html: true }); });
// Center the graph
var initialScale = 0.75;
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
.scale(initialScale)
.event(svg);
svg.attr('height', g.graph().height * initialScale + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,173 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre Interactive Demo</title>
<script src="http://d3js.org/d3.v3.js"></script>
<script src="http://cpettitt.github.io/project/graphlib-dot/v0.5.2/graphlib-dot.js"></script>
<script src="../build/dagre-d3.js"></script>
<style>
svg {
border: 1px solid #999;
overflow: hidden;
}
.node {
white-space: nowrap;
}
.node rect,
.node cicrce,
.node ellipse {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.cluster rect {
stroke: #333;
fill: #000;
fill-opacity: 0.1;
stroke-width: 1.5px;
}
.edgePath path.path {
stroke: #333;
stroke-width: 1.5px;
fill: none;
}
</style>
<style>
h1, h2 {
color: #333;
}
textarea {
width: 800px;
}
label {
margin-top: 1em;
display: block;
}
.error {
color: red;
}
</style>
<body onLoad="tryDraw();">
<h1>Dagre Interactive Demo</h1>
<h2>Input</h2>
<form>
<label for="inputGraph">Graphviz Definition</label>
<textarea id="inputGraph" rows="5" style="display: block" onKeyUp="tryDraw();">
/* Example */
digraph {
/* Note: HTML labels do not work in IE, which lacks support for &lt;foreignObject&gt; tags. */
node [rx=5 ry=5 labelStyle="font: 300 14px 'Helvetica Neue', Helvetica"]
edge [labelStyle="font: 300 14px 'Helvetica Neue', Helvetica"]
A [labelType="html"
label="A <span style='font-size:32px'>Big</span> <span style='color:red;'>HTML</span> Source!"];
C;
E [label="Bold Red Sink" style="fill: #f77; font-weight: bold"];
A -&gt; B -&gt; C;
B -&gt; D [label="A blue label" labelStyle="fill: #55f; font-weight: bold;"];
D -&gt; E [label="A thick red edge" style="stroke: #f77; stroke-width: 2px;" arrowheadStyle="fill: #f77"];
C -&gt; E;
A -&gt; D [labelType="html" label="A multi-rank <span style='color:blue;'>HTML</span> edge!"];
}
</textarea>
<a id="graphLink">Link for this graph</a>
</form>
<h2>Graph Visualization</h2>
<svg width=800 height=600>
<g/>
</svg>
<script>
// Input related code goes here
function graphToURL() {
var elems = [window.location.protocol, '//',
window.location.host,
window.location.pathname,
'?'];
var queryParams = [];
if (debugAlignment) {
queryParams.push('alignment=' + debugAlignment);
}
queryParams.push('graph=' + encodeURIComponent(inputGraph.value));
elems.push(queryParams.join('&'));
return elems.join('');
}
var inputGraph = document.querySelector("#inputGraph");
var graphLink = d3.select("#graphLink");
var oldInputGraphValue;
var graphRE = /[?&]graph=([^&]+)/;
var graphMatch = window.location.search.match(graphRE);
if (graphMatch) {
inputGraph.value = decodeURIComponent(graphMatch[1]);
}
var debugAlignmentRE = /[?&]alignment=([^&]+)/;
var debugAlignmentMatch = window.location.search.match(debugAlignmentRE);
var debugAlignment;
if (debugAlignmentMatch) debugAlignment = debugAlignmentMatch[1];
// Set up zoom support
var svg = d3.select("svg"),
inner = d3.select("svg g"),
zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Create and configure the renderer
var render = dagreD3.render();
function tryDraw() {
var g;
if (oldInputGraphValue !== inputGraph.value) {
inputGraph.setAttribute("class", "");
oldInputGraphValue = inputGraph.value;
try {
g = graphlibDot.read(inputGraph.value);
} catch (e) {
inputGraph.setAttribute("class", "error");
throw e;
}
// Save link to new graph
graphLink.attr("href", graphToURL());
// Set margins, if not present
if (!g.graph().hasOwnProperty("marginx") &&
!g.graph().hasOwnProperty("marginy")) {
g.graph().marginx = 20;
g.graph().marginy = 20;
}
g.graph().transition = function(selection) {
return selection.transition().duration(500);
};
// Render the graph into svg g
d3.select("svg g").call(render, g);
}
}
</script>

View File

@ -0,0 +1,105 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Sentence Tokenization</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<h1>Dagre D3 Demo: Sentence Tokenization</h1>
<style id="css">
/* This sets the color for "TK" nodes to a light blue green. */
g.type-TK > rect {
fill: #00ffd0;
}
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
.node rect {
stroke: #999;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path {
stroke: #333;
stroke-width: 1.5px;
}
</style>
<svg id="svg-canvas" width=960 height=600></svg>
<section>
<p>An example of visualizing the tokenization of a sentence. This example shows
how CSS classes can be applied to a rendered graph.
</section>
<script id="js">
// Create the input graph
var g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function() { return {}; });
// Here we"re setting nodeclass, which is used by our custom drawNodes function
// below.
g.setNode(0, { label: "TOP", class: "type-TOP" });
g.setNode(1, { label: "S", class: "type-S" });
g.setNode(2, { label: "NP", class: "type-NP" });
g.setNode(3, { label: "DT", class: "type-DT" });
g.setNode(4, { label: "This", class: "type-TK" });
g.setNode(5, { label: "VP", class: "type-VP" });
g.setNode(6, { label: "VBZ", class: "type-VBZ" });
g.setNode(7, { label: "is", class: "type-TK" });
g.setNode(8, { label: "NP", class: "type-NP" });
g.setNode(9, { label: "DT", class: "type-DT" });
g.setNode(10, { label: "an", class: "type-TK" });
g.setNode(11, { label: "NN", class: "type-NN" });
g.setNode(12, { label: "example", class: "type-TK" });
g.setNode(13, { label: ".", class: "type-." });
g.setNode(14, { label: "sentence", class: "type-TK" });
g.nodes().forEach(function(v) {
var node = g.node(v);
// Round the corners of the nodes
node.rx = node.ry = 5;
});
// Set up edges, no special attributes.
g.setEdge(3, 4);
g.setEdge(2, 3);
g.setEdge(1, 2);
g.setEdge(6, 7);
g.setEdge(5, 6);
g.setEdge(9, 10);
g.setEdge(8, 9);
g.setEdge(11,12);
g.setEdge(8, 11);
g.setEdge(5, 8);
g.setEdge(1, 5);
g.setEdge(13,14);
g.setEdge(1, 13);
g.setEdge(0, 1)
// Create the renderer
var render = new dagreD3.render();
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
svgGroup = svg.append("g");
// Run the renderer. This is what draws the final graph.
render(d3.select("svg g"), g);
// Center the graph
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
svg.attr("height", g.graph().height + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,71 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Shapes</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<style id="css">
body {
font: 300 14px 'Helvetica Neue', Helvetica;
}
.node rect,
.node circle,
.node ellipse {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path {
stroke: #333;
fill: #333;
stroke-width: 1.5px;
}
</style>
<h1>Dagre D3 Demo: Shapes</h1>
<svg width=960 height=600><g/></svg>
<section>
<p>A sample that shows the different node shapes available in dagre-d3.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
g.setNode("rect", { shape: "rect" });
g.setNode("circle", { shape: "circle" });
g.setNode("ellipse", { shape: "ellipse" });
var svg = d3.select("svg"),
inner = svg.select("g");
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Create the renderer
var render = new dagreD3.render();
// Run the renderer. This is what draws the final graph.
render(inner, g);
// Center the graph
var initialScale = 0.75;
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
.scale(initialScale)
.event(svg);
svg.attr('height', g.graph().height * initialScale + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,80 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Style Attributes</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<h1>Dagre D3 Demo: Style Attributes</h1>
<style id="css">
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
.node rect {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path.path {
stroke: #333;
fill: none;
stroke-width: 1.5px;
}
</style>
<svg id="svg" width=960 height=600></svg>
<section>
<p>An example showing how styles that are set in the input graph can be applied
to nodes, node labels, edges, and edge labels in the rendered graph.
</section>
<script id="js">
// Create the input graph
var g = new dagreD3.graphlib.Graph().setGraph({});
// Fill node "A" with the color green
g.setNode("A", { style: "fill: #afa" });
// Make the label for node "B" bold
g.setNode("B", { labelStyle: "font-weight: bold" });
// Double the size of the font for node "C"
g.setNode("C", { labelStyle: "font-size: 2em" });
// Make the edge from "A" to "B" red, thick, and dashed
g.setEdge("A", "B", {
style: "stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;",
arrowheadStyle: "fill: #f66"
});
// Make the label for the edge from "C" to "B" italic and underlined
g.setEdge("C", "B", {
label: "A to C",
labelStyle: "font-style: italic; text-decoration: underline;"
});
// Create the renderer
var render = new dagreD3.render();
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
inner = svg.append("g");
// Run the renderer. This is what draws the final graph.
render(inner, g);
// Center the graph
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
inner.attr("transform", "translate(" + xCenterOffset + ", 20)");
svg.attr("height", g.graph().height + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,105 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: TCP State Diagram</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<style id="css">
body {
font: 300 14px 'Helvetica Neue', Helvetica;
}
.node rect {
stroke: #333;
fill: #fff;
}
.edgePath path {
stroke: #333;
fill: #333;
stroke-width: 1.5px;
}
</style>
<h1>Dagre D3 Demo: TCP State Diagram</h1>
<svg width=960 height=600><g/></svg>
<section>
<p>A sample rendering of a TCP state diagram
(<a href="http://www.rfc-editor.org/rfc/rfc793.txt">RFC 793</a>). This example
shows how to set custom styles in the input graph and how to set a custom
initial zoom.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
// States and transitions from RFC 793
var states = [ "CLOSED", "LISTEN", "SYN RCVD", "SYN SENT",
"ESTAB", "FINWAIT-1", "CLOSE WAIT", "FINWAIT-2",
"CLOSING", "LAST-ACK", "TIME WAIT" ];
// Automatically label each of the nodes
states.forEach(function(state) { g.setNode(state, { label: state }); });
// Set up the edges
g.setEdge("CLOSED", "LISTEN", { label: "open" });
g.setEdge("LISTEN", "SYN RCVD", { label: "rcv SYN" });
g.setEdge("LISTEN", "SYN SENT", { label: "send" });
g.setEdge("LISTEN", "CLOSED", { label: "close" });
g.setEdge("SYN RCVD", "FINWAIT-1", { label: "close" });
g.setEdge("SYN RCVD", "ESTAB", { label: "rcv ACK of SYN" });
g.setEdge("SYN SENT", "SYN RCVD", { label: "rcv SYN" });
g.setEdge("SYN SENT", "ESTAB", { label: "rcv SYN, ACK" });
g.setEdge("SYN SENT", "CLOSED", { label: "close" });
g.setEdge("ESTAB", "FINWAIT-1", { label: "close" });
g.setEdge("ESTAB", "CLOSE WAIT", { label: "rcv FIN" });
g.setEdge("FINWAIT-1", "FINWAIT-2", { label: "rcv ACK of FIN" });
g.setEdge("FINWAIT-1", "CLOSING", { label: "rcv FIN" });
g.setEdge("CLOSE WAIT", "LAST-ACK", { label: "close" });
g.setEdge("FINWAIT-2", "TIME WAIT", { label: "rcv FIN" });
g.setEdge("CLOSING", "TIME WAIT", { label: "rcv ACK of FIN" });
g.setEdge("LAST-ACK", "CLOSED", { label: "rcv ACK of FIN" });
g.setEdge("TIME WAIT", "CLOSED", { label: "timeout=2MSL" });
// Set some general styles
g.nodes().forEach(function(v) {
var node = g.node(v);
node.rx = node.ry = 5;
});
// Add some custom colors based on state
g.node('CLOSED').style = "fill: #f77";
g.node('ESTAB').style = "fill: #7f7";
var svg = d3.select("svg"),
inner = svg.select("g");
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Create the renderer
var render = new dagreD3.render();
// Run the renderer. This is what draws the final graph.
render(inner, g);
// Center the graph
var initialScale = 0.75;
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
.scale(initialScale)
.event(svg);
svg.attr('height', g.graph().height * initialScale + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,25 @@
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
.tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
/* Rounded corners */
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
/* Uncomment for shadow */
.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
/* Rules to colour arrows */
.tipsy-arrow-n { border-bottom-color: #000; }
.tipsy-arrow-s { border-top-color: #000; }
.tipsy-arrow-e { border-left-color: #000; }
.tipsy-arrow-w { border-right-color: #000; }
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }

View File

@ -0,0 +1,288 @@
// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license
(function($) {
function maybeCall(thing, ctx) {
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
}
function Tipsy(element, options) {
this.$element = $(element);
this.options = options;
this.enabled = true;
this.fixTitle();
}
Tipsy.prototype = {
show: function() {
var title = this.getTitle();
if (title && this.enabled) {
var $tip = this.tip();
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
var pos = $.extend({}, this.$element.offset(), {
width: this.$element[0].offsetWidth || 0,
height: this.$element[0].offsetHeight || 0
});
if (typeof this.$element[0].nearestViewportElement == 'object') {
// SVG
var el = this.$element[0];
var rect = el.getBoundingClientRect();
pos.width = rect.width;
pos.height = rect.height;
}
var actualWidth = $tip[0].offsetWidth,
actualHeight = $tip[0].offsetHeight,
gravity = maybeCall(this.options.gravity, this.$element[0]);
var tp;
switch (gravity.charAt(0)) {
case 'n':
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 's':
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 'e':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
break;
case 'w':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
break;
}
if (gravity.length == 2) {
if (gravity.charAt(1) == 'w') {
tp.left = pos.left + pos.width / 2 - 15;
} else {
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
}
}
$tip.css(tp).addClass('tipsy-' + gravity);
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
if (this.options.className) {
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
}
if (this.options.fade) {
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
} else {
$tip.css({visibility: 'visible', opacity: this.options.opacity});
}
var t = this;
var set_hovered = function(set_hover){
return function(){
t.$tip.stop();
t.tipHovered = set_hover;
if (!set_hover){
if (t.options.delayOut === 0) {
t.hide();
} else {
setTimeout(function() {
if (t.hoverState == 'out') t.hide(); }, t.options.delayOut);
}
}
};
};
$tip.hover(set_hovered(true), set_hovered(false));
}
},
hide: function() {
if (this.options.fade) {
this.tip().stop().fadeOut(function() { $(this).remove(); });
} else {
this.tip().remove();
}
},
fixTitle: function() {
var $e = this.$element;
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
}
if (typeof $e.context.nearestViewportElement == 'object'){
if ($e.children('title').length){
$e.append('<original-title>' + ($e.children('title').text() || '') + '</original-title>')
.children('title').remove();
}
}
},
getTitle: function() {
var title, $e = this.$element, o = this.options;
this.fixTitle();
if (typeof o.title == 'string') {
var title_name = o.title == 'title' ? 'original-title' : o.title;
if ($e.children(title_name).length){
title = $e.children(title_name).html();
} else{
title = $e.attr(title_name);
}
} else if (typeof o.title == 'function') {
title = o.title.call($e[0]);
}
title = ('' + title).replace(/(^\s*|\s*$)/, "");
return title || o.fallback;
},
tip: function() {
if (!this.$tip) {
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
}
return this.$tip;
},
validate: function() {
if (!this.$element[0].parentNode) {
this.hide();
this.$element = null;
this.options = null;
}
},
enable: function() { this.enabled = true; },
disable: function() { this.enabled = false; },
toggleEnabled: function() { this.enabled = !this.enabled; }
};
$.fn.tipsy = function(options) {
if (options === true) {
return this.data('tipsy');
} else if (typeof options == 'string') {
var tipsy = this.data('tipsy');
if (tipsy) tipsy[options]();
return this;
}
options = $.extend({}, $.fn.tipsy.defaults, options);
if (options.hoverlock && options.delayOut === 0) {
options.delayOut = 100;
}
function get(ele) {
var tipsy = $.data(ele, 'tipsy');
if (!tipsy) {
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
$.data(ele, 'tipsy', tipsy);
}
return tipsy;
}
function enter() {
var tipsy = get(this);
tipsy.hoverState = 'in';
if (options.delayIn === 0) {
tipsy.show();
} else {
tipsy.fixTitle();
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
}
}
function leave() {
var tipsy = get(this);
tipsy.hoverState = 'out';
if (options.delayOut === 0) {
tipsy.hide();
} else {
var to = function() {
if (!tipsy.tipHovered || !options.hoverlock){
if (tipsy.hoverState == 'out') tipsy.hide();
}
};
setTimeout(to, options.delayOut);
}
}
if (options.trigger != 'manual') {
var binder = options.live ? 'live' : 'bind',
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
this[binder](eventIn, enter)[binder](eventOut, leave);
}
return this;
};
$.fn.tipsy.defaults = {
className: null,
delayIn: 0,
delayOut: 0,
fade: false,
fallback: '',
gravity: 'n',
html: false,
live: false,
offset: 0,
opacity: 0.8,
title: 'title',
trigger: 'hover',
hoverlock: false
};
// Overwrite this method to provide options on a per-element basis.
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
// (remember - do not modify 'options' in place!)
$.fn.tipsy.elementOptions = function(ele, options) {
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
};
$.fn.tipsy.autoNS = function() {
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
};
$.fn.tipsy.autoWE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
};
/**
* yields a closure of the supplied parameters, producing a function that takes
* no arguments and is suitable for use as an autogravity function like so:
*
* @param margin (int) - distance from the viewable region edge that an
* element should be before setting its tooltip's gravity to be away
* from that edge.
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
* if there are no viewable region edges effecting the tooltip's
* gravity. It will try to vary from this minimally, for example,
* if 'sw' is preferred and an element is near the right viewable
* region edge, but not the top edge, it will set the gravity for
* that element's tooltip to be 'se', preserving the southern
* component.
*/
$.fn.tipsy.autoBounds = function(margin, prefer) {
return function() {
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
boundTop = $(document).scrollTop() + margin,
boundLeft = $(document).scrollLeft() + margin,
$this = $(this);
if ($this.offset().top < boundTop) dir.ns = 'n';
if ($this.offset().left < boundLeft) dir.ew = 'w';
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
return dir.ns + (dir.ew ? dir.ew : '');
};
};
})(jQuery);

View File

@ -0,0 +1,115 @@
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: User-defined Shapes and Arrows</title>
<link rel="stylesheet" href="demo.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="../build/dagre-d3.js"></script>
<style id="css">
body {
font: 300 14px 'Helvetica Neue', Helvetica;
}
.node rect,
.node circle,
.node ellipse,
.node polygon {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path.path {
stroke: #333;
fill: none;
stroke-width: 1.5px;
}
</style>
<h1>Dagre D3 Demo: User-defined Shapes and Arrows</h1>
<svg width=960 height=600><g/></svg>
<section>
<p>An example that shows how to create and use user-defined shapes and arrows.
</section>
<script id="js">
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});
g.setNode("house", { shape: "house", label: "house" });
g.setNode("rect", { shape: "rect" });
g.setEdge("house", "rect", { arrowhead: "hollowPoint" });
var svg = d3.select("svg"),
inner = svg.select("g");
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
});
svg.call(zoom);
// Create the renderer
var render = new dagreD3.render();
// Add our custom shape (a house)
render.shapes().house = function(parent, bbox, node) {
var w = bbox.width,
h = bbox.height,
points = [
{ x: 0, y: 0 },
{ x: w, y: 0 },
{ x: w, y: -h },
{ x: w/2, y: -h * 3/2 },
{ x: 0, y: -h }
];
shapeSvg = parent.insert("polygon", ":first-child")
.attr("points", points.map(function(d) { return d.x + "," + d.y; }).join(" "))
.attr("transform", "translate(" + (-w/2) + "," + (h * 3/4) + ")");
node.intersect = function(point) {
return dagreD3.intersect.polygon(node, points, point);
};
return shapeSvg;
};
// Add our custom arrow (a hollow-point)
render.arrows().hollowPoint = function normal(parent, id, edge, type) {
var marker = parent.append("marker")
.attr("id", id)
.attr("viewBox", "0 0 10 10")
.attr("refX", 9)
.attr("refY", 5)
.attr("markerUnits", "strokeWidth")
.attr("markerWidth", 8)
.attr("markerHeight", 6)
.attr("orient", "auto");
var path = marker.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z")
.style("stroke-width", 1)
.style("stroke-dasharray", "1,0")
.style("fill", "#fff")
.style("stroke", "#333");
dagreD3.util.applyStyle(path, edge[type + "Style"]);
};
// Run the renderer. This is what draws the final graph.
render(inner, g);
// Center the graph
var initialScale = 0.75;
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
.scale(initialScale)
.event(svg);
svg.attr('height', g.graph().height * initialScale + 40);
</script>
<script src="demo.js"></script>

View File

@ -0,0 +1,36 @@
{
"name": "dagre",
"version": "0.6.4",
"main": [
"dist/dagre.core.js",
"dist/dagre.core.min.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"dist/dagre.js",
"dist/dagre.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"graphlib": "^1.0.1",
"lodash": "^2.4.1"
},
"homepage": "https://github.com/cpettitt/dagre",
"_release": "0.6.4",
"_resolution": {
"type": "version",
"tag": "v0.6.4",
"commit": "cf4d9131df03d0e3dd46a45390c39f183d99e9cc"
},
"_source": "git://github.com/cpettitt/dagre.git",
"_target": "^0.6.1",
"_originalSource": "dagre"
}

View File

@ -0,0 +1,19 @@
Copyright (c) 2012-2014 Chris Pettitt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,26 @@
{
"name": "dagre",
"version": "0.6.4",
"main": [
"dist/dagre.core.js",
"dist/dagre.core.min.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"dist/dagre.js",
"dist/dagre.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"graphlib": "^1.0.1",
"lodash": "^2.4.1"
}
}

View File

@ -0,0 +1,35 @@
{
"name": "graphlib",
"version": "1.0.7",
"main": [
"dist/graphlib.core.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"browser.js",
"dist/graphlib.js",
"dist/graphlib.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"lodash": "^3.10.0"
},
"homepage": "https://github.com/cpettitt/graphlib",
"_release": "1.0.7",
"_resolution": {
"type": "version",
"tag": "v1.0.7",
"commit": "fbd547f8f19bd743a4344d385ee1ec37eb34279f"
},
"_source": "git://github.com/cpettitt/graphlib.git",
"_target": "^1.0.1",
"_originalSource": "graphlib"
}

View File

@ -0,0 +1,19 @@
Copyright (c) 2012-2014 Chris Pettitt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,25 @@
{
"name": "graphlib",
"version": "1.0.7",
"main": [
"dist/graphlib.core.js"
],
"ignore": [
".*",
"README.md",
"CHANGELOG.md",
"Makefile",
"browser.js",
"dist/graphlib.js",
"dist/graphlib.min.js",
"index.js",
"karma*",
"lib/**",
"package.json",
"src/**",
"test/**"
],
"dependencies": {
"lodash": "^3.10.0"
}
}

View File

@ -0,0 +1,33 @@
{
"name": "lodash",
"version": "2.4.2",
"main": "dist/lodash.compat.js",
"ignore": [
".*",
"*.custom.*",
"*.template.*",
"*.map",
"*.md",
"/*.min.*",
"/lodash.js",
"index.js",
"component.json",
"package.json",
"doc",
"modularize",
"node_modules",
"perf",
"test",
"vendor"
],
"homepage": "https://github.com/lodash/lodash",
"_release": "2.4.2",
"_resolution": {
"type": "version",
"tag": "2.4.2",
"commit": "47289d89e0155462ea6888e6bb2e258dc4daa9d0"
},
"_source": "git://github.com/lodash/lodash.git",
"_target": "^2.4.1",
"_originalSource": "lodash"
}

View File

@ -0,0 +1,22 @@
Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,23 @@
{
"name": "lodash",
"version": "2.4.2",
"main": "dist/lodash.compat.js",
"ignore": [
".*",
"*.custom.*",
"*.template.*",
"*.map",
"*.md",
"/*.min.*",
"/lodash.js",
"index.js",
"component.json",
"package.json",
"doc",
"modularize",
"node_modules",
"perf",
"test",
"vendor"
]
}

View File

@ -1,4 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Topology" %}{% endblock %}
@ -12,5 +15,12 @@
<div ng-cloak ng-init='init({{ TOPOLOGY_VITRAGE_SETTINGS }})'>
<ng-include src="'{{STATIC_URL}}dashboard/project/layout/main/main.html'"></ng-include>
</div>
<script src="{{STATIC_URL}}vendor/d3/d3.js"></script>
<script src="{{STATIC_URL}}vendor/lodash/dist/lodash.js"></script>
<script src="{{STATIC_URL}}vendor/graphlib/dist/graphlib.core.js"></script>
<script src="{{STATIC_URL}}vendor/dagre/dist/dagre.core.js"></script>
<script src="{{STATIC_URL}}vendor/dagre-d3/dist/dagre-d3.core.js"></script>
{% endblock %}