Skip to content

Commit d6ce83c

Browse files
committed
Update deprecated APIs with alternatives.
1 parent abf41e4 commit d6ce83c

File tree

3 files changed

+100
-100
lines changed

3 files changed

+100
-100
lines changed

src/backend/mi_parse.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface MIInfo {
66

77
const octalMatch = /^[0-7]{3}/;
88
function parseString(str: string): string {
9-
const ret = new Buffer(str.length * 4);
9+
const ret = Buffer.alloc(str.length * 4);
1010
let bufIndex = 0;
1111

1212
if (str[0] != '"' || str[str.length - 1] != '"')

src/test/suite/gdb_expansion.test.ts

+27-27
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@ suite("GDB Value Expansion", () => {
55
const variableCreate = (variable) => { return { expanded: variable }; };
66
test("Various values", () => {
77
assert.strictEqual(isExpandable(`false`), 0);
8-
assert.equal(expandValue(variableCreate, `false`), "false");
8+
assert.strictEqual(expandValue(variableCreate, `false`), "false");
99
assert.strictEqual(isExpandable(`5`), 0);
10-
assert.equal(expandValue(variableCreate, `5`), "5");
10+
assert.strictEqual(expandValue(variableCreate, `5`), "5");
1111
assert.strictEqual(isExpandable(`"hello world!"`), 0);
12-
assert.equal(expandValue(variableCreate, `"hello world!"`), `"hello world!"`);
12+
assert.strictEqual(expandValue(variableCreate, `"hello world!"`), `"hello world!"`);
1313
assert.strictEqual(isExpandable(`0x7fffffffe956 "foobar"`), 0);
14-
assert.equal(expandValue(variableCreate, `0x7fffffffe956 "foobar"`), `"foobar"`);
14+
assert.strictEqual(expandValue(variableCreate, `0x7fffffffe956 "foobar"`), `"foobar"`);
1515
assert.strictEqual(isExpandable(`0x0`), 0);
16-
assert.equal(expandValue(variableCreate, `0x0`), "<nullptr>");
16+
assert.strictEqual(expandValue(variableCreate, `0x0`), "<nullptr>");
1717
assert.strictEqual(isExpandable(`0x000000`), 0);
18-
assert.equal(expandValue(variableCreate, `0x000000`), "<nullptr>");
18+
assert.strictEqual(expandValue(variableCreate, `0x000000`), "<nullptr>");
1919
assert.strictEqual(isExpandable(`{...}`), 2);
20-
assert.equal(expandValue(variableCreate, `{...}`), "<...>");
20+
assert.strictEqual(expandValue(variableCreate, `{...}`), "<...>");
2121
assert.strictEqual(isExpandable(`0x00abc`), 2);
22-
assert.equal(expandValue(variableCreate, `0x007ffff7ecb480`), "*0x007ffff7ecb480");
22+
assert.strictEqual(expandValue(variableCreate, `0x007ffff7ecb480`), "*0x007ffff7ecb480");
2323
assert.strictEqual(isExpandable(`{a = b, c = d}`), 1);
24-
assert.deepEqual(expandValue(variableCreate, `{a = b, c = d}`), [
24+
assert.deepStrictEqual(expandValue(variableCreate, `{a = b, c = d}`), [
2525
{
2626
name: "a",
2727
value: "b",
@@ -32,7 +32,7 @@ suite("GDB Value Expansion", () => {
3232
variablesReference: 0
3333
}]);
3434
assert.strictEqual(isExpandable(`{[0] = 0x400730 "foo", [1] = 0x400735 "bar"}`), 1);
35-
assert.deepEqual(expandValue(variableCreate, `{[0] = 0x400730 "foo", [1] = 0x400735 "bar"}`), [
35+
assert.deepStrictEqual(expandValue(variableCreate, `{[0] = 0x400730 "foo", [1] = 0x400735 "bar"}`), [
3636
{
3737
name: "[0]",
3838
value: "\"foo\"",
@@ -43,7 +43,7 @@ suite("GDB Value Expansion", () => {
4343
variablesReference: 0
4444
}]);
4545
assert.strictEqual(isExpandable(`{{a = b}}`), 1);
46-
assert.deepEqual(expandValue(variableCreate, `{{a = b}}`), [
46+
assert.deepStrictEqual(expandValue(variableCreate, `{{a = b}}`), [
4747
{
4848
name: "[0]",
4949
value: "Object",
@@ -58,7 +58,7 @@ suite("GDB Value Expansion", () => {
5858
}
5959
}
6060
]);
61-
assert.deepEqual(expandValue(variableCreate, `{1, 2, 3, 4}`), [
61+
assert.deepStrictEqual(expandValue(variableCreate, `{1, 2, 3, 4}`), [
6262
{
6363
name: "[0]",
6464
value: "1",
@@ -79,11 +79,11 @@ suite("GDB Value Expansion", () => {
7979
});
8080
test("Error values", () => {
8181
assert.strictEqual(isExpandable(`<No data fields>`), 0);
82-
assert.equal(expandValue(variableCreate, `<No data fields>`), "<No data fields>");
82+
assert.strictEqual(expandValue(variableCreate, `<No data fields>`), "<No data fields>");
8383
});
8484
test("Nested values", () => {
8585
assert.strictEqual(isExpandable(`{a = {b = e}, c = d}`), 1);
86-
assert.deepEqual(expandValue(variableCreate, `{a = {b = e}, c = d}`), [
86+
assert.deepStrictEqual(expandValue(variableCreate, `{a = {b = e}, c = d}`), [
8787
{
8888
name: "a",
8989
value: "Object",
@@ -105,21 +105,21 @@ suite("GDB Value Expansion", () => {
105105
test("Simple node", () => {
106106
assert.strictEqual(isExpandable(`{a = false, b = 5, c = 0x0, d = "foobar"}`), 1);
107107
const variables = expandValue(variableCreate, `{a = false, b = 5, c = 0x0, d = "foobar"}`);
108-
assert.equal(variables.length, 4);
109-
assert.equal(variables[0].name, "a");
110-
assert.equal(variables[0].value, "false");
111-
assert.equal(variables[1].name, "b");
112-
assert.equal(variables[1].value, "5");
113-
assert.equal(variables[2].name, "c");
114-
assert.equal(variables[2].value, "<nullptr>");
115-
assert.equal(variables[3].name, "d");
116-
assert.equal(variables[3].value, `"foobar"`);
108+
assert.strictEqual(variables.length, 4);
109+
assert.strictEqual(variables[0].name, "a");
110+
assert.strictEqual(variables[0].value, "false");
111+
assert.strictEqual(variables[1].name, "b");
112+
assert.strictEqual(variables[1].value, "5");
113+
assert.strictEqual(variables[2].name, "c");
114+
assert.strictEqual(variables[2].value, "<nullptr>");
115+
assert.strictEqual(variables[3].name, "d");
116+
assert.strictEqual(variables[3].value, `"foobar"`);
117117
});
118118
test("Complex node", () => {
119119
const node = `{quit = false, _views = {{view = 0x7ffff7ece1e8, renderer = 0x7ffff7eccc50, world = 0x7ffff7ece480}}, deltaTimer = {_flagStarted = false, _timeStart = {length = 0}, _timeMeasured = {length = 0}}, _start = {callbacks = 0x0}, _stop = {callbacks = 0x0}}`;
120120
assert.strictEqual(isExpandable(node), 1);
121121
const variables = expandValue(variableCreate, node);
122-
assert.deepEqual(variables, [
122+
assert.deepStrictEqual(variables, [
123123
{
124124
name: "quit",
125125
value: "false",
@@ -227,7 +227,7 @@ suite("GDB Value Expansion", () => {
227227
const node = `{_enableMipMaps = false, _minFilter = <incomplete type>, _magFilter = <incomplete type>, _wrapX = <incomplete type>, _wrapY = <incomplete type>, _inMode = 6408, _mode = 6408, _id = 1, _width = 1024, _height = 1024}`;
228228
assert.strictEqual(isExpandable(node), 1);
229229
const variables = expandValue(variableCreate, node);
230-
assert.deepEqual(variables, [
230+
assert.deepStrictEqual(variables, [
231231
{
232232
name: "_enableMipMaps",
233233
value: "false",
@@ -284,7 +284,7 @@ suite("GDB Value Expansion", () => {
284284
const node = `{ name = {...} }`;
285285
assert.strictEqual(isExpandable(node), 1);
286286
const variables = expandValue(variableCreate, node);
287-
assert.deepEqual(variables, [
287+
assert.deepStrictEqual(variables, [
288288
{
289289
name: "name",
290290
value: "...",
@@ -296,7 +296,7 @@ suite("GDB Value Expansion", () => {
296296
const node = `{ intval1 = 123, floatval1 = 123.456, intval2 = 3, floatval2 = 234.45 }`;
297297
const variables = expandValue(variableCreate, node);
298298

299-
assert.deepEqual(variables, [
299+
assert.deepStrictEqual(variables, [
300300
{ name: "intval1", value: "123", variablesReference: 0 },
301301
{ name: "floatval1", value: "123.456", variablesReference: 0 },
302302
{ name: "intval2", value: "3", variablesReference: 0 },

src/test/suite/mi_parse.test.ts

+72-72
Original file line numberDiff line numberDiff line change
@@ -15,74 +15,74 @@ suite("MI Parse", () => {
1515
test("Simple out of band record", () => {
1616
const parsed = parseMI(`4=thread-exited,id="3",group-id="i1"`);
1717
assert.ok(parsed);
18-
assert.equal(parsed.token, 4);
19-
assert.equal(parsed.outOfBandRecord.length, 1);
20-
assert.equal(parsed.outOfBandRecord[0].isStream, false);
21-
assert.equal(parsed.outOfBandRecord[0].asyncClass, "thread-exited");
22-
assert.equal(parsed.outOfBandRecord[0].output.length, 2);
23-
assert.deepEqual(parsed.outOfBandRecord[0].output[0], ["id", "3"]);
24-
assert.deepEqual(parsed.outOfBandRecord[0].output[1], ["group-id", "i1"]);
25-
assert.equal(parsed.resultRecords, undefined);
18+
assert.strictEqual(parsed.token, 4);
19+
assert.strictEqual(parsed.outOfBandRecord.length, 1);
20+
assert.strictEqual(parsed.outOfBandRecord[0].isStream, false);
21+
assert.strictEqual(parsed.outOfBandRecord[0].asyncClass, "thread-exited");
22+
assert.strictEqual(parsed.outOfBandRecord[0].output.length, 2);
23+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[0], ["id", "3"]);
24+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[1], ["group-id", "i1"]);
25+
assert.strictEqual(parsed.resultRecords, undefined);
2626
});
2727
test("Console stream output with new line", () => {
2828
const parsed = parseMI(`~"[Thread 0x7fffe993a700 (LWP 11002) exited]\\n"`);
2929
assert.ok(parsed);
30-
assert.equal(parsed.token, undefined);
31-
assert.equal(parsed.outOfBandRecord.length, 1);
32-
assert.equal(parsed.outOfBandRecord[0].isStream, true);
33-
assert.equal(parsed.outOfBandRecord[0].content, "[Thread 0x7fffe993a700 (LWP 11002) exited]\n");
34-
assert.equal(parsed.resultRecords, undefined);
30+
assert.strictEqual(parsed.token, undefined);
31+
assert.strictEqual(parsed.outOfBandRecord.length, 1);
32+
assert.strictEqual(parsed.outOfBandRecord[0].isStream, true);
33+
assert.strictEqual(parsed.outOfBandRecord[0].content, "[Thread 0x7fffe993a700 (LWP 11002) exited]\n");
34+
assert.strictEqual(parsed.resultRecords, undefined);
3535
});
3636
test("Unicode", () => {
3737
let parsed = parseMI(`~"[Depuraci\\303\\263n de hilo usando libthread_db enabled]\\n"`);
3838
assert.ok(parsed);
39-
assert.equal(parsed.token, undefined);
40-
assert.equal(parsed.outOfBandRecord.length, 1);
41-
assert.equal(parsed.outOfBandRecord[0].isStream, true);
42-
assert.equal(parsed.outOfBandRecord[0].content, "[Depuración de hilo usando libthread_db enabled]\n");
43-
assert.equal(parsed.resultRecords, undefined);
39+
assert.strictEqual(parsed.token, undefined);
40+
assert.strictEqual(parsed.outOfBandRecord.length, 1);
41+
assert.strictEqual(parsed.outOfBandRecord[0].isStream, true);
42+
assert.strictEqual(parsed.outOfBandRecord[0].content, "[Depuración de hilo usando libthread_db enabled]\n");
43+
assert.strictEqual(parsed.resultRecords, undefined);
4444
parsed = parseMI(`~"4\\t std::cout << \\"\\345\\245\\275\\345\\245\\275\\345\\255\\246\\344\\271\\240\\357\\274\\214\\345\\244\\251\\345\\244\\251\\345\\220\\221\\344\\270\\212\\" << std::endl;\\n"`);
4545
assert.ok(parsed);
46-
assert.equal(parsed.token, undefined);
47-
assert.equal(parsed.outOfBandRecord.length, 1);
48-
assert.equal(parsed.outOfBandRecord[0].isStream, true);
49-
assert.equal(parsed.outOfBandRecord[0].content, `4\t std::cout << "好好学习,天天向上" << std::endl;\n`);
50-
assert.equal(parsed.resultRecords, undefined);
46+
assert.strictEqual(parsed.token, undefined);
47+
assert.strictEqual(parsed.outOfBandRecord.length, 1);
48+
assert.strictEqual(parsed.outOfBandRecord[0].isStream, true);
49+
assert.strictEqual(parsed.outOfBandRecord[0].content, `4\t std::cout << "好好学习,天天向上" << std::endl;\n`);
50+
assert.strictEqual(parsed.resultRecords, undefined);
5151
});
5252
test("Empty line", () => {
5353
const parsed = parseMI(``);
5454
assert.ok(parsed);
55-
assert.equal(parsed.token, undefined);
56-
assert.equal(parsed.outOfBandRecord.length, 0);
57-
assert.equal(parsed.resultRecords, undefined);
55+
assert.strictEqual(parsed.token, undefined);
56+
assert.strictEqual(parsed.outOfBandRecord.length, 0);
57+
assert.strictEqual(parsed.resultRecords, undefined);
5858
});
5959
test("'(gdb)' line", () => {
6060
const parsed = parseMI(`(gdb)`);
6161
assert.ok(parsed);
62-
assert.equal(parsed.token, undefined);
63-
assert.equal(parsed.outOfBandRecord.length, 0);
64-
assert.equal(parsed.resultRecords, undefined);
62+
assert.strictEqual(parsed.token, undefined);
63+
assert.strictEqual(parsed.outOfBandRecord.length, 0);
64+
assert.strictEqual(parsed.resultRecords, undefined);
6565
});
6666
test("Simple result record", () => {
6767
const parsed = parseMI(`1^running`);
6868
assert.ok(parsed);
69-
assert.equal(parsed.token, 1);
70-
assert.equal(parsed.outOfBandRecord.length, 0);
71-
assert.notEqual(parsed.resultRecords, undefined);
72-
assert.equal(parsed.resultRecords.resultClass, "running");
73-
assert.equal(parsed.resultRecords.results.length, 0);
69+
assert.strictEqual(parsed.token, 1);
70+
assert.strictEqual(parsed.outOfBandRecord.length, 0);
71+
assert.notStrictEqual(parsed.resultRecords, undefined);
72+
assert.strictEqual(parsed.resultRecords.resultClass, "running");
73+
assert.strictEqual(parsed.resultRecords.results.length, 0);
7474
});
7575
test("Advanced out of band record (Breakpoint hit)", () => {
7676
const parsed = parseMI(`*stopped,reason="breakpoint-hit",disp="keep",bkptno="1",frame={addr="0x00000000004e807f",func="D main",args=[{name="args",value="..."}],file="source/app.d",fullname="/path/to/source/app.d",line="157"},thread-id="1",stopped-threads="all",core="0"`);
7777
assert.ok(parsed);
78-
assert.equal(parsed.token, undefined);
79-
assert.equal(parsed.outOfBandRecord.length, 1);
80-
assert.equal(parsed.outOfBandRecord[0].isStream, false);
81-
assert.equal(parsed.outOfBandRecord[0].asyncClass, "stopped");
82-
assert.equal(parsed.outOfBandRecord[0].output.length, 7);
83-
assert.deepEqual(parsed.outOfBandRecord[0].output[0], ["reason", "breakpoint-hit"]);
84-
assert.deepEqual(parsed.outOfBandRecord[0].output[1], ["disp", "keep"]);
85-
assert.deepEqual(parsed.outOfBandRecord[0].output[2], ["bkptno", "1"]);
78+
assert.strictEqual(parsed.token, undefined);
79+
assert.strictEqual(parsed.outOfBandRecord.length, 1);
80+
assert.strictEqual(parsed.outOfBandRecord[0].isStream, false);
81+
assert.strictEqual(parsed.outOfBandRecord[0].asyncClass, "stopped");
82+
assert.strictEqual(parsed.outOfBandRecord[0].output.length, 7);
83+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[0], ["reason", "breakpoint-hit"]);
84+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[1], ["disp", "keep"]);
85+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[2], ["bkptno", "1"]);
8686
const frame = [
8787
["addr", "0x00000000004e807f"],
8888
["func", "D main"],
@@ -91,20 +91,20 @@ suite("MI Parse", () => {
9191
["fullname", "/path/to/source/app.d"],
9292
["line", "157"]
9393
];
94-
assert.deepEqual(parsed.outOfBandRecord[0].output[3], ["frame", frame]);
95-
assert.deepEqual(parsed.outOfBandRecord[0].output[4], ["thread-id", "1"]);
96-
assert.deepEqual(parsed.outOfBandRecord[0].output[5], ["stopped-threads", "all"]);
97-
assert.deepEqual(parsed.outOfBandRecord[0].output[6], ["core", "0"]);
98-
assert.equal(parsed.resultRecords, undefined);
94+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[3], ["frame", frame]);
95+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[4], ["thread-id", "1"]);
96+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[5], ["stopped-threads", "all"]);
97+
assert.deepStrictEqual(parsed.outOfBandRecord[0].output[6], ["core", "0"]);
98+
assert.strictEqual(parsed.resultRecords, undefined);
9999
});
100100
test("Advanced result record", () => {
101101
const parsed = parseMI(`2^done,asm_insns=[src_and_asm_line={line="134",file="source/app.d",fullname="/path/to/source/app.d",line_asm_insn=[{address="0x00000000004e7da4",func-name="_Dmain",offset="0",inst="push %rbp"},{address="0x00000000004e7da5",func-name="_Dmain",offset="1",inst="mov %rsp,%rbp"}]}]`);
102102
assert.ok(parsed);
103-
assert.equal(parsed.token, 2);
104-
assert.equal(parsed.outOfBandRecord.length, 0);
105-
assert.notEqual(parsed.resultRecords, undefined);
106-
assert.equal(parsed.resultRecords.resultClass, "done");
107-
assert.equal(parsed.resultRecords.results.length, 1);
103+
assert.strictEqual(parsed.token, 2);
104+
assert.strictEqual(parsed.outOfBandRecord.length, 0);
105+
assert.notStrictEqual(parsed.resultRecords, undefined);
106+
assert.strictEqual(parsed.resultRecords.resultClass, "done");
107+
assert.strictEqual(parsed.resultRecords.results.length, 1);
108108
const asmInsns = [
109109
"asm_insns",
110110
[
@@ -135,8 +135,8 @@ suite("MI Parse", () => {
135135
]
136136
]
137137
];
138-
assert.deepEqual(parsed.resultRecords.results[0], asmInsns);
139-
assert.equal(parsed.result("asm_insns.src_and_asm_line.line_asm_insn[1].address"), "0x00000000004e7da5");
138+
assert.deepStrictEqual(parsed.resultRecords.results[0], asmInsns);
139+
assert.strictEqual(parsed.result("asm_insns.src_and_asm_line.line_asm_insn[1].address"), "0x00000000004e7da5");
140140
});
141141
test("valueof children", () => {
142142
const obj = [
@@ -169,39 +169,39 @@ suite("MI Parse", () => {
169169
]
170170
];
171171

172-
assert.equal(MINode.valueOf(obj[0], "@frame.level"), "0");
173-
assert.equal(MINode.valueOf(obj[0], "@frame.addr"), "0x0000000000435f70");
174-
assert.equal(MINode.valueOf(obj[0], "@frame.func"), "D main");
175-
assert.equal(MINode.valueOf(obj[0], "@frame.file"), "source/app.d");
176-
assert.equal(MINode.valueOf(obj[0], "@frame.fullname"), "/path/to/source/app.d");
177-
assert.equal(MINode.valueOf(obj[0], "@frame.line"), "5");
172+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.level"), "0");
173+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.addr"), "0x0000000000435f70");
174+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.func"), "D main");
175+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.file"), "source/app.d");
176+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.fullname"), "/path/to/source/app.d");
177+
assert.strictEqual(MINode.valueOf(obj[0], "@frame.line"), "5");
178178

179-
assert.equal(MINode.valueOf(obj[1], "@frame.level"), "1");
180-
assert.equal(MINode.valueOf(obj[1], "@frame.addr"), "0x00000000004372d3");
181-
assert.equal(MINode.valueOf(obj[1], "@frame.func"), "rt.dmain2._d_run_main()");
182-
assert.equal(MINode.valueOf(obj[1], "@frame.file"), undefined);
183-
assert.equal(MINode.valueOf(obj[1], "@frame.fullname"), undefined);
184-
assert.equal(MINode.valueOf(obj[1], "@frame.line"), undefined);
179+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.level"), "1");
180+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.addr"), "0x00000000004372d3");
181+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.func"), "rt.dmain2._d_run_main()");
182+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.file"), undefined);
183+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.fullname"), undefined);
184+
assert.strictEqual(MINode.valueOf(obj[1], "@frame.line"), undefined);
185185
});
186186
test("empty string values", () => {
187187
const parsed = parseMI(`15^done,register-names=["r0","pc","","xpsr","","control"]`);
188188
const result = parsed.result('register-names');
189-
assert.deepEqual(result, ["r0", "pc", "", "xpsr", "", "control"]);
189+
assert.deepStrictEqual(result, ["r0", "pc", "", "xpsr", "", "control"]);
190190
});
191191
test("empty string value first and last", () => {
192192
const parsed = parseMI(`15^done,register-names=["","r0","pc","","xpsr","","control",""]`);
193193
const result = parsed.result('register-names');
194-
assert.deepEqual(result, ["", "r0", "pc", "", "xpsr", "", "control", ""]);
194+
assert.deepStrictEqual(result, ["", "r0", "pc", "", "xpsr", "", "control", ""]);
195195
});
196196
test("empty array values", () => {
197197
const parsed = parseMI(`15^done,foo={x=[],y="y"}`);
198-
assert.deepEqual(parsed.result('foo.x'), []);
199-
assert.equal(parsed.result('foo.y'), "y");
198+
assert.deepStrictEqual(parsed.result('foo.x'), []);
199+
assert.strictEqual(parsed.result('foo.y'), "y");
200200
});
201201
test("empty object values", () => {
202202
// GDB may send {} as empty array
203203
const parsed = parseMI(`15^done,foo={x={},y="y"}`);
204-
assert.deepEqual(parsed.result('foo.x'), []);
205-
assert.equal(parsed.result('foo.y'), "y");
204+
assert.deepStrictEqual(parsed.result('foo.x'), []);
205+
assert.strictEqual(parsed.result('foo.y'), "y");
206206
});
207207
});

0 commit comments

Comments
 (0)