emojidex 0.0.10 β†’ 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/Gemfile +1 -1
  4. data/Guardfile +26 -1
  5. data/emojidex.gemspec +3 -2
  6. data/lib/emojidex.rb +1 -0
  7. data/lib/emojidex/cache.rb +16 -15
  8. data/lib/emojidex/client.rb +1 -1
  9. data/lib/emojidex/collection_checker.rb +91 -0
  10. data/lib/emojidex/extended.rb +1 -1
  11. data/lib/emojidex/service.rb +3 -3
  12. data/lib/emojidex/utf.rb +2 -2
  13. data/spec/collection_checker_spec.rb +67 -0
  14. data/spec/spec_helper.rb +6 -0
  15. data/spec/support/sample_collections/good/emoji.json +30 -0
  16. data/spec/support/sample_collections/good/mouth.svg +49 -0
  17. data/spec/support/sample_collections/good/nut_and_bolt.svg +372 -0
  18. data/spec/support/sample_collections/good/purple_heart.svg +24 -0
  19. data/spec/support/sample_collections/good/px32/mouth.png +0 -0
  20. data/spec/support/sample_collections/good/px32/nut_and_bolt.png +0 -0
  21. data/spec/support/sample_collections/good/px32/purple_heart.png +0 -0
  22. data/spec/support/sample_collections/good/px32/woman_with_bunny_ears.png +0 -0
  23. data/spec/support/sample_collections/good/woman_with_bunny_ears.svg +90 -0
  24. data/spec/support/sample_collections/missing_assets/emoji.json +30 -0
  25. data/spec/support/sample_collections/missing_assets/mouth.svg +49 -0
  26. data/spec/support/sample_collections/missing_assets/purple_heart.svg +24 -0
  27. data/spec/support/sample_collections/missing_assets/px32/mouth.png +0 -0
  28. data/spec/support/sample_collections/missing_assets/px32/nut_and_bolt.png +0 -0
  29. data/spec/support/sample_collections/missing_assets/px32/woman_with_bunny_ears.png +0 -0
  30. data/spec/support/sample_collections/missing_assets/woman_with_bunny_ears.svg +90 -0
  31. data/spec/support/sample_collections/missing_index/emoji.json +23 -0
  32. data/spec/support/sample_collections/missing_index/mouth.svg +49 -0
  33. data/spec/support/sample_collections/missing_index/nut_and_bolt.svg +372 -0
  34. data/spec/support/sample_collections/missing_index/purple_heart.svg +24 -0
  35. data/spec/support/sample_collections/missing_index/px32/mouth.png +0 -0
  36. data/spec/support/sample_collections/missing_index/px32/nut_and_bolt.png +0 -0
  37. data/spec/support/sample_collections/missing_index/px32/purple_heart.png +0 -0
  38. data/spec/support/sample_collections/missing_index/px32/woman_with_bunny_ears.png +0 -0
  39. data/spec/support/sample_collections/missing_index/woman_with_bunny_ears.svg +90 -0
  40. data/spec/utf_spec.rb +2 -1
  41. metadata +29 -7
  42. data/Rakefile +0 -8
  43. data/spec/support/test1/animation.json +0 -6
  44. data/spec/support/test2/animation.json +0 -6
  45. data/spec/support/test3/animation.json +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 276dff0ca7ffb746ffc6c75d0138d6f6f63b2516
4
- data.tar.gz: 62c8c3b0386fb62407bc2b847003ed0d542ce61c
3
+ metadata.gz: 4630fa81f0b4c20f7934cc0f5266e413ca7112a1
4
+ data.tar.gz: bfc71b18f0cfcc880d68bdefc3a7a27af1fa9592
5
5
  SHA512:
6
- metadata.gz: 56ec17e506c7e7c3d418e25cad759610d973e403db41465ddc86c153678dd3cda6e72b7e5f87c303caced3f91123a5768a816ab14bfb68b335510975896029f6
7
- data.tar.gz: 0a7d1020b60277df33755bd83b09a76fbbf7603823ab00910c315cafdb66b7b00f9e88529904638f665eff191f2ed184c8e1b755944efc6f07a828fc41008eba
6
+ metadata.gz: 2edf4d9472f06706872132dfdbc5b2c1abf41fb2bd5f79f6ee7bcc0daf1887f5ef150bbb70828e8d6e46b71d9a23566808e736b36b8afe4389c97482b5d8d499
7
+ data.tar.gz: a5e307c155ef9a1e78e1d89d812a147d2cd0a485d064fb585ad7a4204ddd0f1d28ea59fbfcd534329d66cda2fcf71bc109bda69865511b47be76d345eef993c7
data/.travis.yml CHANGED
@@ -5,7 +5,6 @@ rvm:
5
5
  - 2.0.0
