Skip to content

Commit ca8c695

Browse files
committed
Revamp coords parsing to be more compatible and less insane
The old parser tried to mimic IE as close as possible. Now Edge is instead interested in aligning with Gecko/WebKit/Presto. This new algorithm was designed by studying implementations as well as invalid Web content. At the same time, support parsing of floating point numbers, as suggested by Travis Leithead in the bug below. Fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=28148.
1 parent 8558f93 commit ca8c695

File tree

1 file changed

+38
-228
lines changed

1 file changed

+38
-228
lines changed

source

Lines changed: 38 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -4507,16 +4507,17 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d
45074507
</div>
45084508

45094509

4510-
<h5>Lists of integers</h5>
4510+
<h5>Lists of floating-point numbers</h5>
45114511

4512-
<p>A <dfn>valid list of integers</dfn> is a number of <span data-x="valid integer">valid
4513-
integers</span> separated by U+002C COMMA characters, with no other characters (e.g. no <span
4514-
data-x="space character">space characters</span>). In addition, there might be restrictions on the
4515-
number of integers that can be given, or on the range of values allowed.</p>
4512+
<p>A <dfn>valid list of floating-point numbers</dfn> is a number of <span data-x="valid
4513+
floating-point number">valid floating-point numbers</span> separated by U+002C COMMA characters,
4514+
with no other characters (e.g. no <span data-x="space character">space characters</span>). In
4515+
addition, there might be restrictions on the number of floating-point numbers that can be given,
4516+
or on the range of values allowed.</p>
45164517

45174518
<div w-nodev>
45184519

4519-
<p>The <dfn>rules for parsing a list of integers</dfn> are as follows:</p>
4520+
<p>The <dfn>rules for parsing a list of floating-point numbers</dfn> are as follows:</p>
45204521

45214522
<ol>
45224523

@@ -4525,232 +4526,41 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d
45254526
<li><p>Let <var>position</var> be a pointer into <var>input</var>, initially pointing at the
45264527
start of the string.</p></li>
45274528

4528-
<li><p>Let <var>numbers</var> be an initially empty list of integers. This list will be the
4529-
result of this algorithm.</p></li>
4529+
<li><p>Let <var>numbers</var> be an initially empty list of floating-point numbers. This list
4530+
will be the result of this algorithm.</p></li>
45304531

4531-
<li><p>If there is a character in the string <var>input</var> at position <var>position</var>,
4532-
and it is either a U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON character, then advance
4533-
<var>position</var> to the next character in <var>input</var>, or to beyond the end of the string
4534-
if there are no more characters.</p></li>
4532+
<li><p><span>Collect a sequence of characters</span> that are <span data-x="space
4533+
character">space characters</span>, U+002C COMMA, or U+003B SEMICOLON characters. This skips past
4534+
any leading delimiters.</p></li>
45354535

