arrayfu 0.0.8 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/arrayfu.gemspec +0 -0
  3. data/lib/arrayfu/array_definition.rb +84 -0
  4. data/lib/arrayfu/arrayfu.rb +31 -0
  5. data/lib/arrayfu/generate_mutators.rb +28 -0
  6. data/lib/arrayfu/{readable_step.rb → generate_readers.rb} +6 -4
  7. data/lib/arrayfu/generate_visitors.rb +18 -0
  8. data/lib/arrayfu/{writeable_step.rb → generate_writers.rb} +6 -4
  9. data/lib/arrayfu/initializer.rb +21 -0
  10. data/lib/arrayfu/item_constraint.rb +17 -0
  11. data/lib/arrayfu/module_registry.rb +9 -7
  12. data/lib/arrayfu/mutator_definition.rb +15 -0
  13. data/lib/arrayfu/version.rb +1 -1
  14. data/lib/arrayfu/visitor_definition.rb +19 -0
  15. data/lib/arrayfu.rb +10 -9
  16. data/spec/examples/{instance_usage.rb → usage.rb} +169 -72
  17. data/spec/specs/{dsl_spec.rb → array_definition_spec.rb} +20 -22
  18. data/spec/specs/dsl_usage_spec.rb +86 -52
  19. data/spec/specs/{mutator_step_spec.rb → generate_mutators_spec.rb} +5 -5
  20. data/spec/specs/{readable_step_spec.rb → generate_readers_spec.rb} +3 -3
  21. data/spec/specs/{visitor_detail_step_spec.rb → generate_visitors_spec.rb} +5 -5
  22. data/spec/specs/{writeable_step_spec.rb → generate_writers_step_spec.rb} +3 -3
  23. data/spec/specs/{object_extensions_spec.rb → initializer_spec.rb} +4 -1
  24. data/spec/specs/{add_criterion_spec.rb → item_constraint_spec.rb} +11 -11
  25. data/spec/specs/sample.rb +2 -0
  26. metadata +28 -29
  27. data/lib/arrayfu/add_criterion.rb +0 -16
  28. data/lib/arrayfu/dsl.rb +0 -43
  29. data/lib/arrayfu/mutator_detail.rb +0 -10
  30. data/lib/arrayfu/mutator_step.rb +0 -18
  31. data/lib/arrayfu/object_extensions.rb +0 -27
  32. data/lib/arrayfu/visitor_detail.rb +0 -10
  33. data/lib/arrayfu/visitor_detail_step.rb +0 -14
  34. data/spec/examples/class_usage.rb +0 -210
@@ -1,15 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe Dsl do
4
+ describe ArrayDefinition do
5
5
  context "using the dsl" do
6
6
  it "should be able to initialize all arrays specified on the instance and provide a method to expose addition" do
7
7
  class Item
8
+ include ArrayFu
9
+
10
+ array :kids do|a|
11
+ a.readable
12
+ a.mutator :register_child
13
+ end
8
14
 
9
15
  def initialize
10
- array :kids do|a|
11
- a.mutator :register_child
12
- end
16
+ initialize_arrayfu
13
17
  end
14
18
  end
15
19
 
@@ -20,18 +24,21 @@ module ArrayFu
20
24
  end
21
25
  it "should be able to expose a mutator with custom logic" do
22
26
  class Item
27
+ include ArrayFu
23
28
  attr_accessor :added,:item_added
24
29
 
30
+ array :kids do|a|
31
+ a.readable
32
+ a.mutator :register_child do|the_item|
33
+ @item_added = the_item
34
+ @added +=1
35
+ @kids.push(the_item)
36
+ end
37
+ end
38
+
25
39
  def initialize
26
40
  @added = 0
27
-
28
- array :kids do|a|
29
- a.mutator :register_child do|the_item|
30
- @item_added = the_item
31
- @added +=1
32
- @kids.push(the_item)
33
- end
34
- end
41
+ initialize_arrayfu
35
42
  end
36
43
  end
37
44
 