6
6
  - 2.1.2
7
7
  - jruby-19mode
8
- - rbx-2
9
8
 
10
9
  bundler_args: -j4 --without development
11
10
 
data/Gemfile CHANGED
@@ -9,7 +9,6 @@ group :development do
9
9
  gem 'guard-rspec'
10
10
  gem 'rubocop'
11
11
  gem 'guard-rubocop'
12
- #gem 'emojidex-vectors', path: '../emojidex-vectors'
13
12
  end
14
13
 
15
14
  group :test do
@@ -17,4 +16,5 @@ group :test do
17
16
  gem 'rspec'
18
17
  gem 'webmock'
19
18
  gem 'emojidex-vectors', github: 'emojidex/emojidex-vectors'
19
+ gem 'emojidex-rasters', github: 'emojidex/emojidex-rasters'
20
20
  end
data/Guardfile CHANGED
@@ -1,12 +1,37 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # Note: The cmd option is now required due to the increasing number of ways
5
+ # rspec may be run, below are examples of the most common uses.
6
+ # * bundler: 'bundle exec rspec'
7
+ # * bundler binstubs: 'bin/rspec'
8
+ # * spring: 'bin/rsspec' (This will use spring if running and you have
9
+ # installed the spring binstubs per the docs)
10
+ # * zeus: 'zeus rspec' (requires the server to be started separetly)
11
+ # * 'just' rspec: 'rspec'
1
12
  guard :rubocop do
2
13
  watch(%r{.+\.rb$})
3
14
  watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
4
15
  end
5
16
 
6
- guard :rspec do
17
+ guard :rspec, cmd: 'bundle exec rspec' do
7
18
  watch(%r{^spec/.+_spec\.rb$})
8
19
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
20
  watch('spec/spec_helper.rb') { "spec" }
10
21
 
22
+ # Rails example
23
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
24
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
25
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
11
26
  watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
27
+ watch('config/routes.rb') { "spec/routing" }
28
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
29
+ watch('spec/rails_helper.rb') { "spec" }
30
+
31
+ # Capybara features specs
32
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
33
+
34
+ # Turnip features and steps
35
+ watch(%r{^spec/acceptance/(.+)\.feature$})
36
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
12
37
  end
data/emojidex.gemspec CHANGED
@@ -1,9 +1,10 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'emojidex'
3
- s.version = '0.0.10'
3
+ s.version = '0.0.11'
4
4
  s.license = 'GPL-3, AGPL-3'
5
5
  s.summary = 'emojidex Ruby tools'
6
- s.description = 'emojidex emoji handling, search and lookup, listing and caching functionality and user info (favorites/etc).'
6
+ s.description = 'emojidex emoji handling, search and lookup, listing and caching functionality' \
7
+ ' and user info (favorites/etc).'
7
8
  s.authors = ['Rei Kagetsuki', 'Jun Tohyama', 'Vassil Kalkov', 'Rika Yoshida']
8
9
  s.email = 'info@emojidex.com'
9
10
  s.files = `git ls-files`.split("\n")
data/lib/emojidex.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'json'
2
2
  require 'emojidex/emoji'
3
+ require 'emojidex/collection_checker'
3
4
  require 'emojidex/collection'
4
5
  require 'emojidex/utf'
5
6
  require 'emojidex/extended'
@@ -5,28 +5,29 @@ require 'fileutils'
5
5
  module Emojidex
6
6
  # local caching functionality for collections
7
7
  module Cache
8
- attr_reader :cache_dir
8
+ attr_reader :cache_path
9
9
 
10
10
  def setup_cache(path = nil)
11
11
  # check if cache dir is already set
12
- return @cache_dir if @cache_dir && path.nil?
12
+ return @cache_path if @cache_path && path.nil?
13
13
  # setup cache