4536-
<li><p>If <var>position</var> points to beyond the end of <var>input</var>, return
4537-
<var>numbers</var> and abort.</p></li>
4538-
4539-
<li><p>If the character in the string <var>input</var> at position <var>position</var> is a
4540-
U+0020 SPACE, U+002C COMMA, or U+003B SEMICOLON character, then return to step 4.</li>
4541-
4542-
<li><p>Let <var>negated</var> be false.</p></li> <li><p>Let <var>value</var> be 0.</p></li>
4543-
4544-
<li><p>Let <var>started</var> be false. This variable is set to true when the parser sees a
4545-
number or a U+002D HYPHEN-MINUS character (-).</p></li>
4546-
4547-
<li><p>Let <var>got number</var> be false. This variable is set to true when the parser sees a
4548-
number.</p></li>
4549-
4550-
<li><p>Let <var>finished</var> be false. This variable is set to true to switch parser into a
4551-
mode where it ignores characters until the next separator.</p></li>
4552-
4553-
<li><p>Let <var>bogus</var> be false.</p></li>
4554-
4555-
<li><p><i>Parser</i>: If the character in the string <var>input</var> at position
4556-
<var>position</var> is:</p>
4557-
4558-
<dl class="switch">
4559-
4560-
<dt>A U+002D HYPHEN-MINUS character</dt>
4561-
4562-
<dd>
4563-
4564-
<p>Follow these substeps:</p>
4565-
4566-
<ol>
4567-
4568-
<li>If <var>got number</var> is true, let <var>finished</var> be true.</li>
4569-
4570-
<li>If <var>finished</var> is true, skip to the next step in the overall set of steps.</li>
4571-
4572-
<li>If <var>started</var> is true, let <var>negated</var> be false.</li>
4573-
4574-
<li>Otherwise, if <var>started</var> is false and if <var>bogus</var> is false, let
4575-
<var>negated</var> be true.</li>
4576-
4577-
<li>Let <var>started</var> be true.</li>
4578-
4579-
</ol>
4580-
4581-
</dd>
4582-
4583-
<dt>An <span data-x="ASCII digits">ASCII digit</span></dt>
4584-
4585-
<dd>
4586-
4587-
<p>Follow these substeps:</p>
4588-
4589-
<ol>
4590-
4591-
<li>If <var>finished</var> is true, skip to the next step in the overall set of steps.</li>
4592-
4593-
<li>Multiply <var>value</var> by ten.</li>
4594-
4595-
<li>Add the value of the digit, interpreted in base ten, to <var>value</var>.</li>
4596-
4597-
<li>Let <var>started</var> be true.</li>
4598-
4599-
<li>Let <var>got number</var> be true.</li>
4600-
4601-
</ol>
4602-
4603-
</dd>
4604-
4605-
4606-
<dt>A U+0020 SPACE character</dt>
4607-
<dt>A U+002C COMMA character</dt>
4608-
<dt>A U+003B SEMICOLON character</dt>
4609-
4610-
<dd>
4611-
4612-
<p>Follow these substeps:</p>
4613-
4614-
<ol>
4615-
4616-
<li>If <var>got number</var> is false, return the <var>numbers</var> list and abort. This
4617-
happens if an entry in the list has no digits, as in "<code data-x="">1,2,x,4</code>".</li>
4618-
4619-
<li>If <var>negated</var> is true, then negate <var>value</var>.</li>
4620-
4621-
<li>Append <var>value</var> to the <var>numbers</var> list.</li>
4622-
4623-
<li>Jump to step 4 in the overall set of steps.</li>
4624-
4625-
</ol>
4626-
4627-
</dd>
4628-
4629-
4630-
<!-- <dt>A U+002E FULL STOP character</dt> -->
4631-
<dt>A character in the range U+0001 to U+001F, <!-- space --> U+0021 to U+002B, <!-- comma --> U+002D to U+002F, <!-- digits --> U+003A, <!-- semicolon --> U+003C to U+0040, <!-- a-z --> U+005B to U+0060, <!-- A-Z --> U+007b to U+007F
4632-
(i.e. any other non-alphabetic ASCII character)</dt>
4633-
4634-
<!--
4635-
Test: http://www.hixie.ch/tests/adhoc/html/flow/image-maps/004-demo.html
4636-
IE6 on Wine treats the following characters like this also: U+1-U+1f, U+21-U+2b, U+2d-U+2f, U+3a,
4637-
U+3c-U+40, U+5b-U+60, U+7b-U+82, U+84-U+89, U+8b, U+8d, U+8f-U+99, U+9b, U+9d, U+a0-U+bf, U+d7,
4638-
U+f7, U+1f6-U+1f9, U+218-U+24f, U+2a9-U+385, U+387, U+38b, U+38d, U+3a2, U+3cf, U+3d7-U+3d9, U+3db,
4639-
U+3dd, U+3df, U+3e1, U+3f4-U+400, U+40d, U+450, U+45d, U+482-U+48f, U+4c5-U+4c6, U+4c9-U+4ca,
4640-
U+4cd-U+4cf, U+4ec-U+4ed, U+4f6-U+4f7, U+4fa-U+530, U+557-U+560, U+588-U+5cf, U+5eb-U+5ef,
4641-
U+5f3-U+620, U+63b-U+640, U+64b-U+670, U+6b8-U+6b9, U+6bf, U+6cf, U+6d4, U+6d6-U+904, U+93a-U+957,
4642-
U+962-U+984, U+98d-U+98e, U+991-U+992, U+9a9, U+9b1, U+9b3-U+9b5, U+9ba-U+9db, U+9de, U+9e2-U+9ef,
4643-
U+9f2-U+a04, U+a0b-U+a0e, U+a11-U+a12, U+a29, U+a31, U+a34, U+a37, U+a3a-U+a58, U+a5d, U+a5f-U+a84,
4644-
U+a8c, U+a8e, U+a92, U+aa9, U+ab1, U+ab4, U+aba-U+adf, U+ae1-U+b04, U+b0d-U+b0e, U+b11-U+b12,
4645-
U+b29, U+b31, U+b34-U+b35, U+b3a-U+b5b, U+b5e, U+b62-U+b84, U+b8b-U+b8d, U+b91, U+b96-U+b98, U+b9b,
4646-
U+b9d, U+ba0-U+ba2, U+ba5-U+ba7, U+bab-U+bad, U+bb6, U+bba-U+c04, U+c0d, U+c11, U+c29, U+c34,
4647-
U+c3a-U+c5f, U+c62-U+c84, U+c8d, U+c91, U+ca9, U+cb4, U+cba-U+cdd, U+cdf, U+ce2-U+d04, U+d0d,
4648-
U+d11, U+d29, U+d3a-U+d5f, U+d62-U+e00, U+e2f, U+e31, U+e34-U+e3f, U+e46-U+e80, U+e83, U+e85-U+e86,
4649-
U+e89, U+e8b-U+e8c, U+e8e-U+e93, U+e98, U+ea0, U+ea4, U+ea6, U+ea8-U+ea9, U+eac, U+eaf-U+edb,
4650-
U+ede-U+109f, U+10c6-U+10cf, U+10f7-U+10ff, U+115a-U+115e, U+11a3-U+11a7, U+11fa-U+1dff,
4651-
U+1e9b-U+1e9f, U+1efa-U+1eff, U+1f16-U+1f17, U+1f1e-U+1f1f, U+1f46-U+1f47, U+1f4e-U+1f4f, U+1f58,
4652-
U+1f5a, U+1f5c, U+1f5e, U+1f7e-U+1f7f, U+1fb5, U+1fbd-U+1fc1, U+1fc5, U+1fcd-U+1fcf, U+1fd4-U+1fd5,
4653-
U+1fdc-U+1fdf, U+1fed-U+1ff1, U+1ff5, U+1ffd-U+249b, U+24ea-U+3004, U+3006-U+3040, U+3095-U+309a,
4654-
U+309f-U+30a0, U+30fb, U+30ff-U+3104, U+312d-U+3130, U+318f-U+4dff, U+9fa6-U+abff, U+d7a4-U+d7ff,
4655-
U+e000-U+f8ff, U+fa2e-U+faff, U+fb07-U+fb12, U+fb18-U+fb1e, U+fb37, U+fb3d, U+fb3f, U+fb42, U+fb45,
4656-
U+fbb2-U+fbd2, U+fbe9, U+fce1, U+fd3e-U+fd4f, U+fd90-U+fd91, U+fdc8-U+fdef, U+fdfc-U+fe7f,
4657-
U+fefd-U+ff20, U+ff3b-U+ff40, U+ff5b-U+ff65, U+ffa0, U+ffbf-U+ffc1, U+ffc8-U+ffc9, U+ffd0-U+ffd1,
4658-
U+ffd8-U+ffd9, U+ffdd-U+ffff
4659-
IE7 on Win2003 treats the following characters like this also instead: U+1-U+1f, U+21-U+2b,
4660-
U+2d-U+2f, U+3a, U+3c-U+40, U+5b-U+60, U+7b-U+82, U+84-U+89, U+8b, U+8d, U+8f-U+99, U+9b, U+9d,
4661-
U+a0-U+a9, U+ab-U+b4, U+b6-U+b9, U+bb-U+bf, U+d7, U+f7, U+220-U+221, U+234-U+24f, U+2ae-U+2af,
4662-
U+2b9-U+2ba, U+2c2-U+2df, U+2e5-U+2ed, U+2ef-U+344, U+346-U+379, U+37b-U+385, U+387, U+38b, U+38d,
4663-
U+3a2, U+3cf, U+3d8-U+3d9, U+3f4-U+3ff, U+482-U+48b, U+4c5-U+4c6, U+4c9-U+4ca, U+4cd-U+4cf,
4664-
U+4f6-U+4f7, U+4fa-U+530, U+557-U+558, U+55a-U+560, U+588-U+5cf, U+5eb-U+5ef, U+5f3-U+620,
4665-
U+63b-U+640, U+656-U+66f, U+6d4, U+6dd-U+6e0, U+6e9-U+6ec, U+6ee-U+6f9, U+6fd-U+70f, U+72d-U+72f,
4666-
U+740-U+77f, U+7b1-U+900, U+904, U+93a-U+93c, U+94d - U+94f, U+951-U+957, U+964-U+980, U+984,
4667-
U+98d-U+98e, U+991-U+992, U+9a9, U+9b1, U+9b3-U+9b5, U+9ba-U+9bd, U+9c5-U+9c6, U+9c9-U+9ca,
4668-
U+9cd-U+9d6, U+9d8-U+9db, U+9de, U+9e4-U+9ef, U+9f2-U+a01, U+a03-U+a04, U+a0b-U+a0e, U+a11-U+a12,
4669-
U+a29, U+a31, U+a34, U+a37, U+a3a-U+a3d, U+a43-U+a46, U+a49-U+a4a, U+a4d-U+a58, U+a5d, U+a5f-U+a6f,
4670-
U+a75-U+a80, U+a84, U+a8c, U+a8e, U+a92, U+aa9, U+ab1, U+ab4, U+aba-U+abc, U+ac6, U+aca,
4671-
U+acd-U+acf, U+ad1-U+adf, U+ae1-U+b00, U+b04, U+b0d-U+b0e, U+b11-U+b12, U+b29, U+b31, U+b34-U+b35,
4672-
U+b3a-U+b3c, U+b44-U+b46, U+b49 - U+b4a, U+b4d-U+b55, U+b58-U+b5b, U+b5e, U+b62-U+b81, U+b84,
4673-
U+b8b-U+b8d, U+b91, U+b96-U+b98, U+b9b, U+b9d, U+ba0 - U+ba2, U+ba5-U+ba7, U+bab-U+bad, U+bb6,
4674-
U+bba-U+bbd, U+bc3-U+bc5, U+bc9, U+bcd-U+bd6, U+bd8-U+c00, U+c04, U+c0d, U+c11, U+c29, U+c34,
4675-
U+c3a-U+c3d, U+c45, U+c49, U+c4d-U+c54, U+c57-U+c5f, U+c62-U+c81, U+c84, U+c8d, U+c91, U+ca9,
4676-
U+cb4, U+cba-U+cbd, U+cc5, U+cc9, U+ccd-U+cd4, U+cd7-U+cdd, U+cdf, U+ce2-U+d01, U+d04, U+d0d,
4677-
U+d11, U+d29, U+d3a-U+d3d, U+d44-U+d45, U+d49, U+d4d-U+d56, U+d58-U+d5f, U+d62-U+d81, U+d84,
4678-
U+d97-U+d99, U+db2, U+dbc, U+dbe - U+dbf, U+dc7-U+dce, U+dd5, U+dd7, U+de0-U+df1, U+df4-U+e00,
4679-
U+e3b-U+e3f, U+e4f-U+e80, U+e83, U+e85-U+e86, U+e89, U+e8b-U+e8c, U+e8e-U+e93, U+e98, U+ea0, U+ea4,
4680-
U+ea6, U+ea8-U+ea9, U+eac, U+eba, U+ebe-U+ebf, U+ec5-U+ecc, U+ece-U+edb, U+ede-U+eff, U+f01-U+f3f,
4681-
U+f48, U+f6b-U+f70, U+f82-U+f87, U+f8c-U+f8f, U+f98, U+fbd-U+fff, U+1022, U+1028, U+102b,
4682-
U+1033-U+1035, U+1037, U+1039-U+104f, U+105a-U+109f, U+10c6-U+10cf, U+10f7-U+10ff, U+115a - U+115e,
4683-
U+11a3-U+11a7, U+11fa-U+11ff, U+1207, U+1247, U+1249, U+124e-U+124f, U+1257, U+1259, U+125e-U+125f,
4684-
U+1287, U+1289, U+128e-U+128f, U+12af, U+12b1, U+12b6-U+12b7, U+12bf, U+12c1, U+12c6-U+12c7,
4685-
U+12cf, U+12d7, U+12ef, U+130f, U+1311, U+1316-U+1317, U+131f, U+1347, U+135b-U+139f,
4686-
U+13f5-U+1400, U+166d-U+166e, U+1677-U+1680, U+169b - U+169f, U+16eb-U+177f, U+17c9-U+181f, U+1843,
4687-
U+1878-U+187f, U+18aa-U+1dff, U+1e9c-U+1e9f, U+1efa-U+1eff, U+1f16-U+1f17, U+1f1e-U+1f1f,
4688-
U+1f46-U+1f47, U+1f4e-U+1f4f, U+1f58, U+1f5a, U+1f5c, U+1f5e, U+1f7e-U+1f7f, U+1fb5, U+1fbd,
4689-
U+1fbf-U+1fc1, U+1fc5, U+1fcd-U+1fcf, U+1fd4-U+1fd5, U+1fdc-U+1fdf, U+1fed-U+1ff1, U+1ff5,
4690-
U+1ffd-U+207e, U+2080-U+2101, U+2103-U+2106, U+2108-U+2109, U+2114, U+2116-U+2118, U+211e-U+2123,
4691-
U+2125, U+2127, U+2129, U+212e, U+2132, U+213a-U+215f, U+2184-U+3005, U+3008-U+3020, U+302a-U+3037,
4692-
U+303b-U+3104, U+312d-U+3130, U+318f - U+319f, U+31b8-U+33ff, U+4db6-U+4dff, U+9fa6-U+9fff,
4693-
U+a48d-U+abff, U+d7a4-U+d7ff, U+e000-U+f8ff, U+fa2e-U+faff, U+fb07-U+fb12, U+fb18-U+fb1c, U+fb1e,
4694-
U+fb29, U+fb37, U+fb3d, U+fb3f, U+fb42, U+fb45, U+fbb2-U+fbd2, U+fd3e-U+fd4f, U+fd90-U+fd91,
4695-
U+fdc8-U+fdef, U+fdfc-U+fe6f, U+fe73, U+fe75, U+fefd-U+ff20, U+ff3b-U+ff40, U+ff5b-U+ff9f,
4696-
U+ffbf-U+ffc1, U+ffc8-U+ffc9, U+ffd0-U+ffd1, U+ffd8-U+ffd9, U+ffdd-U+ffff
4697-
-->
4698-
4699-
<dd>
4700-
4701-
<p>Follow these substeps:</p>
4702-
4703-
<ol>
4704-
4705-
<li>If <var>got number</var> is true, let <var>finished</var> be true.</li>
4706-
4707-
<li>If <var>finished</var> is true, skip to the next step in the overall set of steps.</li>
4708-
4709-
<li>Let <var>negated</var> be false.</li>
4710-
4711-
</ol>
4712-
4713-
</dd>
4714-
4715-
4716-
<dt>Any other character</dt>
4717-
<!-- alphabetic a-z A-Z, and non-ASCII -->
4718-
4719-
<dd>
4720-
4721-
<p>Follow these substeps:</p>
4536+
<li><p>While <var>position</var> is not past the end of <var>input</var>:</p>
47224537