@@ -43,20 +50,11 @@ module ArrayFu
43
50
  end
44
51
 
45
52
  it "should be able to expose a processing visitor" do
46
- class Item
47
- attr_accessor :added
48
-
49
- def initialize(visitor)
50
- @added = 0
51
- array :kids do|a|
52
- a.mutator :register_child
53
- a.process_using :register_kids,visitor
54
- end
55
- end
56
- end
57
-
58
53
  class OurVisitor
54
+ include Singleton
55
+
59
56
  attr_accessor :items
57
+
60
58
  def initialize
61
59
  @items = 0
62
60
  end
@@ -65,24 +63,42 @@ module ArrayFu
65
63
  end
66
64
  end
67
65
 
68
- our_visitor = OurVisitor.new
69
- item = Item.new(our_visitor)
66
+ class Item
67
+ include ArrayFu
68
+ attr_accessor :added
69
+
70
+ array :kids do|a|
71
+ a.mutator :register_child
72
+ a.process_using :register_kids, OurVisitor.instance
73
+ end
74
+
75
+ def initialize
76
+ @added = 0
77
+ initialize_arrayfu
78
+ end
79
+ end
80
+
81
+
82
+ item = Item.new
70
83
  item.register_child("hello")
71
84
  item.kids.count.should == 1
72
85
  item.register_kids
73
- our_visitor.items.should == 1
86
+ OurVisitor.instance.items.should == 1
74
87
  end
75
88
 
76
89
  it "should be able to expose a processing visitor by symbol" do
77
90
  class Item
91
+ include ArrayFu
78
92
  attr_accessor :added
79
93
 
94
+ array :kids do|a|
95
+ a.mutator :register_child
96
+ a.process_using :register_kids,:speak
97
+ end
98
+
80
99
  def initialize
81
100
  @added = 0
82
- array :kids do|a|
83
- a.mutator :register_child
84
- a.process_using :register_kids,:speak
85
- end
101
+ initialize_arrayfu
86
102
  end
87
103
  end
88
104
 
@@ -108,11 +124,15 @@ module ArrayFu
108
124
  context "and no block is provided" do
109
125
  it "should expose the specified method to trigger addition" do
110
126
  class Item
127
+ include ArrayFu
128
+
129
+ array :kids do|a|
130
+ a.readable
131
+ a.mutator :register_child
132
+ end
111
133
 
112
134
  def initialize
113
- array :kids do|a|
114
- a.mutator :register_child
115
- end
135
+ initialize_arrayfu
116
136
  end
117
137
  end
118
138
 
@@ -126,17 +146,19 @@ module ArrayFu
126
146
  context "and a block is provided" do
127
147
  it "should provide a method that delegates to the block when invoked" do
128
148
  class Item
149
+ include ArrayFu
129
150
  attr_accessor :added
130
151
 
152
+ array :kids do|a|
153
+ a.mutator :register_child do|item|
154
+ @kids.push(item)
155
+ @added+=1
156
+ end
157
+ end
158
+
131
159
  def initialize
132
160
  @added = 0
133
-
134
- array :kids do|a|
135
- a.mutator :register_child do|item|
136
- @kids.push(item)
137
- @added+=1
138
- end
139
- end
161
+ initialize_arrayfu
140
162
  end
141
163
  end
142
164
 
@@ -149,27 +171,34 @@ module ArrayFu
149
171
 
150
172
 
151
173
  context "when criterias have been specified on the array" do
152
- class BeGreaterThanZero
174
+ module BeGreaterThanZero
175
+ extend self
153
176
  def name
154
177
  return "Be greater than 0"
155
178
  end
156
- def is_satisfied_by(item)
179
+ def matches?(item)
157
180
  return item > 0
158
181
  end
159
182
  end
160
183
  context "and the criteria is not met" do
161
184
  context "and the failure strategy is set to raise an error" do
162
- class RaiseCriteriaFailure
185
+ module RaiseCriteriaFailure
186
+ extend self
163
187
  def run(name,value)
164
188
  raise "The value #{value} does not meet the criteria #{name}"