14
- @cache_dir = File.expand_path(path || ENV['EMOJI_CACHE'] || "#{ENV['HOME']}/.emojidex/cache")
15
- FileUtils.mkdir_p(@cache_dir)
14
+ @cache_path = File.expand_path(path || ENV['EMOJI_CACHE'] || "#{ENV['HOME']}/.emojidex/cache")
15
+ ENV['EMOJI_CACHE'] = @cache_path
16
+ FileUtils.mkdir_p(@cache_path)
16
17
  Emojidex::Defaults.sizes.keys.each do |size|
17
- FileUtils.mkdir_p(@cache_dir + "/#{size}")
18
+ FileUtils.mkdir_p(@cache_path + "/#{size}")
18
19
  end
19
- @cache_dir
20
+ @cache_path
20
21
  end
21
22
 
22
23
  # Caches emoji to local emoji storage cache
23
24
  # Options:
24
- # cache_dir: manually specify cache location
25
+ # cache_path: manually specify cache location
25
26
  # (default is ENV['EMOJI_CACHE'] or '$HOME/.emoji_cache')
26
27
  # formats: formats to cache (default is SVG only)
27
28
  # sizes: sizes to cache (default is px32, but this is irrelivant for SVG)
28
29
  def cache!(options = {})
29
- setup_cache options[:cache_dir]
30
+ setup_cache options[:cache_path]
30
31
  formats = options[:formats] || [:svg, :png]
31
32
  sizes = options[:sizes] || [:px32]
32
33
  @emoji.values.each do |moji|
@@ -37,7 +38,7 @@ module Emojidex
37
38
  end
38
39
 
39
40
  def cache_index(destination = nil)
40
- destination = destination || @cache_dir
41
+ destination ||= @cache_path
41
42
  idx = Emojidex::Collection.new
42
43
  idx.load_local_collection(destination) if FileTest.exist? "#{destination}/emoji.json"
43
44
  idx.add_emoji @emoji.values
@@ -51,19 +52,19 @@ module Emojidex
51
52
  def _svg_check_copy(moji)
52
53
  src = @source_path + "/#{moji.code}"
53
54
  if File.exist? "#{src}.svg"
54
- unless File.exist?("#{@cache_dir}/#{moji.code}.svg") &&
55
- FileUtils.compare_file("#{src}.svg", "#{@cache_dir}/#{moji.code}.svg")
56
- FileUtils.cp("#{src}.svg", @cache_dir)
55
+ unless File.exist?("#{@cache_path}/#{moji.code}.svg") &&
56
+ FileUtils.compare_file("#{src}.svg", "#{@cache_path}/#{moji.code}.svg")
57
+ FileUtils.cp("#{src}.svg", @cache_path)
57
58
  end
58
59
  end
59
- FileUtils.cp_r src, @cache_dir if File.directory? src
60
+ FileUtils.cp_r src, @cache_path if File.directory? src
60
61
  end
61
62
 
62
63
  def _raster_check_copy(moji, format, sizes)
63
64
  sizes.each do |size|
64
65
  src = @source_path + "/#{size}/#{moji.code}"
65
- FileUtils.cp "src.#{format}", (@cache_dir + "/#{size}") if FileTest.exist? "src.#{format}"
66
- FileUtils.cp_r src, @cache_dir if File.directory? src
66
+ FileUtils.cp "#{src}.#{format}", (@cache_path + "/#{size}") if FileTest.exist? "#{src}.#{format}"
67
+ FileUtils.cp_r src, @cache_path if File.directory? src
67
68
  end
68
69
  end
69
70
  end
@@ -54,7 +54,7 @@ module Emojidex
54
54
  response = connection.send(method.to_sym, path, params)
55
55
  response.env
56
56
  rescue Faraday::Error::ClientError, JSON::ParserError
57
- raise Emojidex::Error
57
+ raise Emojidex::Error
58
58
  end
59
59
  end
60
60
  end
