rubysmith 0.16.1 → 1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/LICENSE.adoc +207 -155
- data/README.adoc +340 -94
- data/lib/rubysmith/builder.rb +1 -2
- data/lib/rubysmith/builders/bundler.rb +7 -11
- data/lib/rubysmith/builders/circle_ci.rb +8 -2
- data/lib/rubysmith/builders/console.rb +8 -2
- data/lib/rubysmith/builders/core.rb +7 -3
- data/lib/rubysmith/builders/documentation/{change.rb → citation.rb} +8 -8
- data/lib/rubysmith/builders/documentation/license.rb +9 -4
- data/lib/rubysmith/builders/documentation/readme.rb +12 -18
- data/lib/rubysmith/builders/documentation/{contribution.rb → version.rb} +10 -5
- data/lib/rubysmith/builders/git/commit.rb +3 -1
- data/lib/rubysmith/builders/git/setup.rb +2 -1
- data/lib/rubysmith/builders/git_hub.rb +8 -3
- data/lib/rubysmith/builders/guard.rb +9 -3
- data/lib/rubysmith/builders/rake.rb +8 -3
- data/lib/rubysmith/builders/reek.rb +7 -2
- data/lib/rubysmith/builders/rspec/context.rb +8 -2
- data/lib/rubysmith/builders/rspec/helper.rb +8 -2
- data/lib/rubysmith/builders/rubocop.rb +34 -0
- data/lib/rubysmith/builders/setup.rb +8 -2
- data/lib/rubysmith/cli/actions/build.rb +10 -12
- data/lib/rubysmith/cli/actions/config.rb +4 -2
- data/lib/rubysmith/cli/actions/publish.rb +21 -0
- data/lib/rubysmith/cli/parser.rb +31 -0
- data/lib/rubysmith/cli/parsers/build.rb +80 -45
- data/lib/rubysmith/cli/parsers/core.rb +14 -10
- data/lib/rubysmith/cli/shell.rb +22 -15
- data/lib/rubysmith/configuration/content.rb +170 -0
- data/lib/rubysmith/configuration/defaults.yml +88 -0
- data/lib/rubysmith/configuration/enhancers/current_time.rb +24 -0
- data/lib/rubysmith/configuration/enhancers/git_email.rb +31 -0
- data/lib/rubysmith/configuration/enhancers/git_hub_user.rb +31 -0
- data/lib/rubysmith/configuration/enhancers/git_user.rb +33 -0
- data/lib/rubysmith/configuration/loader.rb +48 -0
- data/lib/rubysmith/container.rb +1 -1
- data/lib/rubysmith/extensions/bundler.rb +30 -0
- data/lib/rubysmith/extensions/milestoner.rb +35 -0
- data/lib/rubysmith/extensions/pragmater.rb +35 -0
- data/lib/rubysmith/extensions/rubocop.rb +29 -0
- data/lib/rubysmith/extensions/tocer.rb +37 -0
- data/lib/rubysmith/identity.rb +1 -1
- data/lib/rubysmith/templates/%project_name%/.github/ISSUE_TEMPLATE.md.erb +1 -4
- data/lib/rubysmith/templates/%project_name%/.rubocop.yml.erb +2 -0
- data/lib/rubysmith/templates/%project_name%/CITATION.cff.erb +16 -0
- data/lib/rubysmith/templates/%project_name%/Gemfile.erb +12 -9
- data/lib/rubysmith/templates/%project_name%/LICENSE-hippocratic.adoc.erb +214 -0
- data/lib/rubysmith/templates/%project_name%/LICENSE-hippocratic.md.erb +214 -0
- data/lib/rubysmith/templates/%project_name%/README.adoc.erb +20 -21
- data/lib/rubysmith/templates/%project_name%/README.md.erb +20 -21
- data/lib/rubysmith/templates/%project_name%/VERSIONS.adoc.erb +5 -0
- data/lib/rubysmith/templates/%project_name%/VERSIONS.md.erb +5 -0
- data/lib/rubysmith/templates/%project_name%/bin/rubocop.erb +0 -1
- data.tar.gz.sig +0 -0
- metadata +54 -38
- metadata.gz.sig +3 -2
- data/lib/rubysmith/builders/documentation/conduct.rb +0 -32
- data/lib/rubysmith/builders/pragma.rb +0 -32
- data/lib/rubysmith/builders/rubocop/formatter.rb +0 -31
- data/lib/rubysmith/builders/rubocop/setup.rb +0 -31
- data/lib/rubysmith/cli/configuration/content.rb +0 -97
- data/lib/rubysmith/cli/configuration/defaults.yml +0 -46
- data/lib/rubysmith/cli/configuration/enhancers/current_time.rb +0 -26
- data/lib/rubysmith/cli/configuration/enhancers/git_hub_user.rb +0 -33
- data/lib/rubysmith/cli/configuration/enhancers/version.rb +0 -26
- data/lib/rubysmith/cli/configuration/loader.rb +0 -46
- data/lib/rubysmith/cli/parsers/assembler.rb +0 -32
- data/lib/rubysmith/cli/parsers.rb +0 -11
- data/lib/rubysmith/templates/%project_name%/CHANGES.adoc.erb +0 -5
- data/lib/rubysmith/templates/%project_name%/CHANGES.md.erb +0 -5
- data/lib/rubysmith/templates/%project_name%/CODE_OF_CONDUCT.adoc.erb +0 -114
- data/lib/rubysmith/templates/%project_name%/CODE_OF_CONDUCT.md.erb +0 -115
- data/lib/rubysmith/templates/%project_name%/CONTRIBUTING.adoc.erb +0 -22
- data/lib/rubysmith/templates/%project_name%/CONTRIBUTING.md.erb +0 -22
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "refinements/structs"
|
4
|
+
|
5
|
+
module Rubysmith
|
6
|
+
module Configuration
|
7
|
+
module Enhancers
|
8
|
+
# Adds current time to content.
|
9
|
+
class CurrentTime
|
10
|
+
using Refinements::Structs
|
11
|
+
|
12
|
+
def initialize now = Time.now
|
13
|
+
@now = now
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(content) = content.merge(now:)
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :now
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "git_plus"
|
4
|
+
require "refinements/strings"
|
5
|
+
require "refinements/structs"
|
6
|
+
|
7
|
+
module Rubysmith
|
8
|
+
module Configuration
|
9
|
+
module Enhancers
|
10
|
+
# Dynamically adds Git email if defined.
|
11
|
+
class GitEmail
|
12
|
+
using Refinements::Strings
|
13
|
+
using Refinements::Structs
|
14
|
+
|
15
|
+
def initialize repository: GitPlus::Repository.new
|
16
|
+
@repository = repository
|
17
|
+
end
|
18
|
+
|
19
|
+
def call content
|
20
|
+
String(content.author_email).blank? ? content.merge(author_email: email) : content
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :repository
|
26
|
+
|
27
|
+
def email = repository.config_get("user.email")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "git_plus"
|
4
|
+
require "refinements/strings"
|
5
|
+
require "refinements/structs"
|
6
|
+
|
7
|
+
module Rubysmith
|
8
|
+
module Configuration
|
9
|
+
module Enhancers
|
10
|
+
# Dynamically adds GitHub user if user is defined.
|
11
|
+
class GitHubUser
|
12
|
+
using Refinements::Strings
|
13
|
+
using Refinements::Structs
|
14
|
+
|
15
|
+
def initialize repository: GitPlus::Repository.new
|
16
|
+
@repository = repository
|
17
|
+
end
|
18
|
+
|
19
|
+
def call content
|
20
|
+
String(content.git_hub_user).blank? ? content.merge(git_hub_user: user) : content
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :repository
|
26
|
+
|
27
|
+
def user = repository.config_get("github.user")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "git_plus"
|
4
|
+
require "refinements/strings"
|
5
|
+
require "refinements/structs"
|
6
|
+
|
7
|
+
module Rubysmith
|
8
|
+
module Configuration
|
9
|
+
module Enhancers
|
10
|
+
# Dynamically adds Git user if defined.
|
11
|
+
class GitUser
|
12
|
+
using Refinements::Strings
|
13
|
+
using Refinements::Structs
|
14
|
+
|
15
|
+
def initialize repository: GitPlus::Repository.new
|
16
|
+
@repository = repository
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(content) = String(content.author_name).blank? ? content.merge(**user) : content
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :repository
|
24
|
+
|
25
|
+
def user
|
26
|
+
repository.config_get("user.name")
|
27
|
+
.then { |name| String(name).split }
|
28
|
+
.then { |first, last| {author_given_name: first, author_family_name: last} }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "refinements/hashes"
|
5
|
+
require "refinements/structs"
|
6
|
+
require "runcom"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
module Rubysmith
|
10
|
+
module Configuration
|
11
|
+
# Represents the fully assembled Command Line Interface (CLI) configuration.
|
12
|
+
class Loader
|
13
|
+
using Refinements::Hashes
|
14
|
+
using Refinements::Structs
|
15
|
+
|
16
|
+
DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
|
17
|
+
CLIENT = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
|
18
|
+
|
19
|
+
ENHANCERS = [
|
20
|
+
Enhancers::CurrentTime.new,
|
21
|
+
Enhancers::GitEmail.new,
|
22
|
+
Enhancers::GitHubUser.new,
|
23
|
+
Enhancers::GitUser.new
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
def self.call(...) = new(...).call
|
27
|
+
|
28
|
+
def self.with_defaults = new(client: DEFAULTS, enhancers: [])
|
29
|
+
|
30
|
+
def initialize content: Content.new, client: CLIENT, enhancers: ENHANCERS
|
31
|
+
@content = content
|
32
|
+
@client = client
|
33
|
+
@enhancers = enhancers
|
34
|
+
end
|
35
|
+
|
36
|
+
def call
|
37
|
+
enhancers.reduce(preload_content) { |preload, enhancer| enhancer.call preload }
|
38
|
+
.freeze
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :content, :client, :enhancers
|
44
|
+
|
45
|
+
def preload_content = content.merge(**client.to_h.flatten_keys)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/rubysmith/container.rb
CHANGED
@@ -9,7 +9,7 @@ module Rubysmith
|
|
9
9
|
module Container
|
10
10
|
extend Dry::Container::Mixin
|
11
11
|
|
12
|
-
register(:configuration
|
12
|
+
register(:configuration) { Configuration::Loader.call }
|
13
13
|
register(:colorizer) { Pastel.new enabled: $stdout.tty? }
|
14
14
|
register(:kernel) { Kernel }
|
15
15
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler"
|
4
|
+
require "bundler/cli"
|
5
|
+
require "refinements/pathnames"
|
6
|
+
|
7
|
+
module Rubysmith
|
8
|
+
module Extensions
|
9
|
+
# Ensures gem dependencies are installed.
|
10
|
+
class Bundler
|
11
|
+
using Refinements::Pathnames
|
12
|
+
|
13
|
+
def self.call(...) = new(...).call
|
14
|
+
|
15
|
+
def initialize configuration, client: ::Bundler::CLI
|
16
|
+
@configuration = configuration
|
17
|
+
@client = client
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
configuration.project_root.change_dir { client.start %w[install --quiet] }
|
22
|
+
configuration
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :configuration, :client
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "milestoner"
|
4
|
+
|
5
|
+
module Rubysmith
|
6
|
+
module Extensions
|
7
|
+
# Ensures project can be published (tagged) in a reliable and consistent fashion.
|
8
|
+
class Milestoner
|
9
|
+
def self.call(...) = new(...).call
|
10
|
+
|
11
|
+
def initialize configuration,
|
12
|
+
client: ::Milestoner::Tags::Publisher.new,
|
13
|
+
content: ::Milestoner::Configuration::Content
|
14
|
+
@configuration = configuration
|
15
|
+
@client = client
|
16
|
+
@content = content
|
17
|
+
end
|
18
|
+
|
19
|
+
def call = client.call(settings) && configuration
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :configuration, :client, :content
|
24
|
+
|
25
|
+
def settings
|
26
|
+
content[
|
27
|
+
documentation_format: configuration.extensions_milestoner_documentation_format,
|
28
|
+
prefixes: configuration.extensions_milestoner_prefixes,
|
29
|
+
sign: configuration.extensions_milestoner_sign,
|
30
|
+
version: configuration.project_version
|
31
|
+
]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pragmater"
|
4
|
+
|
5
|
+
module Rubysmith
|
6
|
+
module Extensions
|
7
|
+
# Ensures project skeleton has pragmas.
|
8
|
+
class Pragmater
|
9
|
+
def self.call(...) = new(...).call
|
10
|
+
|
11
|
+
def initialize configuration,
|
12
|
+
client: ::Pragmater::Runner.new,
|
13
|
+
content: ::Pragmater::Configuration::Content
|
14
|
+
@configuration = configuration
|
15
|
+
@client = client
|
16
|
+
@content = content
|
17
|
+
end
|
18
|
+
|
19
|
+
def call = client.call(settings) && configuration
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :configuration, :client, :content
|
24
|
+
|
25
|
+
def settings
|
26
|
+
content[
|
27
|
+
action_insert: true,
|
28
|
+
comments: configuration.extensions_pragmater_comments,
|
29
|
+
includes: configuration.extensions_pragmater_includes,
|
30
|
+
root_dir: configuration.project_root
|
31
|
+
]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
require "refinements/ios"
|
5
|
+
|
6
|
+
module Rubysmith
|
7
|
+
module Extensions
|
8
|
+
# Ensures project skeleton adheres to style guide.
|
9
|
+
class Rubocop
|
10
|
+
using Refinements::IOs
|
11
|
+
|
12
|
+
def self.call(...) = new(...).call
|
13
|
+
|
14
|
+
def initialize configuration, client: ::RuboCop::CLI.new
|
15
|
+
@configuration = configuration
|
16
|
+
@client = client
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
STDOUT.squelch { client.run ["--auto-correct", configuration.project_root.to_s] }
|
21
|
+
configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :configuration, :client
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tocer"
|
4
|
+
|
5
|
+
module Rubysmith
|
6
|
+
module Extensions
|
7
|
+
# Ensures project skeleton documentation has table of contents.
|
8
|
+
class Tocer
|
9
|
+
def self.call(...) = new(...).call
|
10
|
+
|
11
|
+
def initialize configuration,
|
12
|
+
client: ::Tocer::Runner.new,
|
13
|
+
content: ::Tocer::Configuration::Content
|
14
|
+
@configuration = configuration
|
15
|
+
@client = client
|
16
|
+
@content = content
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
client.call(settings) if configuration.build_readme
|
21
|
+
configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :configuration, :client, :content
|
27
|
+
|
28
|
+
def settings
|
29
|
+
content[
|
30
|
+
includes: configuration.extensions_tocer_includes,
|
31
|
+
label: configuration.extensions_tocer_label,
|
32
|
+
root_dir: configuration.project_root
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/rubysmith/identity.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
## Overview
|
2
|
-
<!-- Required. Describe, briefly, the behavior experienced. -->
|
2
|
+
<!-- Required. Describe, briefly, the behavior experienced and desired. -->
|
3
3
|
|
4
4
|
## Screenshots/Screencasts
|
5
5
|
<!-- Optional. Attach screenshot(s) and/or screencast(s) that demo the behavior. -->
|
@@ -7,8 +7,5 @@
|
|
7
7
|
## Steps to Recreate
|
8
8
|
<!-- Required. List exact steps (numbered list) to reproduce errant behavior. -->
|
9
9
|
|
10
|
-
## Desired Behavior
|
11
|
-
<!-- Required. Describe the behavior you'd like to see or your idea of a proposed solution. -->
|
12
|
-
|
13
10
|
## Environment
|
14
11
|
<!-- Required. What is your operating system, software version(s), etc. -->
|
@@ -1,6 +1,8 @@
|
|
1
1
|
inherit_from:
|
2
2
|
- https://raw.githubusercontent.com/bkuhlmann/code_quality/main/configurations/rubocop/ruby.yml
|
3
|
+
<% if configuration.build_rake %>
|
3
4
|
- https://raw.githubusercontent.com/bkuhlmann/code_quality/main/configurations/rubocop/rake.yml
|
5
|
+
<% end %>
|
4
6
|
- https://raw.githubusercontent.com/bkuhlmann/code_quality/main/configurations/rubocop/performance.yml
|
5
7
|
<% if configuration.build_rspec %>
|
6
8
|
- https://raw.githubusercontent.com/bkuhlmann/code_quality/main/configurations/rubocop/rspec.yml
|
@@ -0,0 +1,16 @@
|
|
1
|
+
cff-version: 1.2.0
|
2
|
+
message: <%= configuration.citation_message %>
|
3
|
+
title: <%= configuration.project_label %>
|
4
|
+
abstract:
|
5
|
+
version: <%= configuration.project_version %>
|
6
|
+
license: <%= configuration.license_label_version %>
|
7
|
+
date-released: <%= configuration.now.strftime "%Y-%m-%d" %>
|
8
|
+
authors:
|
9
|
+
- family-names: <%= configuration.author_family_name %>
|
10
|
+
given-names: <%= configuration.author_given_name %>
|
11
|
+
affiliation: <%= configuration.citation_affiliation %>
|
12
|
+
orcid: https://orcid.org/<%= configuration.citation_orcid %>
|
13
|
+
keywords:
|
14
|
+
- ruby
|
15
|
+
repository-code: <%= configuration.computed_project_url_source %>
|
16
|
+
repository-artifact: <%= configuration.computed_project_url_download %>
|
@@ -3,7 +3,7 @@ ruby File.read(".ruby-version").strip
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
5
|
<% if configuration.build_refinements %>
|
6
|
-
gem "refinements", "~>
|
6
|
+
gem "refinements", "~> 9.0"
|
7
7
|
<% end %>
|
8
8
|
<% if configuration.build_zeitwerk %>
|
9
9
|
gem "zeitwerk", "~> 2.5"
|
@@ -13,22 +13,25 @@ group :code_quality do
|
|
13
13
|
<% if configuration.build_bundler_leak %>
|
14
14
|
gem "bundler-leak", "~> 0.2"
|
15
15
|
<% end %>
|
16
|
+
<% if configuration.build_dead_end %>
|
17
|
+
gem "dead_end", "~> 3.0"
|
18
|
+
<% end %>
|
16
19
|
<% if configuration.build_git && configuration.build_git_lint %>
|
17
|
-
gem "git-lint", "~>
|
20
|
+
gem "git-lint", "~> 3.0"
|
18
21
|
<% end %>
|
19
22
|
<% if configuration.build_reek %>
|
20
23
|
gem "reek", "~> 6.0"
|
21
24
|
<% end %>
|
22
25
|
<% if configuration.build_rubocop %>
|
23
|
-
gem "rubocop", "~> 1.
|
24
|
-
gem "rubocop-performance", "~> 1.
|
26
|
+
gem "rubocop", "~> 1.24"
|
27
|
+
gem "rubocop-performance", "~> 1.12"
|
25
28
|
gem "rubocop-rake", "~> 0.6"
|
26
29
|
<% end %>
|
27
30
|
<% if configuration.build_rspec && configuration.build_rubocop %>
|
28
|
-
gem "rubocop-rspec", "~> 2.
|
31
|
+
gem "rubocop-rspec", "~> 2.6"
|
29
32
|
<% end %>
|
30
33
|
<% if configuration.build_simple_cov %>
|
31
|
-
gem "simplecov", "~> 0.
|
34
|
+
gem "simplecov", "~> 0.21"
|
32
35
|
<% end %>
|
33
36
|
end
|
34
37
|
|
@@ -37,7 +40,7 @@ group :development do
|
|
37
40
|
gem "rake", "~> 13.0"
|
38
41
|
<% end %>
|
39
42
|
<% if configuration.markdown? %>
|
40
|
-
gem "tocer", "~>
|
43
|
+
gem "tocer", "~> 13.0"
|
41
44
|
<% end %>
|
42
45
|
end
|
43
46
|
|
@@ -52,9 +55,9 @@ end
|
|
52
55
|
|
53
56
|
group :tools do
|
54
57
|
<% if configuration.build_amazing_print %>
|
55
|
-
gem "amazing_print", "~> 1.
|
58
|
+
gem "amazing_print", "~> 1.4"
|
56
59
|
<% end %>
|
57
60
|
<% if configuration.build_debug %>
|
58
|
-
gem "debug", "~> 1.
|
61
|
+
gem "debug", "~> 1.4"
|
59
62
|
<% end %>
|
60
63
|
end
|