165
189
  end
166
190
  end
167
191
  class OneClass
192
+ include ArrayFu
193
+
194
+ array :items do|a|
195
+ a.readable
196
+ a.mutator :add_item,:add_this,:add_that
197
+ a.new_item_must BeGreaterThanZero, RaiseCriteriaFailure
198
+ end
199
+
168
200
  def initialize
169
- array :items do|a|
170
- a.mutator :add_item,:add_this,:add_that
171
- a.new_item_must BeGreaterThanZero.new, RaiseCriteriaFailure.new
172
- end
201
+ initialize_arrayfu
173
202
  end
174
203
  end
175
204
  let(:target){OneClass.new}
@@ -196,11 +225,16 @@ module ArrayFu
196
225
  end
197
226
  end
198
227
  class AnotherClass
228
+ include ArrayFu
229
+
230
+ array :items do|a|
231
+ a.readable
232
+ a.mutator :add_item,:add_this,:add_that
233
+ a.new_item_must BeGreaterThanZero, DisplayCriteriaFailure.instance
234
+ end
235
+
199
236
  def initialize
200
- array :items do|a|
201
- a.mutator :add_item,:add_this,:add_that
202
- a.new_item_must BeGreaterThanZero.new, DisplayCriteriaFailure.instance
203
- end
237
+ initialize_arrayfu
204
238
  end
205
239
  end
206
240
  let(:target){AnotherClass.new}
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe MutatorStep do
4
+ describe GenerateMutators do
5
5
  context "when run" do
6
6
  let(:numbers){[]}
7
7
  let(:target){Sample.new(numbers)}
8
8
  let(:mutators){[]}
9
- let(:sut){MutatorStep.new}
10
- let(:builder){Dsl.new(:numbers)}
9
+ let(:sut){GenerateMutators}
10
+ let(:builder){ArrayDefinition.new(:numbers)}
11
11
 
12
12
  context "using a dsl fragment that contains no block usage" do
13
13
  before (:each) do
@@ -24,7 +24,7 @@ module ArrayFu
24
24
  end
25
25
  context "using a dsl fragment that contains block usage" do
26
26
  before (:each) do
27
- builder.mutator(:add_a_number) do|value|
27
+ builder.mutator :add_a_number do|value|
28
28
  @value_attempted_to_be_added = value
29
29
  end
30
30
  end
@@ -35,7 +35,7 @@ module ArrayFu
35
35
  target.respond_to?(:add_a_number).should be_true
36
36
  target.add_a_number(2)
37
37
  numbers.count.should == 0
38
- @value_attempted_to_be_added.should == 2
38
+ target.value_attempted_to_be_added.should == 2
39
39
  end
40
40
  end
41
41
 
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe ReadableStep do
4
+ describe GenerateReaders do
5
5
  context "when run" do
6
6
  let(:target){Sample.new}
7
7
  let(:mutators){[]}
8
- let(:sut){ReadableStep.new}
9
- let(:builder){Dsl.new(:numbers)}
8
+ let(:sut){GenerateReaders}
9
+ let(:builder){ArrayDefinition.new(:numbers)}
10
10
 
11
11
  context "using a dsl fragment that contains no block usage" do
12
12
  before (:each) do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe VisitorDetailStep do
4
+ describe GenerateVisitors do
5
5
  class OurSet
6
6
  attr_accessor :items
7
7
 
@@ -26,8 +26,8 @@ module ArrayFu
26
26
  let(:target){OurSet.new}
27
27
  let(:mutators){[]}
28
28
  let(:invocations){[]}
29
- let(:sut){VisitorDetailStep.new}
30
- let(:builder){Dsl.new(:items)}
29
+ let(:sut){GenerateVisitors}
30
+ let(:builder){ArrayDefinition.new(:items)}
31
31
  before (:each) do
32
32
  (1..10).each{|item| target.add(Speak.new(invocations))}
33
33
  builder.process_using(:run,:hello)
@@ -55,8 +55,8 @@ module ArrayFu
55
55
  let(:visitor){TheVisitor.new}