@@ -0,0 +1,91 @@
1
+
2
+ require 'find'
3
+ require_relative 'defaults.rb'
4
+
5
+ module Emojidex
6
+ # Check collections for presence of image assets and discrepencies in emoji indexes.
7
+ class CollectionChecker
8
+ attr_reader :index_only, :asset_only
9
+
10
+ def initialize(collections, options = {})
11
+ collections = *collections
12
+ @index_only = {}
13
+ @asset_only = {}
14
+ asset_path = options[:asset_path] || collections.first.source_path
15
+ sizes = options[:sizes] || Defaults.sizes.keys
16
+ formats = options[:formats] || Defaults.formats
17
+
18
+ asset_files = create_asset_file_list(asset_path, sizes, formats)
19
+ check_for_index_only(collections, asset_files, sizes, formats)
20
+ check_for_asset_only(collections, asset_files)
21
+ end
22
+
23
+ private
24
+
25
+ def create_asset_file_list(dir, sizes, formats)
26
+ result = {}
27
+ result.merge!(create_file_list(dir, '.svg', '')) if formats.include?(':svg')
28
+ if formats.include?(':png')
29
+ sizes.each do |size|
30
+ result.merge!(create_file_list("#{dir}/#{size}", '.png', "#{size}/"))
31
+ end
32
+ end
33
+ result
34
+ end
35
+
36
+ def create_file_list(dir, ext, prefix)
37
+ result = {}
38
+ Dir.foreach(dir) do |file|
39
+ result["#{prefix}#{File.basename(file, '.*')}".to_sym] =
40
+ "#{prefix}#{file}" if File.extname(file) == ext
41
+ end
42
+ result
43
+ end
44
+
45
+ def check_for_index_only(collections, asset_files, sizes, formats)
46
+ collections.each do |collection|
47
+ collection.emoji.values.each do |emoji|
48
+ tmp = []
49
+ tmp += create_svg_array(emoji, asset_files) if formats.include?(':svg')
50
+ tmp += create_png_array(emoji, asset_files, sizes) if formats.include?(':png')
51
+ @index_only[emoji.code.to_sym] = tmp unless tmp.empty?
52
+ end
53
+ end
54
+ end
55
+
56
+ def create_svg_array(emoji, asset_files)
57
+ result = []
58
+ result << emoji.code if asset_files[emoji.code.to_sym].nil?
59
+ result
60
+ end
61
+
62
+ def create_png_array(emoji, asset_files, sizes)
63
+ result = []
64
+ sizes.each do |size|
65
+ name = "#{size}/#{emoji.code}"
66
+ result << name if asset_files[name.to_sym].nil?
67
+ end
68
+ result
69
+ end
70
+
71
+ def check_for_asset_only(collections, asset_files)
72
+ asset_files.each do |_key, value|
73
+ code = File.basename(value, '.*')
74
+
75
+ next if find_emoji_from_collections(collections, code)
76
+
77
+ symbol = code.to_sym
78
+ @asset_only[symbol] = [] if @asset_only[symbol].nil?
79
+ @asset_only[symbol] << value
80
+ end
81
+ end
82
+
83
+ def find_emoji_from_collections(collections, code)
84
+ symbol = code.to_sym
85
+ collections.each do |collection|
86
+ return true unless collection.emoji[symbol].nil?
87
+ end
88
+ false
89
+ end
90
+ end # class CollectionChecker
91
+ end # module Emojidex
@@ -8,7 +8,7 @@ module Emojidex
8
8
  if defined? Emojidex::Vectors
9
9
  load_local_collection Emojidex::Vectors.path + '/extended'
10
10
  else
11
- # TODO load from service
11
+ # TODO: load from service
12
12
  end
13
13
  end
14
14
  end
@@ -13,12 +13,12 @@ module Emojidex
13
13
  # sends an API search, adding results with add_emoji
14
14
  # returns a collection, and adds results to the @emoji array
15
15
  def search(criteria = {})
16
- # TODO *NOTE try and replicate regex search functionality by passing regex to server
16
+ # TODO: *NOTE try and replicate regex search functionality by passing regex to server
17
17
  end
18
18
 
19
19
  # directly retrieves the emoji with the given code
20
20
  def find_by_code(code)
21
- # TODO
21
+ # TODO: perform a query on emojidex API
22
22
  end
23
23
 
24
24
  # emoji on the emojidex service make no language distinctions
@@ -27,6 +27,6 @@ module Emojidex
27
27
  find_by_code(code)
28
28
  end
29
29
 
30
- # TODO override or add caching functionality to retrieve sized png or svg from service
30
+ # TODO: override or add caching functionality to retrieve sized png or svg from service
31
31
  end
32
32
  end
data/lib/emojidex/utf.rb CHANGED
@@ -4,11 +4,11 @@ module Emojidex
4
4
  # listing and search of standard UTF emoji
5
5
  class UTF < Collection
