datagrid 1.6.1 → 1.6.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/datagrid.gemspec +26 -164
- data/lib/datagrid/columns.rb +5 -10
- data/lib/datagrid/filters.rb +3 -6
- data/lib/datagrid/filters/base_filter.rb +8 -0
- data/lib/datagrid/form_builder.rb +14 -13
- data/lib/datagrid/version.rb +3 -0
- metadata +10 -196
- data/.document +0 -5
- data/.rspec +0 -1
- data/.travis.yml +0 -23
- data/Gemfile +0 -33
- data/Rakefile +0 -43
- data/VERSION +0 -1
- data/spec/datagrid/active_model_spec.rb +0 -33
- data/spec/datagrid/column_names_attribute_spec.rb +0 -86
- data/spec/datagrid/columns/column_spec.rb +0 -19
- data/spec/datagrid/columns_spec.rb +0 -592
- data/spec/datagrid/core_spec.rb +0 -210
- data/spec/datagrid/drivers/active_record_spec.rb +0 -79
- data/spec/datagrid/drivers/array_spec.rb +0 -106
- data/spec/datagrid/drivers/mongo_mapper_spec.rb +0 -101
- data/spec/datagrid/drivers/mongoid_spec.rb +0 -109
- data/spec/datagrid/drivers/sequel_spec.rb +0 -111
- data/spec/datagrid/filters/base_filter_spec.rb +0 -19
- data/spec/datagrid/filters/boolean_enum_filter_spec.rb +0 -5
- data/spec/datagrid/filters/composite_filters_spec.rb +0 -65
- data/spec/datagrid/filters/date_filter_spec.rb +0 -198
- data/spec/datagrid/filters/date_time_filter_spec.rb +0 -157
- data/spec/datagrid/filters/dynamic_filter_spec.rb +0 -175
- data/spec/datagrid/filters/enum_filter_spec.rb +0 -51
- data/spec/datagrid/filters/extended_boolean_filter_spec.rb +0 -46
- data/spec/datagrid/filters/float_filter_spec.rb +0 -15
- data/spec/datagrid/filters/integer_filter_spec.rb +0 -144
- data/spec/datagrid/filters/string_filter_spec.rb +0 -35
- data/spec/datagrid/filters_spec.rb +0 -332
- data/spec/datagrid/form_builder_spec.rb +0 -611
- data/spec/datagrid/helper_spec.rb +0 -683
- data/spec/datagrid/ordering_spec.rb +0 -150
- data/spec/datagrid/scaffold_spec.rb +0 -45
- data/spec/datagrid/stylesheet_spec.rb +0 -12
- data/spec/datagrid/utils_spec.rb +0 -19
- data/spec/datagrid_spec.rb +0 -94
- data/spec/spec_helper.rb +0 -123
- data/spec/support/active_record.rb +0 -38
- data/spec/support/configuration.rb +0 -28
- data/spec/support/i18n_helpers.rb +0 -6
- data/spec/support/matchers.rb +0 -101
- data/spec/support/mongo_mapper.rb +0 -32
- data/spec/support/mongoid.rb +0 -36
- data/spec/support/sequel.rb +0 -39
- data/spec/support/simple_report.rb +0 -64
- data/spec/support/test_partials/_actions.html.erb +0 -1
- data/spec/support/test_partials/client/datagrid/_form.html.erb +0 -13
- data/spec/support/test_partials/client/datagrid/_head.html.erb +0 -9
- data/spec/support/test_partials/client/datagrid/_order_for.html.erb +0 -11
- data/spec/support/test_partials/client/datagrid/_row.html.erb +0 -6
- data/spec/support/test_partials/client/datagrid/_table.html.erb +0 -19
- data/spec/support/test_partials/custom_checkboxes/_enum_checkboxes.html.erb +0 -1
- data/spec/support/test_partials/custom_form/_form.html.erb +0 -7
- data/spec/support/test_partials/custom_range/_range_filter.html.erb +0 -1
data/spec/datagrid/core_spec.rb
DELETED
@@ -1,210 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require "action_controller/metal/strong_parameters"
|
3
|
-
|
4
|
-
describe Datagrid::Core do
|
5
|
-
|
6
|
-
context 'with 2 persisted entries' do
|
7
|
-
before { 2.times { Entry.create } }
|
8
|
-
|
9
|
-
let(:report_class) do
|
10
|
-
class ScopeTestReport
|
11
|
-
include Datagrid
|
12
|
-
scope { Entry.order("id desc") }
|
13
|
-
end
|
14
|
-
ScopeTestReport
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#scope' do
|
18
|
-
context 'in the class' do
|
19
|
-
let(:report) { report_class.new }
|
20
|
-
|
21
|
-
it { expect(report.scope.to_a.size).to eq(2) }
|
22
|
-
it { expect(report).to_not be_redefined_scope }
|
23
|
-
|
24
|
-
context "when redefined" do
|
25
|
-
it "should accept previous scope" do
|
26
|
-
module Ns83827
|
27
|
-
class TestGrid < ScopeTestReport
|
28
|
-
scope do |previous|
|
29
|
-
previous.reorder("id asc")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
expect(Ns83827::TestGrid.new.assets.order_values).to eq(["id asc"])
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'changes scope on the fly' do
|
41
|
-
let(:report) do
|
42
|
-
report_class.new.tap do |r|
|
43
|
-
r.scope { Entry.limit(1)}
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it { expect(report.scope.to_a.size).to eq(1) }
|
48
|
-
it { expect(report).to be_redefined_scope }
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'overriding scope by initializer' do
|
52
|
-
let(:report) { report_class.new { Entry.limit(1) } }
|
53
|
-
|
54
|
-
it { expect(report).to be_redefined_scope }
|
55
|
-
it { expect(report.scope.to_a.size).to eq(1) }
|
56
|
-
|
57
|
-
context "reset scope to default" do
|
58
|
-
before do
|
59
|
-
report.reset_scope
|
60
|
-
end
|
61
|
-
it { expect(report.scope.to_a.size).to eq(2) }
|
62
|
-
it { expect(report).to_not be_redefined_scope }
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "appending scope by initializer " do
|
67
|
-
let(:report) { report_class.new {|scope| scope.limit(1)} }
|
68
|
-
it { expect(report.scope.to_a.size).to eq(1) }
|
69
|
-
it { expect(report.scope.order_values.size).to eq(1) }
|
70
|
-
it { expect(report).to be_redefined_scope }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe "#inspect" do
|
76
|
-
it "should show all attribute values" do
|
77
|
-
class InspectTest
|
78
|
-
include Datagrid
|
79
|
-
scope {Entry}
|
80
|
-
filter(:created_at, :date, :range => true)
|
81
|
-
column(:name)
|
82
|
-
end
|
83
|
-
|
84
|
-
grid = InspectTest.new(:created_at => ['2014-01-01', '2014-08-05'], :descending => true, :order => 'name')
|
85
|
-
expect(grid.inspect).to eq('#<InspectTest order: :name, descending: true, created_at: [Wed, 01 Jan 2014, Tue, 05 Aug 2014]>')
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe "#==" do
|
90
|
-
class EqualTest
|
91
|
-
include Datagrid
|
92
|
-
scope {Entry}
|
93
|
-
filter(:created_at, :date)
|
94
|
-
column(:name)
|
95
|
-
column(:created_at)
|
96
|
-
end
|
97
|
-
it "work on empty objects" do
|
98
|
-
expect(EqualTest.new).to eq(EqualTest.new)
|
99
|
-
end
|
100
|
-
it "sees the difference on the filter value" do
|
101
|
-
expect(EqualTest.new(created_at: Date.yesterday)).to_not eq(EqualTest.new(created_at: Date.today))
|
102
|
-
end
|
103
|
-
it "sees the difference on order" do
|
104
|
-
expect(EqualTest.new(order: :created_at)).to_not eq(EqualTest.new(order: :name))
|
105
|
-
end
|
106
|
-
it "doesn't destinguish between String and Symbol order" do
|
107
|
-
expect(EqualTest.new(order: :created_at)).to eq(EqualTest.new(order: "created_at"))
|
108
|
-
end
|
109
|
-
it "checks for redefined scope" do
|
110
|
-
expect(EqualTest.new).to_not eq(EqualTest.new {|s| s.reorder(:name)})
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe 'dynamic helper' do
|
115
|
-
it "should work" do
|
116
|
-
grid = test_report do
|
117
|
-
scope {Entry}
|
118
|
-
column(:id)
|
119
|
-
dynamic {
|
120
|
-
column(:name)
|
121
|
-
column(:category)
|
122
|
-
}
|
123
|
-
end
|
124
|
-
|
125
|
-
expect(grid.columns.map(&:name)).to eq([:id, :name, :category])
|
126
|
-
expect(grid.class.columns.map(&:name)).to eq([:id])
|
127
|
-
|
128
|
-
expect(grid.column_by_name(:id)).not_to be_nil
|
129
|
-
expect(grid.column_by_name(:name)).not_to be_nil
|
130
|
-
end
|
131
|
-
|
132
|
-
it "has access to attributes" do
|
133
|
-
grid = test_report(:attribute_name => 'value') do
|
134
|
-
scope {Entry}
|
135
|
-
datagrid_attribute :attribute_name
|
136
|
-
dynamic {
|
137
|
-
value = attribute_name
|
138
|
-
column(:name) { value }
|
139
|
-
}
|
140
|
-
end
|
141
|
-
|
142
|
-
expect(grid.data_value(:name, Entry.create!)).to eq('value')
|
143
|
-
end
|
144
|
-
|
145
|
-
it "applies before instance scope" do
|
146
|
-
klass = test_report_class do
|
147
|
-
scope {Entry}
|
148
|
-
dynamic do
|
149
|
-
scope do |s|
|
150
|
-
s.limit(1)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
grid = klass.new do |s|
|
156
|
-
s.limit(2)
|
157
|
-
end
|
158
|
-
|
159
|
-
expect(grid.assets.limit_value).to eq(2)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
describe "ActionController::Parameters" do
|
164
|
-
|
165
|
-
let(:params) do
|
166
|
-
::ActionController::Parameters.new(name: 'one')
|
167
|
-
end
|
168
|
-
|
169
|
-
it "permites all attributes by default" do
|
170
|
-
expect {
|
171
|
-
test_report(params) do
|
172
|
-
scope { Entry }
|
173
|
-
filter(:name)
|
174
|
-
end
|
175
|
-
}.to_not raise_error
|
176
|
-
end
|
177
|
-
it "doesn't permit attributes when forbidden_attributes_protection is set" do
|
178
|
-
expect {
|
179
|
-
test_report(params) do
|
180
|
-
scope { Entry }
|
181
|
-
self.forbidden_attributes_protection = true
|
182
|
-
filter(:name)
|
183
|
-
end
|
184
|
-
}.to raise_error(ActiveModel::ForbiddenAttributesError)
|
185
|
-
end
|
186
|
-
it "permits attributes when forbidden_attributes_protection is set and attributes are permitted" do
|
187
|
-
expect {
|
188
|
-
test_report(params.permit!) do
|
189
|
-
scope { Entry }
|
190
|
-
self.forbidden_attributes_protection = true
|
191
|
-
filter(:name)
|
192
|
-
end
|
193
|
-
}.to_not raise_error
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
describe ".query_param" do
|
199
|
-
it "works" do
|
200
|
-
grid = test_report(name: 'value') do
|
201
|
-
scope {Entry}
|
202
|
-
filter(:name)
|
203
|
-
def param_name
|
204
|
-
'grid'
|
205
|
-
end
|
206
|
-
end
|
207
|
-
expect(grid.query_params).to eq({grid: {name: 'value'}})
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Datagrid::Drivers::ActiveRecord do
|
4
|
-
|
5
|
-
describe ".match?" do
|
6
|
-
subject { described_class }
|
7
|
-
|
8
|
-
it {should be_match(Entry)}
|
9
|
-
it {should be_match(Entry.where(:id => 1))}
|
10
|
-
it {should_not be_match(MongoidEntry)}
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should convert any scope to AR::Relation" do
|
14
|
-
expect(subject.to_scope(Entry)).to be_a(ActiveRecord::Relation)
|
15
|
-
expect(subject.to_scope(Entry.limit(5))).to be_a(ActiveRecord::Relation)
|
16
|
-
expect(subject.to_scope(Group.create!.entries)).to be_a(ActiveRecord::Relation)
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should support append_column_queries" do
|
20
|
-
scope = subject.append_column_queries(Entry.where({}), [Datagrid::Columns::Column.new(test_report_class, :sum_group_id, 'sum(entries.group_id)')])
|
21
|
-
expect(scope.to_sql.strip).to eq('SELECT "entries".*, sum(entries.group_id) AS sum_group_id FROM "entries"')
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "Arel" do
|
25
|
-
subject do
|
26
|
-
test_report(:order => :test, :descending => true) do
|
27
|
-
scope { Entry }
|
28
|
-
column(:test, order: Entry.arel_table[:group_id].count)
|
29
|
-
end.assets
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should support ordering by Arel columns" do
|
33
|
-
expect(subject.to_sql.strip).to include 'ORDER BY COUNT("entries"."group_id") DESC'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "gotcha #datagrid_where_by_timestamp" do
|
38
|
-
|
39
|
-
subject do
|
40
|
-
test_report(created_at: 10.days.ago..5.days.ago) do
|
41
|
-
scope {Entry}
|
42
|
-
|
43
|
-
filter(:created_at, :date, range: true) do |value, scope, grid|
|
44
|
-
scope.joins(:group).datagrid_where_by_timestamp("groups.created_at", value)
|
45
|
-
end
|
46
|
-
end.assets
|
47
|
-
end
|
48
|
-
it "includes object created in proper range" do
|
49
|
-
expect(subject).to include(
|
50
|
-
Entry.create!(group: Group.create!(created_at: 7.days.ago)),
|
51
|
-
)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "excludes object created before the range" do
|
55
|
-
expect(subject).to_not include(
|
56
|
-
Entry.create!(created_at: 7.days.ago, group: Group.create!(created_at: 11.days.ago)),
|
57
|
-
)
|
58
|
-
end
|
59
|
-
it "excludes object created after the range" do
|
60
|
-
expect(subject).to_not include(
|
61
|
-
Entry.create!(created_at: 7.days.ago, group: Group.create!(created_at: 4.days.ago)),
|
62
|
-
)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe "batches usage" do
|
67
|
-
|
68
|
-
it "should be incompatible with scope with limit" do
|
69
|
-
report = test_report do
|
70
|
-
scope {Entry.limit(5)}
|
71
|
-
self.batch_size = 20
|
72
|
-
column(:id)
|
73
|
-
end
|
74
|
-
expect { report.data }.to raise_error(Datagrid::ConfigurationError)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Datagrid::Drivers::Array do
|
4
|
-
|
5
|
-
describe ".match?" do
|
6
|
-
subject { described_class }
|
7
|
-
|
8
|
-
it {should be_match(Array.new)}
|
9
|
-
it {should_not be_match({})}
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "api" do
|
13
|
-
|
14
|
-
class ArrayGrid
|
15
|
-
class User < Struct.new(:name, :age); end
|
16
|
-
include Datagrid
|
17
|
-
scope do
|
18
|
-
[]
|
19
|
-
end
|
20
|
-
|
21
|
-
filter(:name)
|
22
|
-
filter(:age, :integer, :range => true)
|
23
|
-
|
24
|
-
column(:name)
|
25
|
-
column(:age)
|
26
|
-
end
|
27
|
-
|
28
|
-
let(:first) { ArrayGrid::User.new("Vasya", 15) }
|
29
|
-
let(:second) { ArrayGrid::User.new("Petya", 12) }
|
30
|
-
let(:third) { ArrayGrid::User.new("Vova", 13) }
|
31
|
-
|
32
|
-
subject do
|
33
|
-
ArrayGrid.new(
|
34
|
-
defined?(_attributes) ? _attributes : {}
|
35
|
-
).scope do
|
36
|
-
[ first, second, third ]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
describe '#assets' do
|
42
|
-
subject { super().assets }
|
43
|
-
describe '#size' do
|
44
|
-
subject { super().size }
|
45
|
-
it {should == 3}
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#rows' do
|
50
|
-
subject { super().rows }
|
51
|
-
it {should == [["Vasya", 15], ["Petya", 12], ["Vova", 13]]}
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '#header' do
|
55
|
-
subject { super().header }
|
56
|
-
it {should ==[ "Name", "Age"]}
|
57
|
-
end
|
58
|
-
|
59
|
-
describe '#data' do
|
60
|
-
subject { super().data }
|
61
|
-
it {should == [[ "Name", "Age"], ["Vasya", 15], ["Petya", 12], ["Vova", 13]]}
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
|
-
describe "when some filters specified" do
|
66
|
-
let(:_attributes) { {:age => [12,14]} }
|
67
|
-
|
68
|
-
describe '#assets' do
|
69
|
-
subject { super().assets }
|
70
|
-
it {should_not include(first)}
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#assets' do
|
74
|
-
subject { super().assets }
|
75
|
-
it {should include(second)}
|
76
|
-
end
|
77
|
-
|
78
|
-
describe '#assets' do
|
79
|
-
subject { super().assets }
|
80
|
-
it {should include(third)}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe "when reverse ordering is specified" do
|
85
|
-
let(:_attributes) { {:order => :name, :descending => true} }
|
86
|
-
|
87
|
-
describe '#assets' do
|
88
|
-
subject { super().assets }
|
89
|
-
it {should == [third, first, second]}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
describe "when using enumerator scope" do
|
95
|
-
|
96
|
-
it "should work fine" do
|
97
|
-
grid = test_report(to_enum: true) do
|
98
|
-
scope {[]}
|
99
|
-
filter(:to_enum, :boolean) do |_, scope|
|
100
|
-
scope.to_enum
|
101
|
-
end
|
102
|
-
end
|
103
|
-
grid.assets.should_not be_any
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Datagrid::Drivers::MongoMapper, :mongomapper do
|
4
|
-
|
5
|
-
if defined?(MongoMapper)
|
6
|
-
describe ".match?" do
|
7
|
-
|
8
|
-
subject { described_class }
|
9
|
-
|
10
|
-
it {should be_match(MongoMapperEntry)}
|
11
|
-
# MongoMapper doesn't have a scoped method, instead it has a query method which returns a Plucky::Query object
|
12
|
-
it {should be_match(MongoMapperEntry.query)}
|
13
|
-
it {should_not be_match(Entry.where(:id => 1))}
|
14
|
-
|
15
|
-
end
|
16
|
-
describe "api" do
|
17
|
-
|
18
|
-
subject do
|
19
|
-
MongoMapperGrid.new(
|
20
|
-
defined?(_attributes) ? _attributes : {}
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
let!(:first) do
|
25
|
-
MongoMapperEntry.create!(
|
26
|
-
:group_id => 2,
|
27
|
-
:name => "Main First",
|
28
|
-
:disabled => false
|
29
|
-
)
|
30
|
-
end
|
31
|
-
let!(:second) do
|
32
|
-
MongoMapperEntry.create!(
|
33
|
-
:group_id => 3,
|
34
|
-
:name => "Main Second",
|
35
|
-
:disabled => true
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
describe '#assets' do
|
41
|
-
subject { super().assets }
|
42
|
-
it {should include(first, second)}
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '#assets' do
|
46
|
-
subject { super().assets }
|
47
|
-
describe '#size' do
|
48
|
-
subject { super().size }
|
49
|
-
it {should == 2}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe '#rows' do
|
54
|
-
subject { super().rows }
|
55
|
-
it {should == [["Main First", 2, false], ["Main Second", 3, true]]}
|
56
|
-
end
|
57
|
-
|
58
|
-
describe '#header' do
|
59
|
-
subject { super().header }
|
60
|
-
it {should ==[ "Name", "Group", "Disabled"]}
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#data' do
|
64
|
-
subject { super().data }
|
65
|
-
it {should == [[ "Name", "Group", "Disabled"], ["Main First", 2, false], ["Main Second", 3, true]]}
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
describe "when some filters specified" do
|
70
|
-
let(:_attributes) { {:from_group_id => 3} }
|
71
|
-
|
72
|
-
describe '#assets' do
|
73
|
-
subject { super().assets }
|
74
|
-
it {should_not include(first)}
|
75
|
-
end
|
76
|
-
|
77
|
-
describe '#assets' do
|
78
|
-
subject { super().assets }
|
79
|
-
it {should include(second)}
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "when reverse ordering is specified" do
|
84
|
-
let(:_attributes) { {:order => :name, :descending => true} }
|
85
|
-
|
86
|
-
describe '#rows' do
|
87
|
-
subject { super().rows }
|
88
|
-
it {should == [["Main Second", 3, true], ["Main First", 2, false]]}
|
89
|
-
end
|
90
|
-
end
|
91
|
-
it "should not provide default order for non declared fields" do
|
92
|
-
expect {
|
93
|
-
test_report(:order => :test) do
|
94
|
-
scope { MongoMapperEntry }
|
95
|
-
column(:test)
|
96
|
-
end.assets
|
97
|
-
}.to raise_error(Datagrid::OrderUnsupported)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|