dev_suite 0.2.4 → 0.2.5
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/Gemfile +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +53 -0
- data/dev_suite.gemspec +0 -4
- data/lib/dev_suite/cli/commands/base.rb +0 -2
- data/lib/dev_suite/cli/commands/tree.rb +3 -3
- data/lib/dev_suite/cli/commands/version.rb +1 -1
- data/lib/dev_suite/cli/main.rb +1 -1
- data/lib/dev_suite/dev_suite.rb +12 -0
- data/lib/dev_suite/directory_tree/config/config.rb +11 -0
- data/lib/dev_suite/directory_tree/config/configuration.rb +21 -0
- data/lib/dev_suite/directory_tree/config.rb +2 -36
- data/lib/dev_suite/directory_tree/directory_tree.rb +0 -1
- data/lib/dev_suite/directory_tree/renderer/base.rb +0 -6
- data/lib/dev_suite/performance/analyzer.rb +1 -1
- data/lib/dev_suite/performance/config/config.rb +11 -0
- data/lib/dev_suite/performance/config/configuration.rb +30 -0
- data/lib/dev_suite/performance/config.rb +2 -30
- data/lib/dev_suite/performance/{reportor → reporter}/base.rb +1 -1
- data/lib/dev_suite/performance/{reportor → reporter}/helpers/stat_mappings.rb +1 -1
- data/lib/dev_suite/performance/{reportor → reporter}/helpers/table_builder.rb +1 -1
- data/lib/dev_suite/performance/{reportor → reporter}/helpers.rb +1 -1
- data/lib/dev_suite/performance/{reportor → reporter}/simple.rb +1 -1
- data/lib/dev_suite/performance/reporter.rb +22 -0
- data/lib/dev_suite/performance.rb +1 -1
- data/lib/dev_suite/request_logger/adapter/adapter.rb +27 -0
- data/lib/dev_suite/request_logger/adapter/base.rb +17 -0
- data/lib/dev_suite/request_logger/adapter/net_http.rb +42 -0
- data/lib/dev_suite/request_logger/adapter.rb +9 -0
- data/lib/dev_suite/request_logger/config/config.rb +11 -0
- data/lib/dev_suite/request_logger/config/configuration.rb +24 -0
- data/lib/dev_suite/request_logger/config.rb +9 -0
- data/lib/dev_suite/request_logger/logger.rb +93 -0
- data/lib/dev_suite/request_logger/request_logger.rb +29 -0
- data/lib/dev_suite/request_logger.rb +7 -0
- data/lib/dev_suite/utils/color/color.rb +12 -0
- data/lib/dev_suite/utils/color/config/config.rb +13 -0
- data/lib/dev_suite/utils/color/config/configuration.rb +31 -0
- data/lib/dev_suite/utils/color/config.rb +2 -31
- data/lib/dev_suite/utils/color/strategy/theme.rb +6 -7
- data/lib/dev_suite/utils/color/strategy.rb +2 -4
- data/lib/dev_suite/utils/color.rb +1 -4
- data/lib/dev_suite/utils/construct/config/attribute/attribute.rb +15 -0
- data/lib/dev_suite/utils/construct/config/attribute/manager.rb +63 -0
- data/lib/dev_suite/utils/construct/config/attribute/resolver.rb +31 -0
- data/lib/dev_suite/utils/construct/config/attribute/validator.rb +55 -0
- data/lib/dev_suite/utils/construct/config/attribute.rb +13 -0
- data/lib/dev_suite/utils/construct/config/base.rb +20 -0
- data/lib/dev_suite/utils/construct/config/config.rb +24 -0
- data/lib/dev_suite/utils/construct/config/configuration.rb +13 -0
- data/lib/dev_suite/utils/construct/config/hook/hook.rb +13 -0
- data/lib/dev_suite/utils/construct/config/hook/manager.rb +36 -0
- data/lib/dev_suite/utils/construct/config/hook.rb +13 -0
- data/lib/dev_suite/utils/construct/config/initializer.rb +21 -0
- data/lib/dev_suite/utils/construct/config/manager.rb +33 -0
- data/lib/dev_suite/utils/construct/config/settings/base.rb +59 -0
- data/lib/dev_suite/utils/construct/config/settings/manager.rb +38 -0
- data/lib/dev_suite/utils/construct/config/settings/settings.rb +14 -0
- data/lib/dev_suite/utils/construct/config/settings.rb +13 -0
- data/lib/dev_suite/utils/construct/config.rb +11 -0
- data/lib/dev_suite/utils/construct/construct.rb +9 -0
- data/lib/dev_suite/utils/construct.rb +16 -0
- data/lib/dev_suite/utils/emoji.rb +71 -0
- data/lib/dev_suite/utils/error_handler.rb +24 -0
- data/lib/dev_suite/utils/file_loader/config/config.rb +13 -0
- data/lib/dev_suite/utils/file_loader/config/configuration.rb +33 -0
- data/lib/dev_suite/utils/file_loader/config.rb +11 -0
- data/lib/dev_suite/utils/file_loader/file_loader.rb +23 -0
- data/lib/dev_suite/utils/file_loader/loader/base.rb +21 -0
- data/lib/dev_suite/utils/file_loader/loader/json.rb +21 -0
- data/lib/dev_suite/utils/file_loader/loader/text.rb +21 -0
- data/lib/dev_suite/utils/file_loader/loader/yaml.rb +38 -0
- data/lib/dev_suite/utils/file_loader/loader.rb +41 -0
- data/lib/dev_suite/utils/file_loader/loader_manager.rb +34 -0
- data/lib/dev_suite/utils/file_loader/loader_registry.rb +36 -0
- data/lib/dev_suite/utils/file_loader.rb +9 -0
- data/lib/dev_suite/utils/logger.rb +58 -0
- data/lib/dev_suite/utils/path_matcher/matcher.rb +31 -0
- data/lib/dev_suite/utils/path_matcher/path_matcher.rb +17 -0
- data/lib/dev_suite/utils/path_matcher/pattern.rb +35 -0
- data/lib/dev_suite/utils/path_matcher.rb +9 -0
- data/lib/dev_suite/utils/table/config/config.rb +13 -0
- data/lib/dev_suite/utils/table/config/configuration.rb +32 -0
- data/lib/dev_suite/utils/table/config.rb +2 -23
- data/lib/dev_suite/utils/table/renderer/base.rb +0 -6
- data/lib/dev_suite/utils/table/renderer/simple.rb +9 -5
- data/lib/dev_suite/utils/table/renderer.rb +2 -2
- data/lib/dev_suite/utils/table/table.rb +6 -0
- data/lib/dev_suite/utils/table.rb +0 -6
- data/lib/dev_suite/utils/utils.rb +14 -0
- data/lib/dev_suite/utils.rb +1 -3
- data/lib/dev_suite/version.rb +1 -1
- data/lib/dev_suite.rb +1 -10
- metadata +68 -44
- data/lib/dev_suite/directory_tree/settings.rb +0 -18
- data/lib/dev_suite/emoji.rb +0 -33
- data/lib/dev_suite/error_handler.rb +0 -22
- data/lib/dev_suite/logger.rb +0 -56
- data/lib/dev_suite/performance/reportor.rb +0 -22
- data/lib/dev_suite/utils/config_tools/configuration.rb +0 -134
- data/lib/dev_suite/utils/config_tools/settings.rb +0 -67
- data/lib/dev_suite/utils/config_tools.rb +0 -10
- data/lib/dev_suite/utils/table/settings.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d90d0f33e4d0651dbc5ed388a62c7c0b3a665cb27db805631d8771245b21129e
|
4
|
+
data.tar.gz: e87b028766648877eea33d3c2910d3879510a50d4425fd9b19bf96212cb141a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7a4fdb6138b2c9e75bafa923f095479827d58c229fdc60f2ae8c2b5e2a6a04f8e39c6ed27cf26ab3c53a62f606c5931c851698c1b577f6bdb1bad45289b344e
|
7
|
+
data.tar.gz: 1d10bd660e02d4100ee58fb7607626cfaf2ef714811a9407d25ae12f9fe71ae3ed9fd36d8b21de8bdba6b288223ed9a8b58ae22deb6e3ac297d24692e90ca86e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -153,6 +153,59 @@ DevSuite also provides a command-line interface for various utilities. Below are
|
|
153
153
|
```
|
154
154
|
</details>
|
155
155
|
|
156
|
+
### Request Logging
|
157
|
+
<details>
|
158
|
+
<summary>Show more</summary>
|
159
|
+
|
160
|
+
**Purpose**: The `RequestLogger` feature enables detailed logging of HTTP requests and responses across different adapters (e.g., `Net::HTTP`, `Faraday`). This can be useful for debugging, monitoring, and auditing API interactions.
|
161
|
+
|
162
|
+
**How to Use**:
|
163
|
+
```ruby
|
164
|
+
require 'dev_suite'
|
165
|
+
|
166
|
+
DevSuite::RequestLogger.with_logging do
|
167
|
+
# Make an HTTP request using Net::HTTP
|
168
|
+
uri = URI('https://jsonplaceholder.typicode.com/posts')
|
169
|
+
response = Net::HTTP.get(uri)
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
**Configuration Guide**:
|
174
|
+
Customize the request logging behavior by setting configuration options:
|
175
|
+
```ruby
|
176
|
+
DevSuite::RequestLogger.configure do |config|
|
177
|
+
config.adapters = [:net_http]
|
178
|
+
...
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
**Configuration Options**:
|
183
|
+
|
184
|
+
Below is a table describing the available configuration settings:
|
185
|
+
|
186
|
+
| Setting | Description | Example Values |
|
187
|
+
|----------------|----------------------------------------------------|------------------------------------|
|
188
|
+
| `:adapters` | List of adapters for which logging is enabled. | `[:net_http, :faraday]` |
|
189
|
+
<!-- | `:log_level` | Set the logging level (e.g., info, debug). | `:info`, `:debug`, `:warn`, `:error` |
|
190
|
+
| `:log_response` | Enable or disable response logging. | `true`, `false` |
|
191
|
+
| `:log_emoji` | Customize emojis for request and response logs. | `{ request: :globe, response: :envelope }` | -->
|
192
|
+
|
193
|
+
**Adapters Supported**:
|
194
|
+
|
195
|
+
The `RequestLogger` currently supports the following adapters:
|
196
|
+
|
197
|
+
| Adapter | Description | Example Usage |
|
198
|
+
|--------------|--------------------------------------------|---------------------------------------------------|
|
199
|
+
| `Net::HTTP` | Logs requests made with the Net::HTTP class.| `DevSuite::RequestLogger::Adapter::NetHttp.new(config)` |
|
200
|
+
<!-- | `Faraday` | Logs requests made with the Faraday gem. | `DevSuite::RequestLogger::Adapter::Faraday.new(config)` | -->
|
201
|
+
|
202
|
+
**Sample Output**:
|
203
|
+
```bash
|
204
|
+
[INFO] 🌐 Net::HTTP Request: GET http://example.com
|
205
|
+
[DEBUG] 📄 Net::HTTP Response: 200 OK
|
206
|
+
```
|
207
|
+
</details>
|
208
|
+
|
156
209
|
## Development
|
157
210
|
|
158
211
|
After checking out the repo, run `bin/setup`for an interactive prompt that will allow you to experiment.
|
data/dev_suite.gemspec
CHANGED
@@ -33,8 +33,4 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_dependency("benchmark", "~> 0.1")
|
34
34
|
spec.add_dependency("get_process_mem", "~> 1.0")
|
35
35
|
spec.add_dependency("thor", "~> 1.1")
|
36
|
-
|
37
|
-
# Development dependencies
|
38
|
-
spec.add_development_dependency("rspec", "~> 3.9")
|
39
|
-
spec.add_development_dependency("simplecov", "~> 0.21")
|
40
36
|
end
|
@@ -6,14 +6,14 @@ module DevSuite
|
|
6
6
|
class Tree < Base
|
7
7
|
desc "visualize PATH", "Visualize the directory structure at given PATH"
|
8
8
|
def execute(path, options: {})
|
9
|
-
Logger.log("Starting visualization for: #{path}", emoji: :start)
|
9
|
+
Utils::Logger.log("Starting visualization for: #{path}", emoji: :start)
|
10
10
|
|
11
11
|
apply_configure(options)
|
12
12
|
visualize(path)
|
13
13
|
|
14
|
-
Logger.log("Visualization complete!", emoji: :success)
|
14
|
+
Utils::Logger.log("Visualization complete!", emoji: :success)
|
15
15
|
rescue StandardError => e
|
16
|
-
ErrorHandler.handle_error(e)
|
16
|
+
Utils::ErrorHandler.handle_error(e)
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
data/lib/dev_suite/cli/main.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
require_relative "version"
|
5
|
+
require_relative "utils"
|
6
|
+
require_relative "cli"
|
7
|
+
require_relative "performance"
|
8
|
+
require_relative "directory_tree"
|
9
|
+
require_relative "request_logger"
|
10
|
+
|
11
|
+
class Error < StandardError; end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module DirectoryTree
|
5
|
+
module Config
|
6
|
+
class Configuration < BaseConfiguration
|
7
|
+
set_default_settings(
|
8
|
+
skip_hidden: false,
|
9
|
+
skip_types: [],
|
10
|
+
max_depth: nil,
|
11
|
+
max_size: 100 * 1024 * 1024, # 100 MB
|
12
|
+
)
|
13
|
+
|
14
|
+
# Define configuration attributes
|
15
|
+
config_attr :builder, default_value: :base, type: :symbol, resolver: ->(value) { Builder.create(value) }
|
16
|
+
config_attr :renderer, default_value: :simple, type: :symbol, resolver: ->(value) { Renderer.create(value) }
|
17
|
+
config_attr :visualizer, default_value: :tree, type: :symbol, resolver: ->(value) { Visualizer.create(value) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,42 +2,8 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module DirectoryTree
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Define configuration attributes
|
9
|
-
config_attr :settings, default_value: {}
|
10
|
-
config_attr :builder, default_value: :base
|
11
|
-
config_attr :renderer, default_value: :simple
|
12
|
-
config_attr :visualizer, default_value: :tree
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def validate_attr!(attr, value)
|
17
|
-
case attr
|
18
|
-
when :settings
|
19
|
-
validate_hash!(attr, value)
|
20
|
-
when :builder, :renderer, :visualizer
|
21
|
-
validate_symbol!(attr, value)
|
22
|
-
else
|
23
|
-
raise ArgumentError, "Invalid attribute: #{attr}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def resolve_attr(attr, value)
|
28
|
-
case attr
|
29
|
-
when :settings
|
30
|
-
Settings.new(value)
|
31
|
-
when :builder
|
32
|
-
Builder.create(value)
|
33
|
-
when :renderer
|
34
|
-
Renderer.create(value)
|
35
|
-
when :visualizer
|
36
|
-
Visualizer.create(value)
|
37
|
-
else
|
38
|
-
super # Return the value directly if no special resolution is needed
|
39
|
-
end
|
40
|
-
end
|
5
|
+
module Config
|
6
|
+
require_relative "config/config"
|
41
7
|
end
|
42
8
|
end
|
43
9
|
end
|
@@ -25,7 +25,7 @@ module DevSuite
|
|
25
25
|
# @param benchmark_result [Benchmark::Tms] The benchmark result
|
26
26
|
# @param memory_stats [Hash] The memory statistics
|
27
27
|
def generate_report(results)
|
28
|
-
Config.configuration.
|
28
|
+
Config.configuration.reporter.generate(
|
29
29
|
description: @description,
|
30
30
|
results: results,
|
31
31
|
)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Performance
|
5
|
+
module Config
|
6
|
+
class Configuration < BaseConfiguration
|
7
|
+
# Define configuration attributes
|
8
|
+
config_attr :profilers,
|
9
|
+
default_value: [:execution_time, :memory],
|
10
|
+
type: :array,
|
11
|
+
resolver: :resolve_profilers
|
12
|
+
|
13
|
+
config_attr :reporter,
|
14
|
+
default_value: :simple,
|
15
|
+
type: :symbol,
|
16
|
+
resolver: :resolve_reporter
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def resolve_profilers(value)
|
21
|
+
Profiler.create_multiple(value)
|
22
|
+
end
|
23
|
+
|
24
|
+
def resolve_reporter(value)
|
25
|
+
Reporter.create(value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -2,36 +2,8 @@
|
|
2
2
|
|
3
3
|
module DevSuite
|
4
4
|
module Performance
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Define configuration attributes
|
9
|
-
config_attr :profilers, default_value: [:execution_time, :memory]
|
10
|
-
config_attr :reportor, default_value: :simple
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def validate_attr!(attr, value)
|
15
|
-
case attr
|
16
|
-
when :profilers
|
17
|
-
validate_array!(attr, value)
|
18
|
-
when :reportor
|
19
|
-
validate_symbol!(attr, value)
|
20
|
-
else
|
21
|
-
raise ArgumentError, "Invalid attribute: #{attr}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def resolve_attr(attr, value)
|
26
|
-
case attr
|
27
|
-
when :profilers
|
28
|
-
Profiler.create_multiple(value)
|
29
|
-
when :reportor
|
30
|
-
Reportor.create(value)
|
31
|
-
else
|
32
|
-
value
|
33
|
-
end
|
34
|
-
end
|
5
|
+
module Config
|
6
|
+
require_relative "config/config"
|
35
7
|
end
|
36
8
|
end
|
37
9
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module Performance
|
5
|
+
module Reporter
|
6
|
+
require_relative "reporter/base"
|
7
|
+
require_relative "reporter/simple"
|
8
|
+
require_relative "reporter/helpers"
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def create(reporter)
|
12
|
+
case reporter
|
13
|
+
when :simple
|
14
|
+
Simple.new
|
15
|
+
else
|
16
|
+
raise ArgumentError, "Invalid reporter: #{reporter}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -8,7 +8,7 @@ module DevSuite
|
|
8
8
|
require_relative "performance/data"
|
9
9
|
require_relative "performance/profiler"
|
10
10
|
require_relative "performance/profiler_manager"
|
11
|
-
require_relative "performance/
|
11
|
+
require_relative "performance/reporter"
|
12
12
|
require_relative "performance/analyzer"
|
13
13
|
require_relative "performance/config"
|
14
14
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module RequestLogger
|
5
|
+
module Adapter
|
6
|
+
require "net/http"
|
7
|
+
|
8
|
+
require_relative "base"
|
9
|
+
require_relative "net_http"
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def create(adapter)
|
13
|
+
case adapter
|
14
|
+
when :net_http
|
15
|
+
NetHttp.new
|
16
|
+
else
|
17
|
+
raise ArgumentError, "Adapter not found: #{adapter}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_multiple(adapters)
|
22
|
+
adapters.map { |adapter| create(adapter) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module RequestLogger
|
5
|
+
module Adapter
|
6
|
+
class NetHttp < Base
|
7
|
+
# Enables the logging of Net::HTTP requests by monkey patching the request method
|
8
|
+
def enable
|
9
|
+
::Net::HTTP.class_eval do
|
10
|
+
# Alias the original request method with a unique name (_original_request)
|
11
|
+
# This preserves the original functionality so it can still be called after logging is added
|
12
|
+
alias_method(:_original_request, :request)
|
13
|
+
|
14
|
+
# Override the request method to add logging functionality
|
15
|
+
def request(request, body = nil, &block)
|
16
|
+
# Log the full URL of the HTTP request using the DevSuite::Utils::Logger
|
17
|
+
Logger.log_request(self, request)
|
18
|
+
|
19
|
+
# Call the original request method (now aliased as _original_request) to perform the actual HTTP request
|
20
|
+
response = _original_request(request, body, &block)
|
21
|
+
|
22
|
+
# Optionally log the response details
|
23
|
+
Logger.log_response(self, response)
|
24
|
+
|
25
|
+
# Return the response object so that the calling code receives the expected result
|
26
|
+
response
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Disables the logging by restoring the original Net::HTTP request method
|
32
|
+
def disable
|
33
|
+
::Net::HTTP.class_eval do
|
34
|
+
# Restore the original request method by aliasing it back from _original_request
|
35
|
+
# This effectively removes the logging functionality and returns Net::HTTP to its original state
|
36
|
+
alias_method(:request, :_original_request)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module RequestLogger
|
5
|
+
module Config
|
6
|
+
class Configuration < BaseConfiguration
|
7
|
+
set_default_settings(
|
8
|
+
log_headers: true,
|
9
|
+
log_cookies: true,
|
10
|
+
log_body: true,
|
11
|
+
log_level: :debug,
|
12
|
+
)
|
13
|
+
|
14
|
+
config_attr :adapters, default_value: [:net_http], type: :array, resolver: :resolve_adapters
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def resolve_adapters(value)
|
19
|
+
Adapter.create_multiple(value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|