6
6
  def initialize
7
- super
7
+ super
8
8
  if defined? Emojidex::Vectors
9
9
  load_local_collection Emojidex::Vectors.path + '/utf'
10
10
  else
11
- # TODO load from service
11
+ # TODO: load from service
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,67 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe Emojidex::CollectionChecker do
5
+
6
+ before(:all) do
7
+ @sizes = [:px32]
8
+ end
9
+
10
+
11
+
12
+
13
+ let(:col_good) do
14
+ sample_collection 'good'
15
+ end
16
+
17
+ let(:col_missing_assets) do
18
+ sample_collection 'missing_assets'
19
+ end
20
+
21
+ let(:col_missing_index) do # just missing entries in index, not missing the actual index
22
+ sample_collection 'missing_index'
23
+ end
24
+
25
+ describe 'Spec Collections' do
26
+ it 'load cleanly' do
27
+ expect(col_good).to be_an_instance_of(Emojidex::Collection)
28
+ expect(col_missing_assets).to be_an_instance_of(Emojidex::Collection)
29
+ expect(col_missing_index).to be_an_instance_of(Emojidex::Collection)
30
+ end
31
+ end
32
+
33
+ describe '.new' do
34
+ it 'creates a valid CollectionChecker instance and checks a valid collection' do
35
+ checker = Emojidex::CollectionChecker.new(col_good, {sizes: @sizes})
36
+
37
+ expect(checker).to be_an_instance_of(Emojidex::CollectionChecker)
38
+ expect(checker.index_only).to be_empty
39
+ expect(checker.asset_only).to be_empty
40
+ end
41
+
42
+ it 'checks for and identifies missing assets' do
43
+ checker = Emojidex::CollectionChecker.new(col_missing_assets, {sizes: @sizes})
44
+
45
+ expect(checker.asset_only).to be_empty
46
+ expect(checker.index_only.size).to eq(2)
47
+ expect(checker.index_only).to eq(
48
+ {:nut_and_bolt=>["nut_and_bolt"], :purple_heart=>["px32/purple_heart"]})
49
+ end
50
+
51
+ it 'checks for and identifies missing index entries' do
52
+ checker = Emojidex::CollectionChecker.new(col_missing_index, {sizes: @sizes})
53
+
54
+ expect(checker.index_only).to be_empty
55
+ expect(checker.asset_only.size).to eq(1)
56
+ expect(checker.asset_only).to eq(
57
+ {purple_heart: ["purple_heart.svg", "px32/purple_heart.png"]})
58
+ end
59
+ it 'checks collections against a specified asset directory' do
60
+ checker = Emojidex::CollectionChecker.new([col_missing_index, col_missing_assets],
61
+ {sizes: @sizes, asset_path: col_good.source_path})
62
+
63
+ expect(checker.index_only).to be_empty
64
+ expect(checker.asset_only).to be_empty
65
+ end
66
+ end
67
+ end
data/spec/spec_helper.rb CHANGED
@@ -62,3 +62,9 @@ end
62
62
  def fixture(file)
63
63
  File.new(fixture_path + '/' + file)
64
64
  end
