statemachine 1.2.0 → 2.0.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.
Files changed (141) hide show
  1. data/.gitignore +12 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +12 -0
  4. data/Rakefile +21 -20
  5. data/doc/website/README +6 -0
  6. data/doc/website/config.yaml +2 -0
  7. data/doc/website/index.html +39 -0
  8. data/doc/website/src/default.css +110 -0
  9. data/doc/website/src/default.template +41 -0
  10. data/doc/website/src/documentation.page +45 -0
  11. data/doc/website/src/example.page +13 -0
  12. data/doc/website/src/example1.page +59 -0
  13. data/doc/website/src/example2.page +96 -0
  14. data/doc/website/src/example3.page +76 -0
  15. data/doc/website/src/example4.page +65 -0
  16. data/doc/website/src/images/8l_star.png +0 -0
  17. data/doc/website/src/images/bg.png +0 -0
  18. data/doc/website/src/images/bottom_border.png +0 -0
  19. data/doc/website/src/images/bottom_edge.png +0 -0
  20. data/doc/website/src/images/examples/vending_machine.png +0 -0
  21. data/doc/website/src/images/examples/vending_machine2.png +0 -0
  22. data/doc/website/src/images/examples/vending_machine3.png +0 -0
  23. data/doc/website/src/images/examples/vending_machine4a.png +0 -0
  24. data/doc/website/src/images/examples/vending_machine4b.png +0 -0
  25. data/doc/website/src/images/left_edge.png +0 -0
  26. data/doc/website/src/images/logo.png +0 -0
  27. data/doc/website/src/images/right_edge.png +0 -0
  28. data/doc/website/src/images/side_borders.png +0 -0
  29. data/doc/website/src/index.page +20 -0
  30. data/generate_tests/dot_graph/turnstile.rb +29 -0
  31. data/generate_tests/dot_graph/turnstile2.rb +48 -0
  32. data/generate_tests/java/turnstile.rb +54 -0
  33. data/generate_tests/java/turnstile2.rb +72 -0
  34. data/lib/statemachine/action_invokation.rb +0 -19
  35. data/lib/statemachine/version.rb +2 -2
  36. data/rails_plugin/README +183 -0
  37. data/rails_plugin/Rakefile +11 -0
  38. data/rails_plugin/app/controllers/admin_controller.rb +43 -0
  39. data/rails_plugin/app/controllers/application.rb +7 -0
  40. data/rails_plugin/app/controllers/main_controller.rb +34 -0
  41. data/rails_plugin/app/helpers/admin_helper.rb +2 -0
  42. data/rails_plugin/app/helpers/application_helper.rb +3 -0
  43. data/rails_plugin/app/helpers/main_helper.rb +7 -0
  44. data/rails_plugin/app/models/product.rb +21 -0
  45. data/rails_plugin/app/models/vending_machine.rb +36 -0
  46. data/rails_plugin/app/models/vending_machine_interface.rb +101 -0
  47. data/rails_plugin/app/models/vending_statemachine.rb +41 -0
  48. data/rails_plugin/app/views/admin/index.rhtml +45 -0
  49. data/rails_plugin/app/views/layouts/main.rhtml +12 -0
  50. data/rails_plugin/app/views/main/_info.rhtml +13 -0
  51. data/rails_plugin/app/views/main/event.rjs +27 -0
  52. data/rails_plugin/app/views/main/index.rhtml +38 -0
  53. data/rails_plugin/config/boot.rb +45 -0
  54. data/rails_plugin/config/database.yml +21 -0
  55. data/rails_plugin/config/environment.rb +60 -0
  56. data/rails_plugin/config/environments/development.rb +21 -0
  57. data/rails_plugin/config/environments/production.rb +18 -0
  58. data/rails_plugin/config/environments/test.rb +19 -0
  59. data/rails_plugin/config/routes.rb +23 -0
  60. data/rails_plugin/db/migrate/001_create_vending_machines.rb +12 -0
  61. data/rails_plugin/db/migrate/002_create_products.rb +14 -0
  62. data/rails_plugin/db/migrate/003_add_position_to_products.rb +9 -0
  63. data/rails_plugin/db/schema.rb +20 -0
  64. data/rails_plugin/doc/README_FOR_APP +2 -0
  65. data/rails_plugin/lib/tasks/base.rake +5 -0
  66. data/rails_plugin/public/.htaccess +40 -0
  67. data/rails_plugin/public/404.html +30 -0
  68. data/rails_plugin/public/500.html +30 -0
  69. data/rails_plugin/public/dispatch.cgi +10 -0
  70. data/rails_plugin/public/dispatch.fcgi +24 -0
  71. data/rails_plugin/public/dispatch.rb +10 -0
  72. data/rails_plugin/public/favicon.ico +0 -0
  73. data/rails_plugin/public/images/bricks.jpg +0 -0
  74. data/rails_plugin/public/images/cash_release_button.png +0 -0
  75. data/rails_plugin/public/images/change.png +0 -0
  76. data/rails_plugin/public/images/dime.png +0 -0
  77. data/rails_plugin/public/images/dollar.png +0 -0
  78. data/rails_plugin/public/images/money_panel.png +0 -0
  79. data/rails_plugin/public/images/nickel.png +0 -0
  80. data/rails_plugin/public/images/quarter.png +0 -0
  81. data/rails_plugin/public/images/rails.png +0 -0
  82. data/rails_plugin/public/images/vending_machine_body.png +0 -0
  83. data/rails_plugin/public/index.html +277 -0
  84. data/rails_plugin/public/javascripts/application.js +2 -0
  85. data/rails_plugin/public/javascripts/controls.js +833 -0
  86. data/rails_plugin/public/javascripts/dragdrop.js +942 -0
  87. data/rails_plugin/public/javascripts/effects.js +1088 -0
  88. data/rails_plugin/public/javascripts/prototype.js +2515 -0
  89. data/rails_plugin/public/robots.txt +1 -0
  90. data/rails_plugin/public/stylesheets/layout.css +163 -0
  91. data/rails_plugin/script/about +3 -0
  92. data/rails_plugin/script/breakpointer +3 -0
  93. data/rails_plugin/script/console +3 -0
  94. data/rails_plugin/script/destroy +3 -0
  95. data/rails_plugin/script/generate +3 -0
  96. data/rails_plugin/script/performance/benchmarker +3 -0
  97. data/rails_plugin/script/performance/profiler +3 -0
  98. data/rails_plugin/script/plugin +3 -0
  99. data/rails_plugin/script/process/inspector +3 -0
  100. data/rails_plugin/script/process/reaper +3 -0
  101. data/rails_plugin/script/process/spawner +3 -0
  102. data/rails_plugin/script/rails_spec +11 -0
  103. data/rails_plugin/script/rails_spec_server +43 -0
  104. data/rails_plugin/script/runner +3 -0
  105. data/rails_plugin/script/server +3 -0
  106. data/rails_plugin/spec/controllers/admin_controller_spec.rb +7 -0
  107. data/rails_plugin/spec/controllers/main_controller_spec.rb +38 -0
  108. data/rails_plugin/spec/fixtures/products.yml +2 -0
  109. data/rails_plugin/spec/fixtures/vending_machines.yml +2 -0
  110. data/rails_plugin/spec/helpers/admin_helper_spec.rb +5 -0
  111. data/rails_plugin/spec/helpers/main_helper_spec.rb +5 -0
  112. data/rails_plugin/spec/models/product_spec.rb +16 -0
  113. data/rails_plugin/spec/models/vending_machine_interface_spec.rb +168 -0
  114. data/rails_plugin/spec/models/vending_machine_spec.rb +30 -0
  115. data/rails_plugin/spec/models/vending_statemachine_spec.rb +130 -0
  116. data/rails_plugin/spec/plugins/context_support_spec.rb +28 -0
  117. data/rails_plugin/spec/plugins/controller_support_spec.rb +98 -0
  118. data/rails_plugin/spec/spec.opts +1 -0
  119. data/rails_plugin/spec/spec_helper.rb +28 -0
  120. data/rails_plugin/spec/views/main/event_spec.rb +61 -0
  121. data/rails_plugin/vendor/plugins/statemachine/README +4 -0
  122. data/rails_plugin/vendor/plugins/statemachine/Rakefile +22 -0
  123. data/rails_plugin/vendor/plugins/statemachine/init.rb +2 -0
  124. data/rails_plugin/vendor/plugins/statemachine/install.rb +1 -0
  125. data/rails_plugin/vendor/plugins/statemachine/lib/context_support.rb +22 -0
  126. data/rails_plugin/vendor/plugins/statemachine/lib/controller_support.rb +85 -0
  127. data/rails_plugin/vendor/plugins/statemachine/lib/statemachine_on_rails.rb +11 -0
  128. data/rails_plugin/vendor/plugins/statemachine/tasks/statemachine_tasks.rake +4 -0
  129. data/spec/action_invokation_spec.rb +1 -1
  130. data/spec/builder_spec.rb +1 -1
  131. data/spec/default_transition_spec.rb +1 -1
  132. data/spec/generate/dot_graph/dot_graph_stagemachine_spec.rb +1 -1
  133. data/spec/history_spec.rb +1 -1
  134. data/spec/sm_action_parameterization_spec.rb +1 -1
  135. data/spec/sm_entry_exit_actions_spec.rb +1 -1
  136. data/spec/sm_odds_n_ends_spec.rb +1 -1
  137. data/spec/sm_simple_spec.rb +1 -1
  138. data/spec/sm_super_state_spec.rb +1 -1
  139. data/spec/sm_turnstile_spec.rb +1 -1
  140. data/spec/transition_spec.rb +1 -1
  141. metadata +162 -46
