glimmer-libui-cc-graphs_and_charts 0.2.1 → 0.2.2

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: 263ed1c13a5130568949ac82714104e494a4e8ffd1ded95fec7d14110d5fc364
4
- data.tar.gz: 2eea70d52135a1381d2ae30c2fb03dac37f5a07c0f74ba94875ea8a5fb82b867
3
+ metadata.gz: 6b1c01b4d2bd5df0119a5da0969ea0f8697880f5e82b951df8fb11e7ff64cef5
4
+ data.tar.gz: 277fd2a3c47009ae872f84393c2f59700c099ea5da6ad472307c4d581fac8b2f
5
5
  SHA512:
6
- metadata.gz: 8cf72862f552c4d9de06163653465ea4cf4779f371080b8fb4a345fa1bce9315ad190e12c8cdffaf71ae546d43510804d1574e12a7080e30a35901e3e842d947
7
- data.tar.gz: cff63fd75943908ee9084e821c7a6a32d517c729796cbdc705f4928431f27540d904c0ea1080c9248a0542a43cbc660e652d07b0cb69e8e641153956d1354e47
6
+ metadata.gz: 3bc2bb802a8a058bf9ffb4fb65c5fa2afa9a3fc0578a0956c9ea4e1d2ab1ddc47fe1f2f89ba3afa2e16500c6f4c28a7154caa541d7961075c56c5d8976f4e06f
7
+ data.tar.gz: bc82a867fa5ee64776a724d46db62c7039c353cbfaaebabb9e822901faea7e3371fe8ca9c8b1324b96decd880c52e46637dc1c871a4a98175c33abe19ee977d3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.2
4
+
5
+ - Display `bar_chart` axis labels `x_axis_label` and `y_axis_label`
6
+ - Display `bar_chart` x-axis values below the chart
7
+ - Fix issue with `bar_chart` vertical scaling of grid markers when numbers are larger than 1000 and have `K` in them by disabling `K` formatting for now (the issue was seeing the same marker number twice because two consecutive markers were calculated with similar shortened values; e.g. both 10K when one is 10100 and the other is 10750).
8
+
3
9
  ## 0.2.1
4
10
 
5
11
  - Fix clipped text of grid markers when they include 1000 displayed as 1K
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2023 Andy Maleh
1
+ Copyright (c) 2023-2024 Andy Maleh
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Graphs and Charts 0.2.1 (Alpha)
1
+ # Graphs and Charts 0.2.2 (Alpha)
2
2
  ## [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui) Custom Controls
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-libui-cc-graphs_and_charts.svg)](http://badge.fury.io/rb/glimmer-libui-cc-graphs_and_charts)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -14,7 +14,7 @@ Graphs and Charts (Custom Controls) for [Glimmer DSL for LibUI](https://github.c
14
14
  Add this line to Bundler `Gemfile`:
15
15
 
16
16
  ```ruby
17
- gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.2.1'
17
+ gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.2.2'
18
18
  ```
19
19
 
20
20
  Run:
@@ -332,5 +332,5 @@ Copyright
332
332
 
333
333
  [MIT](LICENSE.txt)
334
334
 
335
- Copyright (c) 2023 Andy Maleh. See
335
+ Copyright (c) 2023-2024 Andy Maleh. See
336
336
  [LICENSE.txt](LICENSE.txt) for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.2.2
@@ -12,6 +12,8 @@ class BasicBarChart
12
12
  @bar_chart = bar_chart(
13
13
  width: 900,
14
14
  height: 300,
15
+ x_axis_label: 'Month',
16
+ y_axis_label: 'New Customer Accounts',
15
17
  values: {
16
18
  'Jan' => 30,
17
19
  'Feb' => 49,
@@ -25,7 +27,7 @@ class BasicBarChart
25
27
  'Oct' => 68,
26
28
  'Nov' => 52,
27
29
  'Dec' => 36,
28
- }
30
+ },
29
31
  )
30
32
 
31
33
  on_content_size_changed do
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: glimmer-libui-cc-graphs_and_charts 0.2.1 ruby lib
5
+ # stub: glimmer-libui-cc-graphs_and_charts 0.2.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-libui-cc-graphs_and_charts".freeze
9
- s.version = "0.2.1".freeze
9
+ s.version = "0.2.2".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2023-12-29"
14
+ s.date = "2024-01-01"
15
15
  s.description = "Graphs and Charts (Custom Controls) for Glimmer DSL for LibUI, like Line Graph.".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
 