65
+
66
+ def sample_collection(name)
67
+ e =Emojidex::Collection.new
68
+ e.load_local_collection(File.expand_path("../support/sample_collections/#{name}", __FILE__))
69
+ e
70
+ end
@@ -0,0 +1,30 @@
1
+ [
2
+ {
3
+ "moji": "πŸ‘„",
4
+ "code": "mouth",
5
+ "code_ja": "口",
6
+ "category": "people",
7
+ "unicode": "1f444"
8
+ },
9
+ {
10
+ "moji": "πŸ”©",
11
+ "code": "nut_and_bolt",
12
+ "code_ja": "γƒœγƒ«γƒˆοΌ†γƒŠγƒƒγƒˆ",
13
+ "category": "tools",
14
+ "unicode": "1f529"
15
+ },
16
+ {
17
+ "moji": "πŸ’œ",
18
+ "code": "purple_heart",
19
+ "code_ja": "γƒγƒΌγƒˆ(η΄«)",
20
+ "category": "abstract",
21
+ "unicode": "1f49c"
22
+ },
23
+ {
24
+ "moji": "πŸ‘―",
25
+ "code": "woman_with_bunny_ears",
26
+ "code_ja": "バニーガール",
27
+ "category": "people",
28
+ "unicode": "1f46f"
29
+ }
30
+ ]
@@ -0,0 +1,49 @@
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="レむダー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
5
+ y="0px" width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
6
+ <polygon fill="#661222" points="9.333,35.667 8.167,29.833 18.667,19.167 46,22.581 55.167,31.666 46.333,38 "/>
7
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="17.8975" y1="24.9985" x2="52.2147" y2="26.0599">
8
+ <stop offset="0" style="stop-color:#9C9C9C"/>
9
+ <stop offset="0.0142" style="stop-color:#A9A9A9"/>
10
+ <stop offset="0.0497" style="stop-color:#C4C4C4"/>
11
+ <stop offset="0.0905" style="stop-color:#DADADA"/>
12
+ <stop offset="0.1381" style="stop-color:#EBEBEB"/>
13
+ <stop offset="0.197" style="stop-color:#F6F6F6"/>
14
+ <stop offset="0.2797" style="stop-color:#FDFDFD"/>
15
+ <stop offset="0.5091" style="stop-color:#FFFFFF"/>
16
+ <stop offset="0.6532" style="stop-color:#FDFDFD"/>
17
+ <stop offset="0.7265" style="stop-color:#F5F5F5"/>
18
+ <stop offset="0.7838" style="stop-color:#E8E8E8"/>
19
+ <stop offset="0.8329" style="stop-color:#D5D5D5"/>
20
+ <stop offset="0.8766" style="stop-color:#BCBCBC"/>
21
+ <stop offset="0.9166" style="stop-color:#9E9E9E"/>
22
+ <stop offset="0.9537" style="stop-color:#7A7A7A"/>
23
+ <stop offset="0.9876" style="stop-color:#525252"/>
24
+ <stop offset="1" style="stop-color:#414141"/>
25
+ </linearGradient>
26
+ <path fill="url(#SVGID_1_)" d="M12.833,24.991c0,0,11.146,4.919,19.284,4.919s21.407-3.876,21.407-3.876l-10.438-4.55l-20.345-0.818
27
+ L12.833,24.991z"/>
28
+ <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="28.4619" y1="12.6665" x2="32.6284" y2="33.6665">
29
+ <stop offset="0" style="stop-color:#FF9FB0"/>
30
+ <stop offset="0.2186" style="stop-color:#FF7D94"/>
31
+ <stop offset="0.5773" style="stop-color:#FF4A6A"/>
32
+ <stop offset="0.849" style="stop-color:#FF2B51"/>
33
+ <stop offset="1" style="stop-color:#FF1F47"/>
34
+ </linearGradient>
35
+ <path fill="url(#SVGID_2_)" stroke="#BC001B" stroke-miterlimit="10" d="M3.426,29.167c1.833-4.219,8.689-12.639,16.023-16.472
36
+ s9.811,3.021,12.811,3.021c3,0,7.528-7.002,13.668-2.384c6.28,4.723,15.503,15.396,15.003,16.896s-3.035,5.341-8.701,2.007
37
+ s-7.124-7.073-10.946-6.852C38.5,25.544,38,27.667,32,27.667c-6.5,0-7.711-3.631-11.878-2.606S8.679,34.47,5.913,33.563
38
+ C3.881,32.897,2.297,31.763,3.426,29.167z"/>
39
+ <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="32.0557" y1="35.5488" x2="34.3892" y2="57.8818">
40
+ <stop offset="0" style="stop-color:#FF9FB0"/>
41
+ <stop offset="0.2186" style="stop-color:#FF7D94"/>
42
+ <stop offset="0.5773" style="stop-color:#FF4A6A"/>
43
+ <stop offset="0.849" style="stop-color:#FF2B51"/>
44
+ <stop offset="1" style="stop-color:#FF1F47"/>
45
+ </linearGradient>
46
+ <path fill="url(#SVGID_3_)" stroke="#BC001B" stroke-miterlimit="10" d="M5.885,32.888c10.333-3.5,16.333,1.668,27,1.334
47
+ s14.833-4.167,25.167-1.751c3.644,0.852,1.747,5.584-1.834,9.047c-2.797,2.705-14.5,7.87-23.333,7.87
48
+ c-8.833,0-22.333-5-25.833-8.666C4.679,38.236,2.14,34.156,5.885,32.888z"/>
49
+ </svg>