56
56
  let(:mutators){[]}
57
57
  let(:invocations){[]}
58
- let(:sut){VisitorDetailStep.new}
59
- let(:builder){Dsl.new(:items)}
58
+ let(:sut){GenerateVisitors}
59
+ let(:builder){ArrayDefinition.new(:items)}
60
60
 
61
61
  before (:each) do
62
62
  (1..10).each{|item| target.add(item)}
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe WriteableStep do
4
+ describe GenerateWriters do
5
5
  context "when run" do
6
6
  context "using a dsl fragment that contains no block usage" do
7
7
  let(:target){Sample.new}
8
8
  let(:mutators){[]}
9
- let(:sut){WriteableStep.new}
10
- let(:builder){Dsl.new(:numbers)}
9
+ let(:sut){GenerateWriters}
10
+ let(:builder){ArrayDefinition.new(:numbers)}
11
11
  before (:each) do
12
12
  builder.writable
13
13
  end
@@ -1,9 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Object do
3
+ describe ArrayFu::Initializer do
4
4
  context "when initializing fields with defaults" do
5
5
  it "should initialize based on the factory provided" do
6
6
  class Item
7
+ include ArrayFu::Initializer
7
8
  attr_accessor :kids,:cars,:name
8
9
 
9
10
  def initialize
@@ -21,6 +22,7 @@ describe Object do
21
22
  context "when initializing simple arrays" do
22
23
  it "should initialize all arrays specified on the instance" do
23
24
  class Item
25
+ include ArrayFu::Initializer
24
26
  attr_accessor :kids,:cars,:bikes
25
27
 
26
28
  def initialize
@@ -38,6 +40,7 @@ describe Object do
38
40
  context "when initializing hashes" do
39
41
  it "should initialize all hashes specified" do
40
42
  class Item
43
+ include ArrayFu::Initializer
41
44
  attr_accessor :kids,:cars,:bikes
42
45
 
43
46
  def initialize
@@ -1,31 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module ArrayFu
4
- describe AddCriterion do
4
+ describe ItemConstraint do
5
5
  context "when applied to a value" do
6
6
  let(:failure_strategy){fake}
7
- let(:criteria){fake}
7
+ let(:constraint){fake}
8
8
  let(:value){42}
9
- let(:name){"Name of criteria"}
10
- let(:sut){AddCriterion.new(criteria,failure_strategy)}
9
+ let(:name){"Name of constraint"}
10
+ let(:sut){ItemConstraint.new(constraint, failure_strategy)}
11
11
 
12
- context "and the value does not match the criteria" do
12
+ context "and the value does not match the constraint" do
13
13
  before (:each) do
14
- criteria.stub(:is_satisfied_by).with(value).and_return(false)
15
- criteria.stub(:name).and_return(name)
14
+ constraint.stub(:matches?).with(value).and_return(false)
15
+ constraint.stub(:name).and_return(name)
16
16
  end
17
17
  before (:each) do
18
18
  sut.apply_to(value)
19
19
  end
20
20
  it "should run the failure strategy with the correct information" do
21
- failure_strategy.should have_received(:run,name,value)
21
+ failure_strategy.should have_received(:run, name, value)
22
22
  end
23
23
  end
24
24
 
25
- context "and the value matches the criteria" do
25
+ context "and the value matches the constraint" do
26
26
  before (:each) do
27
- criteria.stub(:is_satisfied_by).with(value).and_return(true)
28
- criteria.stub(:name).and_return(name)
27
+ constraint.stub(:matches?).with(value).and_return(true)
28
+ constraint.stub(:name).and_return(name)
29
29
  end
30
30
  before (:each) do
31
31
  @result = sut.apply_to(value)
data/spec/specs/sample.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  class Sample
2
+ attr_reader :value_attempted_to_be_added
3
+
2
4
  def initialize(numbers = [])
3
5
  @numbers = numbers