40
40
  s.specification_version = 4
41
41
 
42
- s.add_runtime_dependency(%q<glimmer-dsl-libui>.freeze, ["~> 0.11".freeze])
42
+ s.add_runtime_dependency(%q<glimmer-dsl-libui>.freeze, [">= 0.11.8".freeze, "< 2.0.0".freeze])
43
43
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0".freeze])
44
44
  s.add_development_dependency(%q<juwelier>.freeze, ["= 2.4.9".freeze])
45
45
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
@@ -16,9 +16,19 @@ module Glimmer
16
16
 
17
17
  DEFAULT_CHART_PADDING_WIDTH = 5.0
18
18
  DEFAULT_CHART_PADDING_HEIGHT = 5.0
19
- DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH = 37.0
20
19
  DEFAULT_CHART_BAR_PADDING_WIDTH_PERCENTAGE = 30.0
21
20
 
21
+ # This is y-axis grid marker padding that is to the left of the bar chart
22
+ DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH = 37.0
23
+ # This is x-axis grid marker padding that is below the bar chart
24
+ DEFAULT_CHART_GRID_MARKER_PADDING_HEIGHT = 30.0
25
+
26
+ # This is y-axis label padding that is to the left of the bar chart
27
+ DEFAULT_CHART_Y_AXIS_LABEL_PADDING_WIDTH = 25.0
28
+
29
+ # This is x-axis label padding that is below the bar chart
30
+ DEFAULT_CHART_X_AXIS_LABEL_PADDING_HEIGHT = 25.0
31
+
22
32
  DEFAULT_CHART_STROKE_GRID = [185, 184, 185]
23
33
  DEFAULT_CHART_STROKE_MARKER = [185, 184, 185]
24
34
  DEFAULT_CHART_STROKE_MARKER_LINE = [217, 217, 217, thickness: 1, dashes: [1, 1]]
@@ -33,9 +43,20 @@ module Glimmer
33
43
 
34
44
  option :chart_padding_width, default: DEFAULT_CHART_PADDING_WIDTH
35
45
  option :chart_padding_height, default: DEFAULT_CHART_PADDING_HEIGHT
36
- option :chart_grid_marker_padding_width, default: DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH
37
46
  option :chart_bar_padding_width_percentage, default: DEFAULT_CHART_BAR_PADDING_WIDTH_PERCENTAGE
38
47
 
48
+ # This is y-axis grid marker padding that is to the left of the bar chart
49
+ option :chart_grid_marker_padding_width, default: DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH
50
+
51
+ # This is x-axis grid marker padding that is below the bar chart
52
+ option :chart_grid_marker_padding_height, default: DEFAULT_CHART_GRID_MARKER_PADDING_HEIGHT
53
+
54
+ # This is y-axis label padding that is to the left of the bar chart
55
+ option :chart_y_axis_label_padding_width, default: DEFAULT_CHART_Y_AXIS_LABEL_PADDING_WIDTH
56
+
57
+ # This is x-axis label padding that is below the bar chart
58
+ option :chart_x_axis_label_padding_height, default: DEFAULT_CHART_X_AXIS_LABEL_PADDING_HEIGHT
59
+
39
60
  option :chart_stroke_grid, default: DEFAULT_CHART_STROKE_GRID
40
61
  option :chart_stroke_marker, default: DEFAULT_CHART_STROKE_MARKER
41
62
  option :chart_stroke_marker_line, default: DEFAULT_CHART_STROKE_MARKER_LINE
@@ -57,9 +78,16 @@ module Glimmer
57
78
  # '7' => 03,
58
79
  # }
59
80
  option :values, default: {}
81
+ option :x_axis_label, default: nil
82
+ option :y_axis_label, default: nil
60
83
 
61
84
  attr_reader :bar_width_including_padding
62
85
 
86
+ before_body do
87
+ self.chart_y_axis_label_padding_width = 0 if y_axis_label.to_s.empty?
88
+ self.chart_x_axis_label_padding_height = 0 if x_axis_label.to_s.empty?
89
+ end
90
+
63
91
  after_body do
