bugsnag-capistrano 1.1.0 → 2.1.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 +5 -5
- data/.github/ISSUE_TEMPLATE/A.md +14 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.github/support.md +22 -0
- data/.github/workflows/tests.yml +34 -0
- data/CHANGELOG.md +25 -0
- data/CONTRIBUTING.md +2 -1
- data/Gemfile +6 -3
- data/README.md +1 -3
- data/Rakefile +1 -19
- data/UPGRADING.md +27 -0
- data/VERSION +1 -1
- data/lib/bugsnag-capistrano/capistrano.rb +1 -1
- data/lib/bugsnag-capistrano/capistrano2.rb +14 -11
- data/lib/bugsnag-capistrano/release.rb +85 -0
- data/lib/bugsnag-capistrano/tasks/bugsnag.cap +13 -17
- data/spec/capistrano_spec.rb +93 -42
- data/spec/helpers/capistrano.rb +71 -0
- data/spec/helpers/server.rb +63 -0
- data/spec/release_spec.rb +94 -0
- data/spec/spec_helper.rb +2 -0
- metadata +15 -10
- data/.travis.yml +0 -77
- data/lib/bugsnag-capistrano/deploy.rb +0 -98
- data/lib/bugsnag-capistrano/tasks.rb +0 -2
- data/lib/bugsnag-capistrano/tasks/bugsnag-capistrano.rake +0 -85
- data/spec/deploy_spec.rb +0 -66
- data/spec/rake_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3168c9e9326354256532148f5b3e4549c265ed24f5e2839d1acdad19dc11aae6
|
4
|
+
data.tar.gz: 168d0ce8410d7bb134a3c25e3419c3fa443fa3f87c261fc3e206fdb713780203
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ded5c9418e59257e5fb753df27810d85e1d7577c65551fb35f250379f41bf131e3187f30c740a6dc70792e851381a1227316a6cf56be4d09cf4e01444eb4bf6
|
7
|
+
data.tar.gz: 384d6f05fcec38924bf69e26f6d54ccd0953c55c6d79145660257729f95561b7f1bfb898df7f51b4eea5671e4e06a454f8833d46b6e39756a7af75bc68902613
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
name: Having trouble getting started?
|
3
|
+
about: Please contact us at support@bugsnag.com for assistance with integrating Bugsnag
|
4
|
+
into your application.
|
5
|
+
title: ''
|
6
|
+
labels: ''
|
7
|
+
assignees: ''
|
8
|
+
|
9
|
+
---
|
10
|
+
Please checkout our [documentation](https://docs.bugsnag.com/build-integrations/capistrano/) for guides, references and tutorials.
|
11
|
+
|
12
|
+
If you have questions about your integration please contact us at [support@bugsnag.com](mailto:support@bugsnag.com).
|
13
|
+
|
14
|
+
Alternatively, view additional options at [support.md](../SUPPORT.md).
|
@@ -0,0 +1,50 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve the library
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!-- Before raising, please check if somebody else has already reported your issue. -->
|
11
|
+
|
12
|
+
### Describe the bug
|
13
|
+
A clear and concise description of what the bug is.
|
14
|
+
|
15
|
+
### Steps to reproduce
|
16
|
+
1. Go to '...'
|
17
|
+
2. Click on '....'
|
18
|
+
3. Scroll down to '....'
|
19
|
+
4. See error
|
20
|
+
|
21
|
+
### Environment
|
22
|
+
* Bugsnag version:
|
23
|
+
* Ruby version:
|
24
|
+
* Bundle version:
|
25
|
+
* Capfile:
|
26
|
+
|
27
|
+
<!--
|
28
|
+
Below are a few approaches you might take to communicate the issue, in
|
29
|
+
descending order of awesomeness. Please choose one and feel free to delete
|
30
|
+
the others from this template.
|
31
|
+
-->
|
32
|
+
|
33
|
+
### Example Repo <!-- Option 1 -->
|
34
|
+
|
35
|
+
- [ ] Create a minimal repository that can reproduce the issue
|
36
|
+
- [ ] Link to it here:
|
37
|
+
|
38
|
+
### Example code snippet <!-- Option 2 -->
|
39
|
+
|
40
|
+
```
|
41
|
+
# (Insert code sample to reproduce the problem)
|
42
|
+
```
|
43
|
+
|
44
|
+
<!-- Error messages, if any -->
|
45
|
+
<details><summary>Error messages:</summary>
|
46
|
+
|
47
|
+
```
|
48
|
+
|
49
|
+
```
|
50
|
+
</details>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!-- Before creating, please check if somebody else has already reported your feature request. -->
|
11
|
+
|
12
|
+
### Description
|
13
|
+
<!-- Is your feature request related to a problem? Please describe.
|
14
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
15
|
+
-->
|
16
|
+
|
17
|
+
**Describe the solution you'd like**
|
18
|
+
<!-- A clear and concise description of what you want to happen. -->
|
19
|
+
|
20
|
+
**Describe alternatives you've considered**
|
21
|
+
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
22
|
+
|
23
|
+
**Additional context**
|
24
|
+
<!--Add any other context about the feature request here.-->
|
@@ -0,0 +1,16 @@
|
|
1
|
+
## Goal
|
2
|
+
|
3
|
+
<!-- Why is this change necessary? -->
|
4
|
+
|
5
|
+
## Design
|
6
|
+
|
7
|
+
<!-- Why was this approach used? -->
|
8
|
+
|
9
|
+
## Changeset
|
10
|
+
|
11
|
+
<!-- What changed? -->
|
12
|
+
|
13
|
+
## Testing
|
14
|
+
|
15
|
+
<!-- How was it tested? What manual and automated tests were
|
16
|
+
run/added? -->
|
data/.github/support.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
## Are you having trouble getting started?
|
2
|
+
If you haven't already, please checkout our [documentation](https://docs.bugsnag.com/build-integrations/capistrano/) for guides, references and tutorials.
|
3
|
+
|
4
|
+
Or, if you wish you can [contact us directly](mailto:support@bugsnag.com) for assistance on integrating Bugsnag into your application, troubleshooting an issue or a question about our supported features.
|
5
|
+
|
6
|
+
When contacting support, please include as much information as necessary, including:
|
7
|
+
|
8
|
+
- example code snippet
|
9
|
+
- steps to reproduce
|
10
|
+
- expected/actual behaviour
|
11
|
+
|
12
|
+
* Bugsnag version:
|
13
|
+
* Ruby version:
|
14
|
+
* Bundle version:
|
15
|
+
* Capfile:
|
16
|
+
|
17
|
+
## Bug or Feature Requests
|
18
|
+
If you would like to raise a bug or feature request please do so by creating a [New Issue](https://github.com/bugsnag/bugsnag-capistrano/issues/new/choose) and selecting bug or feature.
|
19
|
+
Please note: we cannot promise that we will fulfil all requests
|
20
|
+
|
21
|
+
## Pull Requests
|
22
|
+
If you have made a fix and would like to raise a pull request, please read our [CONTRIBUTING.md](../CONTRIBUTING.md) file before creating the pull request.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
specs:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby-version: ['2.0', '2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '3.0']
|
12
|
+
use-capistrano-2: ['false']
|
13
|
+
include:
|
14
|
+
- ruby-version: '2.0'
|
15
|
+
use-capistrano-2: 'true'
|
16
|
+
- ruby-version: '2.1'
|
17
|
+
use-capistrano-2: 'true'
|
18
|
+
|
19
|
+
env:
|
20
|
+
BUNDLE_WITH: test
|
21
|
+
CAP_2_TEST: ${{ matrix.use-capistrano-2 }}
|
22
|
+
|
23
|
+
steps:
|
24
|
+
- uses: actions/checkout@v2
|
25
|
+
|
26
|
+
- name: Install Ruby
|
27
|
+
uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: ${{ matrix.ruby-version }}
|
30
|
+
bundler-cache: true
|
31
|
+
|
32
|
+
- run: bundle info capistrano
|
33
|
+
|
34
|
+
- run: bundle exec rake spec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
## 2.1.0 (13-07-2021)
|
2
|
+
|
3
|
+
### Enhancements
|
4
|
+
|
5
|
+
* Allow using a Bugsnag-specific repo URL with a new `:bugsnag_repo_url` variable
|
6
|
+
| [#22](https://github.com/bugsnag/bugsnag-capistrano/pull/22)
|
7
|
+
| [Simon](https://github.com/stoivo)
|
8
|
+
|
9
|
+
## 2.0.0 (03-04-2018)
|
10
|
+
|
11
|
+
Major changes have been made with the 2.0.0 release. For a full list please consult the [upgrading guide](https://github.com/bugsnag/bugsnag-capistrano/blob/master/UPGRADING.md).
|
12
|
+
|
13
|
+
### Enhancements
|
14
|
+
|
15
|
+
* Rewritten tool to notify [Bugsnag Build API](https://docs.bugsnag.com/build-integrations/)
|
16
|
+
| [#13](https://github.com/bugsnag/bugsnag-capistrano/pull/13)
|
17
|
+
|
18
|
+
## 1.1.1 (14-12-2017)
|
19
|
+
|
20
|
+
### Fixes
|
21
|
+
|
22
|
+
* Load BUGSNAG_RELEASE_STAGE before RAILS_ENV
|
23
|
+
| [#6](https://github.com/bugsnag/bugsnag-capistrano/pull/6)
|
24
|
+
| [Samnang Chhun](https://github.com/samnang)
|
25
|
+
|
1
26
|
## 1.1.0 (23-11-2017)
|
2
27
|
|
3
28
|
### Enhancements
|
data/CONTRIBUTING.md
CHANGED
data/Gemfile
CHANGED
@@ -8,10 +8,13 @@ group :test, optional: true do
|
|
8
8
|
gem 'addressable', '~>2.3.8'
|
9
9
|
gem 'webmock', RUBY_VERSION <= '1.9.3' ? '2.3.2': '>2.3.2'
|
10
10
|
gem 'capistrano', ENV['CAP_2_TEST'] == 'true' ? '~> 2.15.0': '~> 3.9.0'
|
11
|
-
end
|
12
11
|
|
13
|
-
|
14
|
-
gem '
|
12
|
+
# WEBrick is no longer in the stdlib in Ruby 3.0
|
13
|
+
gem 'webrick' if RUBY_VERSION >= '3.0.0'
|
14
|
+
gem 'rexml', '< 3.2.5' if RUBY_VERSION == '2.0.0'
|
15
|
+
|
16
|
+
# i18n added a call to Module#using in 1.3.0, which doesn't exist until Ruby 2.1
|
17
|
+
gem 'i18n', '< 1.3.0' if RUBY_VERSION == '2.0.0'
|
15
18
|
end
|
16
19
|
|
17
20
|
gemspec
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# Bugsnag deploy tracking with Capistrano
|
2
|
-
[](https://travis-ci.org/bugsnag/bugsnag-capistrano)
|
3
2
|
|
4
3
|
Bugsnag Capistrano automatically notifies Bugsnag when you deploy your
|
5
4
|
application with [Capistrano](https://github.com/capistrano/capistrano),
|
@@ -16,8 +15,7 @@ capturing exceptions from your applications.
|
|
16
15
|
|
17
16
|
## Getting started
|
18
17
|
|
19
|
-
* [Integrating with Capistrano](https://docs.bugsnag.com/
|
20
|
-
* [Integrating with Rake](https://docs.bugsnag.com/api/deploy-tracking/rake/)
|
18
|
+
* [Integrating with Capistrano](https://docs.bugsnag.com/build-integrations/capistrano/)
|
21
19
|
|
22
20
|
## Contributing
|
23
21
|
|
data/Rakefile
CHANGED
@@ -1,16 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler'
|
5
|
-
require 'bundler/gem_tasks'
|
6
|
-
begin
|
7
|
-
Bundler.setup(:default)
|
8
|
-
rescue Bundler::BundlerError => e
|
9
|
-
$stderr.puts e.message
|
10
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
-
exit e.status_code
|
12
|
-
end
|
13
|
-
|
14
3
|
require 'rdoc/task'
|
15
4
|
RDoc::Task.new do |rdoc|
|
16
5
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
@@ -25,14 +14,7 @@ end
|
|
25
14
|
require 'rspec/core'
|
26
15
|
require "rspec/core/rake_task"
|
27
16
|
|
28
|
-
tags = '--format documentation
|
29
|
-
|
30
|
-
begin
|
31
|
-
require 'bugsnag'
|
32
|
-
tags += '--tag with_notifier '
|
33
|
-
rescue LoadError
|
34
|
-
tags += '--tag without_notifier '
|
35
|
-
end
|
17
|
+
tags = '--format documentation'
|
36
18
|
|
37
19
|
RSpec::Core::RakeTask.new(:spec) do |opts|
|
38
20
|
opts.rspec_opts = tags
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Upgrade Guide
|
2
|
+
|
3
|
+
## 1.x to 2.x
|
4
|
+
|
5
|
+
_Our Capistrano build-integration has changed to accommodate changes to our [Build API](https://docs.bugsnag.com/build-integrations/), and there may be changes required to continue to notify of your Capistrano releases_
|
6
|
+
|
7
|
+
#### Heroku
|
8
|
+
|
9
|
+
Heroku deployment notifications have been removed from this gem. You can find information on how to set up a Heroku deploy hook at [our documentation](https://docs.bugsnag.com/build-integrations/heroku/).
|
10
|
+
|
11
|
+
#### Rake
|
12
|
+
|
13
|
+
Rake deployment notifications have been removed from this gem. While we don't have an explicit replacement for the Rake tasks, information on how to send a build notification can be found in [our Build API documentation](https://docs.bugsnag.com/build-integrations/).
|
14
|
+
|
15
|
+
#### Task names
|
16
|
+
|
17
|
+
The task `:deploy` has been renamed to `:release`. Any references to it should be renamed accordingly.
|
18
|
+
|
19
|
+
#### Configuration
|
20
|
+
|
21
|
+
- `branch` has been removed.
|
22
|
+
- `bugsnag_builder` has been added. This should be the name of the person or machine that has triggered the release. Can also be set using the environment variables `BUGSNAG_BUILDER_NAME` or `USER`. Will default to the result of the `whoami` command on the releasing machine.
|
23
|
+
- `bugsnag_auto_assign_release` has been added. Thi#s will ensure **all** event notifications received will be assigned to this release. This should only be used if you are not using the `app_version` configuration option within your application. Can be set using the environment variable `BUGSNAG_AUTO_ASSIGN_RELEASE`. Will default to `false`.
|
24
|
+
- `bugsnag_source_control_provider` has been added. This contains the type of on-premise server the application uses for source-control, and therefore should only be used if an on-premise source-control solution is used. Valid settings are: `github-enterprise`, `gitlab-onpremise`, and `bitbucket-server`. Can be set using the environment variable `BUGSNAG_SOURCE_CONTROL_PROVIDER`. Defaults to `nil`.
|
25
|
+
- `bugsnag-metadata` has been added. This should be a hash containing any additional data you wish to attach to your release notification.
|
26
|
+
|
27
|
+
A full list of configuration options can be found at the [Capistrano build-integration guide](https://docs.bugsnag.com/build-integrations/capistrano/).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.1.0
|
@@ -2,25 +2,28 @@ module Bugsnag
|
|
2
2
|
module Capistrano
|
3
3
|
def self.load_into(configuration)
|
4
4
|
configuration.load do
|
5
|
-
after "deploy", "bugsnag:
|
6
|
-
after "deploy:migrations", "bugsnag:deploy"
|
5
|
+
after "deploy", "bugsnag:release"
|
7
6
|
|
8
7
|
namespace :bugsnag do
|
9
|
-
desc "Notify Bugsnag that new production code has been
|
10
|
-
task :
|
8
|
+
desc "Notify Bugsnag that new production code has been released"
|
9
|
+
task :release, :except => { :no_release => true }, :on_error => :continue do
|
11
10
|
begin
|
12
|
-
|
11
|
+
auto_assign_release_bool = ENV["BUGSNAG_AUTO_ASSIGN_RELEASE"] == 'true'
|
12
|
+
Bugsnag::Capistrano::Release.notify({
|
13
13
|
:api_key => fetch(:bugsnag_api_key, ENV["BUGSNAG_API_KEY"]),
|
14
|
+
:app_version => fetch(:app_version, ENV["BUGSNAG_APP_VERSION"]),
|
15
|
+
:auto_assign_release => fetch(:bugsnag_auto_assign_release, auto_assign_release_bool),
|
16
|
+
:builder_name => fetch(:bugsnag_builder, ENV["BUGSNAG_BUILDER_NAME"] || ENV["USER"]),
|
17
|
+
:metadata => fetch(:bugsnag_metadata, nil),
|
14
18
|
:release_stage => fetch(:bugsnag_env) || ENV["BUGSNAG_RELEASE_STAGE"] || fetch(:rails_env) || fetch(:stage) || "production",
|
15
19
|
:revision => fetch(:current_revision, ENV["BUGSNAG_REVISION"]),
|
16
|
-
:repository => fetch(:repo_url, ENV["BUGSNAG_REPOSITORY"]),
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:endpoint => fetch(:bugsnag_endpoint)
|
20
|
+
:repository => fetch(:bugsnag_repo_url, fetch(:repo_url, ENV["BUGSNAG_REPOSITORY"])),
|
21
|
+
:source_control_provider => fetch(:bugsnag_source_control_provider, ENV["BUGSNAG_SOURCE_CONTROL_PROVIDER"]),
|
22
|
+
:endpoint => fetch(:bugsnag_endpoint, nil)
|
20
23
|
})
|
21
|
-
logger.info "Bugsnag
|
24
|
+
logger.info "Bugsnag release notification complete."
|
22
25
|
rescue
|
23
|
-
logger.important("
|
26
|
+
logger.important("Bugsnag release notification failed, #{$!.inspect}")
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
module Bugsnag
|
6
|
+
module Capistrano
|
7
|
+
class Release
|
8
|
+
|
9
|
+
HEADERS = {"Content-Type" => "application/json"}
|
10
|
+
DEFAULT_BUILD_ENDPOINT = "https://build.bugsnag.com/"
|
11
|
+
DEFAULT_BUILD_TOOL_NAME = "bugsnag-capistrano"
|
12
|
+
|
13
|
+
def self.notify(opts = {})
|
14
|
+
# Try and get some config from Bugsnag
|
15
|
+
begin
|
16
|
+
require 'bugsnag'
|
17
|
+
|
18
|
+
opts[:api_key] ||= Bugsnag.configuration.api_key
|
19
|
+
opts[:app_version] ||= Bugsnag.configuration.app_version
|
20
|
+
opts[:release_stage] ||= Bugsnag.configuration.release_stage
|
21
|
+
rescue LoadError
|
22
|
+
end
|
23
|
+
|
24
|
+
opts[:endpoint] ||= DEFAULT_BUILD_ENDPOINT
|
25
|
+
opts[:builder_name] ||= `whoami`
|
26
|
+
opts[:build_tool] ||= DEFAULT_BUILD_TOOL_NAME
|
27
|
+
|
28
|
+
parameters = {
|
29
|
+
"apiKey" => opts[:api_key],
|
30
|
+
"appVersion" => opts[:app_version],
|
31
|
+
"autoAssignRelease" => opts[:auto_assign_release],
|
32
|
+
"builderName" => opts[:builder_name],
|
33
|
+
"buildTool" => opts[:build_tool],
|
34
|
+
"metadata" => opts[:metadata],
|
35
|
+
"releaseStage" => opts[:release_stage],
|
36
|
+
"sourceControl" => {
|
37
|
+
"provider" => opts[:source_control_provider],
|
38
|
+
"revision" => opts[:revision],
|
39
|
+
"repository" => opts[:repository]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
if parameters["apiKey"].nil?
|
44
|
+
logger.warn("Cannot deliver notification. Missing required apiKey")
|
45
|
+
elsif parameters["appVersion"].nil?
|
46
|
+
logger.warn("Cannot deliver notification. Missing required appVersion")
|
47
|
+
else
|
48
|
+
payload_string = ::JSON.dump(parameters)
|
49
|
+
self.deliver(opts[:endpoint], payload_string)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.deliver(url, body)
|
54
|
+
begin
|
55
|
+
request(url, body)
|
56
|
+
rescue StandardError => e
|
57
|
+
logger.warn("Notification to #{url} failed, #{e.inspect}")
|
58
|
+
logger.warn(e.backtrace)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.request(url, body)
|
63
|
+
uri = URI.parse(url)
|
64
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
65
|
+
http.read_timeout = 15
|
66
|
+
http.open_timeout = 15
|
67
|
+
|
68
|
+
http.use_ssl = uri.scheme == "https"
|
69
|
+
|
70
|
+
uri.path == "" ? "/" : uri.path
|
71
|
+
request = Net::HTTP::Post.new(uri, HEADERS)
|
72
|
+
request.body = body
|
73
|
+
http.request(request)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.logger
|
77
|
+
if @logger.nil?
|
78
|
+
@logger = Logger.new(STDOUT)
|
79
|
+
@logger.level = Logger::INFO
|
80
|
+
end
|
81
|
+
@logger
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|