linkify-it-rb 2.0.3 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +21 -10
- data/lib/linkify-it-rb/index.rb +32 -6
- data/lib/linkify-it-rb/re.rb +39 -35
- data/lib/linkify-it-rb/version.rb +1 -3
- data/spec/linkify-it-rb/test_spec.rb +34 -0
- metadata +11 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 68c5de781544ec81b757b1099b8c24643449e121546d03cdda5da57d6b033afb
|
4
|
+
data.tar.gz: 9534d8d1a44ec68d531dea91df209b391d46aee363b04f2d0c30969debd77bf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96664d9ffb34ac85e7038394dd9e1504625ae4ce87e5498ec62c0b698cb9ddbcae780a3f966a0c77abeca1c533ef5ce1984195d1d1e14b54bfcb563b7972255d
|
7
|
+
data.tar.gz: 4194118a1da63b10a827aca05f57254debee07759a06b25a5b0b71d1928be0669c92416afb76950c85fa85455ef944b0b2008d789254ad04ac254052a8805b34
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# linkify-it-rb
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/linkify-it-rb.svg)](http://badge.fury.io/rb/linkify-it-rb)
|
4
|
-
[![Build Status](https://
|
4
|
+
[![Build Status](https://github.com/digitalmoksha/linkify-it-rb/actions/workflows/ci.yml/badge.svg)](https://github.com/digitalmoksha/linkify-it-rb/actions/workflows/ci.yml)
|
5
5
|
|
6
6
|
This gem is a port of the [linkify-it javascript package](https://github.com/markdown-it/linkify-it) by Vitaly Puzrin, that is used for the [markdown-it](https://github.com/markdown-it/markdown-it) package.
|
7
7
|
|
8
|
-
_Currently synced with linkify-it
|
8
|
+
_Currently synced with linkify-it 4.0.1_
|
9
9
|
|
10
10
|
---
|
11
11
|
|
@@ -53,8 +53,8 @@ linkify = Linkify.new
|
|
53
53
|
|
54
54
|
# Reload full tlds list & add unofficial `.onion` domain.
|
55
55
|
linkify.tlds('onion', true) # Add unofficial `.onion` domain
|
56
|
-
linkify.add('git:', 'http:') # Add `git:`
|
57
|
-
linkify.add('ftp:', null) # Disable `ftp:`
|
56
|
+
linkify.add('git:', 'http:') # Add `git:` protocol as "alias"
|
57
|
+
linkify.add('ftp:', null) # Disable `ftp:` protocol
|
58
58
|
linkify.set({fuzzyIP: true}) # Enable IPs in fuzzy links (without schema)
|
59
59
|
|
60
60
|
linkify.test('Site github.com!'))
|
@@ -106,8 +106,11 @@ By default understands:
|
|
106
106
|
- __value__ - rule to check tail after link prefix
|
107
107
|
- _String_ - just alias to existing rule
|
108
108
|
- _Hash_
|
109
|
-
- _validate_ -
|
110
|
-
or
|
109
|
+
- _validate_ - either a `RegExp (start with `^`, and don't include the
|
110
|
+
link prefix itself), or a validator block which, given arguments,
|
111
|
+
_text_, _pos_, and _self_, returns the length of a match in _text_
|
112
|
+
starting at index _pos_. _pos_ is the index right after the link prefix.
|
113
|
+
_self_ can be used to access the linkify object to cache data.
|
111
114
|
- _normalize_ - optional block to normalize text & url of matched result
|
112
115
|
(for example, for twitter mentions).
|
113
116
|
|
@@ -152,6 +155,11 @@ Each match has:
|
|
152
155
|
- __text__ - normalized text
|
153
156
|
- __url__ - link, generated from matched text
|
154
157
|
|
158
|
+
### .matchAtStart(text)
|
159
|
+
|
160
|
+
Checks if a match exists at the start of the string. Returns `Match`
|
161
|
+
(see docs for `match(text)`) or nil if no URL is at the start.
|
162
|
+
Doesn't work with fuzzy links.
|
155
163
|
|
156
164
|
### .tlds(list[, keepOld])
|
157
165
|
|
@@ -162,12 +170,15 @@ to avoid false positives. By default this algorithm uses:
|
|
162
170
|
- biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф are ok.
|
163
171
|
- encoded (`xn--...`) root zones are ok.
|
164
172
|
|
165
|
-
If that's not
|
173
|
+
If that's not enough, you can reload defaults with more detailed zones list.
|
166
174
|
|
167
|
-
### .add(
|
175
|
+
### .add(key, value)
|
168
176
|
|
169
|
-
Add new
|
170
|
-
|
177
|
+
Add a new schema to the schemas object. As described in the constructor
|
178
|
+
definition, `key` is a link prefix (`skype:`, for example), and `value`
|
179
|
+
is a String to alias to another schema, or an Object with `validate` and
|
180
|
+
optionally `normalize` definitions. To disable an existing rule, use
|
181
|
+
`.add(key, null)`.
|
171
182
|
|
172
183
|
### .set(options)
|
173
184
|
|
data/lib/linkify-it-rb/index.rb
CHANGED
@@ -204,12 +204,14 @@ class Linkify
|
|
204
204
|
slist = @__compiled__.select {|name, val| name.length > 0 && !val.nil? }.keys.map {|str| escapeRE(str)}.join('|')
|
205
205
|
|
206
206
|
# (?!_) cause 1.5x slowdown
|
207
|
-
@re[:schema_test]
|
208
|
-
@re[:schema_search]
|
207
|
+
@re[:schema_test] = Regexp.new('(^|(?!_)(?:[><\uff5c]|' + @re[:src_XPCc] + '))(' + slist + ')', 'i')
|
208
|
+
@re[:schema_search] = Regexp.new('(^|(?!_)(?:[><\uff5c]|' + @re[:src_XPCc] + '))(' + slist + ')', 'i')
|
209
|
+
@re[:schema_at_start] = Regexp.new('^' + @re[:schema_search].source, 'i')
|
209
210
|
|
210
|
-
@re[:pretest]
|
211
|
-
|
212
|
-
|
211
|
+
@re[:pretest] = Regexp.new(
|
212
|
+
'(' + @re[:schema_test].source + ')|(' + @re[:host_fuzzy_test].source + ')|@',
|
213
|
+
'i'
|
214
|
+
)
|
213
215
|
|
214
216
|
#
|
215
217
|
# Cleanup
|
@@ -505,6 +507,30 @@ class Linkify
|
|
505
507
|
return nil
|
506
508
|
end
|
507
509
|
|
510
|
+
# LinkifyIt#matchAtStart(text) -> Match|null
|
511
|
+
#
|
512
|
+
# Returns fully-formed (not fuzzy) link if it starts at the beginning
|
513
|
+
# of the string, and null otherwise.
|
514
|
+
#------------------------------------------------------------------------------
|
515
|
+
def matchAtStart(text)
|
516
|
+
# Reset scan cache
|
517
|
+
@__text_cache__ = text
|
518
|
+
@__index__ = -1
|
519
|
+
|
520
|
+
return unless text.length
|
521
|
+
|
522
|
+
m = @re[:schema_at_start].match(text)
|
523
|
+
return nil unless m
|
524
|
+
|
525
|
+
len = testSchemaAt(text, m[2], m[0].length)
|
526
|
+
return nil unless len > 0
|
527
|
+
|
528
|
+
@__schema__ = m[2];
|
529
|
+
@__index__ = m.begin(0) + m[1].length
|
530
|
+
@__last_index__ = m.begin(0) + m[0].length + len
|
531
|
+
|
532
|
+
return Match.createMatch(self, 0)
|
533
|
+
end
|
508
534
|
|
509
535
|
# chainable
|
510
536
|
# LinkifyIt#tlds(list [, keepOld]) -> this
|
@@ -561,4 +587,4 @@ class Linkify
|
|
561
587
|
def onCompile
|
562
588
|
end
|
563
589
|
|
564
|
-
end
|
590
|
+
end
|
data/lib/linkify-it-rb/re.rb
CHANGED
@@ -32,11 +32,13 @@ module LinkifyRe
|
|
32
32
|
|
33
33
|
SRC_PORT = '(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?'
|
34
34
|
|
35
|
-
|
35
|
+
# moved SRC_HOST_TERMINATOR into re_src_host_terminator
|
36
36
|
|
37
37
|
# moved SRC_PATH into re_src_path
|
38
38
|
|
39
|
-
|
39
|
+
# Allow anything in markdown spec, forbid quote (") at the first position
|
40
|
+
# because emails enclosed in quotes are far more common
|
41
|
+
SRC_EMAIL_NAME = '[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*'
|
40
42
|
SRC_XN = 'xn--[a-z0-9\\-]{1,59}'
|
41
43
|
|
42
44
|
# More to read about domain names
|
@@ -56,10 +58,7 @@ module LinkifyRe
|
|
56
58
|
'|' +
|
57
59
|
'(?:' + SRC_PSEUDO_LETTER + ')' +
|
58
60
|
'|' +
|
59
|
-
|
60
|
-
# - that can conflict with markdown — / –
|
61
|
-
# - nobody use those anyway
|
62
|
-
'(?:' + SRC_PSEUDO_LETTER + '(?:-(?!-)|' + SRC_PSEUDO_LETTER + '){0,61}' + SRC_PSEUDO_LETTER + ')' +
|
61
|
+
'(?:' + SRC_PSEUDO_LETTER + '(?:-|' + SRC_PSEUDO_LETTER + '){0,61}' + SRC_PSEUDO_LETTER + ')' +
|
63
62
|
')'
|
64
63
|
|
65
64
|
SRC_HOST =
|
@@ -80,23 +79,16 @@ module LinkifyRe
|
|
80
79
|
TPL_HOST_NO_IP_FUZZY =
|
81
80
|
'(?:(?:(?:' + SRC_DOMAIN + ')\\.)+(?:%TLDS%))'
|
82
81
|
|
83
|
-
SRC_HOST_STRICT = SRC_HOST + SRC_HOST_TERMINATOR
|
84
|
-
TPL_HOST_FUZZY_STRICT = TPL_HOST_FUZZY + SRC_HOST_TERMINATOR
|
85
|
-
SRC_HOST_PORT_STRICT = SRC_HOST + SRC_PORT + SRC_HOST_TERMINATOR
|
86
|
-
TPL_HOST_PORT_FUZZY_STRICT = TPL_HOST_FUZZY + SRC_PORT + SRC_HOST_TERMINATOR
|
87
|
-
TPL_HOST_PORT_NO_IP_FUZZY_STRICT = TPL_HOST_NO_IP_FUZZY + SRC_PORT + SRC_HOST_TERMINATOR
|
88
|
-
|
89
82
|
#------------------------------------------------------------------------------
|
90
83
|
# Main rules
|
91
84
|
|
92
85
|
# Rude test fuzzy links by host, for quick deny
|
93
86
|
TPL_HOST_FUZZY_TEST = 'localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:' + SRC_Z_P_CC + '|>|$))'
|
94
|
-
TPL_EMAIL_FUZZY = '(^|' + TEXT_SEPARATORS + '|\\(|' +SRC_Z_CC + ')(' + SRC_EMAIL_NAME + '@' + TPL_HOST_FUZZY_STRICT + ')'
|
95
87
|
|
96
88
|
# moved TPL_LINK_FUZZY and TPL_LINK_NO_IP_FUZZY into build_re
|
97
89
|
|
98
90
|
#------------------------------------------------------------------------------
|
99
|
-
def build_re(opts)
|
91
|
+
def build_re(opts = {})
|
100
92
|
re = {
|
101
93
|
src_Any: SRC_ANY,
|
102
94
|
src_Cc: SRC_CC,
|
@@ -108,7 +100,7 @@ module LinkifyRe
|
|
108
100
|
src_ip4: SRC_IP4,
|
109
101
|
src_auth: SRC_AUTH,
|
110
102
|
src_port: SRC_PORT,
|
111
|
-
src_host_terminator:
|
103
|
+
src_host_terminator: re_src_host_terminator(opts),
|
112
104
|
src_path: re_src_path(opts),
|
113
105
|
src_email_name: SRC_EMAIL_NAME,
|
114
106
|
src_xn: SRC_XN,
|
@@ -118,60 +110,72 @@ module LinkifyRe
|
|
118
110
|
|
119
111
|
tpl_host_fuzzy: TPL_HOST_FUZZY,
|
120
112
|
tpl_host_no_ip_fuzzy: TPL_HOST_NO_IP_FUZZY,
|
121
|
-
src_host_strict:
|
122
|
-
tpl_host_fuzzy_strict:
|
123
|
-
src_host_port_strict:
|
124
|
-
tpl_host_port_fuzzy_strict:
|
125
|
-
tpl_host_port_no_ip_fuzzy_strict:
|
126
|
-
|
127
|
-
tpl_host_fuzzy_test: TPL_HOST_FUZZY_TEST
|
128
|
-
tpl_email_fuzzy: TPL_EMAIL_FUZZY
|
113
|
+
src_host_strict: SRC_HOST + re_src_host_terminator(opts),
|
114
|
+
tpl_host_fuzzy_strict: TPL_HOST_FUZZY + re_src_host_terminator(opts),
|
115
|
+
src_host_port_strict: SRC_HOST + SRC_PORT + re_src_host_terminator(opts),
|
116
|
+
tpl_host_port_fuzzy_strict: TPL_HOST_FUZZY + SRC_PORT + re_src_host_terminator(opts),
|
117
|
+
tpl_host_port_no_ip_fuzzy_strict: TPL_HOST_NO_IP_FUZZY + SRC_PORT + re_src_host_terminator(opts),
|
118
|
+
|
119
|
+
tpl_host_fuzzy_test: TPL_HOST_FUZZY_TEST
|
129
120
|
}
|
130
121
|
|
122
|
+
re[:tpl_email_fuzzy] =
|
123
|
+
'(^|' + TEXT_SEPARATORS + '|"|\\(|' + SRC_Z_CC + ')' +
|
124
|
+
'(' + SRC_EMAIL_NAME + '@' + re[:tpl_host_fuzzy_strict] + ')'
|
125
|
+
|
131
126
|
# Fuzzy link can't be prepended with .:/\- and non punctuation.
|
132
127
|
# but can start with > (markdown blockquote)
|
133
128
|
re[:tpl_link_fuzzy] =
|
134
129
|
'(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|' + SRC_Z_P_CC + '))' +
|
135
|
-
'((?![$+<=>^`|\uff5c])' +
|
130
|
+
'((?![$+<=>^`|\uff5c])' + re[:tpl_host_port_fuzzy_strict] + re[:src_path] + ')'
|
136
131
|
|
137
132
|
# Fuzzy link can't be prepended with .:/\- and non punctuation.
|
138
133
|
# but can start with > (markdown blockquote)
|
139
134
|
re[:tpl_link_no_ip_fuzzy] =
|
140
135
|
'(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|' + SRC_Z_P_CC + '))' +
|
141
|
-
'((?![$+<=>^`|\uff5c])' +
|
136
|
+
'((?![$+<=>^`|\uff5c])' + re[:tpl_host_port_no_ip_fuzzy_strict] + re[:src_path] + ')'
|
142
137
|
|
143
138
|
return re
|
144
139
|
end
|
145
140
|
|
146
141
|
#------------------------------------------------------------------------------
|
147
|
-
def re_src_path(opts =
|
142
|
+
def re_src_path(opts = {})
|
148
143
|
'(?:' +
|
149
144
|
'[/?#]' +
|
150
145
|
'(?:' +
|
151
|
-
'(?!' + SRC_Z_CC + '|' + TEXT_SEPARATORS + '|[()\\[\\]{}.,"\'
|
146
|
+
'(?!' + SRC_Z_CC + '|' + TEXT_SEPARATORS + '|[()\\[\\]{}.,"\'?!\\-;]).|' +
|
152
147
|
'\\[(?:(?!' + SRC_Z_CC + '|\\]).)*\\]|' +
|
153
148
|
'\\((?:(?!' + SRC_Z_CC + '|[)]).)*\\)|' +
|
154
149
|
'\\{(?:(?!' + SRC_Z_CC + '|[}]).)*\\}|' +
|
155
150
|
'\\"(?:(?!' + SRC_Z_CC + '|["]).)+\\"|' +
|
156
151
|
"\\'(?:(?!" + SRC_Z_CC + "|[']).)+\\'|" +
|
157
|
-
"\\'(?=" + SRC_PSEUDO_LETTER + '|[-])
|
158
|
-
'\\.{2,
|
152
|
+
"\\'(?=" + SRC_PSEUDO_LETTER + '|[-])|' + # allow `I'm_king` if no pair found
|
153
|
+
'\\.{2,}[a-zA-Z0-9%/&]|' + # google has many dots in "google search" links (#66, #81).
|
154
|
+
# github has ... in commit range links,
|
155
|
+
# Restrict to
|
159
156
|
# - english
|
160
157
|
# - percent-encoded
|
161
158
|
# - parts of file path
|
159
|
+
# - params separator
|
162
160
|
# until more examples found.
|
163
|
-
'\\.(?!' + SRC_Z_CC + '|[.])
|
161
|
+
'\\.(?!' + SRC_Z_CC + '|[.]|$)|' +
|
164
162
|
(opts && opts[:'---'] ?
|
165
163
|
'\\-(?!--(?:[^-]|$))(?:-*)|' # `---` => long dash, terminate
|
166
164
|
:
|
167
165
|
'\\-+|'
|
168
166
|
) +
|
169
|
-
'\\,(?!' + SRC_Z_CC + ')
|
170
|
-
'
|
171
|
-
'
|
167
|
+
'\\,(?!' + SRC_Z_CC + '|$)|' + # allow `,,,` in paths
|
168
|
+
'\\;(?!' + SRC_Z_CC + '|$)|' + # allow `;` if not followed by space-like char
|
169
|
+
'\\!+(?!' + SRC_Z_CC + '|[!]|$)|' + # allow `!!!` in paths, but not at the end
|
170
|
+
'\\?(?!' + SRC_Z_CC + '|[?]|$)' +
|
172
171
|
')+' +
|
173
172
|
'|\\/' +
|
174
173
|
')?'
|
175
|
-
end
|
174
|
+
end
|
176
175
|
|
177
|
-
|
176
|
+
#------------------------------------------------------------------------------
|
177
|
+
def re_src_host_terminator(opts = {})
|
178
|
+
'(?=$|' + TEXT_SEPARATORS + '|' + SRC_Z_P_CC + ')' +
|
179
|
+
'(?!' + (opts['---'] ? '-(?!--)|' : '-|') + '_|:\\d|\\.-|\\.(?!$|' + SRC_Z_P_CC + '))'
|
180
|
+
end
|
181
|
+
end
|
@@ -273,5 +273,39 @@ describe 'API' do
|
|
273
273
|
l = Linkify.new(nil, { '---': true })
|
274
274
|
|
275
275
|
expect(l.match('http://e.com/foo---bar')[0].text).to eq 'http://e.com/foo'
|
276
|
+
expect(l.match('text@example.com---foo')).to be_empty
|
277
|
+
end
|
278
|
+
|
279
|
+
#------------------------------------------------------------------------------
|
280
|
+
it 'should find a match at the start' do
|
281
|
+
l = Linkify.new
|
282
|
+
|
283
|
+
l.set({ fuzzyLink: true })
|
284
|
+
|
285
|
+
expect(l.matchAtStart('http://google.com 123').text).to eq 'http://google.com'
|
286
|
+
expect(l.matchAtStart('google.com 123')).to be_nil
|
287
|
+
expect(l.matchAtStart(' http://google.com 123')).to be_nil
|
288
|
+
end
|
289
|
+
|
290
|
+
#------------------------------------------------------------------------------
|
291
|
+
it 'matchAtStart should not interfere with normal match' do
|
292
|
+
l = Linkify.new
|
293
|
+
|
294
|
+
str = 'http://google.com http://google.com'
|
295
|
+
expect(l.matchAtStart(str)).not_to be_nil
|
296
|
+
expect(l.match(str).length).to eq 2
|
297
|
+
|
298
|
+
str = 'aaa http://google.com http://google.com'
|
299
|
+
expect(l.matchAtStart(str)).to be_nil
|
300
|
+
expect(l.match(str).length).to eq 2
|
301
|
+
end
|
302
|
+
|
303
|
+
#------------------------------------------------------------------------------
|
304
|
+
it 'should not match incomplete links' do
|
305
|
+
# regression test for https://github.com/markdown-it/markdown-it/issues/868
|
306
|
+
l = Linkify.new
|
307
|
+
|
308
|
+
expect(l.matchAtStart('http://')).to be_nil
|
309
|
+
expect(l.matchAtStart('https://')).to be_nil
|
276
310
|
end
|
277
311
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linkify-it-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Walker
|
8
8
|
- Vitaly Puzrin
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-01-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: uc.micro-rb
|
@@ -26,19 +26,19 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '1.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: motion-expect
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '0'
|
42
42
|
description: Ruby version of linkify-it for motion-markdown-it, for Ruby and RubyMotion
|
43
43
|
email: github@digitalmoksha.com
|
44
44
|
executables: []
|
@@ -56,7 +56,7 @@ homepage: https://github.com/digitalmoksha/linkify-it-rb
|
|
56
56
|
licenses:
|
57
57
|
- MIT
|
58
58
|
metadata: {}
|
59
|
-
post_install_message:
|
59
|
+
post_install_message:
|
60
60
|
rdoc_options: []
|
61
61
|
require_paths:
|
62
62
|
- lib
|
@@ -71,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
73
|
requirements: []
|
74
|
-
|
75
|
-
|
76
|
-
signing_key:
|
74
|
+
rubygems_version: 3.1.4
|
75
|
+
signing_key:
|
77
76
|
specification_version: 4
|
78
77
|
summary: linkify-it for motion-markdown-it in Ruby
|
79
78
|
test_files:
|