64
92
  observe(self, :values) do
65
93
  clear_drawing_cache
@@ -89,11 +117,12 @@ module Glimmer
89
117
  def clear_drawing_cache
90
118
  @y_resolution = nil
91
119
  @bar_width_including_padding = nil
92
- @grid_marker_points = nil
120
+ @y_axis_grid_marker_points = nil
93
121
  @grid_marker_number_values = nil
94
122
  @grid_marker_numbers = nil
95
123
  @chart_stroke_marker_values = nil
96
124
  @mod_values = nil
125
+ @y_value_max = nil
97
126
  end
98
127
 
99
128
  def calculate_dynamic_options
@@ -118,11 +147,11 @@ module Glimmer
118
147
  end
119
148
 
120
149
  def width_drawable
121
- width - 2.0*chart_padding_width - chart_grid_marker_padding_width
150
+ width - 2.0*chart_padding_width - chart_grid_marker_padding_width - chart_y_axis_label_padding_width
122
151
  end
123
152
 
124
153
  def height_drawable
125
- height - 2.0*chart_padding_height
154
+ height - 2.0*chart_padding_height - chart_grid_marker_padding_height - chart_x_axis_label_padding_height
126
155
  end
127
156
 
128
157
  def chart_background
@@ -130,34 +159,48 @@ module Glimmer
130
159
  fill 255, 255, 255
131
160
  }
132
161
  end
133
-
162
+
134
163
  def grid_lines
