phantom_svg 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +42 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +11 -0
  5. data/.travis.yml +9 -0
  6. data/Gemfile +16 -0
  7. data/Guardfile +12 -0
  8. data/LICENSE +165 -0
  9. data/README.md +6 -0
  10. data/lib/phantom/frame.rb +71 -0
  11. data/lib/phantom/parser/abstract_animation_reader.rb +117 -0
  12. data/lib/phantom/parser/json_animation_reader.rb +42 -0
  13. data/lib/phantom/parser/raster.rb +115 -0
  14. data/lib/phantom/parser/svg_reader.rb +131 -0
  15. data/lib/phantom/parser/svg_writer.rb +163 -0
  16. data/lib/phantom/parser/xml_animation_reader.rb +32 -0
  17. data/lib/phantom/svg.rb +139 -0
  18. data/lib/phantom_svg.rb +1 -0
  19. data/phantom_svg.gemspec +25 -0
  20. data/spec/images/apngasm.png +0 -0
  21. data/spec/images/ninja.svg +63 -0
  22. data/spec/images/stuck_out_tongue/0.svg +103 -0
  23. data/spec/images/stuck_out_tongue/1.svg +103 -0
  24. data/spec/images/stuck_out_tongue/10.svg +103 -0
  25. data/spec/images/stuck_out_tongue/11.svg +103 -0
  26. data/spec/images/stuck_out_tongue/2.svg +103 -0
  27. data/spec/images/stuck_out_tongue/3.svg +103 -0
  28. data/spec/images/stuck_out_tongue/4.svg +103 -0
  29. data/spec/images/stuck_out_tongue/5.svg +103 -0
  30. data/spec/images/stuck_out_tongue/6.svg +103 -0
  31. data/spec/images/stuck_out_tongue/7.svg +103 -0
  32. data/spec/images/stuck_out_tongue/8.svg +103 -0
  33. data/spec/images/stuck_out_tongue/9.svg +103 -0
  34. data/spec/images/stuck_out_tongue/loops_test.json +9 -0
  35. data/spec/images/stuck_out_tongue/loops_test.xml +4 -0
  36. data/spec/images/stuck_out_tongue/skip_first_test.json +10 -0
  37. data/spec/images/stuck_out_tongue/skip_first_test.xml +5 -0
  38. data/spec/images/stuck_out_tongue/test1.json +20 -0
  39. data/spec/images/stuck_out_tongue/test1.xml +15 -0
  40. data/spec/images/stuck_out_tongue/test2.json +13 -0
  41. data/spec/images/stuck_out_tongue/test2.xml +4 -0
  42. data/spec/phantom/svg_spec.rb +421 -0
  43. data/spec/spec_helper.rb +81 -0
  44. metadata +170 -0
