favicon_factory 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1105c6329d7279577f8d478e3be7e80984c3b374b38f66686b293299fa1dc5d8
4
- data.tar.gz: 58300ea64d615ccd2876493467916a47fa6150708e45bbe0e0183ac5b151997d
3
+ metadata.gz: fc00963b3c1d159bb936b8a4f0e146c32d68b1a0bcdc4fb40f5d700cbf38cf3d
4
+ data.tar.gz: 616e4bb03f11554299f8a0dc4f400988d701172f8701f45762cf0511913fe73c
5
5
  SHA512:
6
- metadata.gz: d673025100bef413b41b4026f60e1b435cd8b8f5343a5d928771a6aa33aa72b2b942b8333e92f9923ac2c90798352482b0b221a3dfc38054d74f8649336a4f2f
7
- data.tar.gz: 76ff8e945a1fe543bcb04ed2198fa3e2ebaedcc03511666b497f88a90b6972ec660f428c236904465238b53a2101d6e0965ee02bdca63c31389e23680d83743c
6
+ metadata.gz: 777f954b9cd891583b89ff389bde2aa942a1315c79ac0162634460f77266ec06a97ce47d7551409e5dcc3dead2d1e75ed264468414e4e22ee9f8895ba6b147cb
7
+ data.tar.gz: a15c26c10a9076d7b5010de545c0f813da1c5dc0cb0e933f7c3e03843a0e47c0c542de064b2689df3e447327ee4147f6ef4d375a6b785572d03ffc4c65ac4210
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty/which"
4
+
5
+ module FaviconFactory
6
+ class BaseAdapter
7
+ class << self
8
+ def find
9
+ if TTY::Which.which("vips") || TTY::Which.which("libvips")
10
+ VipsAdapter
11
+ elsif TTY::Which.which("magick") || TTY::Which.which("convert")
12
+ ImageMagickAdapter
13
+ end
14
+ end
15
+ end
16
+
17
+ def initialize(file:, params:, stderr:)
18
+ @file = file
19
+ @params = params
20
+ @stderr = stderr
21
+ end
22
+
23
+ def create_icons
24
+ create_by_name
25
+ .keys
26
+ .map { |name| Thread.new { create(name, params) } }
27
+ .each(&:join)
28
+
29
+ stderr.puts <<~TEXT
30
+ Info: Add the following to the `<head>`
31
+ <!-- favicons generated with the favicon_factory gem -->
32
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml">
33
+ <link rel="icon" href="/favicon.ico" sizes="32x32">
34
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
35
+ <link rel="manifest" href="/manifest.webmanifest">
36
+ TEXT
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :params, :stderr, :file
42
+
43
+ def create(name, params)
44
+ path = file.join(params.dir, name)
45
+ if file.exist?(path)
46
+ stderr.puts "Info: Skipping #{path} because it already exists"
47
+ return
48
+ end
49
+
50
+ stderr.puts "Info: Generating #{path}"
51
+ create_by_name.fetch(name).call(path, params)
52
+ end
53
+
54
+ def create_by_name
55
+ {
56
+ "favicon.ico" => method(:ico!),
57
+ "icon-192.png" => method(:png_192!),
58
+ "icon-512.png" => method(:png_512!),
59
+ "icon-mask.png" => method(:png_mask!),
60
+ "apple-touch-icon.png" => method(:touch!),
61
+ "manifest.webmanifest" => method(:manifest!)
62
+ }
63
+ end
64
+
65
+ def png_192!(path, params)
66
+ png!(path, params, 192)
67
+ end
68
+
69
+ def png_512!(path, params)
70
+ png!(path, params, 512)
71
+ end
72
+
73
+ def png_mask!(path, params)
74
+ mask!(path, params)
75
+ end
76
+
77
+ def manifest!(path, _params)
78
+ file.write(path, <<~MANIFEST.chomp)
79
+ {
80
+ "icons": [
81
+ {
82
+ "src": "/icon-192.png",
83
+ "type": "image/png",
84
+ "sizes": "192x192"
85
+ },
86
+ {
87
+ "src": "/icon-512.png",
88
+ "type": "image/png",
89
+ "sizes": "512x512"
90
+ },
91
+ {
92
+ "src": "/icon-mask.png",
93
+ "type": "image/png",
94
+ "sizes": "512x512",
95
+ "purpose": "maskable"
96
+ }
97
+ ]
98
+ }
99
+ MANIFEST
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaviconFactory
4
+ Params = Data.define(:favicon_svg, :background) do
5
+ def dir
6
+ File.dirname(favicon_svg)
7
+ end
8
+ end
9
+
10
+ class Cli
11
+ def self.call
12
+ exit new(argv: ARGV, file: File, stderr: $stderr).call
13
+ end
14
+
15
+ def initialize(argv:, file:, stderr:, find_adapter: -> { BaseAdapter.find })
16
+ @argv = argv
17
+ @file = file
18
+ @stderr = stderr
19
+ @find_adapter = find_adapter
20
+ end
21
+
22
+ def call
23
+ code, message = catch(:exit) do
24
+ adapter = try_find_adapter
25
+ params = try_parse(argv)
26
+ adapter.new(file: file, params: params, stderr: stderr).create_icons
27
+ [0, nil]
28
+ end
29
+
30
+ stderr.puts message unless message.nil?
31
+ code
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :stderr, :file, :find_adapter, :argv
37
+
38
+ def try_find_adapter
39
+ adapter = find_adapter.call
40
+ throw(:exit, [1, "Error: Neither vips or imagemagick found, install one"]) if adapter.nil?
41
+ adapter
42
+ end
43
+
44
+ def try_parse(argv)
45
+ command = Command.new.parse(argv)
46
+ params = command.params
47
+ throw(:exit, [0, command.help]) if params.fetch(:help) == true
48
+ throw(:exit, [1, params.errors.summary]) if params.errors.any?
49
+
50
+ favicon_svg = params.fetch(:favicon_svg)
51
+ throw(:exit, [1, "Error: #{favicon_svg} does not end with .svg"]) unless favicon_svg.end_with?(".svg")
52
+ throw(:exit, [1, "Error: #{favicon_svg} does not exist"]) unless file.exist?(favicon_svg)
53
+
54
+ background = params.fetch(:background)
55
+ throw(:exit, [1, "Error: #{background} is not a valid color, use a hex value like #0099ff"]) unless hex?(background)
56
+
57
+ Params.new(favicon_svg: favicon_svg, background: background)
58
+ end
59
+
60
+ def hex?(string)
61
+ string = string.delete_prefix("#")
62
+ string.chars.all? { |char| char.match?(/^[0-9a-fA-F]$/) }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty/option"
4
+
5
+ module FaviconFactory
6
+ class Command
7
+ include TTY::Option
8
+
9
+ usage do
10
+ program "favicon_factory"
11
+ no_command
12
+
13
+ desc <<~DESC
14
+ `favicon_factory` generates from an SVG the minimal set of icons needed by modern browsers.
15
+
16
+ The source SVG is ideal for [modern browsers](https://caniuse.com/link-icon-svg). And it may contain a `<style>` tag with `@media (prefers-color-scheme: dark)` to support light/dark themes, which is ignored when generating favicons.
17
+
18
+ Icons will be generated in the same folder as the source SVG unless already existing:
19
+
20
+ - `favicon.ico` (32x32) for legacy browsers; serve it from `/favicon.ico` because tools, like RSS readers, just look there.
21
+ - `apple-touch-icon.png` (180x180) for Apple devices when adding a webpage to the home screen; a background and a padding around the icon is applied to make it look pretty.
22
+ - `manifest.webmanifest` that includes `icon-192.png`, `icon-512.png`, and `icon-mask.png` for Android devices; the first for display on the home screen, the second for different Android launchers, and the last for the splash screen while the PWA is loading.
23
+ DESC
24
+
25
+ example "favicon_factory path/to/favicon.svg"
26
+ example "favicon_factory --background red path/to/favicon.svg"
27
+ example "favicon_factory --background #000000 path/to/favicon.svg"
28
+ end
29
+
30
+ argument :favicon_svg do
31
+ name "favicon_svg"
32
+ desc "Path to the favicon.svg"
33
+ end
34
+
35
+ option :background do
36
+ short "-b"
37
+ long "--background string"
38
+ default "#ffffff"
39
+ desc "Background hex color for apple-touch-icon.png"
40
+ end
41
+
42
+ flag :help do
43
+ short "-h"
44
+ long "--help"
45
+ desc "Print usage"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mini_magick"
4
+
5
+ module FaviconFactory
6
+ class ImageMagickAdapter < BaseAdapter
7
+ SVG_DENSITY = 1_000
8
+
9
+ def initialize(**)
10
+ super
11
+ stderr.puts "Warn: Install imagemagick v7 for best results, using v6" unless MiniMagick.imagemagick7?
12
+ end
13
+
14
+ def ico!(path, params)
15
+ MiniMagick.convert do |convert|
16
+ convert.density(SVG_DENSITY).background("none")
17
+ convert << params.favicon_svg
18
+ convert.resize("32x32")
19
+ convert << path
20
+ end
21
+ end
22
+
23
+ def png!(path, params, size)
24
+ MiniMagick.convert do |convert|
25
+ convert.density(SVG_DENSITY).background("none")
26
+ convert << params.favicon_svg
27
+ convert.resize("#{size}x#{size}")
28
+ convert << path
29
+ end
30
+ end
31
+
32
+ def touch!(path, params)
33
+ MiniMagick.convert do |convert|
34
+ convert.density(SVG_DENSITY).background(params.background)
35
+ convert << params.favicon_svg
36
+ convert.resize("160x160")
37
+ convert.gravity("center").extent("180x180")
38
+ convert << path
39
+ end
40
+ end
41
+
42
+ def mask!(path, params)
43
+ MiniMagick.convert do |convert|
44
+ convert.density(SVG_DENSITY).background(params.background)
45
+ convert << params.favicon_svg
46
+ convert.resize("409x409")
47
+ convert.gravity("center").extent("512x512")
48
+ convert << path
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FaviconFactory
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "vips"
4
+
5
+ module FaviconFactory
6
+ class VipsAdapter < BaseAdapter
7
+ def ico!(path, params)
8
+ png = Vips::Image.thumbnail(params.favicon_svg, 32).write_to_buffer(".png")
9
+ # https://www.meziantou.net/creating-ico-files-from-multiple-images-in-dotnet.htm
10
+ ico = [0, 1, 1].pack("S<*") + [32, 32, 0, 0].pack("C*") + [1, 32].pack("S<*") + [png.size, 22].pack("L<*") + png
11
+ file.write(path, ico)
12
+ end
13
+
14
+ def png!(path, params, size)
15
+ Vips::Image.thumbnail(params.favicon_svg, size).write_to_file(path)
16
+ end
17
+
18
+ def touch!(path, params)
19
+ svg = Vips::Image.thumbnail(params.favicon_svg, 160).gravity("centre", 180, 180)
20
+ image = square(180, params.background).composite(svg, :over)
21
+ image.write_to_file(path)
22
+ end
23
+
24
+ def mask!(path, params)
25
+ svg = Vips::Image.thumbnail(params.favicon_svg, 409).gravity("centre", 512, 512)
26
+ image = square(512, params.background).composite(svg, :over)
27
+ image.write_to_file(path)
28
+ end
29
+
30
+ private
31
+
32
+ def square(size, hex)
33
+ pixel = (Vips::Image.black(1, 1) + hex2rgb(hex)).cast(:uchar)
34
+ pixel.embed(0, 0, size, size, extend: :copy)
35
+ end
36
+
37
+ def hex2rgb(hex)
38
+ hex = hex.delete_prefix("#")
39
+ r = hex[0..1].to_i(16)
40
+ g = hex[2..3].to_i(16)
41
+ b = hex[4..5].to_i(16)
42
+ [r, g, b]
43
+ end
44
+ end
45
+ end
@@ -1,267 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "favicon_factory/version"
4
- require "tty/which"
5
- require "tty/option"
6
-
7
- autoload(:MiniMagick, "mini_magick")
8
- autoload(:Vips, "vips")
4
+ require_relative "favicon_factory/command"
5
+ require_relative "favicon_factory/cli"
6
+ require_relative "favicon_factory/base_adapter"
9
7
 
10
8
  module FaviconFactory
11
- Params = Data.define(:favicon_svg, :background) do
12
- def dir
13
- File.dirname(favicon_svg)
14
- end
15
- end
16
-
17
- class Command
18
- include TTY::Option
19
-
20
- usage do
21
- program "favicon_factory"
22
- no_command
23
-
24
- desc <<~DESC
25
- `favicon_factory` generates from an SVG the minimal set of icons needed by modern browsers.
26
-
27
- The source SVG is ideal for [modern browsers](https://caniuse.com/link-icon-svg). And it may contain a `<style>` tag with `@media (prefers-color-scheme: dark)` to support light/dark themes, which is ignored when generating favicons.
28
-
29
- Icons will be generated in the same folder as the source SVG unless already existing:
30
-
31
- - `favicon.ico` (32x32) for legacy browsers; serve it from `/favicon.ico` because tools, like RSS readers, just look there.
32
- - `apple-touch-icon.png` (180x180) for Apple devices when adding a webpage to the home screen; a background and a padding around the icon is applied to make it look pretty.
33
- - `manifest.webmanifest` that includes `icon-192.png` and `icon-512.png` for Android devices; the former for display on the home screen, and the latter for the splash screen while the PWA is loading.
34
- DESC
35
-
36
- example "favicon_factory path/to/favicon.svg"
37
- example "favicon_factory --background red path/to/favicon.svg"
38
- example "favicon_factory --background #000000 path/to/favicon.svg"
39
- end
40
-
41
- argument :favicon_svg do
42
- name "favicon_svg"
43
- desc "Path to the favicon.svg"
44
- end
45
-
46
- option :background do
47
- short "-b"
48
- long "--background string"
49
- default "#ffffff"
50
- desc "Background hex color for apple-touch-icon.png"
51
- end
52
-
53
- flag :help do
54
- short "-h"
55
- long "--help"
56
- desc "Print usage"
57
- end
58
- end
59
-
60
- class Cli
61
- def self.call
62
- adapter = BaseAdapter.find
63
- if adapter.nil?
64
- stderr.puts "Error: Neither vips or imagemagick found, install one"
65
- exit 1
66
- end
67
- exit new(adapter: adapter, argv: ARGV, file: File, stderr: $stderr).call
68
- end
69
-
70
- def initialize(adapter:, argv:, file:, stderr:)
71
- @adapter = adapter
72
- @argv = argv
73
- @file = file
74
- @stderr = stderr
75
- end
76
-
77
- def call
78
- params, status = parse(argv)
79
- return status if status >= 0
80
-
81
- adapter.new(file: file, params: params, stderr: stderr).create_icons
82
- 0
83
- end
84
-
85
- private
86
-
87
- attr_reader :stderr, :file, :adapter, :argv
88
-
89
- def parse(argv)
90
- command = Command.new.parse(argv)
91
- params = command.params
92
- return exit_message(0, command.help) if params.fetch(:help) == true
93
- return exit_message(1, params.errors.summary) if params.errors.any?
94
-
95
- params = params.to_h
96
- favicon_svg = params.fetch(:favicon_svg)
97
- return exit_message(1, "Error: #{favicon_svg} does not end with .svg") unless favicon_svg.end_with?(".svg")
98
- return exit_message(1, "Error: #{favicon_svg} does not exist") unless file.exist?(favicon_svg)
99
-
100
- background = params.fetch(:background)
101
- unless hex?(background)
102
- return exit_message(1, "Error: #{background} is not a valid color, use a hex value like #0099ff")
103
- end
104
-
105
- [Params.new(favicon_svg: favicon_svg, background: background), -1]
106
- end
107
-
108
- def hex?(string)
109
- string = string.delete_prefix("#")
110
- string.split("").all? { |char| char.match?(/^[0-9a-fA-F]$/) }
111
- end
112
-
113
- def exit_message(status, message)
114
- stderr.puts message
115
- [nil, status]
116
- end
117
- end
118
-
119
- class BaseAdapter
120
- class << self
121
- def find
122
- if TTY::Which.which("vips") || TTY::Which.which("libvips")
123
- VipsAdapter
124
- elsif TTY::Which.which("magick") || TTY::Which.which("convert")
125
- ImageMagickAdapter
126
- end
127
- end
128
- end
129
-
130
- def initialize(file:, params:, stderr:)
131
- @file = file
132
- @params = params
133
- @stderr = stderr
134
- end
135
-
136
- def create_icons
137
- create_by_name
138
- .keys
139
- .map { |name| Thread.new { create(name, params) } }
140
- .each(&:join)
141
-
142
- stderr.puts <<~TEXT
143
- Info: Add the following to the `<head>`
144
- <!-- favicons generated with the favicon_factory gem -->
145
- <link rel="icon" href="/favicon.svg" type="image/svg+xml">
146
- <link rel="icon" href="/favicon.ico" sizes="32x32">
147
- <link rel="apple-touch-icon" href="/apple-touch-icon.png">
148
- <link rel="manifest" href="/manifest.webmanifest">
149
- TEXT
150
- end
151
-
152
- private
153
-
154
- attr_reader :params, :stderr, :file
155
-
156
- def create(name, params)
157
- path = file.join(params.dir, name)
158
- if file.exist?(path)
159
- stderr.puts "Info: Skipping #{path} because it already exists"
160
- return
161
- end
162
-
163
- stderr.puts "Info: Generating #{path}"
164
- create_by_name.fetch(name).call(path, params)
165
- end
166
-
167
- def create_by_name
168
- {
169
- "favicon.ico" => method(:ico!),
170
- "icon-192.png" => method(:png_192!),
171
- "icon-512.png" => method(:png_512!),
172
- "apple-touch-icon.png" => method(:touch!),
173
- "manifest.webmanifest" => method(:manifest!)
174
- }
175
- end
176
-
177
- def png_192!(path, params)
178
- png!(path, params, 192)
179
- end
180
-
181
- def png_512!(path, params)
182
- png!(path, params, 512)
183
- end
184
-
185
- def manifest!(path, _params)
186
- file.write(path, <<~MANIFEST)
187
- {
188
- "icons": [
189
- { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
190
- { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
191
- ]
192
- }
193
- MANIFEST
194
- end
195
- end
196
-
197
- class VipsAdapter < BaseAdapter
198
- def ico!(path, params)
199
- png = Vips::Image.thumbnail(params.favicon_svg, 32).write_to_buffer(".png")
200
- # https://www.meziantou.net/creating-ico-files-from-multiple-images-in-dotnet.htm
201
- ico = [0, 1, 1].pack("S<*") + [32, 32, 0, 0].pack("C*") + [1, 32].pack("S<*") + [png.size, 22].pack("L<*") + png
202
- file.write(path, ico)
203
- end
204
-
205
- def png!(path, params, size)
206
- Vips::Image.thumbnail(params.favicon_svg, size).write_to_file(path)
207
- end
208
-
209
- def touch!(path, params)
210
- svg = Vips::Image.thumbnail(params.favicon_svg, 160).gravity("centre", 180, 180)
211
- image = square(180, params.background).composite(svg, :over)
212
- image.write_to_file(path)
213
- end
214
-
215
- private
216
-
217
- def square(size, hex)
218
- pixel = (Vips::Image.black(1, 1) + hex2rgb(hex)).cast(:uchar)
219
- pixel.embed 0, 0, size, size, extend: :copy
220
- end
221
-
222
- def hex2rgb(hex)
223
- hex = hex.delete_prefix("#")
224
- r = hex[0..1].to_i(16)
225
- g = hex[2..3].to_i(16)
226
- b = hex[4..5].to_i(16)
227
- [r, g, b]
228
- end
229
- end
230
-
231
- class ImageMagickAdapter < BaseAdapter
232
- SVG_DENSITY = 1_000
233
-
234
- def initialize(**)
235
- super
236
- stderr.puts "Warn: Install imagemagick v7 for best results, using v6" unless MiniMagick.imagemagick7?
237
- stderr.puts "Warn: Inkscape not found, install it for best results" unless TTY::Which.which("inkscape")
238
- end
239
-
240
- def ico!(path, params)
241
- MiniMagick::Tool::Convert.new do |convert|
242
- convert.density(SVG_DENSITY).background("none")
243
- convert << params.favicon_svg
244
- convert.resize("32x32")
245
- convert << path
246
- end
247
- end
248
-
249
- def png!(path, params, size)
250
- MiniMagick::Tool::Convert.new do |convert|
251
- convert.density(SVG_DENSITY).background("none")
252
- convert << params.favicon_svg
253
- convert.resize("#{size}x#{size}")
254
- convert << path
255
- end
256
- end
257
-
258
- def touch!(path, params)
259
- MiniMagick::Tool::Convert.new do |convert|
260
- convert.density(SVG_DENSITY).background(params.background)
261
- convert << params.favicon_svg
262
- convert.resize("160x160").gravity("center").extent("180x180")
263
- convert << path
264
- end
265
- end
266
- end
9
+ autoload(:ImageMagickAdapter, "favicon_factory/image_magick_adapter")
10
+ autoload(:VipsAdapter, "favicon_factory/vips_adapter")
267
11
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: favicon_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 3v0k4
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-06-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: mini_magick
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '4.12'
18
+ version: '5.2'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '4.12'
25
+ version: '5.2'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: ruby-vips
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -77,7 +76,12 @@ extra_rdoc_files: []
77
76
  files:
78
77
  - exe/favicon_factory
79
78
  - lib/favicon_factory.rb
79
+ - lib/favicon_factory/base_adapter.rb
80
+ - lib/favicon_factory/cli.rb
81
+ - lib/favicon_factory/command.rb
82
+ - lib/favicon_factory/image_magick_adapter.rb
80
83
  - lib/favicon_factory/version.rb
84
+ - lib/favicon_factory/vips_adapter.rb
81
85
  homepage: https://github.com/3v0k4/favicon_factory
82
86
  licenses:
83
87
  - MIT
@@ -86,7 +90,6 @@ metadata:
86
90
  source_code_uri: https://github.com/3v0k4/favicon_factory
87
91
  changelog_uri: https://github.com/3v0k4/favicon_factory/blob/main/CHANGELOG.md
88
92
  rubygems_mfa_required: 'true'
89
- post_install_message:
90
93
  rdoc_options: []
91
94
  require_paths:
92
95
  - lib
@@ -101,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
104
  - !ruby/object:Gem::Version
102
105
  version: '0'
103
106
  requirements: []
104
- rubygems_version: 3.4.10
105
- signing_key:
107
+ rubygems_version: 3.6.7
106
108
  specification_version: 4
107
109
  summary: Generate favicons from an SVG
108
110
  test_files: []