gemnasium 3.2.1
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.
- data/.gitignore +18 -0
- data/.rvmrc +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +52 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +157 -0
- data/Rakefile +6 -0
- data/bin/gemnasium +43 -0
- data/features/gemnasium.feature +58 -0
- data/features/gemnasium_create.feature +13 -0
- data/features/gemnasium_install.feature +119 -0
- data/features/step_definitions/gemnasium_steps.rb +52 -0
- data/features/support/env.rb +7 -0
- data/gemnasium.gemspec +24 -0
- data/lib/gemnasium.rb +328 -0
- data/lib/gemnasium/configuration.rb +110 -0
- data/lib/gemnasium/connection.rb +42 -0
- data/lib/gemnasium/dependency_files.rb +55 -0
- data/lib/gemnasium/errors.rb +16 -0
- data/lib/gemnasium/options.rb +107 -0
- data/lib/gemnasium/version.rb +3 -0
- data/lib/templates/gemnasium.rake +24 -0
- data/lib/templates/gemnasium.yml +10 -0
- data/lib/templates/post-commit +7 -0
- data/spec/gemnasium/configuration_spec.rb +195 -0
- data/spec/gemnasium/connection_spec.rb +47 -0
- data/spec/gemnasium/dependency_files_spec.rb +80 -0
- data/spec/gemnasium/options_spec.rb +135 -0
- data/spec/gemnasium_spec.rb +520 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/gemnasium_helper.rb +86 -0
- metadata +177 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-2.0.0-p0@gemnasium-gem --create
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# 3.2.1 / 2014-11-27
|
2
|
+
|
3
|
+
* Add deprecation warning
|
4
|
+
|
5
|
+
# 3.2.0 / 2014-06-26
|
6
|
+
|
7
|
+
* [#15][] Add --silence-branch option to the 'push' command
|
8
|
+
|
9
|
+
* [#15][] Add --silence-branch option to the 'push' command
|
10
|
+
|
11
|
+
# 3.1.0 / 2014-06-03
|
12
|
+
|
13
|
+
* [#10][] Add --ignore-branch option to the 'push' command
|
14
|
+
* Parse ERB code in the configuration file
|
15
|
+
|
16
|
+
# 3.0.1 / 2014-02-11
|
17
|
+
|
18
|
+
* Add support for Python and PHP Composer dependency files
|
19
|
+
|
20
|
+
# 3.0.0 / 2014-02-10
|
21
|
+
|
22
|
+
**API V2 is now deprecated and all previous gem releases have been yanked**
|
23
|
+
|
24
|
+
* Update config file syntax: replace `profile_name` with `project_slug`
|
25
|
+
* Add `migrate` command to migrate the config file from previous versions
|
26
|
+
* Add `resolve` command to find a project that matches a name and a branch
|
27
|
+
* Make it compatible with Gemnasium API v3
|
28
|
+
|
29
|
+
# 2.0.2 / 2013-07-31
|
30
|
+
|
31
|
+
* [#6][] Fix spec for fedora packaging (@ktdreyer)
|
32
|
+
|
33
|
+
# 2.0.1 / 2013-07-25
|
34
|
+
|
35
|
+
* Update regexp to fetch dependency files in subrepositories.
|
36
|
+
|
37
|
+
# 2.0.0 / 2013-04-30
|
38
|
+
|
39
|
+
**API V1 is now deprecated and all previous gem releases have been yanked**
|
40
|
+
|
41
|
+
* Drop `project_visibility` option, all offline projects are private now
|
42
|
+
* Add `ignored_paths` options to avoid pushing useless files
|
43
|
+
|
44
|
+
# 1.0.1 / 2013-04-02
|
45
|
+
|
46
|
+
* Fix Git after-commit hook (drop Perl style regexp) (revealed by @veilleperso)
|
47
|
+
* Fix Gem's description
|
48
|
+
|
49
|
+
# 1.0.0 / 2013-03-05
|
50
|
+
|
51
|
+
Initial release
|
52
|
+
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Tech-Angels LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# Gemnasium gem
|
2
|
+
[](https://gemnasium.com/gemnasium/gemnasium-gem)
|
3
|
+
[](https://travis-ci.org/gemnasium/gemnasium-gem)
|
4
|
+
|
5
|
+
**Gemnasium gem has been deprecated. Please use the [Gemnasium Toolbelt](https://github.com/gemnasium/toolbelt) instead!**
|
6
|
+
|
7
|
+
This gem lets you push your dependency files to [Gemnasium](https://gemnasium.com/) to track your project's dependencies and get notified about updates and security advisories.
|
8
|
+
|
9
|
+
Gemnasium app offers Github integration with fully automated synchronization but you can use this gem if you don't want to authorize access to your repositories (ie: for privacy concern).
|
10
|
+
|
11
|
+
Supported dependency files are:
|
12
|
+
|
13
|
+
* Ruby: `Gemfile`, `Gemfile.lock` and `*.gemspec`
|
14
|
+
* NPM: `package.json` and `npm-shrinkwrap.json`
|
15
|
+
* Python: `requirements.txt`, `setup.py` and `requires.txt`
|
16
|
+
* PHP Composer: `composer.json` and `composer.lock`
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
gem 'gemnasium'
|
23
|
+
|
24
|
+
Or in your terminal:
|
25
|
+
|
26
|
+
$ gem install gemnasium
|
27
|
+
|
28
|
+
Add configuration file in your project
|
29
|
+
|
30
|
+
$ gemnasium install
|
31
|
+
|
32
|
+
Install command supports 2 options : `--rake` and `--git` to respectively install the gemnasium [rake task](#2-via-the-rake-task) and a [post-commit git hook](#3-via-the-post-commit-git-hook).
|
33
|
+
|
34
|
+
`gemnasium install` will add the config/gemnasium.yml file to your .gitignore so your private API key won't be committed. If you use another versionning system, please remember to ignore this file.
|
35
|
+
|
36
|
+
__Warning: your api key is dedicated to your own user account and must not be published!__
|
37
|
+
|
38
|
+
Fill the values of the new config/gemnasium.yml file.
|
39
|
+
|
40
|
+
## Migrate from previous versions
|
41
|
+
|
42
|
+
Migrate your configuration file:
|
43
|
+
|
44
|
+
$ gemnasium migrate
|
45
|
+
|
46
|
+
Convert your project name to a unique "project slug":
|
47
|
+
|
48
|
+
$ gemnasium resolve
|
49
|
+
|
50
|
+
The `resolve` command will update your configuration file.
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
There is multiple ways to use the gemnasium gem. You can choose whichever you prefer.
|
55
|
+
|
56
|
+
### 1. Via the command line
|
57
|
+
|
58
|
+
Using gemnasium from the command line is as simple as typing `gemnasium [command]` :
|
59
|
+
|
60
|
+
__To create a project on Gemnasium:__
|
61
|
+
|
62
|
+
$ gemnasium create
|
63
|
+
|
64
|
+
Create command will look for data in your config/gemnasium.yml configuration file to create a project.
|
65
|
+
|
66
|
+
Please note that automatic Github synchronization will be dropped once project is configured with this gem.
|
67
|
+
|
68
|
+
__To push your dependency files on Gemnasium:__
|
69
|
+
|
70
|
+
$ gemnasium push
|
71
|
+
|
72
|
+
### 2. Via the rake task
|
73
|
+
|
74
|
+
Gemnasium gem comes with a rake task ready to be used. To use it, you need to install it via: `gemnasium install --rake`
|
75
|
+
Once installed, you'll have access to 2 tasks:
|
76
|
+
|
77
|
+
__To create a project on Gemnasium:__
|
78
|
+
|
79
|
+
$ rake gemnasium:create
|
80
|
+
|
81
|
+
Create command will look for data in your config/gemnasium.yml configuration file to create a project.
|
82
|
+
|
83
|
+
Please note that automatic Github synchronization will be dropped once project is configured with this gem.
|
84
|
+
|
85
|
+
__To push your dependency files on Gemnasium:__
|
86
|
+
|
87
|
+
$ rake gemnasium:push
|
88
|
+
|
89
|
+
### 3. Via the post-commit git hook
|
90
|
+
|
91
|
+
We wrote for you a ready-to-use [post-commit git hook](lib/templates/post-commit).
|
92
|
+
|
93
|
+
Once installed via `gemnasium install --git`, the gem will push your dependency files after each commit only if they have changed.
|
94
|
+
|
95
|
+
### 4. Directly in your code
|
96
|
+
|
97
|
+
If you need to use Gemnasium gem right into your code, you can do so just like below:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'gemnasium'
|
101
|
+
|
102
|
+
|
103
|
+
# To install gemnasium files
|
104
|
+
#
|
105
|
+
# options is a Hash which can contain the following keys:
|
106
|
+
# project_path (required) - [String] path to the project
|
107
|
+
# install_rake_task - [Boolean] whether or not to install the rake task
|
108
|
+
# install_git_hook - [Boolean] whether or not to install the git hook
|
109
|
+
Gemnasium.install(options)
|
110
|
+
|
111
|
+
# To create your project on gemnasium
|
112
|
+
#
|
113
|
+
# options is a Hash which can contain the following keys:
|
114
|
+
# project_path (required) - [String] path to the project
|
115
|
+
Gemnasium.create_project(options)
|
116
|
+
|
117
|
+
# To push supported dependency files to gemnasium
|
118
|
+
#
|
119
|
+
# options is a Hash which can contain the following keys:
|
120
|
+
# project_path (required) - [String] path to the project
|
121
|
+
Gemnasium.push(options)
|
122
|
+
```
|
123
|
+
|
124
|
+
## Sample config
|
125
|
+
|
126
|
+
Here is a sample config file:
|
127
|
+
|
128
|
+
```yaml
|
129
|
+
api_key: "some_secret_api_key"
|
130
|
+
project_name: "vandamme"
|
131
|
+
project_slug: "40d7fafbc32fe0c9e5b84ecacd71012c"
|
132
|
+
project_branch: "master"
|
133
|
+
ignored_paths:
|
134
|
+
- spec/
|
135
|
+
- tmp/
|
136
|
+
```
|
137
|
+
|
138
|
+
This will handle the dependencies of the _vandamme_ project on _master_ branch.
|
139
|
+
Gemnasium gem will also ignore the project dependency files found in _spec/_ and _tmp/_.
|
140
|
+
|
141
|
+
## Troubleshooting
|
142
|
+
|
143
|
+
Gemnasium will try to display the most accurate error message when something goes wrong.
|
144
|
+
|
145
|
+
Though, if you're stil stuck with something, feel free to contact [Gemnasium support](http://support.gemnasium.com).
|
146
|
+
|
147
|
+
## Contributing
|
148
|
+
|
149
|
+
1. Fork the project.
|
150
|
+
2. Make your feature or bug fix.
|
151
|
+
3. Test it.
|
152
|
+
4. Commit.
|
153
|
+
5. Create new pull request.
|
154
|
+
|
155
|
+
## Credits
|
156
|
+
|
157
|
+
[](http://www.tech-angels.com)
|
data/Rakefile
ADDED
data/bin/gemnasium
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#Adjust path in case called directly and not through gem
|
3
|
+
$:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
|
4
|
+
|
5
|
+
require 'gemnasium'
|
6
|
+
require 'gemnasium/options'
|
7
|
+
require 'gemnasium/version'
|
8
|
+
|
9
|
+
#Parse options
|
10
|
+
begin
|
11
|
+
options, parser = Gemnasium::Options.parse ARGV
|
12
|
+
rescue OptionParser::ParseError => e
|
13
|
+
$stderr.puts e.message.capitalize
|
14
|
+
$stderr.puts "Please see `gemnasium --help` for valid options"
|
15
|
+
abort
|
16
|
+
end
|
17
|
+
|
18
|
+
if options[:show_help]
|
19
|
+
puts parser
|
20
|
+
exit
|
21
|
+
elsif options[:show_version]
|
22
|
+
puts "gemnasium v#{Gemnasium::VERSION}"
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
# Set project path
|
27
|
+
options[:project_path] = File.expand_path(".")
|
28
|
+
|
29
|
+
case options[:command]
|
30
|
+
when 'create'
|
31
|
+
Gemnasium.create_project options
|
32
|
+
when 'install'
|
33
|
+
Gemnasium.install options
|
34
|
+
when 'push'
|
35
|
+
Gemnasium.push options
|
36
|
+
when 'migrate'
|
37
|
+
Gemnasium.migrate options
|
38
|
+
when 'resolve'
|
39
|
+
Gemnasium.resolve_project options
|
40
|
+
else
|
41
|
+
$stdout.puts "Please see `gemnasium --help` for valid options"
|
42
|
+
exit
|
43
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Feature: Help messages about gemnasium gem
|
2
|
+
|
3
|
+
By using gemnasium [options], the user is able to get helpfull messages
|
4
|
+
about how to use the gemnasium gem.
|
5
|
+
|
6
|
+
Scenario: Without options
|
7
|
+
When I run `gemnasium`
|
8
|
+
Then the output should contain "Please see `gemnasium --help` for valid options"
|
9
|
+
And the exit status should be 0
|
10
|
+
|
11
|
+
Scenario: With invalid option
|
12
|
+
When I run `gemnasium -z`
|
13
|
+
Then the output should contain exactly:
|
14
|
+
"""
|
15
|
+
Invalid option: -z
|
16
|
+
Please see `gemnasium --help` for valid options\n
|
17
|
+
"""
|
18
|
+
And the exit status should be 1
|
19
|
+
|
20
|
+
Scenario Outline: With version option
|
21
|
+
When I run `gemnasium <option>`
|
22
|
+
Then the output should contain exactly:
|
23
|
+
"""
|
24
|
+
gemnasium v3.2.1\n
|
25
|
+
"""
|
26
|
+
And the exit status should be 0
|
27
|
+
|
28
|
+
Scenarios: Version options
|
29
|
+
| option |
|
30
|
+
| -v |
|
31
|
+
| --version |
|
32
|
+
|
33
|
+
Scenario Outline: With version option
|
34
|
+
When I run `gemnasium <option>`
|
35
|
+
Then the output should contain exactly:
|
36
|
+
"""
|
37
|
+
Usage: gemnasium [options]
|
38
|
+
-v, --version Show Gemnasium version
|
39
|
+
-h, --help Display this message
|
40
|
+
|
41
|
+
Available commands are:
|
42
|
+
create : Create or update project on Gemnasium
|
43
|
+
install : Install the necessary config file
|
44
|
+
push : Push your dependency files to Gemnasium
|
45
|
+
migrate : Migrate the configuration file
|
46
|
+
resolve : Resolve project name to an existing project on Gemnasium
|
47
|
+
|
48
|
+
See `gemnasium COMMAND --help` for more information on a specific command.
|
49
|
+
|
50
|
+
WARNING! The gemnasium Rubygem has been deprecated.
|
51
|
+
Please use Gemnasium Toolbelt (https://github.com/gemnasium/toolbelt) instead.\n
|
52
|
+
"""
|
53
|
+
And the exit status should be 0
|
54
|
+
|
55
|
+
Scenarios: Version options
|
56
|
+
| option |
|
57
|
+
| -h |
|
58
|
+
| --help |
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Create or update a project on Gemnasium
|
2
|
+
|
3
|
+
By using gemnasium create [options], the user is able to create a new
|
4
|
+
project on Gemnasium. The user cannot create a project if the configuration
|
5
|
+
already refers to an existing project.
|
6
|
+
|
7
|
+
Scenario: Without configuration file
|
8
|
+
Given a directory named "project/foo/bar"
|
9
|
+
And I cd to "project/foo/bar"
|
10
|
+
When I run `gemnasium create`
|
11
|
+
Then the output should contain "/config/gemnasium.yml) does not exist."
|
12
|
+
And the output should contain "Please run `gemnasium install`."
|
13
|
+
And the exit status should be 1
|
@@ -0,0 +1,119 @@
|
|
1
|
+
Feature: Create or update a project on Gemnasium
|
2
|
+
|
3
|
+
By using gemnasium install [options], the user is able to install
|
4
|
+
the necessary files to run gemnasium.
|
5
|
+
|
6
|
+
Scenario: Without option for a clean repo
|
7
|
+
Given a directory named "project/foo/bar"
|
8
|
+
And I cd to "project/foo/bar"
|
9
|
+
When I run `gemnasium install`
|
10
|
+
Then it should create the config directory
|
11
|
+
And it should create the config file
|
12
|
+
And the exit status should be 0
|
13
|
+
|
14
|
+
Scenario: Without option for a repo with a config directory
|
15
|
+
Given a directory named "project/foo/bar/config"
|
16
|
+
And I cd to "project/foo/bar"
|
17
|
+
When I run `gemnasium install`
|
18
|
+
Then it should create the config file
|
19
|
+
And the exit status should be 0
|
20
|
+
|
21
|
+
Scenario: Without option for a repo with the config file already installed
|
22
|
+
Given an empty file named "project/foo/bar/config/gemnasium.yml"
|
23
|
+
And I cd to "project/foo/bar"
|
24
|
+
When I run `gemnasium install`
|
25
|
+
Then the output should match:
|
26
|
+
"""
|
27
|
+
The file .+\/config\/gemnasium.yml already exists
|
28
|
+
"""
|
29
|
+
And the exit status should be 0
|
30
|
+
|
31
|
+
Scenario: With git option for a non git repo
|
32
|
+
Given a directory named "project/foo/bar"
|
33
|
+
And I cd to "project/foo/bar"
|
34
|
+
When I run `gemnasium install --git`
|
35
|
+
Then it should create the config directory
|
36
|
+
And it should create the config file
|
37
|
+
And the output should match:
|
38
|
+
"""
|
39
|
+
.*\/project\/foo\/bar is not a git repository\. Try to run `git init`\.
|
40
|
+
"""
|
41
|
+
And the file ".git/hooks/post-commit" should not exist
|
42
|
+
And the exit status should be 0
|
43
|
+
|
44
|
+
Scenario: With git option for git repo without post-commit hook
|
45
|
+
Given a directory named "project/foo/bar"
|
46
|
+
And I cd to "project/foo/bar"
|
47
|
+
And I run `git init`
|
48
|
+
When I run `gemnasium install --git`
|
49
|
+
Then it should create the config directory
|
50
|
+
And it should create the config file
|
51
|
+
And it should create the post-commit hook
|
52
|
+
And the exit status should be 0
|
53
|
+
|
54
|
+
Scenario: With git option for git repo with a post-commit hook file
|
55
|
+
Given a directory named "project/foo/bar"
|
56
|
+
And I cd to "project/foo/bar"
|
57
|
+
And I run `git init`
|
58
|
+
And an empty file named ".git/hooks/post-commit"
|
59
|
+
When I run `gemnasium install --git`
|
60
|
+
Then it should create the config directory
|
61
|
+
And it should create the config file
|
62
|
+
And the output should match:
|
63
|
+
"""
|
64
|
+
The file .+\/.git\/hooks\/post-commit already exists
|
65
|
+
"""
|
66
|
+
And the exit status should be 0
|
67
|
+
|
68
|
+
Scenario: With rake option for a repo without Rakefile
|
69
|
+
Given a directory named "project/foo/bar"
|
70
|
+
And I cd to "project/foo/bar"
|
71
|
+
When I run `gemnasium install --rake`
|
72
|
+
Then it should create the config directory
|
73
|
+
And it should create the config file
|
74
|
+
And the output should contain "Rakefile not found."
|
75
|
+
And the file "lib/tasks/gemnasium.rake" should not exist
|
76
|
+
And the exit status should be 0
|
77
|
+
|
78
|
+
Scenario: With rake option for a repo with a Rakefile without lib/tasks directory
|
79
|
+
Given an empty file named "project/foo/bar/Rakefile"
|
80
|
+
And I cd to "project/foo/bar"
|
81
|
+
When I run `gemnasium install --rake`
|
82
|
+
Then it should create the config directory
|
83
|
+
And it should create the config file
|
84
|
+
And it should create the tasks directory
|
85
|
+
And it should create the task file
|
86
|
+
And the exit status should be 0
|
87
|
+
|
88
|
+
Scenario: With rake option for a repo with a Rakefile with a lib/tasks directory
|
89
|
+
Given an empty file named "project/foo/bar/Rakefile"
|
90
|
+
And a directory named "project/foo/bar/lib/tasks"
|
91
|
+
And I cd to "project/foo/bar"
|
92
|
+
When I run `gemnasium install --rake`
|
93
|
+
Then it should create the config directory
|
94
|
+
And it should create the config file
|
95
|
+
And it should create the task file
|
96
|
+
And the exit status should be 0
|
97
|
+
|
98
|
+
Scenario: With rake option for a repo with the rake tasks already installed
|
99
|
+
Given an empty file named "project/foo/bar/Rakefile"
|
100
|
+
And an empty file named "project/foo/bar/lib/tasks/gemnasium.rake"
|
101
|
+
And I cd to "project/foo/bar"
|
102
|
+
When I run `gemnasium install --rake`
|
103
|
+
Then it should create the config directory
|
104
|
+
And it should create the config file
|
105
|
+
And the output should match:
|
106
|
+
"""
|
107
|
+
The file .+\/lib\/tasks\/gemnasium\.rake already exists
|
108
|
+
"""
|
109
|
+
And the exit status should be 0
|
110
|
+
|
111
|
+
Scenario: With both rake and git options
|
112
|
+
Given an empty file named "project/foo/bar/Rakefile"
|
113
|
+
And I cd to "project/foo/bar"
|
114
|
+
And I run `git init`
|
115
|
+
When I run `gemnasium install --git --rake`
|
116
|
+
Then it should create the config directory
|
117
|
+
And it should create the config file
|
118
|
+
And it should create the task file
|
119
|
+
And it should create the post-commit hook
|