svelte 4.2.1 → 4.2.2
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.
- package/compiler.cjs +80 -23
- package/elements.d.ts +2 -1
- package/package.json +3 -3
- package/src/compiler/compile/render_dom/invalidate.js +1 -1
- package/src/compiler/compile/render_dom/wrappers/Element/Attribute.js +2 -2
- package/src/compiler/utils/nodes_match.js +3 -3
- package/src/runtime/action/public.d.ts +1 -1
- package/src/runtime/internal/dom.js +4 -1
- package/src/shared/version.js +1 -1
- package/types/index.d.ts +1 -1
package/compiler.cjs
CHANGED
|
@@ -15707,7 +15707,7 @@ function is_dynamic$1(variable) {
|
|
|
15707
15707
|
return false;
|
|
15708
15708
|
}
|
|
15709
15709
|
|
|
15710
|
-
function nodes_match(a, b) {
|
|
15710
|
+
function nodes_match(a, b, ignoreKeys=[]) {
|
|
15711
15711
|
if (!!a !== !!b) return false;
|
|
15712
15712
|
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
15713
15713
|
|
|
@@ -15717,8 +15717,8 @@ function nodes_match(a, b) {
|
|
|
15717
15717
|
return a.every((child, i) => nodes_match(child, b[i]));
|
|
15718
15718
|
}
|
|
15719
15719
|
|
|
15720
|
-
const a_keys = Object.keys(a).sort();
|
|
15721
|
-
const b_keys = Object.keys(b).sort();
|
|
15720
|
+
const a_keys = Object.keys(a).sort().filter(key => !ignoreKeys.includes(key));
|
|
15721
|
+
const b_keys = Object.keys(b).sort().filter(key => !ignoreKeys.includes(key));
|
|
15722
15722
|
|
|
15723
15723
|
if (a_keys.length !== b_keys.length) return false;
|
|
15724
15724
|
|
|
@@ -15789,7 +15789,7 @@ function invalidate(renderer, scope, node, names, main_execution_context = false
|
|
|
15789
15789
|
if (
|
|
15790
15790
|
node.type === 'AssignmentExpression' &&
|
|
15791
15791
|
node.operator === '=' &&
|
|
15792
|
-
nodes_match(node.left, node.right) &&
|
|
15792
|
+
nodes_match(node.left, node.right, ['trailingComments','leadingComments']) &&
|
|
15793
15793
|
tail.length === 0
|
|
15794
15794
|
) {
|
|
15795
15795
|
return get_invalidated(head, node);
|
|
@@ -31491,8 +31491,8 @@ class AttributeWrapper extends BaseAttributeWrapper {
|
|
|
31491
31491
|
this.parent.has_dynamic_value = true;
|
|
31492
31492
|
}
|
|
31493
31493
|
}
|
|
31494
|
-
if (this.parent.node.namespace == namespaces.foreign) {
|
|
31495
|
-
// leave attribute case alone for elements in the "foreign" namespace
|
|
31494
|
+
if (this.parent.node.namespace == namespaces.foreign || this.parent.node.name.includes('-')) {
|
|
31495
|
+
// leave attribute case alone for elements in the "foreign" namespace and for custom elements
|
|
31496
31496
|
this.name = this.node.name;
|
|
31497
31497
|
this.metadata = this.get_metadata();
|
|
31498
31498
|
this.is_indirectly_bound_value = false;
|
|
@@ -41029,6 +41029,13 @@ class Chunk {
|
|
|
41029
41029
|
this.end = index;
|
|
41030
41030
|
|
|
41031
41031
|
if (this.edited) {
|
|
41032
|
+
// after split we should save the edit content record into the correct chunk
|
|
41033
|
+
// to make sure sourcemap correct
|
|
41034
|
+
// For example:
|
|
41035
|
+
// ' test'.trim()
|
|
41036
|
+
// split -> ' ' + 'test'
|
|
41037
|
+
// ✔️ edit -> '' + 'test'
|
|
41038
|
+
// ✖️ edit -> 'test' + ''
|
|
41032
41039
|
// TODO is this block necessary?...
|
|
41033
41040
|
newChunk.edit('', false);
|
|
41034
41041
|
this.content = '';
|
|
@@ -41057,6 +41064,10 @@ class Chunk {
|
|
|
41057
41064
|
if (trimmed.length) {
|
|
41058
41065
|
if (trimmed !== this.content) {
|
|
41059
41066
|
this.split(this.start + trimmed.length).edit('', undefined, true);
|
|
41067
|
+
if (this.edited) {
|
|
41068
|
+
// save the change, if it has been edited
|
|
41069
|
+
this.edit(trimmed, this.storeName, true);
|
|
41070
|
+
}
|
|
41060
41071
|
}
|
|
41061
41072
|
return true;
|
|
41062
41073
|
} else {
|
|
@@ -41075,7 +41086,11 @@ class Chunk {
|
|
|
41075
41086
|
|
|
41076
41087
|
if (trimmed.length) {
|
|
41077
41088
|
if (trimmed !== this.content) {
|
|
41078
|
-
this.split(this.end - trimmed.length);
|
|
41089
|
+
const newChunk = this.split(this.end - trimmed.length);
|
|
41090
|
+
if (this.edited) {
|
|
41091
|
+
// save the change, if it has been edited
|
|
41092
|
+
newChunk.edit(trimmed, this.storeName, true);
|
|
41093
|
+
}
|
|
41079
41094
|
this.edit('', undefined, true);
|
|
41080
41095
|
}
|
|
41081
41096
|
return true;
|
|
@@ -41088,7 +41103,7 @@ class Chunk {
|
|
|
41088
41103
|
}
|
|
41089
41104
|
}
|
|
41090
41105
|
|
|
41091
|
-
function getBtoa
|
|
41106
|
+
function getBtoa() {
|
|
41092
41107
|
if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
|
|
41093
41108
|
return (str) => window.btoa(unescape(encodeURIComponent(str)));
|
|
41094
41109
|
} else if (typeof Buffer === 'function') {
|
|
@@ -41201,6 +41216,8 @@ function getLocator(source) {
|
|
|
41201
41216
|
};
|
|
41202
41217
|
}
|
|
41203
41218
|
|
|
41219
|
+
const wordRegex = /\w/;
|
|
41220
|
+
|
|
41204
41221
|
class Mappings {
|
|
41205
41222
|
constructor(hires) {
|
|
41206
41223
|
this.hires = hires;
|
|
@@ -41213,26 +41230,64 @@ class Mappings {
|
|
|
41213
41230
|
|
|
41214
41231
|
addEdit(sourceIndex, content, loc, nameIndex) {
|
|
41215
41232
|
if (content.length) {
|
|
41233
|
+
let contentLineEnd = content.indexOf('\n', 0);
|
|
41234
|
+
let previousContentLineEnd = -1;
|
|
41235
|
+
while (contentLineEnd >= 0) {
|
|
41236
|
+
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
41237
|
+
if (nameIndex >= 0) {
|
|
41238
|
+
segment.push(nameIndex);
|
|
41239
|
+
}
|
|
41240
|
+
this.rawSegments.push(segment);
|
|
41241
|
+
|
|
41242
|
+
this.generatedCodeLine += 1;
|
|
41243
|
+
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
41244
|
+
this.generatedCodeColumn = 0;
|
|
41245
|
+
|
|
41246
|
+
previousContentLineEnd = contentLineEnd;
|
|
41247
|
+
contentLineEnd = content.indexOf('\n', contentLineEnd + 1);
|
|
41248
|
+
}
|
|
41249
|
+
|
|
41216
41250
|
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
41217
41251
|
if (nameIndex >= 0) {
|
|
41218
41252
|
segment.push(nameIndex);
|
|
41219
41253
|
}
|
|
41220
41254
|
this.rawSegments.push(segment);
|
|
41255
|
+
|
|
41256
|
+
this.advance(content.slice(previousContentLineEnd + 1));
|
|
41221
41257
|
} else if (this.pending) {
|
|
41222
41258
|
this.rawSegments.push(this.pending);
|
|
41259
|
+
this.advance(content);
|
|
41223
41260
|
}
|
|
41224
41261
|
|
|
41225
|
-
this.advance(content);
|
|
41226
41262
|
this.pending = null;
|
|
41227
41263
|
}
|
|
41228
41264
|
|
|
41229
41265
|
addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {
|
|
41230
41266
|
let originalCharIndex = chunk.start;
|
|
41231
41267
|
let first = true;
|
|
41268
|
+
// when iterating each char, check if it's in a word boundary
|
|
41269
|
+
let charInHiresBoundary = false;
|
|
41232
41270
|
|
|
41233
41271
|
while (originalCharIndex < chunk.end) {
|
|
41234
41272
|
if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
|
|
41235
|
-
|
|
41273
|
+
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
41274
|
+
|
|
41275
|
+
if (this.hires === 'boundary') {
|
|
41276
|
+
// in hires "boundary", group segments per word boundary than per char
|
|
41277
|
+
if (wordRegex.test(original[originalCharIndex])) {
|
|
41278
|
+
// for first char in the boundary found, start the boundary by pushing a segment
|
|
41279
|
+
if (!charInHiresBoundary) {
|
|
41280
|
+
this.rawSegments.push(segment);
|
|
41281
|
+
charInHiresBoundary = true;
|
|
41282
|
+
}
|
|
41283
|
+
} else {
|
|
41284
|
+
// for non-word char, end the boundary by pushing a segment
|
|
41285
|
+
this.rawSegments.push(segment);
|
|
41286
|
+
charInHiresBoundary = false;
|
|
41287
|
+
}
|
|
41288
|
+
} else {
|
|
41289
|
+
this.rawSegments.push(segment);
|
|
41290
|
+
}
|
|
41236
41291
|
}
|
|
41237
41292
|
|
|
41238
41293
|
if (original[originalCharIndex] === '\n') {
|
|
@@ -41405,7 +41460,7 @@ class MagicString {
|
|
|
41405
41460
|
sourceIndex,
|
|
41406
41461
|
chunk.content,
|
|
41407
41462
|
loc,
|
|
41408
|
-
chunk.storeName ? names.indexOf(chunk.original) : -1
|
|
41463
|
+
chunk.storeName ? names.indexOf(chunk.original) : -1,
|
|
41409
41464
|
);
|
|
41410
41465
|
} else {
|
|
41411
41466
|
mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);
|
|
@@ -41416,11 +41471,13 @@ class MagicString {
|
|
|
41416
41471
|
|
|
41417
41472
|
return {
|
|
41418
41473
|
file: options.file ? options.file.split(/[/\\]/).pop() : undefined,
|
|
41419
|
-
sources: [
|
|
41474
|
+
sources: [
|
|
41475
|
+
options.source ? getRelativePath(options.file || '', options.source) : options.file || '',
|
|
41476
|
+
],
|
|
41420
41477
|
sourcesContent: options.includeContent ? [this.original] : undefined,
|
|
41421
41478
|
names,
|
|
41422
41479
|
mappings: mappings.raw,
|
|
41423
|
-
x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined
|
|
41480
|
+
x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,
|
|
41424
41481
|
};
|
|
41425
41482
|
}
|
|
41426
41483
|
|
|
@@ -41534,14 +41591,14 @@ class MagicString {
|
|
|
41534
41591
|
|
|
41535
41592
|
insert() {
|
|
41536
41593
|
throw new Error(
|
|
41537
|
-
'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)'
|
|
41594
|
+
'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',
|
|
41538
41595
|
);
|
|
41539
41596
|
}
|
|
41540
41597
|
|
|
41541
41598
|
insertLeft(index, content) {
|
|
41542
41599
|
if (!warned.insertLeft) {
|
|
41543
41600
|
console.warn(
|
|
41544
|
-
'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'
|
|
41601
|
+
'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',
|
|
41545
41602
|
); // eslint-disable-line no-console
|
|
41546
41603
|
warned.insertLeft = true;
|
|
41547
41604
|
}
|
|
@@ -41552,7 +41609,7 @@ class MagicString {
|
|
|
41552
41609
|
insertRight(index, content) {
|
|
41553
41610
|
if (!warned.insertRight) {
|
|
41554
41611
|
console.warn(
|
|
41555
|
-
'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'
|
|
41612
|
+
'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',
|
|
41556
41613
|
); // eslint-disable-line no-console
|
|
41557
41614
|
warned.insertRight = true;
|
|
41558
41615
|
}
|
|
@@ -41611,7 +41668,7 @@ class MagicString {
|
|
|
41611
41668
|
if (end > this.original.length) throw new Error('end is out of bounds');
|
|
41612
41669
|
if (start === end)
|
|
41613
41670
|
throw new Error(
|
|
41614
|
-
'Cannot overwrite a zero-length range – use appendLeft or prependRight instead'
|
|
41671
|
+
'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',
|
|
41615
41672
|
);
|
|
41616
41673
|
|
|
41617
41674
|
this._split(start);
|
|
@@ -41620,7 +41677,7 @@ class MagicString {
|
|
|
41620
41677
|
if (options === true) {
|
|
41621
41678
|
if (!warned.storeName) {
|
|
41622
41679
|
console.warn(
|
|
41623
|
-
'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'
|
|
41680
|
+
'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',
|
|
41624
41681
|
); // eslint-disable-line no-console
|
|
41625
41682
|
warned.storeName = true;
|
|
41626
41683
|
}
|
|
@@ -41842,7 +41899,7 @@ class MagicString {
|
|
|
41842
41899
|
// zero-length edited chunks are a special case (overlapping replacements)
|
|
41843
41900
|
const loc = getLocator(this.original)(index);
|
|
41844
41901
|
throw new Error(
|
|
41845
|
-
`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")
|
|
41902
|
+
`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`,
|
|
41846
41903
|
);
|
|
41847
41904
|
}
|
|
41848
41905
|
|
|
@@ -42001,7 +42058,7 @@ class MagicString {
|
|
|
42001
42058
|
this.overwrite(
|
|
42002
42059
|
match.index,
|
|
42003
42060
|
match.index + match[0].length,
|
|
42004
|
-
getReplacement(match, this.original)
|
|
42061
|
+
getReplacement(match, this.original),
|
|
42005
42062
|
);
|
|
42006
42063
|
});
|
|
42007
42064
|
} else {
|
|
@@ -42010,7 +42067,7 @@ class MagicString {
|
|
|
42010
42067
|
this.overwrite(
|
|
42011
42068
|
match.index,
|
|
42012
42069
|
match.index + match[0].length,
|
|
42013
|
-
getReplacement(match, this.original)
|
|
42070
|
+
getReplacement(match, this.original),
|
|
42014
42071
|
);
|
|
42015
42072
|
}
|
|
42016
42073
|
return this;
|
|
@@ -42056,7 +42113,7 @@ class MagicString {
|
|
|
42056
42113
|
|
|
42057
42114
|
if (!searchValue.global) {
|
|
42058
42115
|
throw new TypeError(
|
|
42059
|
-
'MagicString.prototype.replaceAll called with a non-global RegExp argument'
|
|
42116
|
+
'MagicString.prototype.replaceAll called with a non-global RegExp argument',
|
|
42060
42117
|
);
|
|
42061
42118
|
}
|
|
42062
42119
|
|
|
@@ -43575,7 +43632,7 @@ function is_used_as_reference(node, parent) {
|
|
|
43575
43632
|
* https://svelte.dev/docs/svelte-compiler#svelte-version
|
|
43576
43633
|
* @type {string}
|
|
43577
43634
|
*/
|
|
43578
|
-
const VERSION = '4.2.
|
|
43635
|
+
const VERSION = '4.2.2';
|
|
43579
43636
|
|
|
43580
43637
|
const regex_leading_directory_separator = /^[/\\]/;
|
|
43581
43638
|
const regex_starts_with_term_export = /^Export/;
|
package/elements.d.ts
CHANGED
|
@@ -486,7 +486,7 @@ export interface HTMLAttributes<T extends EventTarget> extends AriaAttributes, D
|
|
|
486
486
|
accesskey?: string | undefined | null;
|
|
487
487
|
autofocus?: boolean | undefined | null;
|
|
488
488
|
class?: string | undefined | null;
|
|
489
|
-
contenteditable?: Booleanish | 'inherit' | undefined | null;
|
|
489
|
+
contenteditable?: Booleanish | 'inherit' | 'plaintext-only' | undefined | null;
|
|
490
490
|
contextmenu?: string | undefined | null;
|
|
491
491
|
dir?: string | undefined | null;
|
|
492
492
|
draggable?: Booleanish | undefined | null;
|
|
@@ -1405,6 +1405,7 @@ export interface SVGAttributes<T extends EventTarget> extends AriaAttributes, DO
|
|
|
1405
1405
|
'text-rendering'?: number | string | undefined | null;
|
|
1406
1406
|
to?: number | string | undefined | null;
|
|
1407
1407
|
transform?: string | undefined | null;
|
|
1408
|
+
'transform-origin'?: string | undefined | null;
|
|
1408
1409
|
u1?: number | string | undefined | null;
|
|
1409
1410
|
u2?: number | string | undefined | null;
|
|
1410
1411
|
'underline-position'?: number | string | undefined | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "Cybernetically enhanced web apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/runtime/index.js",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"estree-walker": "^3.0.3",
|
|
103
103
|
"is-reference": "^3.0.1",
|
|
104
104
|
"locate-character": "^3.0.0",
|
|
105
|
-
"magic-string": "^0.30.
|
|
105
|
+
"magic-string": "^0.30.4",
|
|
106
106
|
"periscopic": "^3.1.0"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"esbuild": "^0.18.11",
|
|
120
120
|
"eslint-plugin-lube": "^0.1.7",
|
|
121
121
|
"happy-dom": "^9.20.3",
|
|
122
|
-
"jsdom": "
|
|
122
|
+
"jsdom": "22.0.0",
|
|
123
123
|
"kleur": "^4.1.5",
|
|
124
124
|
"rollup": "^3.26.2",
|
|
125
125
|
"source-map": "^0.7.4",
|
|
@@ -50,7 +50,7 @@ export function invalidate(renderer, scope, node, names, main_execution_context
|
|
|
50
50
|
if (
|
|
51
51
|
node.type === 'AssignmentExpression' &&
|
|
52
52
|
node.operator === '=' &&
|
|
53
|
-
nodes_match(node.left, node.right) &&
|
|
53
|
+
nodes_match(node.left, node.right, ['trailingComments','leadingComments']) &&
|
|
54
54
|
tail.length === 0
|
|
55
55
|
) {
|
|
56
56
|
return get_invalidated(head, node);
|
|
@@ -103,8 +103,8 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
|
|
|
103
103
|
this.parent.has_dynamic_value = true;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
if (this.parent.node.namespace == namespaces.foreign) {
|
|
107
|
-
// leave attribute case alone for elements in the "foreign" namespace
|
|
106
|
+
if (this.parent.node.namespace == namespaces.foreign || this.parent.node.name.includes('-')) {
|
|
107
|
+
// leave attribute case alone for elements in the "foreign" namespace and for custom elements
|
|
108
108
|
this.name = this.node.name;
|
|
109
109
|
this.metadata = this.get_metadata();
|
|
110
110
|
this.is_indirectly_bound_value = false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function nodes_match(a, b) {
|
|
1
|
+
export function nodes_match(a, b, ignoreKeys=[]) {
|
|
2
2
|
if (!!a !== !!b) return false;
|
|
3
3
|
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
4
4
|
|
|
@@ -8,8 +8,8 @@ export function nodes_match(a, b) {
|
|
|
8
8
|
return a.every((child, i) => nodes_match(child, b[i]));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const a_keys = Object.keys(a).sort();
|
|
12
|
-
const b_keys = Object.keys(b).sort();
|
|
11
|
+
const a_keys = Object.keys(a).sort().filter(key => !ignoreKeys.includes(key));
|
|
12
|
+
const b_keys = Object.keys(b).sort().filter(key => !ignoreKeys.includes(key));
|
|
13
13
|
|
|
14
14
|
if (a_keys.length !== b_keys.length) return false;
|
|
15
15
|
|
|
@@ -50,7 +50,7 @@ export interface ActionReturn<
|
|
|
50
50
|
* // ...
|
|
51
51
|
* }
|
|
52
52
|
* ```
|
|
53
|
-
* `Action<HTMLDivElement>` and `Action<
|
|
53
|
+
* `Action<HTMLDivElement>` and `Action<HTMLDivElement, undefined>` both signal that the action accepts no parameters.
|
|
54
54
|
*
|
|
55
55
|
* You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has.
|
|
56
56
|
* See interface `ActionReturn` for more details.
|
|
@@ -480,7 +480,10 @@ export function set_custom_element_data_map(node, data_map) {
|
|
|
480
480
|
/**
|
|
481
481
|
* @returns {void} */
|
|
482
482
|
export function set_custom_element_data(node, prop, value) {
|
|
483
|
-
|
|
483
|
+
const lower = prop.toLowerCase(); // for backwards compatibility with existing behavior we do lowercase first
|
|
484
|
+
if (lower in node) {
|
|
485
|
+
node[lower] = typeof node[lower] === 'boolean' && value === '' ? true : value;
|
|
486
|
+
} else if (prop in node) {
|
|
484
487
|
node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;
|
|
485
488
|
} else {
|
|
486
489
|
attr(node, prop, value);
|
package/src/shared/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1348,7 +1348,7 @@ declare module 'svelte/action' {
|
|
|
1348
1348
|
* // ...
|
|
1349
1349
|
* }
|
|
1350
1350
|
* ```
|
|
1351
|
-
* `Action<HTMLDivElement>` and `Action<
|
|
1351
|
+
* `Action<HTMLDivElement>` and `Action<HTMLDivElement, undefined>` both signal that the action accepts no parameters.
|
|
1352
1352
|
*
|
|
1353
1353
|
* You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has.
|
|
1354
1354
|
* See interface `ActionReturn` for more details.
|