coalescing_panda 1.1.19 → 1.1.20
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 62ef7c3a4a82f51ecf725ebd9f79df58c72602ad18d3b7ab26ab3bf05edc3590
|
4
|
+
data.tar.gz: 3ac60e603838204bd38208569b280c06c00165f49d70c59e944d5849835eee26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41a58d09537d538182234f1adff14c5c072b2039036990c2b4a132790976a1d011ff124afe212d97c525c53ba27cd13dab1efccdc3c9c583e6ddc6f4c94b6491
|
7
|
+
data.tar.gz: 5cd7905c28a7222bf455cd6a1cf8b6b0de2fbfc83984c641511f523aa9c321f01159e8e6d967f16505c84a4e71f1d4feb85f582f9cf8f817823be7026202652b
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'browser'
|
2
|
+
|
1
3
|
module CoalescingPanda
|
2
4
|
module ControllerHelpers
|
3
5
|
require 'useragent'
|
@@ -59,8 +61,11 @@ module CoalescingPanda
|
|
59
61
|
def lti_authorize!(*roles)
|
60
62
|
authorized = false
|
61
63
|
if @lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key'])
|
64
|
+
sanitized_params = sanitize_params
|
65
|
+
authenticator = IMS::LTI::Services::MessageAuthenticator.new(request.original_url, sanitized_params, @lti_account.secret)
|
66
|
+
authorized = authenticator.valid_signature?
|
62
67
|
@tp = IMS::LTI::ToolProvider.new(@lti_account.key, @lti_account.secret, params)
|
63
|
-
authorized = @tp.valid_request?(request)
|
68
|
+
authorized = authorized && @tp.valid_request?(request)
|
64
69
|
end
|
65
70
|
logger.info 'not authorized on tp valid request' if !authorized
|
66
71
|
authorized = authorized && (roles.count == 0 || (roles & lti_roles).count > 0)
|
@@ -70,9 +75,22 @@ module CoalescingPanda
|
|
70
75
|
if !authorized
|
71
76
|
render :text => 'Invalid Credentials, please contact your Administrator.', :status => :unauthorized
|
72
77
|
end
|
78
|
+
authorized = authorized && check_for_iframes_problem if authorized
|
73
79
|
authorized
|
74
80
|
end
|
75
81
|
|
82
|
+
# code for method taken from panda_pal v 4.0.8
|
83
|
+
# used for safari workaround
|
84
|
+
def sanitize_params
|
85
|
+
sanitized_params = request.request_parameters
|
86
|
+
# These params come over with a safari-workaround launch. The authenticator doesn't like them, so clean them out.
|
87
|
+
safe_unexpected_params = ["full_win_launch_requested", "platform_redirect_url"]
|
88
|
+
safe_unexpected_params.each do |p|
|
89
|
+
sanitized_params.delete(p)
|
90
|
+
end
|
91
|
+
sanitized_params
|
92
|
+
end
|
93
|
+
|
76
94
|
def lti_editor_button_response(return_type, return_params)
|
77
95
|
valid_return_types = [:image_url, :iframe, :url]
|
78
96
|
raise "invalid editor button return type #{return_type}" unless valid_return_types.include?(return_type)
|
@@ -114,19 +132,34 @@ module CoalescingPanda
|
|
114
132
|
end
|
115
133
|
|
116
134
|
def session_check
|
117
|
-
|
118
|
-
if user_agent.browser == 'Safari' # we apply the fix..
|
119
|
-
return if session[:safari_cookie_fixed] # it is already fixed.. continue
|
120
|
-
if params[:safari_cookie_fix].present? # we should be top window and able to set cookies.. so fix the issue :)
|
121
|
-
session[:safari_cookie_fixed] = true
|
122
|
-
redirect_to params[:return_to]
|
123
|
-
else
|
124
|
-
# Redirect the top frame to your server..
|
125
|
-
query = params.to_query
|
126
|
-
render :text => "<script>var referrer = document.referrer; top.window.location='?safari_cookie_fix=true&return_to='.concat(encodeURI(referrer));</script>"
|
127
|
-
end
|
128
|
-
end
|
135
|
+
logger.warn 'session_check is deprecated. Functionality moved to canvas_oauth2.'
|
129
136
|
end
|
130
137
|
|
138
|
+
def check_for_iframes_problem
|
139
|
+
if cookies_need_iframe_fix?
|
140
|
+
fix_iframe_cookies
|
141
|
+
return false
|
142
|
+
end
|
143
|
+
# For safari we may have been launched temporarily full-screen by canvas. This allows us to set the session cookie.
|
144
|
+
# In this case, we should make sure the session cookie is fixed and redirect back to canvas to properly launch the embedded LTI.
|
145
|
+
if params[:platform_redirect_url]
|
146
|
+
session[:safari_cookie_fixed] = true
|
147
|
+
redirect_to params[:platform_redirect_url]
|
148
|
+
return false
|
149
|
+
end
|
150
|
+
true
|
151
|
+
end
|
152
|
+
def cookies_need_iframe_fix?
|
153
|
+
@browser ||= Browser.new(request.user_agent)
|
154
|
+
@browser.safari? && !request.referrer.include?('sessionless_launch') && !session[:safari_cookie_fixed] && !params[:platform_redirect_url]
|
155
|
+
end
|
156
|
+
def fix_iframe_cookies
|
157
|
+
if params[:safari_cookie_fix].present?
|
158
|
+
session[:safari_cookie_fixed] = true
|
159
|
+
redirect_to params[:return_to]
|
160
|
+
else
|
161
|
+
render 'coalescing_panda/lti/iframe_cookie_fix', layout: false
|
162
|
+
end
|
163
|
+
end
|
131
164
|
end
|
132
165
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coalescing_panda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Mills
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.0.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.0.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bearcat
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.9.20
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.9.20
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -56,210 +56,224 @@ dependencies:
|
|
56
56
|
name: ims-lti
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: haml-rails
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: sass-rails
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 4.0.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 4.0.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: jquery-rails
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: coffee-rails
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: 4.0.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 4.0.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: protected_attributes
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: p3p
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: useragent
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
type: :runtime
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- -
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: browser
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "<"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 2.0.0
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "<"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 2.0.0
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: sqlite3
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
|
-
- -
|
185
|
+
- - ">="
|
172
186
|
- !ruby/object:Gem::Version
|
173
187
|
version: '0'
|
174
188
|
type: :development
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
|
-
- -
|
192
|
+
- - ">="
|
179
193
|
- !ruby/object:Gem::Version
|
180
194
|
version: '0'
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: rspec-rails
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
184
198
|
requirements:
|
185
|
-
- -
|
199
|
+
- - ">="
|
186
200
|
- !ruby/object:Gem::Version
|
187
201
|
version: '0'
|
188
202
|
type: :development
|
189
203
|
prerelease: false
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
|
-
- -
|
206
|
+
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '0'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
210
|
name: shoulda-matchers
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
198
212
|
requirements:
|
199
|
-
- -
|
213
|
+
- - ">="
|
200
214
|
- !ruby/object:Gem::Version
|
201
215
|
version: '0'
|
202
216
|
type: :development
|
203
217
|
prerelease: false
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
205
219
|
requirements:
|
206
|
-
- -
|
220
|
+
- - ">="
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: nokogiri
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
|
-
- -
|
227
|
+
- - ">="
|
214
228
|
- !ruby/object:Gem::Version
|
215
229
|
version: '0'
|
216
230
|
type: :development
|
217
231
|
prerelease: false
|
218
232
|
version_requirements: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
|
-
- -
|
234
|
+
- - ">="
|
221
235
|
- !ruby/object:Gem::Version
|
222
236
|
version: '0'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
238
|
name: simplecov
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
226
240
|
requirements:
|
227
|
-
- -
|
241
|
+
- - ">="
|
228
242
|
- !ruby/object:Gem::Version
|
229
243
|
version: '0'
|
230
244
|
type: :development
|
231
245
|
prerelease: false
|
232
246
|
version_requirements: !ruby/object:Gem::Requirement
|
233
247
|
requirements:
|
234
|
-
- -
|
248
|
+
- - ">="
|
235
249
|
- !ruby/object:Gem::Version
|
236
250
|
version: '0'
|
237
251
|
- !ruby/object:Gem::Dependency
|
238
252
|
name: debugger
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
240
254
|
requirements:
|
241
|
-
- -
|
255
|
+
- - ">="
|
242
256
|
- !ruby/object:Gem::Version
|
243
257
|
version: '0'
|
244
258
|
type: :development
|
245
259
|
prerelease: false
|
246
260
|
version_requirements: !ruby/object:Gem::Requirement
|
247
261
|
requirements:
|
248
|
-
- -
|
262
|
+
- - ">="
|
249
263
|
- !ruby/object:Gem::Version
|
250
264
|
version: '0'
|
251
265
|
- !ruby/object:Gem::Dependency
|
252
266
|
name: pry
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|
254
268
|
requirements:
|
255
|
-
- -
|
269
|
+
- - ">="
|
256
270
|
- !ruby/object:Gem::Version
|
257
271
|
version: '0'
|
258
272
|
type: :development
|
259
273
|
prerelease: false
|
260
274
|
version_requirements: !ruby/object:Gem::Requirement
|
261
275
|
requirements:
|
262
|
-
- -
|
276
|
+
- - ">="
|
263
277
|
- !ruby/object:Gem::Version
|
264
278
|
version: '0'
|
265
279
|
description:
|
@@ -291,6 +305,7 @@ files:
|
|
291
305
|
- app/models/coalescing_panda/lti_nonce.rb
|
292
306
|
- app/models/coalescing_panda/session.rb
|
293
307
|
- app/views/coalescing_panda/launch.html.haml
|
308
|
+
- app/views/coalescing_panda/lti/iframe_cookie_fix.html.erb
|
294
309
|
- app/views/coalescing_panda/oauth2/oauth2.html.haml
|
295
310
|
- app/views/coalescing_panda/oauth2/redirect.html.haml
|
296
311
|
- app/views/coalescing_panda/styleguide/styleguide.html
|
@@ -339,7 +354,6 @@ files:
|
|
339
354
|
- spec/dummy/config/locales/en.yml
|
340
355
|
- spec/dummy/config/routes.rb
|
341
356
|
- spec/dummy/db/schema.rb
|
342
|
-
- spec/dummy/log/test.log
|
343
357
|
- spec/dummy/public/404.html
|
344
358
|
- spec/dummy/public/422.html
|
345
359
|
- spec/dummy/public/500.html
|
@@ -355,56 +369,54 @@ require_paths:
|
|
355
369
|
- lib
|
356
370
|
required_ruby_version: !ruby/object:Gem::Requirement
|
357
371
|
requirements:
|
358
|
-
- -
|
372
|
+
- - ">="
|
359
373
|
- !ruby/object:Gem::Version
|
360
374
|
version: '0'
|
361
375
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
362
376
|
requirements:
|
363
|
-
- -
|
377
|
+
- - ">="
|
364
378
|
- !ruby/object:Gem::Version
|
365
379
|
version: '0'
|
366
380
|
requirements: []
|
367
|
-
|
368
|
-
rubygems_version: 2.4.6
|
381
|
+
rubygems_version: 3.1.2
|
369
382
|
signing_key:
|
370
383
|
specification_version: 4
|
371
384
|
summary: Canvas LTI and OAUTH2 mountable engine
|
372
385
|
test_files:
|
373
|
-
- spec/
|
374
|
-
- spec/controllers/
|
386
|
+
- spec/spec_helper.rb
|
387
|
+
- spec/dummy/app/controllers/application_controller.rb
|
388
|
+
- spec/dummy/app/views/layouts/application.html.erb
|
375
389
|
- spec/dummy/app/assets/javascripts/application.js
|
376
390
|
- spec/dummy/app/assets/stylesheets/application.css
|
377
|
-
- spec/dummy/app/controllers/application_controller.rb
|
378
391
|
- spec/dummy/app/helpers/application_helper.rb
|
379
|
-
- spec/dummy/
|
392
|
+
- spec/dummy/bin/rake
|
380
393
|
- spec/dummy/bin/bundle
|
381
394
|
- spec/dummy/bin/rails
|
382
|
-
- spec/dummy/
|
383
|
-
- spec/dummy/config/
|
384
|
-
- spec/dummy/config/boot.rb
|
385
|
-
- spec/dummy/config/database.yml
|
386
|
-
- spec/dummy/config/environment.rb
|
387
|
-
- spec/dummy/config/environments/development.rb
|
395
|
+
- spec/dummy/config/routes.rb
|
396
|
+
- spec/dummy/config/locales/en.yml
|
388
397
|
- spec/dummy/config/environments/production.rb
|
398
|
+
- spec/dummy/config/environments/development.rb
|
389
399
|
- spec/dummy/config/environments/test.rb
|
390
|
-
- spec/dummy/config/
|
391
|
-
- spec/dummy/config/
|
392
|
-
- spec/dummy/config/
|
400
|
+
- spec/dummy/config/environment.rb
|
401
|
+
- spec/dummy/config/application.rb
|
402
|
+
- spec/dummy/config/database.yml
|
403
|
+
- spec/dummy/config/boot.rb
|
393
404
|
- spec/dummy/config/initializers/lti_initializer.rb
|
405
|
+
- spec/dummy/config/initializers/backtrace_silencers.rb
|
394
406
|
- spec/dummy/config/initializers/mime_types.rb
|
395
|
-
- spec/dummy/config/initializers/
|
407
|
+
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
396
408
|
- spec/dummy/config/initializers/session_store.rb
|
397
409
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
398
|
-
- spec/dummy/config/
|
399
|
-
- spec/dummy/config/
|
410
|
+
- spec/dummy/config/initializers/secret_token.rb
|
411
|
+
- spec/dummy/config/initializers/inflections.rb
|
400
412
|
- spec/dummy/config.ru
|
401
|
-
- spec/dummy/
|
402
|
-
- spec/dummy/
|
403
|
-
- spec/dummy/public/404.html
|
413
|
+
- spec/dummy/Rakefile
|
414
|
+
- spec/dummy/public/favicon.ico
|
404
415
|
- spec/dummy/public/422.html
|
405
416
|
- spec/dummy/public/500.html
|
406
|
-
- spec/dummy/public/
|
407
|
-
- spec/dummy/
|
417
|
+
- spec/dummy/public/404.html
|
418
|
+
- spec/dummy/db/schema.rb
|
408
419
|
- spec/dummy/README.rdoc
|
409
420
|
- spec/models/coalescing_panda/canvas_api_auth_spec.rb
|
410
|
-
- spec/
|
421
|
+
- spec/controllers/coalescing_panda/oauth2_controller_spec.rb
|
422
|
+
- spec/controllers/coalescing_panda/lti_controller_spec.rb
|
data/spec/dummy/log/test.log
DELETED
File without changes
|