4723-
<ol>
4538+
<ol>
47244539

4725-
<li>If <var>finished</var> is true, skip to the next step in the overall set of steps.</li>
4540+
<li><p><span>Collect a sequence of characters</span> that are not <span data-x="space
4541+
character">space characters</span>, U+002C COMMA, U+003B SEMICOLON, <span>ASCII digits</span>,
4542+
U+002E FULL STOP, or U+002D HYPHEN-MINUS characters. This skips past leading garbage.</p></li>
47264543

4727-
<li>Let <var>negated</var> be false.</li>
4544+
<li><p><span>Collect a sequence of characters</span> that are not <span data-x="space
4545+
character">space characters</span>, U+002C COMMA, U+003B SEMICOLON characters, and let
4546+
<var>unparsed number</var> be the result.</p></li>
47284547

4729-
<li>Let <var>bogus</var> be true.</li>
4548+
<li><p>Let <var>number</var> be the result of using the <span>rules for parsing floating-point
4549+
number values</span> for <var>unparsed number</var>.</p></li>
47304550

4731-
<li>If <var>started</var> is true, then return the <var>numbers</var> list, and abort. (The
4732-
value in <var>value</var> is not appended to the list first; it is dropped.)</li>
4551+
<li><p>If <var>number</var> is an error, let <var>number</var> be zero.</p></li>
47334552

