nera 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +37 -0
  3. data/README.rdoc +47 -0
  4. data/Rakefile +27 -0
  5. data/bin/nera +29 -0
  6. data/bin/nera_addsim +30 -0
  7. data/lib/nera/nera_cui.rb +417 -0
  8. data/lib/nera/nera_database.rb +281 -0
  9. data/lib/nera/nera_db_folders.rb +226 -0
  10. data/lib/nera/nera_dialog.rb +205 -0
  11. data/lib/nera/nera_job_layer_controller.rb +237 -0
  12. data/lib/nera/nera_job_records.rb +111 -0
  13. data/lib/nera/nera_job_script.rb +202 -0
  14. data/lib/nera/nera_parameter_layer_controller.rb +157 -0
  15. data/lib/nera/nera_parameter_records.rb +186 -0
  16. data/lib/nera/nera_run_layer_controller.rb +192 -0
  17. data/lib/nera/nera_run_records.rb +184 -0
  18. data/lib/nera/nera_simulator.rb +26 -0
  19. data/lib/nera/nera_simulator_layer_controller.rb +66 -0
  20. data/lib/nera/nera_simulator_records.rb +84 -0
  21. data/lib/nera.rb +25 -0
  22. data/lib/nera_addsim/make_simulator.rb +307 -0
  23. data/scripts/make_manifest.rb +21 -0
  24. data/test/runner.rb +3 -0
  25. data/test/test_helper.rb +52 -0
  26. data/test/test_nera_database.rb +221 -0
  27. data/test/test_nera_db_folders.rb +209 -0
  28. data/test/test_nera_dialog.rb +134 -0
  29. data/test/test_nera_job_layer_controller.rb +132 -0
  30. data/test/test_nera_job_records.rb +260 -0
  31. data/test/test_nera_parameter_layer_controller.rb +188 -0
  32. data/test/test_nera_parameter_records.rb +285 -0
  33. data/test/test_nera_run_layer_controller.rb +171 -0
  34. data/test/test_nera_run_records.rb +290 -0
  35. data/test/test_nera_simulator.rb +26 -0
  36. data/test/test_nera_simulator_layer_controller.rb +54 -0
  37. data/test/test_nera_simulator_records.rb +140 -0
  38. metadata +125 -0
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-03-25
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,37 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/nera
6
+ bin/nera_addsim
7
+ lib/nera.rb
8
+ lib/nera/nera_cui.rb
9
+ lib/nera/nera_database.rb
10
+ lib/nera/nera_db_folders.rb
11
+ lib/nera/nera_dialog.rb
12
+ lib/nera/nera_job_layer_controller.rb
13
+ lib/nera/nera_job_records.rb
14
+ lib/nera/nera_job_script.rb
15
+ lib/nera/nera_parameter_layer_controller.rb
16
+ lib/nera/nera_parameter_records.rb
17
+ lib/nera/nera_run_layer_controller.rb
18
+ lib/nera/nera_run_records.rb
19
+ lib/nera/nera_simulator.rb
20
+ lib/nera/nera_simulator_layer_controller.rb
21
+ lib/nera/nera_simulator_records.rb
22
+ lib/nera_addsim/make_simulator.rb
23
+ scripts/make_manifest.rb
24
+ test/runner.rb
25
+ test/test_helper.rb
26
+ test/test_nera_database.rb
27
+ test/test_nera_db_folders.rb
28
+ test/test_nera_dialog.rb
29
+ test/test_nera_job_layer_controller.rb
30
+ test/test_nera_job_records.rb
31
+ test/test_nera_parameter_layer_controller.rb
32
+ test/test_nera_parameter_records.rb
33
+ test/test_nera_run_layer_controller.rb
34
+ test/test_nera_run_records.rb
35
+ test/test_nera_simulator.rb
36
+ test/test_nera_simulator_layer_controller.rb
37
+ test/test_nera_simulator_records.rb
data/README.rdoc ADDED
@@ -0,0 +1,47 @@
1
+ = nera
2
+
3
+ * http://nera.rubyforge.com
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is an application which helps you to manage a database for the Monte Carlo simulations.
8
+ For the dtailed usage, see http://nera.rubyforge.com
9
+
10
+ == SYNOPSIS:
11
+
12
+ If you want to start the program, spcify the name of the database (say, 'nera_db') as the first argument.
13
+
14
+ nera 'neradb'
15
+
16
+ To add your own simulators,
17
+
18
+ nera_addsim 'neradb'
19
+
20
+ == REQUIREMENTS:
21
+
22
+ Ruby 1.8.0 or later
23
+
24
+ == INSTALL:
25
+
26
+ To install,
27
+
28
+ sudo gem install nera
29
+
30
+ == LICENSE:
31
+
32
+ NER_Analyzer : A database management application for Monte Carlo simulations
33
+ Copyright (C) 2009 Yohsuke Murase and Shigenori Matsumoto
34
+
35
+ This program is free software: you can redistribute it and/or modify
36
+ it under the terms of the GNU General Public License as published by
37
+ the Free Software Foundation, either version 3 of the License, or
38
+ (at your option) any later version.
39
+
40
+ This program is distributed in the hope that it will be useful,
41
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43
+ GNU General Public License for more details.
44
+
45
+ You should have received a copy of the GNU General Public License
46
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
47
+
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/nera'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('nera', NERA::VERSION) do |p|
7
+ p.developer('Yohsuke Murase', 'murase@serow.t.u-tokyo.ac.jp')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name # TODO this is default value
10
+ # p.extra_deps = [
11
+ # ['activesupport','>= 2.0.2'],
12
+ # ]
13
+ p.extra_dev_deps = [
14
+ ['newgem', ">= #{::Newgem::VERSION}"]
15
+ ]
16
+
17
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
18
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
19
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
20
+ p.rsync_args = '-av --delete --ignore-errors'
21
+ end
22
+
23
+ require 'newgem/tasks' # load /tasks/*.rake
24
+ Dir['tasks/**/*.rake'].each { |t| load t }
25
+
26
+ # TODO - want other tests/tasks run by default? Add them to the list
27
+ # task :default => [:spec, :features]
data/bin/nera ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Yohsuke Murase on 2009-3-25.
4
+ # Copyright (c) 2009. All rights reserved.
5
+ require 'optparse'
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/nera")
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = <<-BANNER.gsub(/^ /,'')
10
+
11
+ Usage: #{File.basename($0)} [options] 'nera_db_folder'
12
+
13
+ BANNER
14
+ opts.separator ""
15
+ opts.on("-h", "--help",
16
+ "Show this help message.") { $stdout.puts opts; exit }
17
+ opts.on("-v", "--version", "Show version.") { $stdout.puts NERA::VERSION; exit}
18
+ opts.parse!(ARGV)
19
+ end
20
+
21
+ unless ARGV.size == 1
22
+ $stderr.puts "Usage :\t nera \"nera_db_folder\""
23
+ raise "\nSpecify the argument."
24
+ end
25
+
26
+ Dir.chdir( File.dirname( ARGV[0]) ) {
27
+ NERA::CUI_exec.new( File.basename(ARGV[0]) )
28
+ }
29
+
data/bin/nera_addsim ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Yohsuke Murase on 2009-3-25.
4
+ # Copyright (c) 2009. All rights reserved.
5
+
6
+ require 'optparse'
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/nera")
8
+
9
+ parser = OptionParser.new do |opts|
10
+ opts.banner = <<-BANNER.gsub(/^ /,'')
11
+
12
+ Usage: #{File.basename($0)} [options] 'nera_db_folder'
13
+
14
+ BANNER
15
+ opts.separator ""
16
+ opts.on("-h", "--help",
17
+ "Show this help message.") { stdout.puts opts; exit }
18
+ opts.parse!(ARGV)
19
+ end
20
+
21
+ unless ARGV.size == 1
22
+ raise "\n\nUsage:\n nera_addsim 'nera_db_folder'"
23
+ end
24
+ folder_path = ARGV[0]+'/Simulator_classes/'
25
+ unless FileTest.directory?( folder_path)
26
+ raise "Folder #{folder_path} does not exist."
27
+ end
28
+
29
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/nera_addsim/make_simulator")
30
+ test = NERA::CUI_Simulator_Adder.new('hoge')
@@ -0,0 +1,417 @@
1
+ require 'nera_simulator_layer_controller'
2
+ require 'nera_job_layer_controller'
3
+ require 'nera_parameter_layer_controller'
4
+ require 'nera_run_layer_controller'
5
+ require 'nera_dialog'
6
+
7
+ # --- start CUI based NER analyzer ---
8
+ # - db_name : name of the database folder
9
+ module NERA
10
+ class CUI_exec
11
+
12
+ # folder structure
13
+ @path_db_folder
14
+
15
+ # simulator layer controller
16
+ @sim_cont
17
+
18
+ # param layer controller
19
+ @param_cont
20
+
21
+ # run layer controller
22
+ @run_cont
23
+
24
+ # job layer controller
25
+ @job_cont
26
+
27
+ # state [ :simulator_layer, :parameter_layer, :run_layer, :job_layer, :exit]
28
+ @state
29
+
30
+ # model which is currently selected
31
+ @simulator_class
32
+
33
+ # parameter which is currently selected
34
+ @parameter_id
35
+
36
+ # --- main method
37
+ def initialize( path_db_folder)
38
+ @state = :simulator_layer
39
+ @path_db_folder = path_db_folder
40
+ unless FileTest.directory?(@path_db_folder)
41
+ NERA::DbFolders.create_db(@path_db_folder)
42
+ end
43
+
44
+ while true
45
+ case @state
46
+ when :simulator_layer
47
+ @state = sim_layer_action
48
+ when :parameter_layer
49
+ @state = param_layer_action
50
+ when :run_layer
51
+ @state = run_layer_action
52
+ when :job_layer
53
+ @state = job_layer_action
54
+ when :exit
55
+ return 0
56
+ else
57
+ raise "Must not happen"
58
+ end
59
+ end
60
+ end
61
+
62
+ # --- action at simulator layer
63
+ def sim_layer_action
64
+ $stdout.puts <<"HEADER"
65
+ ===============================================
66
+ --- in simulator layer ------------------------
67
+ #{@path_db_folder}
68
+ ===============================================
69
+ HEADER
70
+
71
+ slc = NERA::SimulatorLayerController.new(@path_db_folder)
72
+ list = slc.list
73
+ names = list.map do |r|
74
+ r[:name]
75
+ end
76
+ names.unshift("go to Jobs layer")
77
+ names += ["exit"]
78
+ selected = 0
79
+ Dir.chdir( slc.path_to_sim_layer) {
80
+ selected = Dialog::select_one_or_return_string( names, "Select a simulator.")
81
+ if selected.is_a?(String)
82
+ system( selected)
83
+ return :simulator_layer
84
+ end
85
+ }
86
+ if names[selected] == "go to Jobs layer"
87
+ return :job_layer
88
+ elsif names[selected] == "exit"
89
+ return :exit
90
+ else
91
+ @simulator_class = eval(names[selected])
92
+ return :parameter_layer
93
+ end
94
+ end
95
+
96
+ # --- selection of a parameter set
97
+ def param_layer_action
98
+ $stdout.puts <<"HEADER"
99
+ ===============================================
100
+ --- in parameter layer ------------------------
101
+ #{@path_db_folder} / #{@simulator_class.to_s}
102
+ ===============================================
103
+ HEADER
104
+
105
+ plc = NERA::ParameterLayerController.new( @path_db_folder, @simulator_class)
106
+ unless plc
107
+ Dialog::message("Specified simulator does not exist #{@path_db_folder}/#{@simulator_class.to_s}")
108
+ return :simulator_layer
109
+ end
110
+
111
+ header,list = plc.parameters_list_in_csv
112
+ list.unshift( "Menu")
113
+ selected = 0
114
+ Dir.chdir( plc.path_to_param_layer) {
115
+ selected = Dialog::select_one_or_return_string( list, header)
116
+ if selected.is_a?(String)
117
+ system(selected)
118
+ return :parameter_layer
119
+ end
120
+ }
121
+ if selected == 0
122
+ layer = parameter_layer_menu_select
123
+ return layer
124
+ else
125
+ id = plc.get_id_from_csv_string( list[selected])
126
+ @parameter_id = id
127
+ return :run_layer
128
+ end
129
+ end
130
+
131
+ # --- menu at a parameter layer
132
+ def parameter_layer_menu_select
133
+ menu = ["return to simulator layer",
134
+ "create a new parameter set",
135
+ "move a parameter set into the trashbox",
136
+ "revert a parameter set in the trashbox",
137
+ "delete a parameter set completely",
138
+ "exit"]
139
+ s = Dialog::select_one( menu, "Select one from the following")
140
+ plc = NERA::ParameterLayerController.new( @path_db_folder, @simulator_class)
141
+ case menu[s]
142
+ when "return to simulator layer"
143
+ return :simulator_layer
144
+ when "create a new parameter set"
145
+ plist = plc.list_of_parameters
146
+ new_param_hash = Dialog::set_multiple_values( plist, "Input the new parameter set")
147
+ f = plc.create_a_new_parameter_set( new_param_hash)
148
+ if f
149
+ Dialog::message("A new parameter is successfully added to the table.")
150
+ else
151
+ Dialog::message("This parameter already exists in the database.")
152
+ end
153
+ return :parameter_layer
154
+ when "move a parameter set into the trashbox"
155
+ header,list = plc.parameters_list_in_csv
156
+ list.unshift("Cancel")
157
+ s = Dialog::select_one( list, header)
158
+ if s == 0
159
+ return :parameter_layer
160
+ else
161
+ id = plc.get_id_from_csv_string( list[s])
162
+ f = plc.move_a_parameter_set_into_trashbox(id)
163
+ if f
164
+ Dialog::message("Parameter #{id} was successfully moved into the trashbox")
165
+ else
166
+ Dialog::message("Couldn't move the parameter #{id} to the trashbox.\nYou have to cancel all the jobs that are not finished.")
167
+ end
168
+ return :parameter_layer
169
+ end
170
+ when "revert a parameter set in the trashbox"
171
+ header,list = plc.trashbox_parameter_list_in_csv
172
+ list.unshift("Cancel")
173
+ s = Dialog::select_one( list, header)
174
+ if s == 0
175
+ return :parameter_layer
176
+ else
177
+ id = plc.get_id_from_csv_string( list[s])
178
+ f = plc.revert_a_parameter_set_in_trashbox(id)
179
+ if f
180
+ Dialog::message("Parameter #{id} was successfully reverted.")
181
+ else
182
+ Dialog::message("Couldn't revert the parameter #{id}")
183
+ end
184
+ return :parameter_layer
185
+ end
186
+ when "delete a parameter set completely"
187
+ header,list = plc.trashbox_parameter_list_in_csv
188
+ list.unshift("Cancel")
189
+ s = Dialog::select_one( list, header)
190
+ if s == 0
191
+ return :parameter_layer
192
+ else
193
+ id = plc.get_id_from_csv_string( list[s])
194
+ f = plc.delete_a_parameter_set( id)
195
+ if f
196
+ Dialog::message("Parameter #{id} was successfully deleted.")
197
+ else
198
+ Dialog::message("Couldn't delete the parameter #{id}")
199
+ end
200
+ return :parameter_layer
201
+ end
202
+ when "exit"
203
+ return :exit
204
+ else
205
+ raise "must not happen"
206
+ end
207
+ end
208
+
209
+ # --- action at run layer
210
+ def run_layer_action
211
+ $stdout.puts <<"HEADER"
212
+ ===============================================
213
+ --- in run layer ------------------------------
214
+ #{@path_db_folder} / #{@simulator_class.to_s} / #{@parameter_id}
215
+ ===============================================
216
+ HEADER
217
+
218
+ action_list = ["Back to parameter layer",
219
+ "Show run infos",
220
+ "Create jobs",
221
+ #"Execute created jobs",
222
+ #"Submit created jobs to remote host",
223
+ "Cancel jobs",
224
+ "Analyze data",
225
+ "Exit"]
226
+ rlc = NERA::RunLayerController.new( @path_db_folder, @simulator_class, @parameter_id)
227
+ unless rlc
228
+ Dialog::message("Table #{@path_db_folder}/#{@simulator_class.to_s}/#{@parameter_id} is not found.")
229
+ return :parameter_layer
230
+ end
231
+
232
+ selected = 0
233
+ Dir.chdir( rlc.path_to_run_layer) {
234
+ selected = Dialog::select_one_or_return_string( action_list, "Select one")
235
+ if selected.is_a?(String)
236
+ system( selected)
237
+ return :run_layer
238
+ end
239
+ }
240
+
241
+ case action_list[selected]
242
+ when "Back to parameter layer"
243
+ return :parameter_layer
244
+ when "Show run infos"
245
+ Dir.chdir( rlc.path_to_run_layer) {
246
+ system("less runs.yml")
247
+ }
248
+ return :run_layer
249
+ when "Create jobs"
250
+ num_job = Dialog::get_integer( "Input the number of jobs (must be equal or larget than zero)") { |i| i >= 0 }
251
+ return :run_layer if num_job == 0
252
+ num_run_per_job = Dialog::get_integer( "Input the number of runs per job (must be larger than zero)") { |i| i > 0 }
253
+ jobids = rlc.create_jobs( num_job, num_run_per_job)
254
+ str = jobids.join(", ")
255
+ Dialog::message( "The following jobs are newly created.\n#{str}")
256
+ return :run_layer
257
+ when "Execute created jobs"
258
+ =begin
259
+ header,list = rlc.not_finished_runs_list_in_csv
260
+ list = RunLayerController::get_created_runs_list( @db_folder, @model_id, @parameter_id)
261
+ selected = select_one( list, "Select a job to execute")
262
+ job_id = list[selected][:job_id]
263
+ stat = JobLayerController::execute_one( @db_folder, job_id)
264
+ if stat
265
+ $stderr.puts "Simulation finished successfully"
266
+ else
267
+ $stderr.puts "Simulation failed"
268
+ end
269
+ =end
270
+ return :run_layer
271
+ when "Submit created jobs to remote host"
272
+ =begin
273
+ header,list = rlc.not_finished_runs_list_in_csv
274
+ list.unshift("Cancel")
275
+ selected_jobs = Dialog::select_many( list, header)
276
+ unless selected_jobs.include?(0)
277
+ rc = RemoteConnector.new( @db_folder)
278
+ hosts = rc.hostnames
279
+ hosts.unshift("Cancel")
280
+ s = Dialog::select_one( hosts, "Select a host")
281
+ return :run_layer if s == 0
282
+ if rc.connect( hosts[s])
283
+ Dialog::message( rc.get_status)
284
+ action = Dialog::select_one( ["Transfer", "Transfer and Submit", "Cancel"], "Select action")
285
+ stat = nil
286
+ case action
287
+ when 0
288
+ stat = rc.transfer( selected_jobs)
289
+ Dialog::message("File transfer to #{hosts[s]} failed") unless stat
290
+ when 1
291
+ stat = rc.submit( selected_jobs)
292
+ Dialog::message("Submission to #{hosts[s]} failed") unless stat
293
+ when 2
294
+ end
295
+ Dialog::message("Completed successfully.") if stat
296
+ else
297
+ Dialog::message("Connection to #{hosts[s]} failed.")
298
+ end
299
+ end
300
+ =end
301
+ return :run_layer
302
+ when "Cancel jobs"
303
+ header,list = rlc.not_finished_jobs_list_in_csv
304
+ list.unshift("Cancel")
305
+ selected_jobs = Dialog::select_many( list, header).map do |num|
306
+ list[num].split(',')[0].to_i
307
+ end
308
+ unless selected_jobs.include?(0)
309
+ stat = rlc.cancel_jobs( selected_jobs)
310
+ if stat
311
+ str = selected_jobs.join(", ")
312
+ Dialog::message("The following jobs are successfully cancelled.\n#{str}")
313
+ else
314
+ Dialog::message("Cancellation failed.")
315
+ end
316
+ end
317
+ return :run_layer
318
+ when "Analyze data"
319
+ list = rlc.analysis_methods
320
+ list = [ "Cancel", "All"] + list
321
+ sel = Dialog.select_many( list, "Select numbers.")
322
+ if sel.include?(0)
323
+ return :run_layer
324
+ elsif sel.include?(1)
325
+ rlc.analyze_all
326
+ return :run_layer
327
+ else
328
+ sel.each do |i|
329
+ rlc.analyze( list[i])
330
+ end
331
+ return :run_layer
332
+ end
333
+ when "Exit"
334
+ return :exit
335
+ else
336
+ raise "Must not happen"
337
+ end
338
+ end
339
+
340
+ # --- action at job layer
341
+ def job_layer_action
342
+ $stdout.puts <<"HEADER"
343
+ ===============================================
344
+ --- in job layer ------------------------------
345
+ #{@path_db_folder} / Jobs
346
+ ===============================================
347
+ HEADER
348
+
349
+ action_list = ["Back to simulator layer",
350
+ "Show job infos",
351
+ "Cancel jobs",
352
+ "Include data",
353
+ "Exit"]
354
+ jlc = NERA::JobLayerController.new( @path_db_folder)
355
+
356
+ selected = 0
357
+ Dir.chdir( jlc.path_to_job_layer) {
358
+ selected = Dialog.select_one_or_return_string( action_list, "Select one")
359
+ if selected.is_a?(String)
360
+ system( selected)
361
+ return :job_layer
362
+ end
363
+ }
364
+
365
+ case action_list[selected]
366
+ when "Back to simulator layer"
367
+ return :simulator_layer
368
+ when "Show job infos"
369
+ Dir.chdir( jlc.path_to_job_layer) {
370
+ system("less jobs.yml")
371
+ }
372
+ return :job_layer
373
+ when "Cancel jobs"
374
+ header,list = jlc.not_finished_list_in_csv
375
+ list.unshift("Cancel")
376
+ selected_jobs = Dialog::select_many( list, header).map do |num|
377
+ list[num].split(',')[0].to_i
378
+ end
379
+ unless selected_jobs.include?(0)
380
+ stat = jlc.cancel_jobs( selected_jobs)
381
+ if stat
382
+ str = selected_jobs.join(", ")
383
+ Dialog::message("The following jobs are successfully cancelled.\n#{str}")
384
+ else
385
+ Dialog::message("Cancellation failed.")
386
+ end
387
+ end
388
+ return :job_layer
389
+ when "Include data"
390
+ list = jlc.include_list
391
+ list = ["Cancel","All"] + list
392
+ sel = Dialog::select_many( list)
393
+ status = nil
394
+ if sel.include?(0)
395
+ return :job_layer
396
+ elsif sel.include?(1)
397
+ status = jlc.include_all
398
+ else
399
+ sel.each do |num|
400
+ status = jlc.include( list[num])
401
+ end
402
+ end
403
+ if status
404
+ Dialog::message("Inclusion successfully completed.")
405
+ else
406
+ Dialog::message("Inclusion failed.")
407
+ end
408
+ return :job_layer
409
+ when "Exit"
410
+ return :exit
411
+ end
412
+ end
413
+
414
+
415
+ end
416
+ end
417
+