@@ -0,0 +1,11 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+
10
+ require 'tasks/rails'
11
+
@@ -0,0 +1,43 @@
1
+ class AdminController < ApplicationController
2
+ layout "main"
3
+
4
+ def index
5
+ @vending_machines = VendingMachine.find(:all)
6
+ end
7
+
8
+ def save
9
+ create_vending_machine
10
+
11
+ @vending_machines = VendingMachine.find(:all)
12
+ render :template => "/admin/index"
13
+ end
14
+
15
+ def delete
16
+ VendingMachine.find(params[:id]).destroy
17
+
18
+ @vending_machines = VendingMachine.find(:all)
19
+ render :template => "/admin/index"
20
+ end
21
+
22
+ private
23
+
24
+ def create_vending_machine
25
+ vending_machine = VendingMachine.new
26
+ vending_machine.location = params[:location]
27
+ vending_machine.cash = params[:cash].to_i
28
+
29
+ 8.times do |i|
30
+ name = params["name_#{i}".to_sym]
31
+ price = params["price_#{i}".to_sym].to_i
32
+ inventory = params["inventory_#{i}".to_sym].to_i
33
+ if name.length > 0
34
+ vending_machine.products << Product.new(:name => name,
35
+ :price => price,
36
+ :inventory => inventory
37
+ )
38
+ end
39
+ end
40
+ vending_machine.save!
41
+ end
42
+
43
+ end
@@ -0,0 +1,7 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ # Pick a unique cookie name to distinguish our session data from others'
6
+ session :session_key => '_rails_plugin_session_id'
7
+ end
@@ -0,0 +1,34 @@
1
+ require "vending_statemachine"
2
+
3
+ class MainController < ApplicationController
4
+
5
+ supported_by_statemachine VendingMachineInterface, lambda { VendingStatemachine.statemachine }
6
+
7
+ def index
8
+ return redirect_to("/admin") if (params[:id] == nil)
9
+ begin
10
+ @vending_machine = VendingMachine.find(params[:id])
11
+ rescue Exception => e
12
+ return redirect_to("/admin")
13
+ end
14
+ new_context
15
+ end
16
+
17
+ def insert_money
18
+ params[:event] = params[:id]
19
+ self.event
20
+ render :template => "/main/event", :layout => false
21
+ end
22
+
23
+ protected
24
+
25
+ def after_event
26
+ @vending_machine = @context.vending_machine
27
+ @vending_machine.save!
28
+ end
29
+
30
+ def initialize_context
31
+ @context.vending_machine = @vending_machine
32
+ end
33
+
34
+ end
@@ -0,0 +1,2 @@
1
+ module AdminHelper
2
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,7 @@
1
+ module MainHelper
2
+
3
+ def product_label(product)
4
+ return "#{product.name}<br/><span id=\"product_#{product.id}_price\">#{product.price_str}</span>"
5
+ end
6
+
7
+ end
@@ -0,0 +1,21 @@
1
+ class Product < ActiveRecord::Base
2
+ belongs_to :vending_machine
3
+ acts_as_list :scope => :vending_machine_id
4
+
5
+ def sold_out?
6
+ return self[:inventory] <= 0
7
+ end
8
+
9
+ def price_str
10
+ return sprintf("$%.2f", self[:price]/100.0)
11
+ end
12
+
13
+ def sold
14
+ self[:inventory] = self[:inventory] - 1
15
+ save!
16
+ end
17
+
18
+ def in_stock?
19
+ return self[:inventory] > 0
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ class VendingMachine < ActiveRecord::Base
2
+ has_many :products, :order => :position
3
+
4
+ def initialize(hash = nil)
5
+ super(hash)
6
+ self[:cash] = 0 if not self[:cash]
7
+ end
8
+
9
+ def add_product(inventory, name, price)
10
+ product = Product.new(:inventory => inventory, :name => name, :price => price)
11
+ products << product
12
+ return product
13
+ end
14
+
15
+ def max_price
16
+ max = 0
17
+ self.products.each { |product| max = product.price if product.price > max }
18
+ return max
19
+ end
20
+
21
+ def add_cash(amount)
22
+ self[:cash] = self[:cash] + amount
23
+ end
24
+
25
+ def cash_str
26
+ return sprintf("$%.2f", self[:cash]/100.0)
27
+ end
28
+
29
+ def product_with_id(id)
30
+ products.each do |product|
31
+ return product if product.id.to_s == id.to_s
32
+ end
33
+ raise Exception.new("No product found with id: #{id}")
34
+ end
35
+
36
+ end
@@ -0,0 +1,101 @@
1
+ class VendingMachineInterface
2
+
3
+ include Statemachine::ContextSupport
4
+
5
+ attr_reader :amount_tendered, :accepting_money, :dispensed_item, :change
6
+ attr_accessor :vending_machine
7
+
8
+ def initialize
9
+ @amount_tendered = 0
10
+ @accepting_money = true
11
+ end
12
+
13
+ def message
14
+ if @amount_tendered <= 0
15
+ return "Insert Money"
16
+ elsif not @accepting_money
17
+ return "Select Item"
18
+ else
19
+ return sprintf("$%.2f", @amount_tendered/100.0)
20
+ end
21
+ end
22
+
23
+ def affordable_items
24
+ return @vending_machine.products.reject { |product| product.sold_out? or product.price > @amount_tendered }
25
+ end
26
+
27
+ def non_affordable_items
28
+ return @vending_machine.products.reject { |product| product.sold_out? or product.price <= @amount_tendered }
29
+ end
30
+
31
+ def sold_out_items
32
+ return @vending_machine.products.reject { |product| !product.sold_out? }
33
+ end
34
+
35
+ def add_dollar
36
+ @amount_tendered = @amount_tendered + 100
37
+ end
38
+
39
+ def add_quarter
40
+ @amount_tendered = @amount_tendered + 25
41
+ end
42
+
43
+ def add_dime
44
+ @amount_tendered = @amount_tendered + 10
45
+ end
46
+
47
+ def add_nickel
48
+ @amount_tendered = @amount_tendered + 5
49
+ end
50
+
51
+ def check_max_price
52
+ if @amount_tendered >= @vending_machine.max_price
53
+ @statemachine.process_event(:reached_max_price)
54
+ end
55
+ end
56
+
57
+ def accept_money
58
+ @accepting_money = true
59
+ end
60
+
61
+ def refuse_money
62
+ @accepting_money = false
63
+ end
64
+
65
+ def load_product(id)
66
+ @selected_product = @vending_machine.product_with_id(id)
67
+ end
68
+
69
+ def check_affordability
70
+ if @amount_tendered >= @selected_product.price and @selected_product.in_stock?
71
+ @statemachine.accept_purchase
72
+ else
73
+ @statemachine.refuse_purchase
74
+ end
75
+ end
76
+
77
+ def make_sale
78
+ @dispensed_item = @selected_product
79
+ change_pennies = @amount_tendered - @selected_product.price
80
+ @change = sprintf("$%.2f", change_pennies/100.0)
81
+ @amount_tendered = 0
82
+ @selected_product.sold
83
+ @vending_machine.add_cash @selected_product.price
84
+ @accepting_money = true
85
+ end
86
+
87
+ def dispense_change
88
+ @change = sprintf("$%.2f", @amount_tendered/100.0)
89
+ @amount_tendered = 0
90
+ end
91
+
92
+ def clear_dispensers
93
+ @dispensed_item = nil
94
+ @change = nil
95
+ end
96
+
97
+ def load_and_make_sale(id)
98
+ load_product(id)
99
+ make_sale
100
+ end
101
+ end
@@ -0,0 +1,41 @@
1
+ module VendingStatemachine
2
+
3
+ def self.statemachine
4
+ return Statemachine.build do
5
+ startstate :standby
6
+ superstate :accepting_money do
7
+ on_entry :accept_money
8
+ on_exit :refuse_money
9
+ event :dollar, :collecting_money, :add_dollar
10
+ event :quarter, :collecting_money, :add_quarter
11
+ event :dime, :collecting_money, :add_dime
12
+ event :nickel, :collecting_money, :add_nickel
13
+ state :standby do
14
+ on_exit :clear_dispensers
15
+ event :selection, :standby
16
+ event :release_money, :standby
17
+ end
18
+ state :collecting_money do
19
+ on_entry :check_max_price
20
+ event :reached_max_price, :max_price_tendered
21
+ event :selection, :validating_purchase, :load_product
22
+ event :release_money, :standby, :dispense_change
23
+ end
24
+ state :validating_purchase do
25
+ on_entry :check_affordability
26
+ event :accept_purchase, :standby, :make_sale
27
+ event :refuse_purchase, :collecting_money
28
+ end
29
+ end
30
+ state :max_price_tendered do
31
+ event :selection, :standby, :load_and_make_sale
32
+ event :dollar, :max_price_tendered
33
+ event :quarter, :max_price_tendered
34
+ event :dime, :max_price_tendered
35
+ event :nickel, :max_price_tendered
36
+ event :release_money, :standby, :dispense_change
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,45 @@
1
+ <div style="float: left; width: 50%; text-align: center; font-size: 1.5em;">
2
+ <h3>Vending Machines</h3>
3
+ <table width="100%" cellspacing="0" cellpadding="0">
4
+ <tr>
5
+ <th>Id</th>
6
+ <th>Location</th>
7
+ <th>Cash</th>
8
+ <th>Products</th>
9
+ <th>Delete</th>
10
+ </tr>
11
+ <% @vending_machines.each do |vending_machine| %>
12
+ <tr>
13
+ <td><%= vending_machine.id %></td>
14
+ <td><%= link_to vending_machine.location, :action => "index", :controller => "main", :id => vending_machine.id %></td>
15
+ <td><%= vending_machine.cash_str %></td>
16
+ <td><%= vending_machine.products.length %></td>
17
+ <td><%= link_to "delete", :action => "delete", :id => vending_machine.id %>
18
+ </tr>
19
+ <% end %>
20
+ </table>
21
+ </div>
22
+ <div style="float: right; width: 50%;">
23
+ <h3>Create New Vending Machine</h3>
24
+ <%= form_tag :action => "save" %>
25
+ Location: <input type="text" name="location"><br />
26
+ Cash (in pennies): <input type="text" name="cash"><br />
27
+ <table width="100%" cellspacing="0" cellpadding="0">
28
+ <tr>
29
+ <th></th>
30
+ <th>Name</th>
31
+ <th>Price (in pennies)</th>
32
+ <th>Inventory</th>
33
+ </tr>
34
+ <% 8.times do |i| %>
35
+ <tr>
36
+ <td>Product #<%= i + 1 %></td>
37
+ <td><input type="text" name="name_<%= i %>"></td>
38
+ <td><input type="text" name="price_<%= i %>"></td>
39
+ <td><input type="text" name="inventory_<%= i %>"></td>
40
+ </tr>
41
+ <% end %>
42
+ </table>
43
+ <%= submit_tag "Save" %>
44
+ <%= end_form_tag %>
45
+ </div>
@@ -0,0 +1,12 @@
1
+ <html>
2
+ <head>
3
+ <title>Statemachine Vending</title>
4
+ <%= stylesheet_link_tag "layout", :media => "all" %>
5
+ <%= javascript_include_tag "prototype", "effects", "dragdrop", "controls" %>
6
+ </head>
7
+ <body>
8
+
9
+ <%= @content_for_layout %>
10
+
11
+ </body>
12
+ </html>
@@ -0,0 +1,13 @@
1
+ <h3>Info</h3>
2
+ <b>Location</b> <%= @vending_machine.location %> <br />
3
+ <b>Cash:</b> <%= @vending_machine.cash_str %> <br />
4
+ <table border="0" cellspacing="10" cellpadding="0">
5
+ <tr><th>Product</th><th>Price</th><th>Inventory</th></tr>
6
+ <% @vending_machine.products.each do |product| %>
7
+ <tr>
8
+ <td><%= product.name %></td>
9
+ <td><%= product.price_str %></td>
10
+ <td><%= product.inventory %></td>
11
+ </tr>
12
+ <% end %>
13
+ </table>
@@ -0,0 +1,27 @@
1
+ page.replace_html "quartz_screen", @context.message
2
+
3
+ @context.affordable_items.each do |product|
4
+ page << "document.getElementById('product_#{product.id}').className = 'affordable';"
5
+ end
6
+
7
+ @context.non_affordable_items.each do |product|
8
+ page << "document.getElementById('product_#{product.id}').className = 'non_affordable';"
9
+ end
10
+
11
+ @context.sold_out_items.each do |product|
12
+ page.replace_html "product_#{product.id}_price", "<span style=\"color: red;\">SOLD OUT</span>"
13
+ end
14
+
15
+ if @context.dispensed_item
16
+ page.replace_html "dispenser", "<p>#{@context.dispensed_item.name}</p>"
17
+ page.show "dispenser"
18
+ page.visual_effect :fade, "dispenser", :duration => 3
19
+ end
20
+
21
+ if @context.change
22
+ page.replace_html "change_amount", "<p>#{@context.change}</p>"
23
+ page.show "change_amount"
24
+ page.visual_effect :fade, "change_amount", :duration => 3
25
+ end
26
+
27
+ page.replace_html "info", :partial => "main/info"
@@ -0,0 +1,38 @@
1
+
2
+ <img id="vending_machine_body" src="/images/vending_machine_body.png">
3
+ <div id="links"><%= link_to "Manage Vending Machines", :action => "index", :controller => "admin" %></div>
4
+ <img id="money_panel" src="/images/money_panel.png">
5
+ <%= link_to_remote '<img src="/images/cash_release_button.png">',
6
+ {:url => { :action => "event", :event => "release_money"}},
7
+ { :id => "cash_release_button"} %>
8
+ <div id="product_list">
9
+ <% @vending_machine.products.each do |product| %>
10
+ <%= link_to_remote product_label(product),
11
+ {:url => { :action => "event", :event => "selection", :arg => product.id }},
12
+ { :id => "product_#{product.id}", :class => "non_affordable" } %>
13
+ <% end %>
14
+ </div>
15
+ <img id="change" src="/images/change.png">
16
+ <div id="change_amount"></div>
17
+ <div id="cash">
18
+ <h3>Cash</h3>
19
+ (drag and drop the money)<br/>
20
+ <img id="dollar" class="money" src="/images/dollar.png"><br/>
21
+ <img id="quarter" class="money" src="/images/quarter.png">
22
+ <img id="dime" class="money" src="/images/dime.png">
23
+ <img id="nickel" class="money" src="/images/nickel.png">
24
+ </div>
25
+
26
+ <div id="quartz_screen">Insert Money</div>
27
+ <div id="dispenser"></div>
28
+ <div id="info">
29
+ <%= render :partial => "info" %>
30
+ </div>
31
+
32
+ <%= draggable_element "dollar", :revert => true %>
33
+ <%= draggable_element "quarter", :revert => true %>
34
+ <%= draggable_element "dime", :revert => true %>
35
+ <%= draggable_element "nickel", :revert => true %>
36
+ <%= drop_receiving_element "money_panel",
37
+ :url => { :action => "insert_money" },
38
+ :accept => "money", :hoverclass => "money_active" %>