old_sql 1.13.0 → 1.14.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.
- data/README.rdoc +36 -7
- data/app/controllers/old_sql/report_controller.rb +42 -0
- data/app/views/old_sql/report/chart.html.erb +26 -0
- data/app/views/old_sql/report/index.html.erb +4 -2
- data/config/routes.rb +1 -0
- data/lib/generators/old_sql/install_generator.rb +1 -0
- data/lib/generators/old_sql/templates/reports.yml.example +29 -5
- data/lib/generators/old_sql/templates/user_old_sql_demo_chart_design.yml +8 -0
- data/lib/old_sql/report_design/chart.rb +24 -0
- data/lib/old_sql/report_design/chart_data.rb +29 -0
- data/lib/old_sql/report_design/chart_item.rb +23 -0
- data/lib/old_sql/report_design/chart_parser.rb +32 -0
- data/lib/old_sql/report_processor/base.rb +41 -2
- data/public/javascripts/old_sql/old_sql.js +14 -0
- metadata +9 -3
data/README.rdoc
CHANGED
@@ -10,7 +10,7 @@ Some features of Old SQL are:
|
|
10
10
|
- The design documents, which are nothing more than csv files, can also serve as documentation, and describe the layout of the report in an intuitive way.
|
11
11
|
- If you want more fine grained control and report processor can parse the SQL.
|
12
12
|
- This also makes it simple to convert legacy reports into Old SQL reports.
|
13
|
-
* Multiple report views (jqGrid, HTML table) that can be configured using the old_sql initializer.
|
13
|
+
* Multiple report views (jqGrid, HTML table, and chart) that can be configured using the old_sql initializer.
|
14
14
|
* Old SQL uses Devise for authentication, and will install it for you. It can
|
15
15
|
even add Devise support to an existing model (by default users).
|
16
16
|
* In the report design all data is rounded to a precision that can be set in the old_sql initializer. This feature can also be disabled in the initializer.
|
@@ -67,14 +67,35 @@ Configure your reports config/old_sql/report.yml. An example configuration is cr
|
|
67
67
|
# 'report_design' is also optional, and should point to a file in config/old_sql/report_design.
|
68
68
|
# See config/old_sql/report_design/user_old_sql_demo.csv for an example.
|
69
69
|
#
|
70
|
+
# 'report_view' is optional. It overrides the default_report_view defined in the initializer. It
|
71
|
+
# can be set to jqgrid, table, or chart.
|
72
|
+
#
|
70
73
|
# The 'fields' are the headers for the report.
|
71
74
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
user_jqgrid:
|
76
|
+
description: User jqGrid
|
77
|
+
report_sql: user_old_sql_demo
|
78
|
+
report_design: user_old_sql_demo.csv
|
79
|
+
report_view: jqgrid
|
80
|
+
fields:
|
81
|
+
- 'id'
|
82
|
+
- 'name'
|
83
|
+
|
84
|
+
user_table:
|
85
|
+
description: User HTML Table
|
86
|
+
report_sql: user_old_sql_demo
|
87
|
+
report_processor: User_Old_Sql_Demo_Processor
|
88
|
+
report_view: table
|
89
|
+
fields:
|
90
|
+
- 'id'
|
91
|
+
- 'name'
|
92
|
+
|
93
|
+
user_chart:
|
94
|
+
description: User Chart
|
95
|
+
report_sql: user_old_sql_demo
|
96
|
+
report_design: user_old_sql_demo.yml
|
97
|
+
report_view: chart
|
98
|
+
fields:
|
78
99
|
- 'id'
|
79
100
|
- 'name'
|
80
101
|
|
@@ -144,6 +165,14 @@ All css and html template files can be copied to your installation by executing:
|
|
144
165
|
|
145
166
|
Settings for Old SQL can be configured in config/initializers/old_sql.rb.
|
146
167
|
|
168
|
+
== Rake Examples
|
169
|
+
|
170
|
+
rake old_sql:print:range[user_table,'development','2011-03-01','2011-09-01']
|
171
|
+
|
172
|
+
rake old_sql:print:today[user_table,'development']
|
173
|
+
|
174
|
+
rake old_sql:print:week[user_table,'development']
|
175
|
+
|
147
176
|
== Contributing to old_sql
|
148
177
|
|
149
178
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
@@ -10,6 +10,9 @@ module OldSql
|
|
10
10
|
helper_method :jqgrid_col_model
|
11
11
|
helper_method :jqgrid_col_names
|
12
12
|
helper_method :strip_html
|
13
|
+
helper_method :chart_type
|
14
|
+
helper_method :chart_fields
|
15
|
+
helper_method :chart_data
|
13
16
|
|
14
17
|
layout "old_sql/report.html.erb"
|
15
18
|
|
@@ -50,6 +53,23 @@ module OldSql
|
|
50
53
|
render :template => "old_sql/report/table.html.erb"
|
51
54
|
end
|
52
55
|
|
56
|
+
def chart
|
57
|
+
@start_date = params[:start_date]
|
58
|
+
@end_date = params[:end_date]
|
59
|
+
@report_name = params[:report]
|
60
|
+
@report_sql = params[:report_sql].downcase
|
61
|
+
@report_sql_orig = params[:report_sql].downcase
|
62
|
+
|
63
|
+
@width = OldSql.report_width
|
64
|
+
@height = OldSql.report_height
|
65
|
+
|
66
|
+
processor = load_base_processor
|
67
|
+
@report = processor.execute_query(@report_sql,@start_date,@end_date,query_vars(@report_name),@reports[@report_name]['report_design'],
|
68
|
+
@reports[@report_name]['report_processor'])
|
69
|
+
|
70
|
+
render :template => "old_sql/report/chart.html.erb"
|
71
|
+
end
|
72
|
+
|
53
73
|
def query
|
54
74
|
@start_date = params[:start_date]
|
55
75
|
@end_date = params[:end_date]
|
@@ -173,6 +193,28 @@ module OldSql
|
|
173
193
|
def strip_html html
|
174
194
|
OldSql.strip_html html
|
175
195
|
end
|
196
|
+
|
197
|
+
def chart_fields
|
198
|
+
fields =[]
|
199
|
+
|
200
|
+
i=0
|
201
|
+
@reports[@report_name]['fields'].each do |field|
|
202
|
+
fields << {v:i, label:field}
|
203
|
+
i+=1
|
204
|
+
end
|
205
|
+
|
206
|
+
json = fields.to_json
|
207
|
+
json.html_safe
|
208
|
+
end
|
209
|
+
|
210
|
+
def chart_data
|
211
|
+
json = @report.values.first.to_json
|
212
|
+
json.html_safe
|
213
|
+
end
|
214
|
+
|
215
|
+
def chart_type
|
216
|
+
@report.keys.first
|
217
|
+
end
|
176
218
|
end
|
177
219
|
end
|
178
220
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= javascript_include_tag "old_sql/MochiKit-1.4.2/lib/MochiKit/MochiKit.js" %>
|
2
|
+
<%= javascript_include_tag "old_sql/plotkit-0.9.1/PlotKit/Base.js" %>
|
3
|
+
<%= javascript_include_tag "old_sql/plotkit-0.9.1/PlotKit/Layout.js" %>
|
4
|
+
<%= javascript_include_tag "old_sql/plotkit-0.9.1/PlotKit/Canvas.js" %>
|
5
|
+
<%= javascript_include_tag "old_sql/plotkit-0.9.1/PlotKit/SweetCanvas.js" %>
|
6
|
+
|
7
|
+
<script>
|
8
|
+
var options = {
|
9
|
+
"IECanvasHTC": "/plotkit/iecanvas.htc",
|
10
|
+
"colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),
|
11
|
+
"xTicks": <%=chart_fields%>,
|
12
|
+
"drawYAxis": true
|
13
|
+
};
|
14
|
+
|
15
|
+
function drawGraph() {
|
16
|
+
var layout = new PlotKit.Layout("<%=chart_type%>", options);
|
17
|
+
layout.addDataset("sqrt", <%=chart_data%>);
|
18
|
+
layout.evaluate();
|
19
|
+
var canvas = MochiKit.DOM.getElement("graph");
|
20
|
+
var plotter = new PlotKit.SweetCanvasRenderer(canvas, layout, options);
|
21
|
+
plotter.render();
|
22
|
+
}
|
23
|
+
MochiKit.DOM.addLoadEvent(drawGraph);
|
24
|
+
</script>
|
25
|
+
|
26
|
+
<div><canvas id="graph" height="555" width="555"></canvas></div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<script>
|
2
2
|
var host = "<%=@host%>";
|
3
3
|
var port = "<%=@port%>";
|
4
|
-
var
|
4
|
+
var default_report_view = "<%=@report_view%>";
|
5
5
|
</script>
|
6
6
|
|
7
7
|
<div class="os-block">
|
@@ -17,7 +17,9 @@ var report_view = "<%=@report_view%>";
|
|
17
17
|
onchange="report_selected()">
|
18
18
|
<option></option>
|
19
19
|
<% @reports.each do |report, data| %>
|
20
|
-
<option value="<%= data['name'] %>" report_sql="<%= data['report_sql'] %>"
|
20
|
+
<option value="<%= data['name'] %>" report_sql="<%= data['report_sql'] %>"
|
21
|
+
desc="<%= data['description'] %>" name="<%=report%>"
|
22
|
+
report_view="<%=data['report_view']%>"><%= data['description'] %></option>
|
21
23
|
<% end %>
|
22
24
|
</select>
|
23
25
|
</div>
|
data/config/routes.rb
CHANGED
@@ -6,6 +6,7 @@ Rails.application.routes.draw do
|
|
6
6
|
match "/query", :to => :query, :as => "query"
|
7
7
|
match "/jqgrid", :to => :jqgrid, :as => "jqgrid"
|
8
8
|
match "/table", :to => :table, :as => "table"
|
9
|
+
match "/chart", :to => :chart, :as => "chart"
|
9
10
|
match "/print", :to => :print, :as => "print"
|
10
11
|
end
|
11
12
|
end
|
@@ -59,6 +59,7 @@ module OldSql
|
|
59
59
|
copy_file "user.erb.example", "#{app_path}/config/old_sql/report_sql/user_old_sql_demo.erb"
|
60
60
|
copy_file "user_processor.rb.example", "#{app_path}/lib/old_sql/report_processor/user_old_sql_demo_processor.rb"
|
61
61
|
copy_file "user_design_template.csv", "#{app_path}/config/old_sql/report_design/user_old_sql_demo.csv"
|
62
|
+
copy_file "user_old_sql_demo_chart_design.yml", "#{app_path}/config/old_sql/report_design/user_old_sql_demo.yml"
|
62
63
|
end
|
63
64
|
|
64
65
|
def configure_initializer
|
@@ -15,13 +15,37 @@
|
|
15
15
|
# 'report_design' is also optional, and should point to a file in config/old_sql/report_design.
|
16
16
|
# See config/old_sql/report_design/user_old_sql_demo.csv for an example.
|
17
17
|
#
|
18
|
+
# 'report_view' is optional. It overrides the default_report_view defined in the initializer. It
|
19
|
+
# can be set to jqgrid, table, or chart.
|
20
|
+
#
|
18
21
|
# The 'fields' are the headers for the report.
|
19
22
|
|
20
|
-
|
21
|
-
description: User
|
23
|
+
user_jqgrid:
|
24
|
+
description: User jqGrid
|
25
|
+
report_sql: user_old_sql_demo
|
26
|
+
report_design: user_old_sql_demo.csv
|
27
|
+
report_view: jqgrid
|
28
|
+
fields:
|
29
|
+
- 'id'
|
30
|
+
- 'name'
|
31
|
+
|
32
|
+
user_table:
|
33
|
+
description: User HTML Table
|
22
34
|
report_sql: user_old_sql_demo
|
23
|
-
|
24
|
-
|
35
|
+
report_processor: User_Old_Sql_Demo_Processor
|
36
|
+
report_view: table
|
25
37
|
fields:
|
26
38
|
- 'id'
|
27
|
-
- 'name'
|
39
|
+
- 'name'
|
40
|
+
|
41
|
+
user_chart:
|
42
|
+
description: User Chart
|
43
|
+
report_sql: user_old_sql_demo
|
44
|
+
report_design: user_old_sql_demo.yml
|
45
|
+
report_view: chart
|
46
|
+
fields:
|
47
|
+
- 'zero'
|
48
|
+
- 'one'
|
49
|
+
- 'two'
|
50
|
+
- 'three'
|
51
|
+
- 'four'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module OldSql
|
2
|
+
module ReportDesign
|
3
|
+
class Chart
|
4
|
+
attr_accessor :type, :items
|
5
|
+
|
6
|
+
def initialize(value = [])
|
7
|
+
@items = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def type new_type = nil
|
11
|
+
@type = new_type unless new_type.nil?
|
12
|
+
@type
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(key, value)
|
16
|
+
@items << ChartItem.new(key, value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def item(index)
|
20
|
+
@items[index]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module OldSql
|
2
|
+
module ReportDesign
|
3
|
+
class ChartData
|
4
|
+
attr_accessor :value, :type
|
5
|
+
|
6
|
+
COLUMN = 1
|
7
|
+
OPERATOR = 3
|
8
|
+
NUMERIC_LITERAL = 4
|
9
|
+
|
10
|
+
def initialize(value)
|
11
|
+
@value = value
|
12
|
+
set_type
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def set_type
|
18
|
+
@type = case @value[0]
|
19
|
+
when /[\/*+-\Q()]/
|
20
|
+
OPERATOR
|
21
|
+
when /[0-9]/
|
22
|
+
NUMERIC_LITERAL
|
23
|
+
else
|
24
|
+
COLUMN
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OldSql
|
2
|
+
module ReportDesign
|
3
|
+
class ChartItem
|
4
|
+
attr_accessor :chart_data, :key
|
5
|
+
|
6
|
+
def initialize(key, value)
|
7
|
+
@key = key
|
8
|
+
@value = value
|
9
|
+
@chart_data = []
|
10
|
+
|
11
|
+
@value.split(" ").each {|chart_data| @chart_data << ChartData.new(chart_data)}
|
12
|
+
end
|
13
|
+
|
14
|
+
def expression?
|
15
|
+
if @chart_data.count>1
|
16
|
+
return true
|
17
|
+
else
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module OldSql
|
2
|
+
module ReportDesign
|
3
|
+
class ChartParser
|
4
|
+
def self.read_file file_to_read
|
5
|
+
raise ArgumentError, 'Argument file is null.' unless !file_to_read.nil?
|
6
|
+
full_path = "#{report_design_path}/#{file_to_read}"
|
7
|
+
raise ArgumentError, "File #{full_path} not found." unless File.exists?(full_path)
|
8
|
+
|
9
|
+
@chart = Chart.new
|
10
|
+
|
11
|
+
template = File.read("#{report_design_path}/#{file_to_read}")
|
12
|
+
design_template = YAML.load(Erubis::Eruby.new(template).result)
|
13
|
+
|
14
|
+
design_template.each do |type, i|
|
15
|
+
@chart.type = type
|
16
|
+
i.each do |key, value|
|
17
|
+
@chart.add(key, value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@chart
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.report_design_path
|
25
|
+
app_path = Rails.public_path.split("/")
|
26
|
+
app_path.delete_at(-1)
|
27
|
+
app_path = app_path.join("/")
|
28
|
+
app_path << "/config/old_sql/report_design"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -4,6 +4,11 @@ require 'old_sql/report_design/row'
|
|
4
4
|
require 'old_sql/report_design/cell'
|
5
5
|
require 'old_sql/report_design/cell_data'
|
6
6
|
|
7
|
+
require 'old_sql/report_design/chart_parser'
|
8
|
+
require 'old_sql/report_design/chart'
|
9
|
+
require 'old_sql/report_design/chart_item'
|
10
|
+
require 'old_sql/report_design/chart_data'
|
11
|
+
|
7
12
|
module OldSql
|
8
13
|
module ReportProcessor
|
9
14
|
class Base
|
@@ -35,7 +40,8 @@ module OldSql
|
|
35
40
|
end
|
36
41
|
|
37
42
|
if design
|
38
|
-
parse_design(design, @resultset)
|
43
|
+
parse_design(design, @resultset) if design =~ /csv/
|
44
|
+
parse_chart_design(design, @resultset) if design =~ /yml/
|
39
45
|
else
|
40
46
|
loaded_sub_processor = load_sub_processor(sub_processor)
|
41
47
|
|
@@ -73,7 +79,7 @@ module OldSql
|
|
73
79
|
|
74
80
|
return nil if @rec.nil?
|
75
81
|
|
76
|
-
model = OldSql::ReportDesign::Parser.read_file("#{design}
|
82
|
+
model = OldSql::ReportDesign::Parser.read_file("#{design}")
|
77
83
|
|
78
84
|
init(resultset)
|
79
85
|
|
@@ -108,6 +114,39 @@ module OldSql
|
|
108
114
|
end
|
109
115
|
end
|
110
116
|
|
117
|
+
def parse_chart_design(design, resultset)
|
118
|
+
report_row = []
|
119
|
+
@rec = resultset[0]
|
120
|
+
|
121
|
+
chart = OldSql::ReportDesign::ChartParser.read_file("#{design}")
|
122
|
+
|
123
|
+
chart.items.each do |item|
|
124
|
+
key = item.key
|
125
|
+
expression = ""
|
126
|
+
item.chart_data.each do |data|
|
127
|
+
if item.expression?
|
128
|
+
if data.type == OldSql::ReportDesign::ChartData::COLUMN
|
129
|
+
expression << @rec[data.value].to_s
|
130
|
+
elsif data.type == OldSql::ReportDesign::ChartData::OPERATOR ||
|
131
|
+
data.type == OldSql::ReportDesign::ChartData::NUMERIC_LITERAL
|
132
|
+
expression << data.value
|
133
|
+
end
|
134
|
+
else
|
135
|
+
if data.type == OldSql::ReportDesign::ChartData::COLUMN
|
136
|
+
result = @rec[data.value]
|
137
|
+
if OldSql.round_report_values
|
138
|
+
result = round(result.to_f, OldSql.rounding_precision)
|
139
|
+
end
|
140
|
+
report_row << [key,result]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
report_row << [key,eval_expression(expression)] unless expression.length==0
|
145
|
+
end
|
146
|
+
|
147
|
+
@data = {chart.type=>report_row}
|
148
|
+
end
|
149
|
+
|
111
150
|
def eval_expression expression
|
112
151
|
result = 0.0
|
113
152
|
begin
|
@@ -2,6 +2,7 @@ function load_report()
|
|
2
2
|
{
|
3
3
|
report_name = jQuery("#report option:selected").attr('name');
|
4
4
|
report_sql = jQuery("#report option:selected").attr('report_sql');
|
5
|
+
report_view = get_report_view();
|
5
6
|
|
6
7
|
if (!reported_selected(report_name)) return;
|
7
8
|
|
@@ -18,6 +19,7 @@ function print_report()
|
|
18
19
|
{
|
19
20
|
report_name = jQuery("#report option:selected").attr('name');
|
20
21
|
report_sql = jQuery("#report option:selected").attr('report_sql');
|
22
|
+
report_view = get_report_view();
|
21
23
|
|
22
24
|
if (!reported_selected(report_name)) return;
|
23
25
|
|
@@ -31,6 +33,7 @@ function export_report_to_excel()
|
|
31
33
|
{
|
32
34
|
report_name = jQuery("#report option:selected").attr('name');
|
33
35
|
report_sql = jQuery("#report option:selected").attr('report_sql');
|
36
|
+
report_view = get_report_view();
|
34
37
|
|
35
38
|
if (!reported_selected(report_name)) return;
|
36
39
|
|
@@ -50,6 +53,17 @@ function reported_selected(report_name)
|
|
50
53
|
}
|
51
54
|
}
|
52
55
|
|
56
|
+
function get_report_view()
|
57
|
+
{
|
58
|
+
report_view = jQuery("#report option:selected").attr('report_view');
|
59
|
+
|
60
|
+
if (report_view) {
|
61
|
+
return report_view;
|
62
|
+
} else {
|
63
|
+
return default_report_view;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
53
67
|
jQuery(document).ready(function($){
|
54
68
|
jQuery("#datepicker-start").datetimepicker();
|
55
69
|
jQuery("#datepicker-start").datetimepicker( "option", "dateFormat", "yy/mm/dd" );
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: old_sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.14.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Eddie Gonzales
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-06-
|
13
|
+
date: 2011-06-14 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: devise
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- app/controllers/old_sql/report_controller.rb
|
52
52
|
- app/views/layouts/old_sql/report.html.erb
|
53
53
|
- app/views/old_sql/errors/401.html.erb
|
54
|
+
- app/views/old_sql/report/chart.html.erb
|
54
55
|
- app/views/old_sql/report/datagrid.html.erb
|
55
56
|
- app/views/old_sql/report/index.html.erb
|
56
57
|
- app/views/old_sql/report/print.html.erb
|
@@ -71,11 +72,16 @@ files:
|
|
71
72
|
- lib/generators/old_sql/templates/reports.yml.example
|
72
73
|
- lib/generators/old_sql/templates/user.erb.example
|
73
74
|
- lib/generators/old_sql/templates/user_design_template.csv
|
75
|
+
- lib/generators/old_sql/templates/user_old_sql_demo_chart_design.yml
|
74
76
|
- lib/generators/old_sql/templates/user_processor.rb.example
|
75
77
|
- lib/old_sql.rb
|
76
78
|
- lib/old_sql/engine.rb
|
77
79
|
- lib/old_sql/report_design/cell.rb
|
78
80
|
- lib/old_sql/report_design/cell_data.rb
|
81
|
+
- lib/old_sql/report_design/chart.rb
|
82
|
+
- lib/old_sql/report_design/chart_data.rb
|
83
|
+
- lib/old_sql/report_design/chart_item.rb
|
84
|
+
- lib/old_sql/report_design/chart_parser.rb
|
79
85
|
- lib/old_sql/report_design/model.rb
|
80
86
|
- lib/old_sql/report_design/parser.rb
|
81
87
|
- lib/old_sql/report_design/row.rb
|
@@ -447,7 +453,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
447
453
|
requirements:
|
448
454
|
- - ">="
|
449
455
|
- !ruby/object:Gem::Version
|
450
|
-
hash:
|
456
|
+
hash: 1769007801397558054
|
451
457
|
segments:
|
452
458
|
- 0
|
453
459
|
version: "0"
|