4
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arrayfu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Develop With Passion®
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-24 00:00:00.000000000 Z
11
+ date: 2013-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -79,29 +79,29 @@ files:
79
79
  - Rakefile
80
80
  - arrayfu.gemspec
81
81
  - lib/arrayfu.rb
82
- - lib/arrayfu/add_criterion.rb
83
- - lib/arrayfu/dsl.rb
82
+ - lib/arrayfu/array_definition.rb
83
+ - lib/arrayfu/arrayfu.rb
84
+ - lib/arrayfu/generate_mutators.rb
85
+ - lib/arrayfu/generate_readers.rb
86
+ - lib/arrayfu/generate_visitors.rb
87
+ - lib/arrayfu/generate_writers.rb
88
+ - lib/arrayfu/initializer.rb
89
+ - lib/arrayfu/item_constraint.rb
84
90
  - lib/arrayfu/module_registry.rb
85
- - lib/arrayfu/mutator_detail.rb
86
- - lib/arrayfu/mutator_step.rb
87
- - lib/arrayfu/object_extensions.rb
88
- - lib/arrayfu/readable_step.rb
91
+ - lib/arrayfu/mutator_definition.rb
89
92
  - lib/arrayfu/version.rb
90
- - lib/arrayfu/visitor_detail.rb
91
- - lib/arrayfu/visitor_detail_step.rb
92
- - lib/arrayfu/writeable_step.rb
93
- - spec/examples/class_usage.rb
94
- - spec/examples/instance_usage.rb
93
+ - lib/arrayfu/visitor_definition.rb
94
+ - spec/examples/usage.rb
95
95
  - spec/spec_helper.rb
96
- - spec/specs/add_criterion_spec.rb
97
- - spec/specs/dsl_spec.rb
96
+ - spec/specs/array_definition_spec.rb
98
97
  - spec/specs/dsl_usage_spec.rb
99
- - spec/specs/mutator_step_spec.rb
100
- - spec/specs/object_extensions_spec.rb
101
- - spec/specs/readable_step_spec.rb
98
+ - spec/specs/generate_mutators_spec.rb
99
+ - spec/specs/generate_readers_spec.rb
100
+ - spec/specs/generate_visitors_spec.rb
101
+ - spec/specs/generate_writers_step_spec.rb
102
+ - spec/specs/initializer_spec.rb
103
+ - spec/specs/item_constraint_spec.rb
102
104
  - spec/specs/sample.rb
103
- - spec/specs/visitor_detail_step_spec.rb
104
- - spec/specs/writeable_step_spec.rb
105
105
  homepage: http://www.developwithpassion.com
106
106
  licenses: []
107
107
  metadata: {}
@@ -126,15 +126,14 @@ signing_key:
126
126
  specification_version: 4
127
127
  summary: Simple DSL For Declaritive Arrays
128
128
  test_files:
129
- - spec/examples/class_usage.rb
130
- - spec/examples/instance_usage.rb
129
+ - spec/examples/usage.rb
131
130
  - spec/spec_helper.rb
132
- - spec/specs/add_criterion_spec.rb
133
- - spec/specs/dsl_spec.rb
131
+ - spec/specs/array_definition_spec.rb
134
132
  - spec/specs/dsl_usage_spec.rb
135
- - spec/specs/mutator_step_spec.rb
136
- - spec/specs/object_extensions_spec.rb
137
- - spec/specs/readable_step_spec.rb
133
+ - spec/specs/generate_mutators_spec.rb
134
+ - spec/specs/generate_readers_spec.rb
135
+ - spec/specs/generate_visitors_spec.rb
136
+ - spec/specs/generate_writers_step_spec.rb
137
+ - spec/specs/initializer_spec.rb
138
+ - spec/specs/item_constraint_spec.rb
138
139
  - spec/specs/sample.rb
