chamber 3.1.1 → 3.2.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/lib/chamber/binary/runner.rb +8 -8
- data/lib/chamber/commands/securable.rb +1 -1
- data/lib/chamber/commands/secure.rb +1 -1
- data/lib/chamber/commands/unsecure.rb +1 -1
- data/lib/chamber/encryption_methods/ssl.rb +2 -2
- data/lib/chamber/file_set.rb +7 -9
- data/lib/chamber/files/signature.rb +5 -5
- data/lib/chamber/filters/decryption_filter.rb +3 -3
- data/lib/chamber/filters/encryption_filter.rb +3 -3
- data/lib/chamber/filters/failed_decryption_filter.rb +1 -1
- data/lib/chamber/filters/insecure_filter.rb +3 -3
- data/lib/chamber/instance.rb +11 -13
- data/lib/chamber/key_pair.rb +1 -1
- data/lib/chamber/keys/decryption.rb +1 -1
- data/lib/chamber/keys/encryption.rb +1 -1
- data/lib/chamber/namespace_set.rb +0 -2
- data/lib/chamber/rubinius_fix.rb +1 -1
- data/lib/chamber/settings.rb +18 -24
- data/lib/chamber/version.rb +1 -1
- data.tar.gz.sig +2 -4
- metadata +46 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73bb2ff990eea6d1622bb7911dac66b75dbb3546211bbe50fa20583fad48aa6a
|
|
4
|
+
data.tar.gz: dc995d8051c396f75ef0a96ddebfab5b380c313e1c7639888c2a91cf060946f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cec905ece523d50b0dcc1f842cce493b1b32a9ea9846603b22c25ce1fbd477a3030b69347b8cb4f081105f28a9703ff76f47f29547be0e85550af4a07e629bff
|
|
7
|
+
data.tar.gz: f91ebcd81bcdca33525ada6e187c0147900b96faee3b7c5623de996284fd5104416e09e9d4f4c94fc4f1f1dc7c4262817005004e1930f3c05880fb59aa24cb21
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -75,7 +75,7 @@ class Runner < Thor
|
|
|
75
75
|
'Useful for debugging.'
|
|
76
76
|
|
|
77
77
|
def show
|
|
78
|
-
puts Commands::Show.call(**options.transform_keys(&:to_sym)
|
|
78
|
+
puts Commands::Show.call(**options.transform_keys(&:to_sym), shell: self)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
################################################################################
|
|
@@ -83,7 +83,7 @@ class Runner < Thor
|
|
|
83
83
|
desc 'files', 'Lists the settings files which are parsed with the given options'
|
|
84
84
|
|
|
85
85
|
def files
|
|
86
|
-
puts Commands::Files.call(**options.transform_keys(&:to_sym)
|
|
86
|
+
puts Commands::Files.call(**options.transform_keys(&:to_sym), shell: self)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
################################################################################
|
|
@@ -113,7 +113,7 @@ class Runner < Thor
|
|
|
113
113
|
'destination of the comparison'
|
|
114
114
|
|
|
115
115
|
def compare
|
|
116
|
-
Commands::Compare.call(**options.transform_keys(&:to_sym)
|
|
116
|
+
Commands::Compare.call(**options.transform_keys(&:to_sym), shell: self)
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
################################################################################
|
|
@@ -133,7 +133,7 @@ class Runner < Thor
|
|
|
133
133
|
'what values would be encrypted'
|
|
134
134
|
|
|
135
135
|
def secure
|
|
136
|
-
Commands::Secure.call(**options.transform_keys(&:to_sym)
|
|
136
|
+
Commands::Secure.call(**options.transform_keys(&:to_sym), shell: self)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
################################################################################
|
|
@@ -148,7 +148,7 @@ class Runner < Thor
|
|
|
148
148
|
'what values would be decrypted'
|
|
149
149
|
|
|
150
150
|
def unsecure
|
|
151
|
-
Commands::Unsecure.call(**options.transform_keys(&:to_sym)
|
|
151
|
+
Commands::Unsecure.call(**options.transform_keys(&:to_sym), shell: self)
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
################################################################################
|
|
@@ -167,9 +167,9 @@ class Runner < Thor
|
|
|
167
167
|
|
|
168
168
|
def sign
|
|
169
169
|
if options[:verify]
|
|
170
|
-
Commands::Verify.call(**options.transform_keys(&:to_sym)
|
|
170
|
+
Commands::Verify.call(**options.transform_keys(&:to_sym), shell: self)
|
|
171
171
|
else
|
|
172
|
-
Commands::Sign.call(**options.transform_keys(&:to_sym)
|
|
172
|
+
Commands::Sign.call(**options.transform_keys(&:to_sym), shell: self)
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
@@ -183,7 +183,7 @@ class Runner < Thor
|
|
|
183
183
|
default: false
|
|
184
184
|
|
|
185
185
|
def init
|
|
186
|
-
Commands::Initialize.call(**options.transform_keys(&:to_sym)
|
|
186
|
+
Commands::Initialize.call(**options.transform_keys(&:to_sym), shell: self)
|
|
187
187
|
end
|
|
188
188
|
end
|
|
189
189
|
end
|
|
@@ -11,7 +11,7 @@ module Securable
|
|
|
11
11
|
|
|
12
12
|
ignored_settings_options = args
|
|
13
13
|
.merge(files: ignored_settings_filepaths)
|
|
14
|
-
.
|
|
14
|
+
.except('basepath')
|
|
15
15
|
self.ignored_settings_instance = Chamber::Instance.new(**ignored_settings_options)
|
|
16
16
|
self.current_settings_instance = Chamber::Instance.new(**args)
|
|
17
17
|
self.only_sensitive = only_sensitive
|
|
@@ -5,7 +5,7 @@ require 'base64'
|
|
|
5
5
|
module Chamber
|
|
6
6
|
module EncryptionMethods
|
|
7
7
|
class Ssl
|
|
8
|
-
BASE64_STRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
8
|
+
BASE64_STRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
9
9
|
LARGE_DATA_STRING_PATTERN = /
|
|
10
10
|
\A
|
|
11
11
|
(#{BASE64_STRING_PATTERN})
|
|
@@ -14,7 +14,7 @@ class Ssl
|
|
|
14
14
|
\#
|
|
15
15
|
(#{BASE64_STRING_PATTERN})
|
|
16
16
|
\z
|
|
17
|
-
/x
|
|
17
|
+
/x
|
|
18
18
|
|
|
19
19
|
def self.encrypt(_settings_key, value, encryption_keys) # rubocop:disable Metrics/AbcSize
|
|
20
20
|
value = YAML.dump(value)
|
data/lib/chamber/file_set.rb
CHANGED
|
@@ -293,15 +293,13 @@ class FileSet
|
|
|
293
293
|
end
|
|
294
294
|
|
|
295
295
|
def relevant_namespaced_files
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
file_holder.flatten
|
|
296
|
+
namespaces
|
|
297
|
+
.map { |namespace|
|
|
298
|
+
namespaced_files.select do |file|
|
|
299
|
+
file.basename.fnmatch? "*-#{namespace}.???"
|
|
300
|
+
end
|
|
301
|
+
}
|
|
302
|
+
.flatten
|
|
305
303
|
end
|
|
306
304
|
end
|
|
307
305
|
end
|
|
@@ -8,14 +8,14 @@ module Chamber
|
|
|
8
8
|
module Files
|
|
9
9
|
class Signature
|
|
10
10
|
SIGNATURE_HEADER = '-----BEGIN CHAMBER SIGNATURE-----'
|
|
11
|
-
SIGNATURE_HEADER_PATTERN = /-----BEGIN\sCHAMBER\sSIGNATURE
|
|
11
|
+
SIGNATURE_HEADER_PATTERN = /-----BEGIN\sCHAMBER\sSIGNATURE-----/
|
|
12
12
|
SIGNATURE_FOOTER = '-----END CHAMBER SIGNATURE-----'
|
|
13
|
-
SIGNATURE_FOOTER_PATTERN = /-----END\sCHAMBER\sSIGNATURE
|
|
13
|
+
SIGNATURE_FOOTER_PATTERN = /-----END\sCHAMBER\sSIGNATURE-----/
|
|
14
14
|
SIGNATURE_IN_FILE_PATTERN = /
|
|
15
15
|
#{SIGNATURE_HEADER_PATTERN}\n # Header
|
|
16
16
|
(.*)\n # Signature Body
|
|
17
17
|
#{SIGNATURE_FOOTER_PATTERN} # Footer
|
|
18
|
-
/x
|
|
18
|
+
/x
|
|
19
19
|
|
|
20
20
|
attr_accessor :settings_content,
|
|
21
21
|
:settings_filename,
|
|
@@ -77,8 +77,8 @@ class Signature
|
|
|
77
77
|
@encoded_signature_content ||= signature_filename
|
|
78
78
|
.read
|
|
79
79
|
.match(SIGNATURE_IN_FILE_PATTERN) do |match|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
match[1]
|
|
81
|
+
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def signature_content
|
|
@@ -14,7 +14,7 @@ module Filters
|
|
|
14
14
|
class DecryptionFilter
|
|
15
15
|
using ::Chamber::Refinements::DeepDup
|
|
16
16
|
|
|
17
|
-
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
17
|
+
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
18
18
|
LARGE_DATA_STRING_PATTERN = %r{
|
|
19
19
|
\A # Beginning of String
|
|
20
20
|
(
|
|
@@ -29,7 +29,7 @@ class DecryptionFilter
|
|
|
29
29
|
[A-Za-z0-9+/#]*={0,2} # Base64 Encoded Data
|
|
30
30
|
)
|
|
31
31
|
\z # End of String
|
|
32
|
-
}x
|
|
32
|
+
}x
|
|
33
33
|
|
|
34
34
|
attr_accessor :data,
|
|
35
35
|
:secure_key_token
|
|
@@ -82,7 +82,7 @@ class DecryptionFilter
|
|
|
82
82
|
|
|
83
83
|
decryption_keys.each do |decryption_key|
|
|
84
84
|
return method.decrypt(key, value, decryption_key)
|
|
85
|
-
rescue OpenSSL::PKey::RSAError
|
|
85
|
+
rescue ::OpenSSL::PKey::RSAError, ::Psych::SyntaxError
|
|
86
86
|
next
|
|
87
87
|
end
|
|
88
88
|
|
|
@@ -12,8 +12,8 @@ module Filters
|
|
|
12
12
|
class EncryptionFilter
|
|
13
13
|
using ::Chamber::Refinements::DeepDup
|
|
14
14
|
|
|
15
|
-
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
16
|
-
BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
15
|
+
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
16
|
+
BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
17
17
|
LARGE_DATA_STRING_PATTERN = /
|
|
18
18
|
\A
|
|
19
19
|
(#{BASE64_SUBSTRING_PATTERN})
|
|
@@ -22,7 +22,7 @@ class EncryptionFilter
|
|
|
22
22
|
\#
|
|
23
23
|
(#{BASE64_SUBSTRING_PATTERN})
|
|
24
24
|
\z
|
|
25
|
-
/x
|
|
25
|
+
/x
|
|
26
26
|
|
|
27
27
|
attr_accessor :data,
|
|
28
28
|
:secure_key_token
|
|
@@ -5,8 +5,8 @@ require 'chamber/filters/secure_filter'
|
|
|
5
5
|
module Chamber
|
|
6
6
|
module Filters
|
|
7
7
|
class InsecureFilter < SecureFilter
|
|
8
|
-
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
9
|
-
BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
8
|
+
BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}
|
|
9
|
+
BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}
|
|
10
10
|
LARGE_DATA_STRING_PATTERN = /
|
|
11
11
|
\A
|
|
12
12
|
(#{BASE64_SUBSTRING_PATTERN})
|
|
@@ -15,7 +15,7 @@ class InsecureFilter < SecureFilter
|
|
|
15
15
|
\#
|
|
16
16
|
(#{BASE64_SUBSTRING_PATTERN})
|
|
17
17
|
\z
|
|
18
|
-
/x
|
|
18
|
+
/x
|
|
19
19
|
|
|
20
20
|
protected
|
|
21
21
|
|
data/lib/chamber/instance.rb
CHANGED
|
@@ -71,11 +71,10 @@ class Instance
|
|
|
71
71
|
|
|
72
72
|
Settings
|
|
73
73
|
.new(
|
|
74
|
-
**config
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
),
|
|
74
|
+
**config,
|
|
75
|
+
settings: data,
|
|
76
|
+
pre_filters: [Filters::EncryptionFilter],
|
|
77
|
+
post_filters: [],
|
|
79
78
|
)
|
|
80
79
|
.to_hash
|
|
81
80
|
end
|
|
@@ -85,14 +84,13 @@ class Instance
|
|
|
85
84
|
|
|
86
85
|
Settings
|
|
87
86
|
.new(
|
|
88
|
-
**config
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
),
|
|
87
|
+
**config,
|
|
88
|
+
settings: data,
|
|
89
|
+
pre_filters: [Filters::NamespaceFilter],
|
|
90
|
+
post_filters: [
|
|
91
|
+
Filters::DecryptionFilter,
|
|
92
|
+
Filters::FailedDecryptionFilter,
|
|
93
|
+
],
|
|
96
94
|
)
|
|
97
95
|
.to_hash
|
|
98
96
|
end
|
data/lib/chamber/key_pair.rb
CHANGED
data/lib/chamber/rubinius_fix.rb
CHANGED
data/lib/chamber/settings.rb
CHANGED
|
@@ -48,7 +48,6 @@ class Settings
|
|
|
48
48
|
settings: {},
|
|
49
49
|
**_args
|
|
50
50
|
)
|
|
51
|
-
|
|
52
51
|
::Chamber::Refinements::Enumerable.deep_validate_keys(settings, &:to_s)
|
|
53
52
|
|
|
54
53
|
self.decryption_keys = (decryption_keys || {}).transform_keys(&:to_s)
|
|
@@ -272,41 +271,36 @@ class Settings
|
|
|
272
271
|
end
|
|
273
272
|
|
|
274
273
|
def securable
|
|
275
|
-
Settings.new(**metadata
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
))
|
|
274
|
+
Settings.new(**metadata,
|
|
275
|
+
settings: raw_data,
|
|
276
|
+
pre_filters: [Filters::SecureFilter])
|
|
279
277
|
end
|
|
280
278
|
|
|
281
279
|
def secure
|
|
282
|
-
Settings.new(**metadata
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
))
|
|
280
|
+
Settings.new(**metadata,
|
|
281
|
+
settings: raw_data,
|
|
282
|
+
pre_filters: [Filters::EncryptionFilter],
|
|
283
|
+
post_filters: [Filters::TranslateSecureKeysFilter])
|
|
287
284
|
end
|
|
288
285
|
|
|
289
286
|
def decrypted
|
|
290
|
-
Settings.new(**metadata
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
))
|
|
287
|
+
Settings.new(**metadata,
|
|
288
|
+
settings: raw_data,
|
|
289
|
+
post_filters: [Filters::DecryptionFilter])
|
|
294
290
|
end
|
|
295
291
|
|
|
296
292
|
def encrypted
|
|
297
|
-
Settings.new(**metadata
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
))
|
|
293
|
+
Settings.new(**metadata,
|
|
294
|
+
settings: raw_data,
|
|
295
|
+
pre_filters: [Filters::EncryptionFilter],
|
|
296
|
+
post_filters: [])
|
|
302
297
|
end
|
|
303
298
|
|
|
304
299
|
def insecure
|
|
305
|
-
Settings.new(**metadata
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
))
|
|
300
|
+
Settings.new(**metadata,
|
|
301
|
+
settings: raw_data,
|
|
302
|
+
pre_filters: [Filters::InsecureFilter],
|
|
303
|
+
post_filters: [Filters::TranslateSecureKeysFilter])
|
|
310
304
|
end
|
|
311
305
|
|
|
312
306
|
protected
|
data/lib/chamber/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
mw|�D$�\}�l���ܷ.eL�0b�m���T�o�Ky�'D�zY 1�̱��Viምle�ə<�;h�S��8�
|
|
4
|
-
���GZ0�.��۱zU���K�:���'�uV�q�@oM�E,ޝ�iPQ�LN�}�_�9$z��/h�X�͛ű���W8V�Vݱa���oߙ��Lke^$4
|
|
1
|
+
SΟݴYL�o��_��%;���zP%��[��|�R�.U��2��$/���*a�m�,T�w:�6/�p+��R���
|
|
2
|
+
����� �6" 52���Nt�U�QӖw�mH8I �n��Xz�<�06!h�`�T��3�#�Z��\���<��S����=�����ū@2�����:c�F܀4�Y$��>?��!l#��0W۷�ݣ��7��I���1 \HkVx�L(��J��9�ʠ�VS��Ű�}I���S��� ����]�WWt�K�����)qf�b�0��TZǛI�B��J9���~����3��|ފ`.Vv�����߶S���g��%�����2\B�Lޙ�=��v�_�Wϛ�WsW���2�(�m��}鬗�4���
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: chamber
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thekompanee
|
|
@@ -38,8 +38,50 @@ cert_chain:
|
|
|
38
38
|
Z6HMkN0PHJ6eG0Zl3/H4H8Xb+KreWlEx3sXXfZj6UscrdHAVffRQnM1E98PCqnRX
|
|
39
39
|
l5EwT4ShG/HorJMQSTY1EoBLZf54NrD5WlWcfM0CLrcvT7QM77dIqmue
|
|
40
40
|
-----END CERTIFICATE-----
|
|
41
|
-
date:
|
|
41
|
+
date: 2026-01-08 00:00:00.000000000 Z
|
|
42
42
|
dependencies:
|
|
43
|
+
- !ruby/object:Gem::Dependency
|
|
44
|
+
name: base64
|
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - "~>"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '0.3'
|
|
50
|
+
type: :runtime
|
|
51
|
+
prerelease: false
|
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - "~>"
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0.3'
|
|
57
|
+
- !ruby/object:Gem::Dependency
|
|
58
|
+
name: bigdecimal
|
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - "~>"
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '4.0'
|
|
64
|
+
type: :runtime
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - "~>"
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '4.0'
|
|
71
|
+
- !ruby/object:Gem::Dependency
|
|
72
|
+
name: mutex_m
|
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - "~>"
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0.3'
|
|
78
|
+
type: :runtime
|
|
79
|
+
prerelease: false
|
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - "~>"
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0.3'
|
|
43
85
|
- !ruby/object:Gem::Dependency
|
|
44
86
|
name: thor
|
|
45
87
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -216,14 +258,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
216
258
|
requirements:
|
|
217
259
|
- - ">="
|
|
218
260
|
- !ruby/object:Gem::Version
|
|
219
|
-
version: 2.
|
|
261
|
+
version: 3.2.4
|
|
220
262
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
221
263
|
requirements:
|
|
222
264
|
- - ">="
|
|
223
265
|
- !ruby/object:Gem::Version
|
|
224
266
|
version: '0'
|
|
225
267
|
requirements: []
|
|
226
|
-
rubygems_version: 3.
|
|
268
|
+
rubygems_version: 3.4.19
|
|
227
269
|
signing_key:
|
|
228
270
|
specification_version: 4
|
|
229
271
|
summary: A surprisingly configurable convention-based approach to managing your application's
|
metadata.gz.sig
CHANGED
|
Binary file
|