@@ -0,0 +1,32 @@
1
+
2
+ require 'rexml/document'
3
+
4
+ require_relative '../frame.rb'
5
+ require_relative 'abstract_animation_reader.rb'
6
+
7
+ module Phantom
8
+ module SVG
9
+ module Parser
10
+ # AnimationReader for XML.
11
+ class XMLAnimationReader < AbstractAnimationReader
12
+ private
13
+
14
+ # Read parameter from animation information file.
15
+ def read_parameter(path)
16
+ xml = REXML::Document.new(open(path))
17
+
18
+ animation = xml.elements['animation']
19
+ return if animation.nil?
20
+
21
+ animation.attributes.each do |key, val|
22
+ set_parameter(key, val)
23
+ end
24
+
25
+ animation.elements.each('frame') do |element|
26
+ add_frame_info(element.attributes['src'], element.attributes['delay'])
27
+ end
28
+ end
29
+ end # class XMLAnimationReader < AbstractAnimationReader
30
+ end # module Parser
31
+ end # module SVG
32
+ end # module Phantom
@@ -0,0 +1,139 @@
1
+
2
+ require_relative 'frame.rb'
3
+ require_relative 'parser/raster.rb'
4
+ require_relative 'parser/svg_reader.rb'
5
+ require_relative 'parser/svg_writer.rb'
6
+ require_relative 'parser/json_animation_reader.rb'
7
+ require_relative 'parser/xml_animation_reader.rb'
8
+
9
+ module Phantom
10
+ module SVG
11
+ class Base
12
+ include Parser::Raster
13
+ attr_accessor :frames, :width, :height, :loops, :skip_first
14
+
15
+ def initialize(path = nil, options = {})
16
+ reset
17
+
18
+ add_frame_from_file(path, options) if path
19
+ end
20
+
21
+ def reset
22
+ @frames = []
23
+ @width = 0
24
+ @height = 0
25
+ @loops = 0
26
+ @skip_first = false
27
+ end
28
+
29
+ def add_frame_from_file(path, options = {})
30
+ create_file_list(path).each do |file|
31
+ case File.extname(file)
32
+ when '.svg' then load_from_svg(file, options)
33
+ when '.png' then load_from_png(file, options)
34
+ when '.json' then load_from_json(file, options)
35
+ when '.xml' then load_from_xml(file, options)
36
+ end
37
+ end
38
+ end
39
+
40
+ # Creates a blank frame when no arguments are passed
41
+ # Takes another Phantom::SVG object or file path
42
+ def add_frame(frame = nil, options = {})
43
+ if frame.nil? then @frames << Phantom::SVG::Frame.new
44
+ elsif frame.instance_of?(Phantom::SVG::Frame) then @frames << frame
45
+ elsif frame.instance_of?(Phantom::SVG::Base) then @frames += frame.frames
46
+ elsif frame.instance_of?(String) then add_frame_from_file(frame, options)
47
+ end
48
+ end
49
+
50
+ def set_size
51
+ @width = 0
52
+ @height = 0
53
+ frames.each do |frame|
54
+ @width = frame.width.to_f if frame.width.to_f > @width
55
+ @height = frame.height.to_f if frame.height.to_f > @height
56
+ end
57
+ end
58
+
59
+ def save_svg(path)
60
+ set_size if @width.to_i == 0 || @height.to_i == 0
61
+
62
+ Parser::SVGWriter.new.write(path, self)
63
+ end
64
+
65
+ def save_svg_frame(path, frame, width = nil, height = nil)
66
+ old_width = frame.width
67
+ old_height = frame.height
68
+ frame.width = width unless width.nil?
69
+ frame.height = height unless height.nil?
70
+
71
+ write_size = Parser::SVGWriter.new.write(path, frame)
72
+
73
+ frame.width = old_width
74
+ frame.height = old_height
75
+
76
+ write_size
77
+ end
78
+
79
+ def save_apng(path)
80
+ save_rasterized(path)
81
+ end
82
+
83
+ # Calculate and return total duration.
84
+ def total_duration
85
+ result = 0.0
86
+ @frames.each_with_index do |frame, i|
87
+ next if i == 0 && @skip_first
88
+ result += frame.duration
89
+ end
90
+ result
91
+ end
92
+
93
+ private
94
+
95
+ def load_from_svg(path, options)
96
+ reader = Parser::SVGReader.new(path, options)
97
+ if reader.has_animation?
98
+ @width = reader.width
99
+ @height = reader.height
100
+ @loops = reader.loops
101
+ @skip_first = reader.skip_first
102
+ end
103
+
104
+ @frames += reader.frames
105
+ end
106
+
107
+ def load_from_png(path, options)
108
+ load_raster(path, @frames.size)
109
+ end
110
+
111
+ def load_from_json(path, options)
112
+ load_from_reader(Parser::JSONAnimationReader.new(path), options)
113
+ end
114
+
115
+ def load_from_xml(path, options)
116
+ load_from_reader(Parser::XMLAnimationReader.new(path), options)
117
+ end
118
+
119
+ def load_from_reader(reader, options)
120
+ if @frames.empty?
121
+ @loops = reader.loops
122
+ @skip_first = reader.skip_first
123
+ @frames += reader.frames
124
+ set_size
125
+ elsif reader.skip_first
126
+ @frames += reader.frames.slice(1, reader.frames.length - 1)
127
+ else
128
+ @frames += reader.frames
129
+ end
130
+ end
131
+
132
+ def create_file_list(path)
133
+ result = Dir.glob(path).sort_by { |k| k[/\d+/].to_i }
134
+ result << path if result.empty?
135
+ result
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1 @@
1
+ require 'phantom/svg'
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+ s.platform = Gem::Platform::RUBY
3
+ s.name = 'phantom_svg'
4
+ s.version = '1.0.0'
5
+ s.license = 'LGPL-3.0'
6
+ s.summary = 'Hight end SVG manipulation tools for Ruby'
7
+ s.description = 'Hight end SVG manipulation tools for Ruby.\n' \
8
+ 'Includes chained keyframe generation, (A)PNG conversion and more.'
9
+ s.authors = ['Rika Yoshida', 'Rei Kagetsuki', 'Naoki Iwakawa']
10
+ s.email = 'info@genshin.org'
11
+ s.homepage = 'http://github.com/Genshin/phantom_svg'
12
+
13
+ s.required_ruby_version = '~> 2.0.0'
14
+
15
+ s.files = `git ls-files`.split($RS)
16
+ s.test_files = s.files.grep(/^spec\//)
17
+ s.require_path = 'lib'
18
+
19
+ s.requirements << 'libapngasm'
20
+
21
+ s.add_dependency 'cairo', '~> 1.12'
22
+ s.add_dependency 'rapngasm', '~> 3.1'
23
+ s.add_dependency 'gdk3', '~> 2.2'
24
+ s.add_dependency 'rsvg2', '~> 2.2'
25
+ end
Binary file
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="&#x30EC;&#x30A4;&#x30E4;&#x30FC;_1"
5
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px"
6
+ viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
7
+ <g>
8
+ <line style="fill:none;stroke:#190110;stroke-width:3;stroke-miterlimit:10;" x1="16.007" y1="20.647" x2="48.812" y2="37.975"/>
9
+ <polygon style="fill:#8F72B7;stroke:#1C0801;stroke-width:2.1575;stroke-miterlimit:10;" points="9.07,54.989 19.213,50.722
10
+ 20.518,53.896 11.273,58.126 "/>
11
+ <path style="fill:#967656;stroke:#1C0801;stroke-width:2.0559;stroke-miterlimit:10;" d="M10.739,55.597
12
+ c0,0-2.537-0.584-3.197-3.166l-1.85-1.709L4.333,52.38l2.944,8.092l4.745-2.393L10.739,55.597z"/>
13
+ <path style="fill:#CE5A21;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" d="M19.07,45.302
14
+ c-4.25,1.125-6.145,6.936-6.145,6.936s3.77,6.859,6.77,5.859s5.985-4.213,5.985-4.213l11.016-2.078l-7.063-12.209L19.07,45.302z"/>
15
+ <polygon style="fill:#8F72B7;stroke:#1C0801;stroke-width:2.1575;stroke-miterlimit:10;" points="55.183,46.021 44.54,48.813
16
+ 43.696,45.487 53.444,42.604 "/>
17
+ <path style="fill:#967656;stroke:#1C0801;stroke-width:2.0559;stroke-miterlimit:10;" d="M53.616,45.185
18
+ c0,0,2.43,0.936,2.719,3.586l1.59,1.951l1.742-1.094l-1.934-8.783l-5.037,1.699L53.616,45.185z"/>
19
+ <polygon style="fill:#A53A0A;stroke:#1C0801;stroke-width:1.8151;stroke-miterlimit:10;" points="24.481,27.17 12.597,32.188
20
+ 16.057,37.077 19.991,39.421 26.784,31.184 "/>
21
+ <path style="fill:#EFAF84;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" d="M10.471,33.814c0,0,3.654-3.075,4.654-2.85
22
+ c1,0.225,2.761,3.976,2.761,3.976l-5.011,4.25C12.875,39.19,10.192,36.565,10.471,33.814z"/>
23
+ <g>
24
+ <polygon style="fill:#EFAF84;stroke:#1C0801;stroke-width:1.8205;stroke-miterlimit:10;" points="50.782,9.8 51.396,6.566
25
+ 48.628,3.528 47.055,5.952 44.247,8.237 46.572,12.308 47.106,11.989 48.033,13.26 51.597,12.125 49.435,10.603 "/>
26
+ <path style="fill:#EFAF84;stroke:#1C0801;stroke-width:2.054;stroke-miterlimit:10;" d="M30.205,19.577l0.354-4.393
27
+ c0,0,9.317-3.975,13.338-6.469l2.585,2.723c0,0-13.133,9.837-14.09,11.798C31.436,25.198,30.205,19.577,30.205,19.577z"/>
28
+ <polygon style="fill:#8F72B7;" points="43.543,10.071 45.061,11.43 42.552,13.082 40.702,11.661 "/>
29
+ </g>
30
+ <path style="fill:#CE5A21;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" d="M30.384,49.546c0,0,2.931,2.385,8.529,4.879
31
+ c5.738-2.074,11.799-6.035,11.799-6.035s-0.086-2-2.211-5.25c-4.125-1.25-7.732-2.295-7.732-2.295s0.107-2.424-3.072-4.146
32
+ C33.94,34.663,15.384,32.423,30.384,49.546z"/>
33
+ <g>
34
+ <path style="fill:#847340;stroke:#1C0801;stroke-miterlimit:10;" d="M23.561,39.892c0,0,1.939,2.654,2.439,3.154l8.751-6.25
35
+ l1.945-0.098c0,0-0.182-2.215-1.002-4.254l-8.57,6.232L23.561,39.892z"/>
36
+ <path style="fill:#847340;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" d="M36.696,36.698c0,0-0.182-2.215-1.002-4.254"
37
+ />
38
+ </g>
39
+ <path style="fill:#CE5A21;stroke:#1C0801;stroke-width:1.8151;stroke-miterlimit:10;" d="M20.32,23.595
40
+ c0,0,0.125-4.118,5.625-5.766c2.438-3.034,6.555-5.895,6.555-5.895l0.32,2.153l3.626,6.921l-2,3.735c0,0,0.201,1.017,3.25,3.094
41
+ c-2.25,6.958-3.33,5.037-4.407,6.356c-2.905,3.551-4.281,3.551-8.858,7.508c-4.75-4.324-3.976-15.176-3.976-15.176L20.32,23.595z"
42
+ />
43
+ <polygon style="fill:#EFAF84;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" points="15.82,25.073 20.518,27.838
44
+ 22.999,33.67 23.561,24.693 20.57,19.443 "/>
45
+ <path style="fill:#CE5A21;stroke:#1C0801;stroke-width:2;stroke-miterlimit:10;" d="M8.34,15.101l1.942,9.32
46
+ c0,0,3.669,3.648,5.402,3.405c5.44-5.781,5.565-9.156,5.565-9.156l3.181-0.916l-2.192-3.458L23,7.67c0,0-3.732,1.548-9.221,1.237
47
+ C8.666,11.141,8.34,15.101,8.34,15.101z"/>
48
+ <polygon style="fill:#EFAF84;stroke:#1C0801;stroke-miterlimit:10;" points="8.971,18.129 20.32,15.021 14.646,19.443
49
+ 9.866,22.428 "/>
50
+ <polygon style="fill:#AF400E;" points="20.32,14.43 9.563,15.711 9.813,17.357 "/>
51
+ <path style="fill:#AF400E;" d="M11.125,23.977l8.565-3.49c0,0-2.212,4.188-4.283,6.332C15.407,26.818,13.375,26.284,11.125,23.977z
52
+ "/>
53
+ <polygon style="fill:#AF400E;" points="32.813,16.045 35.376,21.045 31.851,29.311 "/>
54
+ <path style="fill:#AF400E;" d="M36.515,28.107c0,0-10.651,11.138-12.084,11.784C24.431,39.892,35.938,34.571,36.515,28.107z"/>
55
+ <path style="fill:#AF400E;" d="M27.25,47.296l-2.819,4l-8.314,3.613c0,0,1.683,2.951,2.634,2.512
56
+ c5.681-2.625,6.429-4.557,6.429-4.557l6.672-1.006L27.25,47.296z"/>
57
+ <path style="fill:#AF400E;" d="M38.938,53.421l9.563-6.375l-0.619-2.797l1.869,3.672C49.751,47.921,49.44,49.185,38.938,53.421z"/>
58
+ <polygon style="fill:#AF400E;" points="26.784,43.046 36.696,37.745 34.876,37.745 "/>
59
+ <polygon style="fill:#AF400E;" points="39.876,40.845 34.876,43.046 42.001,42.604 39.626,41.702 "/>
60
+ <path style="fill:none;stroke:#4C231B;stroke-width:2.2378;stroke-miterlimit:10;" d="M18.75,27.758c0,0,3.257,9.175,17.765,4.704"
61
+ />
62
+ </g>
63
+ </svg>
@@ -0,0 +1,103 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="_x30_0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5
+ width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
6
+ <g>
7
+ <g>
8
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="15.4937" y1="-0.0762" x2="50.2369" y2="63.8233">
9
+ <stop offset="0" style="stop-color:#F8D8CB"/>
10
+ <stop offset="0.1365" style="stop-color:#F7D1C3"/>
11
+ <stop offset="0.3479" style="stop-color:#F5BEAD"/>
12
+ <stop offset="0.6075" style="stop-color:#F19F8A"/>
13
+ <stop offset="0.903" style="stop-color:#EB7459"/>
14
+ <stop offset="1" style="stop-color:#E96547"/>
15
+ </linearGradient>
16
+ <circle fill="url(#SVGID_1_)" cx="32.149" cy="30.558" r="28.191"/>
17
+ </g>
18
+ <defs>
19
+ <filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="3.958" y="2.367" width="56.383" height="56.382">
20
+
21
+ <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/>
22
+ </filter>
23
+ </defs>
24
+ <mask maskUnits="userSpaceOnUse" x="3.958" y="2.367" width="56.383" height="56.382" id="SVGID_2_">
25
+ <g filter="url(#Adobe_OpacityMaskFilter)">
26
+
27
+ <image overflow="visible" width="62" height="61" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
28
+ EAMCAwYAAAHWAAACYgAAA5X/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
29
+ Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
30
+ JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAD0APgMBIgACEQEDEQH/
31
+ xACUAAADAAMBAQAAAAAAAAAAAAAABgcBBAUDAgEBAAAAAAAAAAAAAAAAAAAAABAAAQMDAwQDAAAA
32
+ AAAAAAAAAwIEBQEGBwAQIEASExUUFhcRAAIBAgIHAg0FAAAAAAAAAAECEQADIQQQIDFBEiITYQVR
33
+ cYGRscHhQoKiMxQVMmIjQyQSAQAAAAAAAAAAAAAAAAAAAED/2gAMAwEAAhEDEQAAAJ/9FVFVjb8i
34
+ YrVzBAcPyCNdUR3kAAAPOR2BLNR/i9jPUAADCE3Ro1G5RC7bURcR85yWmnT4gH//2gAIAQIAAQUA
35
+ 6D//2gAIAQMAAQUA6D//2gAIAQEAAQUA0MZCkh8fSL1IsbQ6UOcaxSxzNkSsYitK0roYyFJaNqgj
36
+ Wm6kpVS+bTQNOsfRSXspxOFBwqgKIuzGQFJZ8nzYaMhYxcp7OTp9VeRLXmKxEq3ONwHhNSYoyP8A
37
+ ZOPZatS9FRaWUizfB2lZ6OiwXJcjmbc7xXve8X6F2SP3/wAD353l2//aAAgBAgIGPwAH/9oACAED
38
+ AgY/AAf/2gAIAQEBBj8ApbdpS7uYVRiSaF3ON9tbIwUYtQF13dwMW4iJ81EWLj233NJPpmmvJ/os
39
+ rJJUcwHi30QRBGBB0LbtqWdzCqNpJpMxmbYbN3AGYnGOwahVhIO0Gm70yKGf7bajb26GzN1Zt5cc
40
+ vg4jrPZcSrggg9tJ3SfpXLnEo/ZBePliszeMQ78vkAHq1+7LgHNdW6W+G05HprNZYtzcQYLOwRr5
41
+ IEjgsh1HxW7gNW77GLL8t3xbjS3rTBkcSCNW7mbjQVU8I3zX5Kf5up1PZ5sNCZLOgtlpARx7g7aW
42
+ 9lrquriRBGlruYuiVGCgyTRxK5ZTyJ4e06g/F9acY4J4duO3loR04j3pmj1Ijf0v1fNR+96nUk/U
43
+ nyxPq0//2Q==" transform="matrix(1 0 0 1 1 0)">
44
+ </image>
45
+ </g>
46
+ </mask>
47
+ <g opacity="0.27" mask="url(#SVGID_2_)">
48
+ <circle fill="#EA7878" cx="32.149" cy="30.558" r="28.191"/>
49
+ </g>
50
+ </g>
51
+ <g opacity="0.8">
52
+
53
+ <image overflow="visible" width="62" height="12" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD8AAAANCAYAAAAe7bZ5AAAACXBIWXMAAAsSAAALEgHS3X78AAAA
54
+ GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAgdJREFUeNrUlttO20AQhteJ41Bx
55
+ iKhKgBtuuOSmFdf0UXgKHoOn6Lv0OkiovUEUCUHFMVXFIQfHDv9In6tRsEKlSk460i977d3R/+/M
56
+ zk4UnN0dfonCG/bhYH8c5sT+hu80zpFzVNOjISR8Gglj5uR8szmZ/ZPDfMbCPd/IcQ3u3Z5DIS3j
57
+ GzlH74Q1YR2RvxEa22Lm14UH4ZfQl8NshsI93wSODaYU7yb82pYIvUm+EaljizeFXeGj0BRuWGzv
58
+ fXbRNuJc+C5clDmsKNU930/CsjAQFpjWh/eTcCx04PvsMyDmmbCDJnxPWGXhiB1MEW9CT4Ul1l2I
59
+ zPMMjoDn+9mONdwSF3nT9si8wOb8FN9hUQPikmNg6bThHNUQXohvk/5pmcMKrciAFbIggWugRkXw
60
+ q3NMLWPvyeY/wgIfLM2/gVuiXliDNGoifge03SZVaUOEnHGmh050cNG38aLwnmfdF/nYIqbIpQju
61
+ INQivM1kG7dctGuuBlRu8LXAdIUT6k8LFAU6o2Ab355wxTHOPO8Yh7kc9igKgbOyxeSmq6gDxlbx
62
+ jyZ2vUrL4fhD+IqwZcevqPIDIm0Zcsn49T1PJa1TMVdxlhPxlrvy/BVyS8Wv/M5/47obuau6RrC6
63
+ XM95qXjnNEZ00SzEE43E1OZhDhqd8USTVtqYRf/SOs5Dq/u/teRzYy8CDAAUkd35+IZT8gAAAABJ
64
+ RU5ErkJggg==" transform="matrix(1 0 0 1 1.0781 19.0781)">
65
+ </image>
66
+ <g>
67
+ <g>
68
+
69
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="5.521" y1="23.466" x2="8.366" y2="26.819"/>
70
+
71
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="8.648" y1="23.466" x2="11.493" y2="26.819"/>
72
+
73
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="11.775" y1="23.466" x2="14.62" y2="26.819"/>
74
+
75
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="49.16" y1="23.466" x2="52.005" y2="26.818"/>
76
+
77
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="52.286" y1="23.466" x2="55.132" y2="26.818"/>
78
+
79
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="55.414" y1="23.466" x2="58.259" y2="26.818"/>
80
+ </g>
81
+ </g>
82
+ </g>
83
+ <ellipse fill="#78211C" cx="43.037" cy="17.842" rx="3.53" ry="5.06"/>
84
+ <ellipse fill="#78211C" cx="21.262" cy="17.842" rx="3.53" ry="5.06"/>
85
+ <path fill="#842C38" d="M50.572,33.182c0,10.365-8.246,18.771-18.423,18.771c-10.175,0-18.423-8.406-18.423-18.771
86
+ c7.438-0.216,8.249,1.555,18.423,1.555C42.326,34.736,42.326,33.182,50.572,33.182z"/>
87
+ <circle fill="none" stroke="#B95E5D" stroke-width="2.435" stroke-miterlimit="10" cx="32.149" cy="30.558" r="27.349"/>
88
+ <circle fill="none" stroke="#541715" stroke-width="2.435" stroke-miterlimit="10" cx="32.149" cy="30.558" r="28.191"/>
89
+ <polygon fill="#FFFFFF" points="50.427,38.572 13.872,38.572 13.872,33.701 31.913,35.256 50.427,33.701 "/>
90
+ <path fill="none" stroke="#51090E" stroke-width="1.948" stroke-miterlimit="10" d="M50.572,33.182
91
+ c0,10.365-8.246,18.771-18.423,18.771c-10.175,0-18.423-8.406-18.423-18.771c8.249,0,8.249,1.555,18.423,1.555
92
+ C42.326,34.736,42.326,33.182,50.572,33.182z"/>
93
+ <g>
94
+ <path fill="#EA7C91" stroke="#65132B" stroke-width="1.8384" stroke-miterlimit="10" d="M20.132,46.857
95
+ c0,0,5.132-1.748,10.785-1.748s9.44,0.297,12.716,2.008c0,0,0,4.999,0,8.024c0,3.026-6.805,6.012-12.029,6.012
96
+ c-5.225,0-11.473-2.588-11.473-6.012C20.132,51.717,20.132,46.857,20.132,46.857z"/>
97
+ <path fill="#E42A56" d="M42.94,46.457c0,0-5.326-2.251-10.937-2.251c-7.139,0-11.715,2.423-11.715,2.423v2.327
98
+ c0,0,4.87-1.18,10.513-1.316l1.202,8.48l1.168-8.501c3.103,0.031,6.27,0.535,9.769,1.183V46.457z"/>
99
+ <path fill="none" stroke="#65132B" stroke-width="1.8384" stroke-miterlimit="10" d="M20.132,45.911c0,0,5.132-1.751,10.785-1.751
100
+ s9.44,0.298,12.716,2.005c0,0,0,5.002,0,8.028c0,3.025-6.805,6.013-12.029,6.013c-5.225,0-11.473-2.589-11.473-6.013
101
+ C20.132,50.768,20.132,45.911,20.132,45.911z"/>
102
+ </g>
103
+ </svg>
@@ -0,0 +1,103 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="_x30_1_10_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5
+ width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
6
+ <g>
7
+ <g>
8
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="15.4937" y1="-0.0762" x2="50.2369" y2="63.8233">
9
+ <stop offset="0" style="stop-color:#F8D8CB"/>
10
+ <stop offset="0.1365" style="stop-color:#F7D1C3"/>
11
+ <stop offset="0.3479" style="stop-color:#F5BEAD"/>
12
+ <stop offset="0.6075" style="stop-color:#F19F8A"/>
13
+ <stop offset="0.903" style="stop-color:#EB7459"/>
14
+ <stop offset="1" style="stop-color:#E96547"/>
15
+ </linearGradient>
16
+ <circle fill="url(#SVGID_1_)" cx="32.149" cy="30.558" r="28.191"/>
17
+ </g>
18
+ <defs>
19
+ <filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="3.958" y="2.367" width="56.383" height="56.382">
20
+
21
+ <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/>
22
+ </filter>
23
+ </defs>
24
+ <mask maskUnits="userSpaceOnUse" x="3.958" y="2.367" width="56.383" height="56.382" id="SVGID_2_">
25
+ <g filter="url(#Adobe_OpacityMaskFilter)">
26
+
27
+ <image overflow="visible" width="62" height="61" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
28
+ EAMCAwYAAAHWAAACYgAAA5X/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
29
+ Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
30
+ JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAD0APgMBIgACEQEDEQH/
31
+ xACUAAADAAMBAQAAAAAAAAAAAAAABgcBBAUDAgEBAAAAAAAAAAAAAAAAAAAAABAAAQMDAwQDAAAA
32
+ AAAAAAAAAwIEBQEGBwAQIEASExUUFhcRAAIBAgIHAg0FAAAAAAAAAAECEQADIQQQIDFBEiITYQVR
33
+ cYGRscHhQoKiMxQVMmIjQyQSAQAAAAAAAAAAAAAAAAAAAED/2gAMAwEAAhEDEQAAAJ/9FVFVjb8i
34
+ YrVzBAcPyCNdUR3kAAAPOR2BLNR/i9jPUAADCE3Ro1G5RC7bURcR85yWmnT4gH//2gAIAQIAAQUA
35
+ 6D//2gAIAQMAAQUA6D//2gAIAQEAAQUA0MZCkh8fSL1IsbQ6UOcaxSxzNkSsYitK0roYyFJaNqgj
36
+ Wm6kpVS+bTQNOsfRSXspxOFBwqgKIuzGQFJZ8nzYaMhYxcp7OTp9VeRLXmKxEq3ONwHhNSYoyP8A
37
+ ZOPZatS9FRaWUizfB2lZ6OiwXJcjmbc7xXve8X6F2SP3/wAD353l2//aAAgBAgIGPwAH/9oACAED
38
+ AgY/AAf/2gAIAQEBBj8ApbdpS7uYVRiSaF3ON9tbIwUYtQF13dwMW4iJ81EWLj233NJPpmmvJ/os
39
+ rJJUcwHi30QRBGBB0LbtqWdzCqNpJpMxmbYbN3AGYnGOwahVhIO0Gm70yKGf7bajb26GzN1Zt5cc
40
+ vg4jrPZcSrggg9tJ3SfpXLnEo/ZBePliszeMQ78vkAHq1+7LgHNdW6W+G05HprNZYtzcQYLOwRr5
41
+ IEjgsh1HxW7gNW77GLL8t3xbjS3rTBkcSCNW7mbjQVU8I3zX5Kf5up1PZ5sNCZLOgtlpARx7g7aW
42
+ 9lrquriRBGlruYuiVGCgyTRxK5ZTyJ4e06g/F9acY4J4duO3loR04j3pmj1Ijf0v1fNR+96nUk/U
43
+ nyxPq0//2Q==" transform="matrix(1 0 0 1 1 0)">
44
+ </image>
45
+ </g>
46
+ </mask>
47
+ <g opacity="0.27" mask="url(#SVGID_2_)">
48
+ <circle fill="#EA7878" cx="32.149" cy="30.558" r="28.191"/>
49
+ </g>
50
+ </g>
51
+ <g opacity="0.8">
52
+
53
+ <image overflow="visible" width="62" height="12" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD8AAAANCAYAAAAe7bZ5AAAACXBIWXMAAAsSAAALEgHS3X78AAAA
54
+ GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAgdJREFUeNrUlttO20AQhteJ41Bx
55
+ iKhKgBtuuOSmFdf0UXgKHoOn6Lv0OkiovUEUCUHFMVXFIQfHDv9In6tRsEKlSk460i977d3R/+/M
56
+ zk4UnN0dfonCG/bhYH8c5sT+hu80zpFzVNOjISR8Gglj5uR8szmZ/ZPDfMbCPd/IcQ3u3Z5DIS3j
57
+ GzlH74Q1YR2RvxEa22Lm14UH4ZfQl8NshsI93wSODaYU7yb82pYIvUm+EaljizeFXeGj0BRuWGzv
58
+ fXbRNuJc+C5clDmsKNU930/CsjAQFpjWh/eTcCx04PvsMyDmmbCDJnxPWGXhiB1MEW9CT4Ul1l2I
59
+ zPMMjoDn+9mONdwSF3nT9si8wOb8FN9hUQPikmNg6bThHNUQXohvk/5pmcMKrciAFbIggWugRkXw
60
+ q3NMLWPvyeY/wgIfLM2/gVuiXliDNGoifge03SZVaUOEnHGmh050cNG38aLwnmfdF/nYIqbIpQju
61
+ INQivM1kG7dctGuuBlRu8LXAdIUT6k8LFAU6o2Ab355wxTHOPO8Yh7kc9igKgbOyxeSmq6gDxlbx
62
+ jyZ2vUrL4fhD+IqwZcevqPIDIm0Zcsn49T1PJa1TMVdxlhPxlrvy/BVyS8Wv/M5/47obuau6RrC6
63
+ XM95qXjnNEZ00SzEE43E1OZhDhqd8USTVtqYRf/SOs5Dq/u/teRzYy8CDAAUkd35+IZT8gAAAABJ
64
+ RU5ErkJggg==" transform="matrix(1 0 0 1 1.0781 19.0781)">
65
+ </image>
66
+ <g>
67
+ <g>
68
+
69
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="5.521" y1="23.466" x2="8.366" y2="26.819"/>
70
+
71
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="8.648" y1="23.466" x2="11.493" y2="26.819"/>
72
+
73
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="11.775" y1="23.466" x2="14.62" y2="26.819"/>
74
+
75
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="49.16" y1="23.466" x2="52.005" y2="26.818"/>
76
+
77
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="52.286" y1="23.466" x2="55.132" y2="26.818"/>
78
+
79
+ <line fill="none" stroke="#E43860" stroke-width="2.922" stroke-miterlimit="10" x1="55.414" y1="23.466" x2="58.259" y2="26.818"/>
80
+ </g>
81
+ </g>
82
+ </g>
83
+ <ellipse fill="#78211C" cx="43.037" cy="17.842" rx="3.53" ry="5.06"/>
84
+ <ellipse fill="#78211C" cx="21.262" cy="17.842" rx="3.53" ry="5.06"/>
85
+ <path fill="#842C38" d="M50.572,33.182c0,10.365-8.246,18.771-18.423,18.771c-10.175,0-18.423-8.406-18.423-18.771
86
+ c7.438-0.216,8.249,1.555,18.423,1.555C42.326,34.736,42.326,33.182,50.572,33.182z"/>
87
+ <circle fill="none" stroke="#B95E5D" stroke-width="2.435" stroke-miterlimit="10" cx="32.149" cy="30.558" r="27.349"/>
88
+ <circle fill="none" stroke="#541715" stroke-width="2.435" stroke-miterlimit="10" cx="32.149" cy="30.558" r="28.191"/>
89
+ <polygon fill="#FFFFFF" points="50.427,38.572 13.872,38.572 13.872,33.701 31.913,35.256 50.427,33.701 "/>
90
+ <path fill="none" stroke="#51090E" stroke-width="1.948" stroke-miterlimit="10" d="M50.572,33.182
91
+ c0,10.365-8.246,18.771-18.423,18.771c-10.175,0-18.423-8.406-18.423-18.771c8.249,0,8.249,1.555,18.423,1.555
92
+ C42.326,34.736,42.326,33.182,50.572,33.182z"/>
93
+ <g>
94
+ <path fill="#EA7C91" stroke="#65132B" stroke-width="1.3207" stroke-miterlimit="10" d="M20.132,43.96
95
+ c0,0,5.132-0.902,10.785-0.902s9.44,0.153,12.716,1.036c0,0,0,2.58,0,4.142c0,1.561-6.805,3.102-12.029,3.102
96
+ c-5.225,0-11.473-1.335-11.473-3.102C20.132,46.468,20.132,43.96,20.132,43.96z"/>
97
+ <path fill="#E42A56" d="M42.94,43.752c0,0-5.326-1.161-10.937-1.161c-7.139,0-11.715,1.251-11.715,1.251v1.201
98
+ c0,0,4.87-0.609,10.513-0.68l1.202,4.377l1.168-4.388c3.103,0.017,6.27,0.275,9.769,0.61V43.752z"/>
99
+ <path fill="none" stroke="#65132B" stroke-width="1.3207" stroke-miterlimit="10" d="M20.132,43.471c0,0,5.132-0.903,10.785-0.903
100
+ s9.44,0.152,12.716,1.034c0,0,0,2.582,0,4.143c0,1.563-6.805,3.104-12.029,3.104c-5.225,0-11.473-1.336-11.473-3.104
101
+ C20.132,45.978,20.132,43.471,20.132,43.471z"/>
102
+ </g>
103
+ </svg>