4734-
</ol>
4553+
<li><p>Append <var>number</var> to <var>numbers</var>.</p></li>
47354554

4736-
</dd>
4555+
<li><p><span>Collect a sequence of characters</span> that are <span data-x="space
4556+
character">space characters</span>, U+002C COMMA, or U+003B SEMICOLON characters. This skips
4557+
past the delimiter.</p></li>
47374558

4738-
</dl>
4559+
</ol>
47394560

47404561
</li>
47414562

4742-
<li><p>Advance <var>position</var> to the next character in <var>input</var>, or to beyond the
4743-
end of the string if there are no more characters.</p></li>
4744-
4745-
<li><p>If <var>position</var> points to a character (and not to beyond the end of
4746-
<var>input</var>), jump to the big <i>Parser</i> step above.</p></li>
4747-
4748-
<li><p>If <var>negated</var> is true, then negate <var>value</var>.</li>
4749-
4750-
<li><p>If <var>got number</var> is true, then append <var>value</var> to the <var>numbers</var>
4751-
list.</li>
4752-
4753-
<li><p>Return the <var>numbers</var> list and abort.</p></li>
4563+
<li><p>Return <var>numbers</var>.</p></li>
47544564

47554565
</ol>
47564566

@@ -37079,10 +36889,10 @@ dictionary <dfn>TrackEventInit</dfn> : <span>EventInit</span> {
3707936889
data-x="attr-area-shape-rect">rectangle</span> state.</p>
3708036890

3708136891
<p>The <dfn><code data-x="attr-area-coords">coords</code></dfn> attribute must, if specified,
37082-
contain a <span>valid list of integers</span>. This attribute gives the coordinates for the shape
37083-
described by the <code data-x="attr-area-shape">shape</code> attribute. <span w-nodev>The
37084-
processing for this attribute is described as part of the <span>image map</span> processing
37085-
model.</span></p>
36892+
contain a <span>valid list of floating-point numbers</span>. This attribute gives the coordinates
36893+
for the shape described by the <code data-x="attr-area-shape">shape</code> attribute. <span
36894+
w-nodev>The processing for this attribute is described as part of the <span>image map</span>
36895+
processing model.</span></p>
3708636896

3708736897
<!-- v2: It was suggested by John S. Urban that coords should support percentages as well as
3708836898
pixels, so that one could use the same image map for images of various sizes. -->
@@ -37308,10 +37118,10 @@ dictionary <dfn>TrackEventInit</dfn> : <span>EventInit</span> {
3730837118
<li><p>Find the state that the element's <code data-x="attr-area-shape">shape</code> attribute
3730937119
represents.</p></li>
3731037120

37311-
<li><p>Use the <span>rules for parsing a list of integers</span> to parse the element's <code
37312-
data-x="attr-area-coords">coords</code> attribute, if it is present, and let the result be the
37313-
<var>coords</var> list. If the attribute is absent, let the <var>coords</var>
37314-
list be the empty list.</p></li>
37121+
<li><p>Use the <span>rules for parsing a list of floating-point numbers</span> to parse the
37122+
element's <code data-x="attr-area-coords">coords</code> attribute, if it is present, and let the
37123+
result be the <var>coords</var> list. If the attribute is absent, let the <var>coords</var> list
37124+
be the empty list.</p></li>
3731537125

3731637126
<li>
3731737127

@@ -114929,7 +114739,7 @@ if (s = prompt('What is your name?')) {
114929114739
<th> <code data-x="">coords</code>
114930114740
<td> <code data-x="attr-area-coords">area</code>
114931114741
<td> Coordinates for the shape to be created in an <span>image map</span>
114932-
<td> <span>Valid list of integers</span>*
114742+
<td> <span>Valid list of floating-point numbers</span>*
114933114743
<tr>
114934114744
<th> <code data-x="">crossorigin</code>
114935114745
<td> <code data-x="attr-media-crossorigin">audio</code>;

0 commit comments

Comments
 (0)