rider-kick 0.0.3 → 0.0.4
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/README.md +9 -8
- data/lib/generators/rider_kick/USAGE +4 -7
- data/lib/generators/rider_kick/clean_arch_generator.rb +6 -8
- data/lib/generators/rider_kick/scaffold_generator.rb +7 -6
- data/lib/generators/rider_kick/structure_generator.rb +14 -15
- data/lib/generators/rider_kick/templates/README.md +1 -3
- data/lib/generators/rider_kick/templates/config/initializers/hashie.rb.tt +1 -0
- data/lib/generators/rider_kick/templates/db/structures/example.yaml.tt +13 -23
- data/lib/generators/rider_kick/templates/domains/core/repositories/abstract_repository.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/contract/default.rb.tt +3 -3
- data/lib/generators/rider_kick/templates/domains/core/use_cases/create.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/destroy.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/fetch_by_id.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/list.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/domains/core/use_cases/update.rb.tt +1 -1
- data/lib/generators/rider_kick/templates/models/application_record.rb +7 -0
- data/lib/generators/rider_kick/templates/models/models.rb +2 -0
- data/lib/rider-kick.rb +0 -3
- data/lib/rider_kick/version.rb +1 -1
- metadata +4 -5
- data/lib/generators/rider_kick/init_generator.rb +0 -15
- data/lib/generators/rider_kick/templates/config/initializers/rider_kick.rb +0 -3
- data/lib/rider_kick/configuration.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca2aedb4749c52fc2cf24c4ab16564c3bb334eca159e674b4e0ce2e1b138af7c
|
4
|
+
data.tar.gz: d48958c8210c77dc852a9a9f7ccb51c1a439848e7397581be5e8546929a1153b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3b44f67e107355e1cb5f6c56df0e071393c612d5b5e36d6b8cba84f7cefb36570c9ef4d0b4e38df94ee6ee5eca1a66f2bca03bfaacc812cffb466c490b01b79
|
7
|
+
data.tar.gz: fc8999432b430ddc353aad9d64f459acbb8974ae42ee824928f4821358e1c1ea98a6531322cec9fa10e75f8f98eca4a93f5791edd4ba689d4fe2592298b4ff38
|
data/README.md
CHANGED
@@ -12,11 +12,16 @@ gem 'rider-kick'
|
|
12
12
|
```
|
13
13
|
|
14
14
|
And then execute:
|
15
|
+
```bash
|
15
16
|
$ rails new kotaro_minami -d=postgresql -T --skip-javascript --skip-asset-pipeline
|
16
17
|
$ bundle install
|
17
|
-
$
|
18
|
+
$ bundle add rider-kick
|
19
|
+
$ bundle add sun-sword
|
18
20
|
$ rails generate rider_kick:clean_arch --setup
|
19
21
|
$ rails db:drop db:create db:migrate db:seed
|
22
|
+
$ rails generate rider_kick:structure Models::User actor:owner
|
23
|
+
$ rails generate rider_kick:scaffold users scope:dashboard
|
24
|
+
```
|
20
25
|
|
21
26
|
## Usage
|
22
27
|
```bash
|
@@ -25,14 +30,10 @@ Description:
|
|
25
30
|
rails new kotaro_minami -d=postgresql -T --skip-javascript --skip-asset-pipeline
|
26
31
|
|
27
32
|
Example:
|
28
|
-
To Generate Init:
|
29
|
-
bin/rails generate rider_kick:init
|
30
|
-
|
31
|
-
To Generate Pattern:
|
32
|
-
bin/rails generate rider_kick:clean_arch --setup
|
33
|
-
|
34
33
|
To Generate scaffold:
|
35
|
-
bin/rails
|
34
|
+
bin/rails generate rider_kick:clean_arch --setup
|
35
|
+
bin/rails generate rider_kick:structure Models::User actor:owner
|
36
|
+
bin/rails generate rider_kick:scaffold users scope:dashboard
|
36
37
|
|
37
38
|
```
|
38
39
|
|
@@ -1,12 +1,9 @@
|
|
1
1
|
Description:
|
2
2
|
Clean Architecture generator
|
3
|
+
rails new kotaro_minami -d=postgresql -T --skip-javascript --skip-asset-pipeline
|
3
4
|
|
4
5
|
Example:
|
5
|
-
To Generate Init:
|
6
|
-
bin/rails generate rider_kick:init
|
7
|
-
|
8
|
-
To Generate Pattern:
|
9
|
-
bin/rails generate rider_kick:clean_arch --setup
|
10
|
-
|
11
6
|
To Generate scaffold:
|
12
|
-
bin/rails
|
7
|
+
bin/rails generate rider_kick:clean_arch --setup
|
8
|
+
bin/rails generate rider_kick:structure Models::User actor:owner
|
9
|
+
bin/rails generate rider_kick:scaffold users scope:dashboard
|
@@ -6,7 +6,6 @@ module RiderKick
|
|
6
6
|
|
7
7
|
def validate_setup_option
|
8
8
|
raise Thor::Error, 'The --setup option must be specified to create the domain structure.' unless options.setup
|
9
|
-
validation!
|
10
9
|
end
|
11
10
|
|
12
11
|
def create_gem_dependencies
|
@@ -22,6 +21,7 @@ module RiderKick
|
|
22
21
|
setup_gitignore
|
23
22
|
setup_rubocop
|
24
23
|
setup_init_migration
|
24
|
+
setup_models
|
25
25
|
setup_active_storage
|
26
26
|
setup_rspec
|
27
27
|
setup_readme
|
@@ -34,13 +34,6 @@ module RiderKick
|
|
34
34
|
run 'rails db:migrate'
|
35
35
|
end
|
36
36
|
|
37
|
-
def validation!
|
38
|
-
unless File.exist?('config/initializers/rider_kick.rb')
|
39
|
-
say 'Error must create init configuration for rider_kick!'
|
40
|
-
raise Thor::Error, 'run: bin/rails generate rider_kick:init'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
37
|
def setup_domain_structure
|
45
38
|
empty_directory File.join("#{path_app}/domains/core/use_cases/contract")
|
46
39
|
empty_directory File.join("#{path_app}/domains/core/repositories")
|
@@ -106,6 +99,11 @@ module RiderKick
|
|
106
99
|
template 'config/database.yml', File.join('config/database.yml')
|
107
100
|
end
|
108
101
|
|
102
|
+
def setup_models
|
103
|
+
template 'models/application_record.rb', File.join('app/models/application_record.rb')
|
104
|
+
template 'models/models.rb', File.join('app/models/models.rb')
|
105
|
+
end
|
106
|
+
|
109
107
|
def copy_env_development
|
110
108
|
template 'env.production', File.join('.env.production')
|
111
109
|
template 'env.development', File.join('.env.development')
|
@@ -4,6 +4,7 @@ module RiderKick
|
|
4
4
|
source_root File.expand_path('templates', __dir__)
|
5
5
|
|
6
6
|
argument :arg_structure, type: :string, default: '', banner: ''
|
7
|
+
argument :arg_scope, type: :hash, default: '', banner: 'scope:dashboard'
|
7
8
|
|
8
9
|
def generate_use_case
|
9
10
|
validation!
|
@@ -21,9 +22,9 @@ module RiderKick
|
|
21
22
|
private
|
22
23
|
|
23
24
|
def validation!
|
24
|
-
unless
|
25
|
-
say 'Error must create
|
26
|
-
raise Thor::Error, 'run: bin/rails generate rider_kick:
|
25
|
+
unless Dir.exist?('app/domains')
|
26
|
+
say 'Error must create clean arch structure first!'
|
27
|
+
raise Thor::Error, 'run: bin/rails generate rider_kick:clean_arch --setup'
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -54,7 +55,7 @@ module RiderKick
|
|
54
55
|
@model_class = model_name.camelize.constantize
|
55
56
|
@subject_class = resource_name.camelize
|
56
57
|
@fields = contract_fields
|
57
|
-
@route_scope_path =
|
58
|
+
@route_scope_path = arg_scope['scope'].to_s.downcase rescue ''
|
58
59
|
@route_scope_class = @route_scope_path.camelize rescue ''
|
59
60
|
|
60
61
|
@type_mapping = {
|
@@ -100,8 +101,8 @@ module RiderKick
|
|
100
101
|
|
101
102
|
def contract_fields
|
102
103
|
skip_contract_fields = @skipped_fields.map(&:strip).uniq
|
103
|
-
if
|
104
|
-
skip_contract_fields <<
|
104
|
+
if @scope_owner_column.present?
|
105
|
+
skip_contract_fields << @scope_owner_column.to_s
|
105
106
|
end
|
106
107
|
@model_class.columns.reject { |column| skip_contract_fields.include?(column.name.to_s) }.map(&:name).map(&:to_s)
|
107
108
|
end
|
@@ -14,25 +14,24 @@ module RiderKick
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def validation!
|
17
|
-
unless
|
18
|
-
say 'Error must create
|
19
|
-
raise Thor::Error, 'run: bin/rails generate rider_kick:
|
17
|
+
unless Dir.exist?('app/domains')
|
18
|
+
say 'Error must create clean arch structure first!'
|
19
|
+
raise Thor::Error, 'run: bin/rails generate rider_kick:clean_arch --setup'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def setup_variables
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
32
|
-
@
|
33
|
-
@route_scope_class = @route_scope_path.camelize
|
24
|
+
@scope_owner_column = (SunSword.scope_owner_column.to_s rescue '')
|
25
|
+
@variable_subject = arg_model_name.split('::').last.underscore.downcase
|
26
|
+
@model_class = arg_model_name.camelize.constantize
|
27
|
+
@subject_class = arg_model_name.split('::').last
|
28
|
+
@scope_path = @subject_class.pluralize.underscore.downcase
|
29
|
+
@scope_class = @scope_path.camelize
|
30
|
+
@fields = contract_fields
|
31
|
+
@uploaders = uploaders
|
32
|
+
@actor = arg_settings['actor'].downcase
|
34
33
|
|
35
|
-
@type_mapping
|
34
|
+
@type_mapping = {
|
36
35
|
'uuid' => ':string',
|
37
36
|
'string' => ':string',
|
38
37
|
'text' => ':string',
|
@@ -62,7 +61,7 @@ module RiderKick
|
|
62
61
|
end
|
63
62
|
|
64
63
|
def contract_fields
|
65
|
-
@model_class.columns.reject { |column| (['id', 'created_at', 'updated_at', 'type'] + [
|
64
|
+
@model_class.columns.reject { |column| (['id', 'created_at', 'updated_at', 'type'] + [@scope_owner_column.to_s]).include?(column.name.to_s) }.map(&:name).map(&:to_s)
|
66
65
|
end
|
67
66
|
|
68
67
|
def get_column_type(field)
|
@@ -5,6 +5,9 @@ fields:
|
|
5
5
|
<% @model_class.columns.each do |field| -%>
|
6
6
|
- <%= field.name.to_s %>
|
7
7
|
<% end -%>
|
8
|
+
<% @uploaders.each do |field| -%>
|
9
|
+
- <%= field %>
|
10
|
+
<% end -%>
|
8
11
|
uploaders:
|
9
12
|
<% @uploaders.each do |field| -%>
|
10
13
|
- <%= field %>
|
@@ -16,7 +19,6 @@ search_able:
|
|
16
19
|
<% end -%>
|
17
20
|
<% end -%>
|
18
21
|
controllers:
|
19
|
-
route_scope: <%= @route_scope_path %>
|
20
22
|
list_fields:
|
21
23
|
<% @fields.each do |field| -%>
|
22
24
|
- <%= field %>
|
@@ -25,31 +27,27 @@ controllers:
|
|
25
27
|
<% @model_class.columns.each do |field| -%>
|
26
28
|
- <%= field.name.to_s %>
|
27
29
|
<% end -%>
|
28
|
-
|
29
|
-
<% (@fields + @uploaders).each do |field| -%>
|
30
|
+
<% @uploaders.each do |field| -%>
|
30
31
|
- <%= field %>
|
32
|
+
<% end -%>
|
33
|
+
form_fields:
|
34
|
+
<% (@fields).each do |field| -%>
|
35
|
+
- name: <%= field %>
|
36
|
+
type: string
|
37
|
+
<% end -%>
|
38
|
+
<% (@uploaders).each do |field| -%>
|
39
|
+
- name: <%= field %>
|
40
|
+
type: file
|
31
41
|
<% end -%>
|
32
42
|
domains:
|
33
43
|
action_list:
|
34
|
-
endpoint:
|
35
|
-
is_auth: true
|
36
|
-
is_skip: false
|
37
|
-
parameters:
|
38
44
|
use_case:
|
39
45
|
contract:
|
40
46
|
action_fetch_by_id:
|
41
|
-
endpoint:
|
42
|
-
is_auth: true
|
43
|
-
is_skip: false
|
44
|
-
parameters:
|
45
47
|
use_case:
|
46
48
|
contract:
|
47
49
|
- required(:id).filled(:string)
|
48
50
|
action_create:
|
49
|
-
endpoint:
|
50
|
-
is_auth: true
|
51
|
-
is_skip: false
|
52
|
-
parameters:
|
53
51
|
use_case:
|
54
52
|
contract:
|
55
53
|
<% (@fields + @uploaders).each do |field| -%>
|
@@ -62,10 +60,6 @@ domains:
|
|
62
60
|
<% end -%>
|
63
61
|
<% end -%>
|
64
62
|
action_update:
|
65
|
-
endpoint:
|
66
|
-
is_auth: true
|
67
|
-
is_skip: false
|
68
|
-
parameters:
|
69
63
|
use_case:
|
70
64
|
contract:
|
71
65
|
- required(:id).filled(:string)
|
@@ -79,10 +73,6 @@ domains:
|
|
79
73
|
<% end -%>
|
80
74
|
<% end -%>
|
81
75
|
action_destroy:
|
82
|
-
endpoint:
|
83
|
-
is_auth: true
|
84
|
-
is_skip: false
|
85
|
-
parameters:
|
86
76
|
use_case:
|
87
77
|
contract:
|
88
78
|
- required(:id).filled(:string)
|
@@ -9,9 +9,9 @@ class Core::UseCases::Contract::Default
|
|
9
9
|
|
10
10
|
def default
|
11
11
|
Dry::Schema.Params do
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
if @scope_owner_column.present?
|
13
|
+
required(@scope_owner_column).filled(:string)
|
14
|
+
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].join("::") %> < RiderKick::UseCases::AbstractUseCase
|
3
|
+
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].reject { |c| c.empty? }.join("::") %> < RiderKick::UseCases::AbstractUseCase
|
4
4
|
contract do
|
5
5
|
params(Core::UseCases::Contract::Default.new.call) do
|
6
6
|
<% @contract_create.each do |field| -%>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].join("::") %> < RiderKick::UseCases::AbstractUseCase
|
3
|
+
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].reject { |c| c.empty? }.join("::") %> < RiderKick::UseCases::AbstractUseCase
|
4
4
|
contract do
|
5
5
|
params(Core::UseCases::Contract::Default.new.call) do
|
6
6
|
<% @contract_destroy.each do |field| -%>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].join("::") %> < RiderKick::UseCases::AbstractUseCase
|
3
|
+
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].reject { |c| c.empty? }.join("::") %> < RiderKick::UseCases::AbstractUseCase
|
4
4
|
contract do
|
5
5
|
params(Core::UseCases::Contract::Default.new.call) do
|
6
6
|
<% @contract_fetch_by_id.each do |field| -%>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].join("::") %> < RiderKick::UseCases::AbstractUseCase
|
3
|
+
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].reject { |c| c.empty? }.join("::") %> < RiderKick::UseCases::AbstractUseCase
|
4
4
|
contract do
|
5
5
|
params(Core::UseCases::Contract::Default.new.call, Core::UseCases::Contract::Pagination.new.call) do
|
6
6
|
<% @contract_list.each do |field| -%>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].join("::") %> < RiderKick::UseCases::AbstractUseCase
|
3
|
+
class Core::UseCases::<%= [@route_scope_class, @scope_class, @use_case_class].reject { |c| c.empty? }.join("::") %> < RiderKick::UseCases::AbstractUseCase
|
4
4
|
contract do
|
5
5
|
params(Core::UseCases::Contract::Default.new.call) do
|
6
6
|
<% @contract_update.each do |field| -%>
|
data/lib/rider-kick.rb
CHANGED
@@ -5,10 +5,7 @@ require 'rider_kick/builders/abstract_active_record_entity_builder'
|
|
5
5
|
require 'rider_kick/matchers/use_case_result'
|
6
6
|
require 'rider_kick/use_cases/abstract_use_case'
|
7
7
|
require 'rider_kick/use_cases/contract'
|
8
|
-
require 'rider_kick/configuration'
|
9
8
|
require 'rider_kick/version'
|
10
9
|
|
11
10
|
module RiderKick
|
12
|
-
extend RiderKick::Configuration
|
13
|
-
define_setting :scope_owner_column, ''
|
14
11
|
end
|
data/lib/rider_kick/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rider-kick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kotaro Minami
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-matcher
|
@@ -151,7 +151,6 @@ files:
|
|
151
151
|
- Rakefile
|
152
152
|
- lib/generators/rider_kick/USAGE
|
153
153
|
- lib/generators/rider_kick/clean_arch_generator.rb
|
154
|
-
- lib/generators/rider_kick/init_generator.rb
|
155
154
|
- lib/generators/rider_kick/scaffold_generator.rb
|
156
155
|
- lib/generators/rider_kick/structure_generator.rb
|
157
156
|
- lib/generators/rider_kick/templates/.gitignore
|
@@ -163,7 +162,6 @@ files:
|
|
163
162
|
- lib/generators/rider_kick/templates/config/initializers/generators.rb.tt
|
164
163
|
- lib/generators/rider_kick/templates/config/initializers/hashie.rb.tt
|
165
164
|
- lib/generators/rider_kick/templates/config/initializers/pagy.rb.tt
|
166
|
-
- lib/generators/rider_kick/templates/config/initializers/rider_kick.rb
|
167
165
|
- lib/generators/rider_kick/templates/config/initializers/version.rb.tt
|
168
166
|
- lib/generators/rider_kick/templates/config/initializers/zeitwerk.rb.tt
|
169
167
|
- lib/generators/rider_kick/templates/db/migrate/20220613145533_init_database.rb
|
@@ -192,6 +190,8 @@ files:
|
|
192
190
|
- lib/generators/rider_kick/templates/env.development
|
193
191
|
- lib/generators/rider_kick/templates/env.production
|
194
192
|
- lib/generators/rider_kick/templates/env.test
|
193
|
+
- lib/generators/rider_kick/templates/models/application_record.rb
|
194
|
+
- lib/generators/rider_kick/templates/models/models.rb
|
195
195
|
- lib/generators/rider_kick/templates/spec/fixtures/sample.pdf
|
196
196
|
- lib/generators/rider_kick/templates/spec/rails_helper.rb
|
197
197
|
- lib/generators/rider_kick/templates/spec/support/file_stuber.rb
|
@@ -199,7 +199,6 @@ files:
|
|
199
199
|
- lib/rider-kick.rb
|
200
200
|
- lib/rider_kick/builders/abstract_active_record_entity_builder.rb
|
201
201
|
- lib/rider_kick/builders/abstract_active_record_entity_builder_spec.rb
|
202
|
-
- lib/rider_kick/configuration.rb
|
203
202
|
- lib/rider_kick/entities/failure_details.rb
|
204
203
|
- lib/rider_kick/matchers/use_case_result.rb
|
205
204
|
- lib/rider_kick/matchers/use_case_result_spec.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module RiderKick
|
2
|
-
class InitGenerator < Rails::Generators::Base
|
3
|
-
source_root File.expand_path('templates', __dir__)
|
4
|
-
|
5
|
-
def setup_configuration
|
6
|
-
copy_initializer('rider_kick')
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
|
11
|
-
def copy_initializer(file_name)
|
12
|
-
template "config/initializers/#{file_name}.rb", File.join("config/initializers/#{file_name}.rb")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RiderKick
|
4
|
-
module Configuration
|
5
|
-
def setup
|
6
|
-
yield self
|
7
|
-
end
|
8
|
-
|
9
|
-
def define_setting(name, default = nil)
|
10
|
-
class_variable_set("@@#{name}", default)
|
11
|
-
|
12
|
-
define_class_method "#{name}=" do |value|
|
13
|
-
class_variable_set("@@#{name}", value)
|
14
|
-
end
|
15
|
-
|
16
|
-
define_class_method name do
|
17
|
-
class_variable_get("@@#{name}")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def define_class_method(name, &block)
|
24
|
-
(class << self; self; end).instance_eval do
|
25
|
-
define_method name, &block
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|