emojidex 0.0.10 β†’ 0.0.11

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 (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>