135
- line(chart_padding_width, chart_padding_height, chart_padding_width, height - chart_padding_height) {
164
+ x_axis_grid_lines
165
+ y_axis_grid_lines
166
+ x_axis_label_text
167
+ y_axis_label_text
168
+ end
169
+
170
+ def x_axis_grid_lines
171
+ line_y = height - chart_padding_height - chart_grid_marker_padding_height - chart_x_axis_label_padding_height
172
+ line(chart_x_axis_label_padding_height + chart_padding_width, line_y, width - chart_padding_width, line_y) {
136
173
  stroke chart_stroke_grid
137
174
  }
138
- line(chart_padding_width, height - chart_padding_height, width - chart_padding_width, height - chart_padding_height) {
175
+ end
176
+
177
+ def y_axis_grid_lines
178
+ line_x = chart_y_axis_label_padding_width + chart_padding_width
179
+ line(line_x, chart_padding_height, line_x, height - chart_padding_height - chart_grid_marker_padding_height - chart_x_axis_label_padding_height) {
139
180
  stroke chart_stroke_grid
140
181
  }
141
- grid_marker_number_font = chart_font_marker_text.merge(size: 11)
182
+ grid_marker_number_font = marker_font
142
183
  @grid_marker_number_values ||= []
143
- @grid_marker_numbers ||= []
184
+ # @grid_marker_numbers ||= []
144
185
  @chart_stroke_marker_values ||= []
145
186
  @mod_values ||= []
146
- grid_marker_points.each_with_index do |marker_point, index|
187
+ y_axis_grid_marker_points.each_with_index do |marker_point, index|
147
188
  @grid_marker_number_values[index] ||= begin
148
- value = (grid_marker_points.size - index).to_i
189
+ value = (y_axis_grid_marker_points.size - index).to_i
149
190
  value = y_value_max if !y_value_max.nil? && y_value_max.to_i != y_value_max && index == 0
150
191
  value
151
192
  end
152
193
  grid_marker_number_value = @grid_marker_number_values[index]
153
- @grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
154
- grid_marker_number = @grid_marker_numbers[index]
194
+ # figuring out how to setup 1K numbers without repeating a number twice is more complicated than just enabling this code
195
+ # disabling for now
196
+ # @grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
197
+ grid_marker_number = grid_marker_number_value.to_s
155
198
  @chart_stroke_marker_values[index] ||= BarChart.interpret_color(chart_stroke_marker).tap do |color_hash|
156
- color_hash[:thickness] = (index != grid_marker_points.size - 1 ? 2 : 1) if color_hash[:thickness].nil?
199
+ color_hash[:thickness] = (index != y_axis_grid_marker_points.size - 1 ? 2 : 1) if color_hash[:thickness].nil?
157
200
  end
158
201
  chart_stroke_marker_value = @chart_stroke_marker_values[index]
159
202
  @mod_values[index] ||= begin
160
- mod_value_multiplier = ((grid_marker_points.size / max_marker_count) + 1)
203
+ mod_value_multiplier = ((y_axis_grid_marker_points.size / max_marker_count) + 1)
161
204
  [(5 * mod_value_multiplier), 1].max
162
205
  end
163
206
  mod_value = @mod_values[index]
@@ -173,7 +216,7 @@ module Glimmer
173
216
  stroke chart_stroke_marker_value
174
217
  }
175
218
  end
176
- if grid_marker_number_value % mod_value == comparison_value && grid_marker_number_value != grid_marker_points.size
219
+ if grid_marker_number_value % mod_value == comparison_value && grid_marker_number_value != y_axis_grid_marker_points.size
177
220
  line(marker_point[:x], marker_point[:y], marker_point[:x] + width - chart_padding_width, marker_point[:y]) {
178
221
  stroke chart_stroke_marker_line
179
222
  }
@@ -190,40 +233,90 @@ module Glimmer
190
233
  end
191
234
  end
192
235
 
193
- def grid_marker_points
194
- if @grid_marker_points.nil?
236
+ def y_axis_grid_marker_points
237
+ if @y_axis_grid_marker_points.nil?
195
238
  if values.any?
196
239
  chart_y_max = [y_value_max, 1].max
197
- current_chart_height = (height - chart_padding_height * 2)
240
+ current_chart_height = (height - chart_padding_height * 2 - chart_grid_marker_padding_height - chart_x_axis_label_padding_height)
198
241
  y_value_count = chart_y_max.ceil
199
- @grid_marker_points = chart_y_max.to_i.times.map do |marker_index|
200
- x = chart_padding_width
242
+ @y_axis_grid_marker_points = chart_y_max.to_i.times.map do |marker_index|
243
+ x = chart_y_axis_label_padding_width + chart_padding_width
201
244
  y_value = y_value_count - marker_index
202
245
  scaled_y_value = y_value.to_f * y_resolution.to_f
203
- y = height - chart_padding_height - scaled_y_value
246
+ y = height - chart_padding_height - chart_grid_marker_padding_height - chart_x_axis_label_padding_height - scaled_y_value
204
247
  {x: x, y: y}
205
248
  end
206
249
  end
207
250
  end
208
251
 
209
- @grid_marker_points
252
+ @y_axis_grid_marker_points
253
+ end
254
+
255
+ def x_axis_label_text
256
+ x_axis_label_font = marker_font
257
+ x_axis_label_width = estimate_width_of_text(x_axis_label, x_axis_label_font)
258
+ middle_of_x_axis_label_padding_x = chart_y_axis_label_padding_width + (width - chart_y_axis_label_padding_width)/2.0
259
+ x_axis_label_x = middle_of_x_axis_label_padding_x - x_axis_label_width/2.0
260
+ middle_of_x_axis_label_padding_y = height - (chart_x_axis_label_padding_height/2.0)
261
+ x_axis_label_y = middle_of_x_axis_label_padding_y - x_axis_label_font[:size]/2.0 - 7.0
262
+ text(x_axis_label_x, x_axis_label_y, x_axis_label_width) {
263
+ string(x_axis_label) {
264
+ font x_axis_label_font
265
+ color chart_color_marker_text
266
+ }
267
+ }
210
268
  end
211
269
 
270
+ def y_axis_label_text
271
+ y_axis_label_font = marker_font
272
+ y_axis_label_width = estimate_width_of_text(y_axis_label, y_axis_label_font)
273
+ middle_of_y_axis_label_padding_x = chart_y_axis_label_padding_width/2.0
274
+ y_axis_label_x = middle_of_y_axis_label_padding_x - y_axis_label_width/2.0
275
+ middle_of_y_axis_label_padding_y = (height - chart_x_axis_label_padding_height)/2.0
276
+ y_axis_label_y = middle_of_y_axis_label_padding_y - y_axis_label_font[:size]/2.0
277
+ text(y_axis_label_x, y_axis_label_y, y_axis_label_width) {
278
+ string(y_axis_label) {
279
+ font y_axis_label_font
280
+ color chart_color_marker_text
281
+ }
282
+ transform {
283
+ rotate(middle_of_y_axis_label_padding_x, middle_of_y_axis_label_padding_y, -90)
284
+ }
285
+ }
286
+ end
212
287
  def max_marker_count
213
288
  [(0.15*height).to_i, 1].max
214
289
  end
215
290
 
216
291
  def bars
217
292
  values.each_with_index do |(x_value, y_value), index|
218
- x = chart_grid_marker_padding_width + chart_padding_width + (index * bar_width_including_padding) + bar_padding_width
293
+ x = chart_y_axis_label_padding_width + chart_grid_marker_padding_width + chart_padding_width + (index * bar_width_including_padding) + bar_padding_width
219
294
  bar_height = y_value * y_resolution
220
- y = height - chart_padding_height - bar_height
295
+ y = height - chart_grid_marker_padding_height - chart_x_axis_label_padding_height - chart_padding_height - bar_height
221
296
  rectangle(x, y, bar_width, bar_height) {
222
297
  fill chart_color_bar
223
298
  }
299
+
300
+ x_axis_grid_marker_text = x_value.to_s
301
+ grid_marker_number_font = marker_font
302
+ x_axis_grid_marker_text_size = estimate_width_of_text(x_axis_grid_marker_text, grid_marker_number_font)
303
+ middle_of_bar_x = x + bar_width/2.0
304
+ x_axis_grid_marker_x = middle_of_bar_x - x_axis_grid_marker_text_size/2.0
305
+ middle_of_x_axis_grid_marker_padding = height - chart_grid_marker_padding_height/2.0 - chart_x_axis_label_padding_height
306
+ x_axis_grid_marker_y = middle_of_x_axis_grid_marker_padding - chart_font_marker_text[:size]/2.0 - 7.0
307
+ text(x_axis_grid_marker_x, x_axis_grid_marker_y, x_axis_grid_marker_text_size) {
308
+ string(x_axis_grid_marker_text) {
309
+ font grid_marker_number_font
310
+ color chart_color_marker_text
311
+ }
312
+ }
224
313
  end
225
314
  end
226
315
 
316
+ def marker_font
317
+ chart_font_marker_text.merge(size: 11)
318
+ end
319
+
227
320
  # this is the multiplier that we must multiply by the relative y value
228
321
  def y_resolution
229
322
  # TODO in the future, we will use the y range, but today, we assume it starts at 0
@@ -238,9 +331,10 @@ module Glimmer
238
331
  end
239
332
 
240
333
  def estimate_width_of_text(text_string, font_properties)
334
+ return 0 if text_string.to_s.empty?
241
335
  # TODO refactor move this method to somewhere common like Glimmer module
242
336
  font_size = font_properties[:size] || 16
243
- estimated_font_width = 0.62 * font_size
337
+ estimated_font_width = 0.63 * font_size
244
338
  text_string.chars.size * estimated_font_width
245
339
  end
246
340
 
@@ -195,6 +195,7 @@ module Glimmer
195
195
  value
196
196
  end
197
197
  grid_marker_number_value = @grid_marker_number_values[index]
198
+ # TODO consider not caching the following line as that might save memory and run faster without caching
198
199
  @grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
199
200
  grid_marker_number = @grid_marker_numbers[index]
200
201
  @graph_stroke_marker_values[index] ||= LineGraph.interpret_color(graph_stroke_marker).tap do |color_hash|
@@ -552,8 +553,9 @@ module Glimmer
552
553
  end
553
554
 
554
555
  def estimate_width_of_text(text_string, font_properties)
556
+ return 0 if text_string.to_s.empty?
555
557
  font_size = font_properties[:size] || 16
556
- estimated_font_width = 0.62 * font_size
558
+ estimated_font_width = 0.63 * font_size
557
559
  text_string.chars.size * estimated_font_width
558
560
  end
559
561
 
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-libui-cc-graphs_and_charts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-29 00:00:00.000000000 Z
11
+ date: 2024-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer-dsl-libui
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.8
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '0.11'
22
+ version: 2.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.11.8
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '0.11'
32
+ version: 2.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rspec
29
35
  requirement: !ruby/object:Gem::Requirement