ellington 0.0.5 → 0.0.6
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/lib/ellington/passenger.rb +4 -0
- data/lib/ellington/route.rb +4 -2
- data/lib/ellington/version.rb +1 -1
- data/lib/ellington/visualizer.rb +186 -74
- metadata +3 -5
- data/Blast.pdf +0 -0
data/lib/ellington/passenger.rb
CHANGED
@@ -43,6 +43,10 @@ module Ellington
|
|
43
43
|
@state_history ||= []
|
44
44
|
end
|
45
45
|
|
46
|
+
def state_history_includes?(*states)
|
47
|
+
(state_history & states).length == states.length
|
48
|
+
end
|
49
|
+
|
46
50
|
def transition_to(new_state)
|
47
51
|
if !locked?
|
48
52
|
message = "Cannot transition an unlocked #{self.class.name}'s state"
|
data/lib/ellington/route.rb
CHANGED
@@ -40,10 +40,11 @@ module Ellington
|
|
40
40
|
(@subclasses ||= []) << subclass
|
41
41
|
end
|
42
42
|
|
43
|
-
def generate_graphs(dir)
|
43
|
+
def generate_graphs(dir, options={})
|
44
|
+
options[:format] ||= :svg
|
44
45
|
FileUtils.mkdir_p(dir)
|
45
46
|
@subclasses.each do |subclass|
|
46
|
-
Ellington::Visualizer.new(subclass.new, dir).
|
47
|
+
Ellington::Visualizer.new(subclass.new, dir, options[:format]).graph_all
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
@@ -122,6 +123,7 @@ module Ellington
|
|
122
123
|
log route_info
|
123
124
|
end
|
124
125
|
Ellington.logger.info "\n" if Ellington.logger
|
126
|
+
binding.pry
|
125
127
|
end
|
126
128
|
|
127
129
|
required_connections.each do |connection|
|
data/lib/ellington/version.rb
CHANGED
data/lib/ellington/visualizer.rb
CHANGED
@@ -28,76 +28,122 @@ module Ellington
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
attr_reader :route, :dir
|
31
|
+
attr_reader :route, :dir, :format
|
32
32
|
|
33
|
-
def initialize(route, dir)
|
33
|
+
def initialize(route, dir, format=:svg)
|
34
34
|
@route = route
|
35
35
|
@dir = dir
|
36
|
+
@format = format
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
FONTNAME = "Helvetica"
|
40
|
+
RANKSEP = 0.4
|
41
|
+
NODE_COLOR = "white"
|
42
|
+
NODE_COLOR_VIRTUAL = "gray50"
|
43
|
+
NODE_COLOR_LINE_GOAL = "green2"
|
44
|
+
NODE_COLOR_ROUTE_GOAL = "gold"
|
45
|
+
NODE_COLOR_PASSENGER_HIT = "royalblue1"
|
46
|
+
NODE_FILLCOLOR = "white"
|
47
|
+
NODE_FILLCOLOR_LINE_GOAL = "green2"
|
48
|
+
NODE_FILLCOLOR_ROUTE_GOAL = "gold"
|
49
|
+
NODE_FONTCOLOR_VIRTUAL = "gray40"
|
50
|
+
NODE_SHAPE = "box"
|
51
|
+
NODE_STYLE = "filled,rounded"
|
52
|
+
NODE_STYLE_VIRTUAL = "rounded"
|
53
|
+
NODE_PENWIDTH_PASSENGER_HIT = 2
|
54
|
+
EDGE_PENWIDTH_PASSENGER_HIT = 2
|
55
|
+
EDGE_COLOR_PASSENGER_HIT = "royalblue1"
|
56
|
+
EDGE_STYLE_PASSENGER_MISS = "dotted"
|
57
|
+
CLUSTER_STYLE = "filled"
|
58
|
+
CLUSTER_COLOR = "gray70"
|
59
|
+
CLUSTER_FILLCOLOR = "gray70"
|
60
|
+
CLUSTER_PENCOLOR = "gray50"
|
61
|
+
|
62
|
+
def graph_all(passenger=nil)
|
63
|
+
graph_route_basic passenger
|
64
|
+
graph_route passenger
|
65
|
+
graph_lines_basic passenger
|
66
|
+
graph_lines passenger
|
43
67
|
end
|
44
68
|
|
45
|
-
def graph_lines_basic
|
46
|
-
g = Node.new(nil, GraphViz.new("
|
69
|
+
def graph_lines_basic(passenger=nil)
|
70
|
+
g = Node.new(nil, GraphViz.new("GraphLinesBasic"))
|
71
|
+
set_graph_defaults g.viz
|
47
72
|
g.viz["label"] = "#{route.name} Lines - basic"
|
48
|
-
g.viz["ranksep"] = 0.4
|
49
|
-
g.viz["fontname"] = "Helvetica"
|
50
|
-
g.viz.node["fontname"] = "Helvetica"
|
51
|
-
g.viz.node["shape"] = "box"
|
52
|
-
g.viz.node["style"] = "rounded"
|
53
73
|
|
54
74
|
route.lines.each_with_index do |line, index|
|
55
75
|
line_cluster = Node.new(line, g.viz.add_graph("cluster#{index}"))
|
76
|
+
set_cluster_defaults line_cluster.viz
|
56
77
|
line_cluster.viz["label"] = line.class.name
|
57
|
-
line_cluster.viz["style"] = "filled"
|
58
78
|
g << line_cluster
|
59
79
|
|
60
80
|
line.stations.each do |station|
|
61
81
|
station_node = Node.new(station, line_cluster.viz.add_nodes(station.class.name))
|
62
|
-
station_node.viz["style"] = "filled,rounded"
|
63
|
-
station_node.viz["color"] = "white"
|
64
82
|
line_cluster << station_node
|
83
|
+
|
84
|
+
if !(line.goal & station.states.keys).empty?
|
85
|
+
station_node.viz["color"] = NODE_COLOR_LINE_GOAL
|
86
|
+
station_node.viz["fillcolor"] = NODE_COLOR_LINE_GOAL
|
87
|
+
end
|
88
|
+
|
89
|
+
if !(route.goal & station.states.keys).empty?
|
90
|
+
station_node.viz["color"] = NODE_COLOR_ROUTE_GOAL
|
91
|
+
station_node.viz["fillcolor"] = NODE_COLOR_ROUTE_GOAL
|
92
|
+
end
|
93
|
+
|
94
|
+
if passenger && !(passenger.state_history & station.states.keys).empty?
|
95
|
+
station_node.viz["color"] = NODE_COLOR_PASSENGER_HIT
|
96
|
+
station_node.viz["penwidth"] = NODE_PENWIDTH_PASSENGER_HIT
|
97
|
+
end
|
65
98
|
end
|
66
99
|
|
67
100
|
line_cluster.each_with_index.each do |node, node_index|
|
68
101
|
next_node = line_cluster[node_index + 1]
|
69
|
-
|
102
|
+
if next_node
|
103
|
+
station = node.base
|
104
|
+
next_station = next_node.base
|
105
|
+
edge = line_cluster.viz.add_edges(node.viz, next_node.viz)
|
106
|
+
if passenger
|
107
|
+
if color_name(node.viz["color"]) == NODE_COLOR_PASSENGER_HIT &&
|
108
|
+
color_name(next_node.viz["color"]) == NODE_COLOR_PASSENGER_HIT
|
109
|
+
edge["color"] = EDGE_COLOR_PASSENGER_HIT
|
110
|
+
edge["penwidth"] = EDGE_PENWIDTH_PASSENGER_HIT
|
111
|
+
else
|
112
|
+
edge["style"] = EDGE_STYLE_PASSENGER_MISS
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
70
116
|
end
|
71
117
|
end
|
72
118
|
|
73
|
-
file_name = "#{route.name.downcase.gsub("::", "_")}-lines-basic
|
74
|
-
g.viz.output(
|
119
|
+
file_name = "#{route.name.downcase.gsub("::", "_")}-lines-basic.#{format}"
|
120
|
+
g.viz.output(format => File.join(dir, file_name))
|
75
121
|
end
|
76
122
|
|
77
|
-
def graph_lines
|
78
|
-
g = Node.new(nil, GraphViz.new("
|
123
|
+
def graph_lines(passenger=nil)
|
124
|
+
g = Node.new(nil, GraphViz.new("GraphLines"))
|
125
|
+
set_graph_defaults g.viz
|
79
126
|
g.viz["label"] = "#{route.name} Lines"
|
80
|
-
g.viz["ranksep"] = 0.4
|
81
|
-
g.viz["fontname"] = "Helvetica"
|
82
|
-
g.viz.node["fontname"] = "Helvetica"
|
83
|
-
g.viz.node["shape"] = "box"
|
84
|
-
g.viz.node["style"] = "rounded"
|
85
127
|
|
86
128
|
route.lines.each_with_index do |line, index|
|
87
129
|
line_cluster = Node.new(line, g.viz.add_graph("cluster#{index}"))
|
130
|
+
set_cluster_defaults line_cluster.viz
|
88
131
|
line_cluster.viz["label"] = line.class.name
|
89
|
-
line_cluster.viz["style"] = "filled"
|
90
132
|
g << line_cluster
|
91
133
|
|
92
134
|
line.states.keys.each do |state|
|
93
135
|
state_node = Node.new(state, line_cluster.viz.add_nodes(state))
|
94
|
-
state_node.viz["style"] = "filled,rounded"
|
95
|
-
state_node.viz["color"] = "white"
|
96
136
|
if line.goal.include?(state)
|
97
|
-
state_node.viz["color"] =
|
137
|
+
state_node.viz["color"] = NODE_COLOR_LINE_GOAL
|
138
|
+
state_node.viz["fillcolor"] = NODE_FILLCOLOR_LINE_GOAL
|
98
139
|
end
|
99
140
|
if route.goal.include?(state)
|
100
|
-
state_node.viz["color"] =
|
141
|
+
state_node.viz["color"] = NODE_COLOR_ROUTE_GOAL
|
142
|
+
state_node.viz["fillcolor"] = NODE_FILLCOLOR_ROUTE_GOAL
|
143
|
+
end
|
144
|
+
if passenger && passenger.state_history_includes?(state)
|
145
|
+
state_node.viz["color"] = NODE_COLOR_PASSENGER_HIT
|
146
|
+
state_node.viz["penwidth"] = NODE_PENWIDTH_PASSENGER_HIT
|
101
147
|
end
|
102
148
|
line_cluster << state_node
|
103
149
|
end
|
@@ -106,45 +152,64 @@ module Ellington
|
|
106
152
|
a = line_cluster.find(state)
|
107
153
|
(transitions || []).each do |transition|
|
108
154
|
b = line_cluster.find(transition)
|
109
|
-
line_cluster.viz.add_edges
|
155
|
+
edge = line_cluster.viz.add_edges(a.viz, b.viz)
|
156
|
+
if passenger
|
157
|
+
if passenger.state_history_includes?(state, transition)
|
158
|
+
edge["color"] = EDGE_COLOR_PASSENGER_HIT
|
159
|
+
edge["penwidth"] = EDGE_PENWIDTH_PASSENGER_HIT
|
160
|
+
else
|
161
|
+
edge["style"] = EDGE_STYLE_PASSENGER_MISS
|
162
|
+
end
|
163
|
+
end
|
110
164
|
end
|
111
165
|
end
|
112
166
|
end
|
113
167
|
|
114
|
-
file_name = "#{route.name.downcase.gsub("::", "_")}-lines
|
115
|
-
g.viz.output(
|
168
|
+
file_name = "#{route.name.downcase.gsub("::", "_")}-lines.#{format}"
|
169
|
+
g.viz.output(format => File.join(dir, file_name))
|
116
170
|
end
|
117
171
|
|
118
|
-
def graph_route_basic
|
119
|
-
g = Node.new(nil, GraphViz.new("
|
172
|
+
def graph_route_basic(passenger=nil)
|
173
|
+
g = Node.new(nil, GraphViz.new("GraphRouteBasic"))
|
174
|
+
set_graph_defaults g.viz
|
175
|
+
g.viz["ranksep"] = 1
|
120
176
|
g.viz["label"] = "#{route.name} Route - basic"
|
121
|
-
g.viz["compound"] = true
|
122
|
-
g.viz["ranksep"] = 1.2
|
123
|
-
g.viz["fontname"] = "Helvetica"
|
124
|
-
g.viz.node["fontname"] = "Helvetica"
|
125
|
-
g.viz.node["shape"] = "box"
|
126
|
-
g.viz.node["style"] = "rounded"
|
127
177
|
|
128
178
|
route.lines.each_with_index do |line, index|
|
129
179
|
line_cluster = Node.new(line, g.viz.add_graph("cluster#{index}"))
|
180
|
+
set_cluster_defaults line_cluster.viz
|
130
181
|
line_cluster.viz["label"] = line.class.name
|
131
|
-
line_cluster.viz["style"] = "filled"
|
132
182
|
g << line_cluster
|
133
183
|
|
184
|
+
passenger_hit = false
|
134
185
|
%w{PASS FAIL ERROR}.each do |state|
|
135
186
|
state_node = Node.new(state, line_cluster.viz.add_nodes("#{line.class.name}#{state}", "label" => state))
|
136
|
-
state_node.viz["style"] = "filled,rounded"
|
137
|
-
state_node.viz["color"] = "white"
|
138
|
-
if !(route.goal & line.stations.map{ |s| "#{state} #{s.name}" }).empty?
|
139
|
-
state_node.viz["color"] = "gold"
|
140
|
-
end
|
141
187
|
line_cluster << state_node
|
188
|
+
states = line.stations.map{ |s| "#{state} #{s.name}" }
|
189
|
+
|
190
|
+
if !(line.goal & states).empty?
|
191
|
+
state_node.viz["color"] = NODE_COLOR_LINE_GOAL
|
192
|
+
state_node.viz["fillcolor"] = NODE_COLOR_LINE_GOAL
|
193
|
+
end
|
194
|
+
|
195
|
+
if !(route.goal & states).empty?
|
196
|
+
state_node.viz["color"] = NODE_COLOR_ROUTE_GOAL
|
197
|
+
state_node.viz["fillcolor"] = NODE_COLOR_ROUTE_GOAL
|
198
|
+
end
|
199
|
+
|
200
|
+
if passenger
|
201
|
+
if !passenger_hit && !(passenger.state_history & line.send("#{state.downcase}ed")).empty?
|
202
|
+
passenger_hit = true
|
203
|
+
state_node.viz["color"] = NODE_COLOR_PASSENGER_HIT
|
204
|
+
state_node.viz["penwidth"] = NODE_PENWIDTH_PASSENGER_HIT
|
205
|
+
end
|
206
|
+
end
|
142
207
|
end
|
143
208
|
end
|
144
209
|
|
145
210
|
route.connections.each do |connection|
|
146
211
|
to_node = g.find(connection.line)
|
147
|
-
|
212
|
+
to_line = to_node.base
|
148
213
|
|
149
214
|
combos = {}
|
150
215
|
g.to_a.each do |node|
|
@@ -157,10 +222,10 @@ module Ellington
|
|
157
222
|
if connection.type == :if_any
|
158
223
|
combos.each do |state, nodes|
|
159
224
|
nodes.each do |node|
|
160
|
-
|
225
|
+
from_line = node.base
|
161
226
|
g.viz.add_edges(
|
162
|
-
node.viz.get_node("#{
|
163
|
-
to_node.viz.get_node("#{
|
227
|
+
node.viz.get_node("#{from_line.class.name}#{state}"),
|
228
|
+
to_node.viz.get_node("#{to_line.class.name}PASS"),
|
164
229
|
"lhead" => to_node.viz.id
|
165
230
|
)
|
166
231
|
end
|
@@ -172,9 +237,9 @@ module Ellington
|
|
172
237
|
node_name = nodes.map{ |n| n.base.class.name }.join + state
|
173
238
|
node_label = nodes.map{ |n| "#{n.base.class.name} #{state}"}.join("\n")
|
174
239
|
viz = g.viz.add_nodes(node_name, "label" => node_label)
|
175
|
-
viz["style"] =
|
176
|
-
viz["color"] =
|
177
|
-
viz["fontcolor"] =
|
240
|
+
viz["style"] = NODE_STYLE_VIRTUAL
|
241
|
+
viz["color"] = NODE_COLOR_VIRTUAL
|
242
|
+
viz["fontcolor"] = NODE_FONTCOLOR_VIRTUAL
|
178
243
|
|
179
244
|
nodes.each do |node|
|
180
245
|
from_viz = node.viz.get_node("#{node.base.class.name}#{state}")
|
@@ -190,41 +255,62 @@ module Ellington
|
|
190
255
|
end
|
191
256
|
end
|
192
257
|
|
193
|
-
file_name = "#{route.name.downcase.gsub("::", "_")}-route-basic
|
194
|
-
g.viz.output(
|
258
|
+
file_name = "#{route.name.downcase.gsub("::", "_")}-route-basic.#{format}"
|
259
|
+
g.viz.output(format => File.join(dir, file_name))
|
195
260
|
end
|
196
261
|
|
197
|
-
def graph_route
|
198
|
-
g = Node.new(nil, GraphViz.new("
|
262
|
+
def graph_route(passenger=nil)
|
263
|
+
g = Node.new(nil, GraphViz.new("GraphRoute"))
|
264
|
+
set_graph_defaults g.viz
|
199
265
|
g.viz["label"] = "#{route.name} Lines"
|
200
|
-
g.viz["compound"] = true
|
201
266
|
g.viz["ranksep"] = 0.8
|
202
|
-
g.viz["fontname"] = "Helvetica"
|
203
|
-
g.viz.node["fontname"] = "Helvetica"
|
204
|
-
g.viz.node["shape"] = "box"
|
205
|
-
g.viz.node["style"] = "rounded"
|
206
267
|
|
207
268
|
route.lines.each_with_index do |line, index|
|
208
269
|
line_cluster = Node.new(line, g.viz.add_graph("cluster#{index}"))
|
270
|
+
set_cluster_defaults line_cluster.viz
|
209
271
|
line_cluster.viz["label"] = line.class.name
|
210
|
-
line_cluster.viz["style"] = "filled"
|
211
272
|
g << line_cluster
|
212
273
|
|
213
274
|
line.states.keys.each do |state|
|
214
275
|
state_node = Node.new(state, line_cluster.viz.add_nodes(state))
|
215
|
-
state_node.viz["style"] = "filled,rounded"
|
216
|
-
state_node.viz["color"] = "white"
|
217
276
|
if line.goal.include?(state)
|
218
|
-
state_node.viz["color"] =
|
277
|
+
state_node.viz["color"] = NODE_COLOR_LINE_GOAL
|
278
|
+
state_node.viz["fillcolor"] = NODE_FILLCOLOR_LINE_GOAL
|
219
279
|
end
|
220
280
|
if route.goal.include?(state)
|
221
|
-
state_node.viz["color"] =
|
281
|
+
state_node.viz["color"] = NODE_COLOR_ROUTE_GOAL
|
282
|
+
state_node.viz["fillcolor"] = NODE_FILLCOLOR_ROUTE_GOAL
|
283
|
+
end
|
284
|
+
if passenger && passenger.state_history_includes?(state)
|
285
|
+
state_node.viz["color"] = NODE_COLOR_PASSENGER_HIT
|
286
|
+
state_node.viz["penwidth"] = NODE_PENWIDTH_PASSENGER_HIT
|
222
287
|
end
|
223
288
|
line_cluster << state_node
|
224
289
|
end
|
225
290
|
end
|
226
291
|
|
227
292
|
viz = g.viz.add_nodes(route.initial_state)
|
293
|
+
rendered_edges = {}
|
294
|
+
|
295
|
+
if passenger
|
296
|
+
passenger_nodes = g.reduce([]) do |memo, line_cluster|
|
297
|
+
line_cluster.children.each do |node|
|
298
|
+
if node.viz["color"].to_s.gsub(/\W/, "") == NODE_COLOR_PASSENGER_HIT
|
299
|
+
memo << node
|
300
|
+
end
|
301
|
+
end
|
302
|
+
memo
|
303
|
+
end
|
304
|
+
previous_node = nil
|
305
|
+
passenger_nodes.each do |node|
|
306
|
+
from_viz = previous_node.nil? ? viz : previous_node.viz
|
307
|
+
rendered_edges[from_viz.id + node.viz.id] = true
|
308
|
+
edge = g.viz.add_edges(from_viz, node.viz)
|
309
|
+
edge["color"] = EDGE_COLOR_PASSENGER_HIT
|
310
|
+
edge["penwidth"] = EDGE_PENWIDTH_PASSENGER_HIT
|
311
|
+
previous_node = node
|
312
|
+
end
|
313
|
+
end
|
228
314
|
|
229
315
|
route.states.each do |from_state, to_states|
|
230
316
|
(to_states || []).each do |to_state|
|
@@ -237,17 +323,43 @@ module Ellington
|
|
237
323
|
to_viz = to_node.viz.get_node(to_state) if to_node
|
238
324
|
to_viz ||= g.viz.get_node(to_state)
|
239
325
|
|
240
|
-
if from_viz && to_viz
|
241
|
-
|
326
|
+
if from_viz && to_viz && !rendered_edges[from_viz.id + to_viz.id]
|
327
|
+
rendered_edges[from_viz.id + to_viz.id] = true
|
328
|
+
edge = g.viz.add_edges(
|
242
329
|
from_viz,
|
243
330
|
to_viz
|
244
331
|
)
|
332
|
+
edge["style"] = EDGE_STYLE_PASSENGER_MISS if passenger
|
245
333
|
end
|
246
334
|
end
|
247
335
|
end
|
248
336
|
|
249
|
-
file_name = "#{route.name.downcase.gsub("::", "_")}-route
|
250
|
-
g.viz.output(
|
337
|
+
file_name = "#{route.name.downcase.gsub("::", "_")}-route.#{format}"
|
338
|
+
g.viz.output(format => File.join(dir, file_name))
|
339
|
+
end
|
340
|
+
|
341
|
+
private
|
342
|
+
|
343
|
+
def color_name(graphviz_color)
|
344
|
+
graphviz_color.to_s.gsub("\"", "")
|
345
|
+
end
|
346
|
+
|
347
|
+
def set_graph_defaults(graph)
|
348
|
+
graph["compound"] = true
|
349
|
+
graph["ranksep"] = RANKSEP
|
350
|
+
graph["fontname"] = FONTNAME
|
351
|
+
graph.node["fontname"] = FONTNAME
|
352
|
+
graph.node["shape"] = NODE_SHAPE
|
353
|
+
graph.node["style"] = NODE_STYLE
|
354
|
+
graph.node["color"] = NODE_COLOR
|
355
|
+
graph.node["fillcolor"] = NODE_FILLCOLOR
|
356
|
+
end
|
357
|
+
|
358
|
+
def set_cluster_defaults(cluster)
|
359
|
+
cluster["style"] = CLUSTER_STYLE
|
360
|
+
cluster["color"] = CLUSTER_COLOR
|
361
|
+
cluster["fillcolor"] = CLUSTER_FILLCOLOR
|
362
|
+
cluster["pencolor"] = CLUSTER_PENCOLOR
|
251
363
|
end
|
252
364
|
|
253
365
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ellington
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hero
|
@@ -90,7 +90,6 @@ files:
|
|
90
90
|
- lib/ellington/version.rb
|
91
91
|
- lib/ellington/visualizer.rb
|
92
92
|
- lib/ellington.rb
|
93
|
-
- Blast.pdf
|
94
93
|
- Gemfile
|
95
94
|
- Gemfile.lock
|
96
95
|
- LICENSE.txt
|
@@ -134,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
133
|
version: '0'
|
135
134
|
requirements: []
|
136
135
|
rubyforge_project:
|
137
|
-
rubygems_version: 1.8.
|
136
|
+
rubygems_version: 1.8.25
|
138
137
|
signing_key:
|
139
138
|
specification_version: 3
|
140
139
|
summary: A micro framework to ensure your projects are easy to manage, develop, &
|
@@ -157,4 +156,3 @@ test_files:
|
|
157
156
|
- test/ticket_test.rb
|
158
157
|
- test/transition_info_test.rb
|
159
158
|
- test/unique_type_array_test.rb
|
160
|
-
has_rdoc:
|
data/Blast.pdf
DELETED
Binary file
|