139
- - spec/specs/visitor_detail_step_spec.rb
140
- - spec/specs/writeable_step_spec.rb
@@ -1,16 +0,0 @@
1
- module ArrayFu
2
- class AddCriterion
3
- attr_accessor :criteria,:failure_strategy
4
-
5
- def initialize(criteria,failure_strategy)
6
- @criteria = criteria
7
- @failure_strategy = failure_strategy
8
- end
9
-
10
- def apply_to(value)
11
- result = @criteria.is_satisfied_by(value)
12
- @failure_strategy.run(@criteria.name,value) unless result
13
- return result
14
- end
15
- end
16
- end
data/lib/arrayfu/dsl.rb DELETED
@@ -1,43 +0,0 @@
1
- module ArrayFu
2
- class Dsl
3
- attr_accessor :mutators,:visitors,:criteria,:name,:writable,:readable
4
-
5
- def initialize(name)
6
- @name = name
7
- initialize_arrays :mutators,:visitors,:criteria
8
- initialize_false :writable,:readable
9
- end
10
-
11
- def mutator(*names,&block)
12
- names.each{|name| @mutators.push(MutatorDetail.new(name,block))}
13
- end
14
-
15
- def new_item_must(criteria,fail_option)
16
- @criteria.push(AddCriterion.new(criteria,fail_option))
17
- end
18
-
19
- def process_using(name,visitor)
20
- @visitors.push(VisitorDetail.new(name,visitor))
21
- end
22
-
23
- def read_and_write
24
- writable
25
- readable
26
- end
27
-
28
- def writable
29
- @writable = true
30
- end
31
-
32
- def readable
33
- @readable = true
34
- end
35
-
36
- def configure_using(*configurators)
37
- configurators.each do|configurator|
38
- method = configurator.respond_to?(:configure) ? :configure : 'call'.to_sym
39
- configurator.send(method,self)
40
- end
41
- end
42
- end
43
- end
@@ -1,10 +0,0 @@
1
- module ArrayFu
2
- class MutatorDetail
3
- attr_accessor :name,:block
4
-
5
- def initialize(name,block)
6
- @name = name
7
- @block = block
8
- end
9
- end
10
- end
@@ -1,18 +0,0 @@
1
- module ArrayFu
2
- class MutatorStep
3
- def create_using(builder)
4
- Module.new do
5
- builder.mutators.each do|mutator|
6
- define_method(mutator.name) do|value|
7
- array_var = instance_variable_get("@#{builder.name}")
8
- continue_add = true
9
- builder.criteria.each{|criteria| continue_add &= criteria.apply_to(value)}
10
- return unless continue_add
11
- array_var.push(value) unless mutator.block
12
- mutator.block.call(value) if mutator.block
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,27 +0,0 @@
1
- class Object
2
- def initialize_defaults(factory,*items)
3
- items.each do|item|
4
- instance_variable_set("@#{item}",factory.call)
5
- end
6
- end
7
-
8
- def initialize_arrays(*items)
9
- initialize_defaults(lambda{[]},*items)
10
- end
11
-
12
- def initialize_hashes(*items)
13
- initialize_defaults(lambda{{}},*items)
14
- end
15
-
16
- def initialize_false(*items)
17
- initialize_defaults(lambda{false},*items)
18
- end
19
-
20
- def array(name,&block)
21
- initialize_arrays(name)
22
- dsl = ArrayFu::Dsl.new(name)
23
- yield dsl if block_given?
24
- ArrayFu::ModuleRegistry.configure(self,dsl)
25
- end
26
-
27
- end
@@ -1,10 +0,0 @@
1
- module ArrayFu
2
- class VisitorDetail
3
- attr_accessor :name,:visitor
4
-
5
- def initialize(name,visitor)
6
- @name = name
7
- @visitor = visitor
8
- end
9
- end
10
- end
@@ -1,14 +0,0 @@
1
- module ArrayFu
2
- class VisitorDetailStep
3
- def create_using(builder)
4
- Module.new do
5
- builder.visitors.each do|visitor|
6
- define_method(visitor.name) do
7
- array_var = instance_variable_get("@#{builder.name}")
8
- array_var.each{|item| visitor.visitor.respond_to?(:run_using) ? visitor.visitor.run_using(item) : item.send(visitor.visitor)}
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end