xml-twig 1.3.2 → 1.3.4

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/doc/twig.md CHANGED
@@ -40,9 +40,6 @@
40
40
  <dt><a href="#onClose">onClose(handler, options, name)</a></dt>
41
41
  <dd><p>Common Event hanlder for closing tag</p>
42
42
  </dd>
43
- <dt><a href="#reset">reset()</a></dt>
44
- <dd><p>Reset global variable if one like to parse multiple files</p>
45
- </dd>
46
43
  </dl>
47
44
 
48
45
  ## Typedefs
@@ -247,13 +244,13 @@ Purges the current, typically used after element has been processed.<br>The root
247
244
  <a name="Twig+purgeUpTo"></a>
248
245
 
249
246
  ### twig.purgeUpTo
250
- Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
247
+ Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.<br>
251
248
 
252
249
  **Kind**: instance property of [<code>Twig</code>](#Twig)
253
250
 
254
251
  | Param | Type | Description |
255
252
  | --- | --- | --- |
256
- | [elt] | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. The `elt` object itself is not purged.<br> If `undefined` then the current element is purged (i.e. `purge()`) |
253
+ | [elt] | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. If `undefined` then the current element is purged (i.e. `purge()`) |
257
254
 
258
255
  <a name="Twig+escapeEntity"></a>
259
256
 
@@ -864,13 +861,13 @@ Purges the current, typically used after element has been processed.<br>The root
864
861
  <a name="Twig+purgeUpTo"></a>
865
862
 
866
863
  ### twig.purgeUpTo
867
- Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
864
+ Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.<br>
868
865
 
869
866
  **Kind**: instance property of [<code>Twig</code>](#Twig)
870
867
 
871
868
  | Param | Type | Description |
872
869
  | --- | --- | --- |
873
- | [elt] | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. The `elt` object itself is not purged.<br> If `undefined` then the current element is purged (i.e. `purge()`) |
870
+ | [elt] | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. If `undefined` then the current element is purged (i.e. `purge()`) |
874
871
 
875
872
  <a name="Twig+escapeEntity"></a>
876
873
 
@@ -1460,12 +1457,6 @@ Common Event hanlder for closing tag
1460
1457
  | options | [<code>ParserOptions</code>](#ParserOptions) | Object of optional options |
1461
1458
  | name | <code>string</code> | Event handler parameter |
1462
1459
 
1463
- <a name="reset"></a>
1464
-
1465
- ## reset()
1466
- Reset global variable if one like to parse multiple files
1467
-
1468
- **Kind**: global function
1469
1460
  <a name="ParserOptions"></a>
1470
1461
 
1471
1462
  ## ParserOptions
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "name": "xml-twig",
7
7
  "description": "Node module for processing huge XML documents in tree mode",
8
- "version": "1.3.2",
8
+ "version": "1.3.4",
9
9
  "main": "twig.js",
10
10
  "directories": {
11
11
  "doc": "doc"
@@ -1,29 +1,45 @@
1
- const { DateTime } = require('luxon');
2
1
  const fs = require('fs');
2
+ const path = require('path');
3
3
  const twig = require('../twig.js');
4
+ const { pipeline } = require('stream/promises');
5
+ const { DateTime } = require('luxon');
4
6
 
5
7
  let NE = 0;
6
- const startTime = DateTime.now();
7
-
8
- let parser = twig.createParser([{ tag: 'subsession', function: anyHandler }], { method: process.argv[2] })
9
- let reader = fs.createReadStream(`${__dirname}/20240304015234.9-MSRAN.xml`);
10
- console.log(`Starting with ${parser.method}...`)
11
- reader.pipe(parser);
8
+ let startTime = DateTime.now();
9
+ let printNE = true;
12
10
 
13
11
  function anyHandler(elt) {
14
12
  NE++;
15
- if (NE % 25 === 0) {
13
+ if (printNE && NE % 25 === 0) {
16
14
  let d = DateTime.now().diff(startTime);
17
15
  console.log(`\t${NE} NE in ${d.toFormat('mm:ss.S')}`);
18
16
  }
19
17
  elt.purge();
20
18
  }
21
19
 
22
- reader.on('end', () => {
20
+ async function parse(method) {
21
+ const parser = twig.createParser([{ tag: 'subsession', function: anyHandler }], { method: method })
22
+ const reader = fs.createReadStream(`${__dirname}/20240304015234.9-MSRAN.xml`);
23
+
24
+ NE = 0;
25
+ startTime = DateTime.now();
26
+ await pipeline(reader, parser);
23
27
  let d = DateTime.now().diff(startTime);
24
- console.log(`All done with ${parser.method} in ${d.toFormat('mm:ss.S')}`);
25
- });
28
+ console.log(`Finished with ${method} in ${d.toFormat('mm:ss.S')}`);
29
+ printNE = false;
30
+ }
26
31
 
32
+ const main = async () => {
33
+
34
+ for (let method of ["sax", "expat", "saxophone"]) {
35
+ console.log(`Running with ${method}...`);
36
+ printNE = true;
37
+ for (let i = 0; i <= 5; i++)
38
+ await parse(method);
39
+ }
40
+ }
41
+
42
+ main();
27
43
 
28
44
 
29
45
  /*
@@ -31,25 +47,61 @@ reader.on('end', () => {
31
47
  * Results
32
48
  **********************
33
49
 
34
- All done with expat in 02:52.676
35
- All done with expat in 02:53.644
36
- All done with expat in 02:54.894
37
- All done with expat in 03:02.545
38
- All done with expat in 03:23.34
50
+ Running with sax...
51
+ 25 NE in 00:21.260
52
+ 50 NE in 00:46.36
53
+ 75 NE in 01:08.314
54
+ 100 NE in 01:36.5
55
+ 125 NE in 02:11.869
56
+ 150 NE in 02:49.940
57
+ 175 NE in 03:15.653
58
+ Finished with sax in 03:37.656
59
+ Finished with sax in 03:41.884
60
+ Finished with sax in 03:45.146
61
+ Finished with sax in 03:42.84
62
+ Finished with sax in 03:57.614
63
+ Finished with sax in 03:42.634
64
+
65
+ Running with expat...
66
+ 25 NE in 00:15.746
67
+ 50 NE in 00:33.605
68
+ 75 NE in 00:48.993
69
+ 100 NE in 01:07.777
70
+ 125 NE in 01:32.327
71
+ 150 NE in 01:59.544
72
+ 175 NE in 02:17.560
73
+ Finished with expat in 02:33.545
74
+ Finished with expat in 02:32.371
75
+ Finished with expat in 02:39.785
76
+ Finished with expat in 02:33.270
77
+ Finished with expat in 02:33.231
78
+ Finished with expat in 02:38.269
39
79
 
40
- All done with sax in 04:28.915
41
- All done with sax in 04:05.760
42
- All done with sax in 04:06.718
43
- All done with sax in 04:03.962
44
- All done with sax in 03:54.540
80
+ Running with saxophone...
81
+ 25 NE in 00:12.874
82
+ 50 NE in 00:27.736
83
+ 75 NE in 00:41.591
84
+ 100 NE in 00:58.430
85
+ 125 NE in 01:20.685
86
+ 150 NE in 01:43.568
87
+ 175 NE in 01:58.438
88
+ Finished with saxophone in 02:11.667
89
+ Finished with saxophone in 02:07.623
90
+ Finished with saxophone in 02:09.538
91
+ Finished with saxophone in 02:09.965
92
+ Finished with saxophone in 02:12.81
93
+ Finished with saxophone in 02:09.792
45
94
 
46
- All done with saxophone in 02:12.565
47
- All done with saxophone in 02:10.86
48
- All done with saxophone in 02:13.447
49
- All done with saxophone in 02:12.14
50
- All done with saxophone in 02:08.658
51
95
 
52
96
  Good old Perl XML::Twig
53
- All done in 9:24
97
+ 25 NE in 1:14
98
+ 50 NE in 2:03
99
+ 75 NE in 3:43
100
+ 100 NE in 5:02
101
+ 125 NE in 6:12
102
+ 150 NE in 7:16
103
+ 175 NE in 8:17
104
+ 200 NE in 9:24
105
+ Finished with perl in 9:24
54
106
 
55
107
  */
package/test.js CHANGED
@@ -1,39 +1,30 @@
1
1
  const fs = require('fs');
2
+ const path = require('path');
2
3
  const twig = require('./twig.js');
4
+ const { pipeline } = require('stream/promises');
5
+
6
+ async function parse(file, handler, options) {
7
+ const parser = twig.createParser(handler, options);
8
+ const reader = fs.createReadStream(file);
9
+ console.log(`Start parsing of ${path.basename(file)} with ${options.method}`);
10
+ await pipeline(reader, parser);
11
+ console.log(`Parsing ${path.basename(file)} done`);
12
+ }
3
13
 
4
-
5
- const parser = twig.createParser({ tag: twig.Any, function: anyHandler }, { method: "sax" });
6
- //const parser = twig.createParser({ tag: twig.Any, function: anyHandler }, { method: "expat" });
7
- //const parser = twig.createParser({ tag: twig.Any, function: anyHandler }, { method: "saxophone" });
8
- fs.createReadStream(`${__dirname}/samples/bookstore.xml`).pipe(parser);
9
- //fs.createReadStream(`${__dirname}/samples/breakfast-menu.xml`).pipe(parser);
10
-
11
- //const parser = twig.createParser({ tag: twig.Any, function: nsHandler }, { method: "sax", xmlns: true });
12
- //const parser = twig.createParser({ tag: twig.Any, function: nsHandler }, { method: "expat", xmlns: true });
13
- //const parser = twig.createParser({ tag: twig.Any, function: nsHandler }, { method: "saxophone", xmlns: true });
14
- //fs.createReadStream(`${__dirname}/samples/xmlns.xml`).pipe(parser);
15
-
16
- //const parser = twig.createParser({ tag: twig.Root, function: piHandler }, { method: "sax" });
17
- //const parser = twig.createParser({ tag: twig.Root, function: piHandler }, { method: "expat" });
18
- //const parser = twig.createParser({ tag: twig.Root, function: piHandler }, { method: "saxophone" });
19
- //fs.createReadStream(`${__dirname}/samples/processingInstruction.xml`).pipe(parser);
14
+ //const parser = twig.createParser({ tag: twig.Root, function: anyHandler }, { method: 'sax' });
15
+ //fs.createReadStream(`${__dirname}/samples/bookstore.xml`).pipe(parser);
20
16
 
21
17
 
22
18
  //fs.createReadStream(`${__dirname}/samples/encoding-UTF-8.xml`).pipe(parser);
23
19
  //fs.createReadStream(`${__dirname}/samples/encoding-UTF-16LE.xml`).pipe(parser);
24
20
  //fs.createReadStream(`${__dirname}/samples/encoding-UTF-16BE.xml`).pipe(parser);
25
21
 
26
-
27
22
  function anyHandler(elt) {
28
23
  console.log(`<${elt.name}> => ${elt.text} -> ${JSON.stringify(elt.attributes)}`);
29
24
  }
30
25
 
31
-
32
26
  function nsHandler(elt) {
33
27
  console.log(`${elt.name} => ${JSON.stringify(elt.namespace)} -> ${JSON.stringify(elt.attributes)}`);
34
- //console.log(`${elt.name} => isRoot = ${elt.isRoot}`);
35
- //console.log(`${elt.name} -> ${JSON.stringify(elt.PI)}`);
36
- //console.log(`${elt.name}`);
37
28
  }
38
29
 
39
30
  function piHandler(elt) {
@@ -41,3 +32,20 @@ function piHandler(elt) {
41
32
  }
42
33
 
43
34
 
35
+ const main = async () => {
36
+
37
+ for (let file of ["bookstore", "breakfast-menu"]) {
38
+ for (let method of ["sax", "expat", "saxophone"])
39
+ await parse(`${__dirname}/samples/${file}.xml`, { tag: twig.Any, function: anyHandler }, { method: method });
40
+ }
41
+
42
+ for (let method of ["sax", "expat", "saxophone"])
43
+ await parse(`${__dirname}/samples/xmlns.xml`, { tag: twig.Any, function: nsHandler }, { method: method, xmlns: true });
44
+
45
+ for (let method of ["sax", "expat", "saxophone"])
46
+ await parse(`${__dirname}/samples/processingInstruction.xml`, { tag: twig.Root, function: piHandler }, { method: method });
47
+
48
+ }
49
+
50
+ main();
51
+
package/twig.js CHANGED
@@ -212,11 +212,11 @@ function createParser(handler, options = {}) {
212
212
  current.text = options.trim ? str.trim() : str;
213
213
  });
214
214
 
215
- const hndl = Array.isArray(handler) ? handler : [handler];
216
- let rootHandler = hndl.find(x => x.tag instanceof RootHandler);
217
- parser.on("end", function () {
218
- if (typeof rootHandler?.function === 'function') rootHandler.function(tree);
219
- if (typeof rootHandler?.event === 'string') parser.emit(rootHandler.event, tree);
215
+ parser.on('end', function () {
216
+ tree = undefined;
217
+ current = undefined;
218
+ parser.emit("finish");
219
+ parser.emit("close");
220
220
  });
221
221
 
222
222
  } else if (options.method === EXPAT) {
@@ -254,6 +254,12 @@ function createParser(handler, options = {}) {
254
254
  tree.PI = { target: target, data: data };
255
255
  });
256
256
 
257
+ parser.on('end', function () {
258
+ tree = undefined;
259
+ current = undefined;
260
+ parser.emit("finish");
261
+ });
262
+
257
263
  } else if (options.method === SAXOPHONE) {
258
264
  const Saxophone = require('saxophone');
259
265
  //const Saxophone = require('@alexbosworth/saxophone');
@@ -306,6 +312,12 @@ function createParser(handler, options = {}) {
306
312
 
307
313
  });
308
314
 
315
+ parser.on('finish', function () {
316
+ // saxophone parser does not emit 'end' Event
317
+ tree = undefined;
318
+ current = undefined;
319
+ });
320
+
309
321
  } else {
310
322
  throw new UnsupportedParser(options.method);
311
323
  }
@@ -389,9 +401,8 @@ function onStart(binds, node, attrs) {
389
401
  if (current.isRoot && current.name === undefined) {
390
402
  current.setRoot(name);
391
403
  if (attrs !== undefined) {
392
- const att = options.xmlns ? attrNS : attrs;
393
- for (let key of Object.keys(att))
394
- current.attribute(key, att[key]);
404
+ for (let [key, val] of Object.entries(options.xmlns ? attrNS : attrs))
405
+ current.attribute(key, val);
395
406
  }
396
407
  } else {
397
408
  let elt = new Twig(name, current, options.xmlns ? attrNS : attrs);
@@ -449,7 +460,7 @@ function onClose(handler, options, name) {
449
460
  if (typeof hndl.function === 'function') hndl.function(current ?? tree);
450
461
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
451
462
  purge = false;
452
- } else if (hndl.tag instanceof RootHandler && [EXPAT, SAXOPHONE].includes(options.method) && current.isRoot) {
463
+ } else if (hndl.tag instanceof RootHandler && current.isRoot) {
453
464
  if (typeof hndl.function === 'function') hndl.function(tree);
454
465
  if (typeof hndl.event === 'string') parser.emit(hndl.event, tree);
455
466
  purge = false;
@@ -474,15 +485,6 @@ function onClose(handler, options, name) {
474
485
 
475
486
  }
476
487
 
477
-
478
- /**
479
- * Reset global variable if one like to parse multiple files
480
- */
481
- function reset() {
482
- tree = undefined;
483
- current = undefined;
484
- }
485
-
486
488
  /**
487
489
  * Generic class modeling a XML Node
488
490
  * @class Twig
@@ -608,19 +610,17 @@ class Twig {
608
610
  };
609
611
 
610
612
  /**
611
- * Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
612
- * @param {Twig} [elt] - Up to this element the tree will be purged. The `elt` object itself is not purged.<br>
613
+ * Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.<br>
614
+ * The `elt` object is not purged. If you like to purge including `elt`, use `.purgeUpTo(elt.previous())`
615
+ * @param {Twig} [elt] - Up to this element the tree will be purged.
613
616
  * If `undefined` then the current element is purged (i.e. `purge()`)
614
617
  */
615
618
  purgeUpTo = function (elt) {
616
619
  if (elt === undefined) {
617
620
  this.purge();
618
621
  } else {
619
- const purgeThis = this.descendantOrSelf();
620
- let toPurge = purgeThis[purgeThis.length - 1];
621
- const descendantOrSelf = elt.descendantOrSelf();
622
- const stopAt = descendantOrSelf[descendantOrSelf.length - 1];
623
- while (toPurge !== null && !Object.is(toPurge, stopAt)) {
622
+ let toPurge = this;
623
+ while (toPurge !== null && !Object.is(toPurge, elt)) {
624
624
  const prev = toPurge.previous();
625
625
  toPurge.purge();
626
626
  toPurge = prev;
@@ -779,7 +779,7 @@ class Twig {
779
779
  xw.writeAttribute(key, val);
780
780
  if (elt.text !== null)
781
781
  xw.text(elt.text);
782
- this.#addChild(xw, elt.children(), elt, debug);
782
+ this.#addChild(xw, elt.children(), elt, debug);
783
783
  }
784
784
  if (!debug || Object.isSealed(cur)) xw.endElement();
785
785
  };
@@ -1309,4 +1309,4 @@ class UnsupportedCondition extends TypeError {
1309
1309
  }
1310
1310
 
1311
1311
 
1312
- module.exports = { createParser, Twig, Any, Root, reset };
1312
+ module.exports = { createParser, Twig, Any, Root };
@@ -1,17 +0,0 @@
1
- node speed-test.js expat
2
- node speed-test.js expat
3
- node speed-test.js expat
4
- node speed-test.js expat
5
- node speed-test.js expat
6
-
7
- node speed-test.js sax
8
- node speed-test.js sax
9
- node speed-test.js sax
10
- node speed-test.js sax
11
- node speed-test.js sax
12
-
13
- node speed-test.js saxophone
14
- node speed-test.js saxophone
15
- node speed-test.js saxophone
16
- node speed-test.js saxophone
17
- node speed-test.js saxophone
@@ -1,164 +0,0 @@
1
- C:\Developing\Source\xml-twig\samples>node speed-test.js expat
2
- Starting with expat...
3
- 25 NE in 00:15.36
4
- 50 NE in 00:33.382
5
- 75 NE in 00:50.253
6
- 100 NE in 01:13.944
7
- 125 NE in 01:42.205
8
- 150 NE in 02:13.746
9
- 175 NE in 02:35.650
10
- All done with expat in 02:52.676
11
-
12
- C:\Developing\Source\xml-twig\samples>node speed-test.js expat
13
- Starting with expat...
14
- 25 NE in 00:18.216
15
- 50 NE in 00:37.92
16
- 75 NE in 00:54.888
17
- 100 NE in 01:17.224
18
- 125 NE in 01:44.272
19
- 150 NE in 02:15.283
20
- 175 NE in 02:36.463
21
- All done with expat in 02:53.644
22
-
23
- C:\Developing\Source\xml-twig\samples>node speed-test.js expat
24
- Starting with expat...
25
- 25 NE in 00:18.639
26
- 50 NE in 00:39.182
27
- 75 NE in 00:59.446
28
- 100 NE in 01:19.566
29
- 125 NE in 01:46.400
30
- 150 NE in 02:16.608
31
- 175 NE in 02:37.242
32
- All done with expat in 02:54.894
33
-
34
- C:\Developing\Source\xml-twig\samples>node speed-test.js expat
35
- Starting with expat...
36
- 25 NE in 00:17.702
37
- 50 NE in 00:36.765
38
- 75 NE in 00:55.178
39
- 100 NE in 01:16.259
40
- 125 NE in 01:47.37
41
- 150 NE in 02:18.862
42
- 175 NE in 02:42.671
43
- All done with expat in 03:02.545
44
-
45
- C:\Developing\Source\xml-twig\samples>node speed-test.js expat
46
- Starting with expat...
47
- 25 NE in 00:18.746
48
- 50 NE in 00:38.461
49
- 75 NE in 00:56.901
50
- 100 NE in 01:17.314
51
- 125 NE in 01:44.938
52
- 150 NE in 02:26.995
53
- 175 NE in 02:58.149
54
- All done with expat in 03:23.34
55
-
56
- C:\Developing\Source\xml-twig\samples>node speed-test.js sax
57
- Starting with sax...
58
- 25 NE in 00:33.781
59
- 50 NE in 01:08.679
60
- 75 NE in 01:39.504
61
- 100 NE in 02:11.68
62
- 125 NE in 02:51.186
63
- 150 NE in 03:36.142
64
- 175 NE in 04:04.731
65
- All done with sax in 04:28.915
66
-
67
- C:\Developing\Source\xml-twig\samples>node speed-test.js sax
68
- Starting with sax...
69
- 25 NE in 00:25.21
70
- 50 NE in 00:52.164
71
- 75 NE in 01:17.550
72
- 100 NE in 01:51.854
73
- 125 NE in 02:30.192
74
- 150 NE in 03:11.461
75
- 175 NE in 03:39.338
76
- All done with sax in 04:05.760
77
-
78
- C:\Developing\Source\xml-twig\samples>node speed-test.js sax
79
- Starting with sax...
80
- 25 NE in 00:25.778
81
- 50 NE in 00:52.603
82
- 75 NE in 01:19.686
83
- 100 NE in 01:52.268
84
- 125 NE in 02:30.279
85
- 150 NE in 03:13.159
86
- 175 NE in 03:42.640
87
- All done with sax in 04:06.718
88
-
89
- C:\Developing\Source\xml-twig\samples>node speed-test.js sax
90
- Starting with sax...
91
- 25 NE in 00:24.549
92
- 50 NE in 00:50.774
93
- 75 NE in 01:14.500
94
- 100 NE in 01:44.116
95
- 125 NE in 02:22.861
96
- 150 NE in 03:03.357
97
- 175 NE in 03:39.237
98
- All done with sax in 04:03.962
99
-
100
- C:\Developing\Source\xml-twig\samples>node speed-test.js sax
101
- Starting with sax...
102
- 25 NE in 00:25.36
103
- 50 NE in 00:51.544
104
- 75 NE in 01:15.580
105
- 100 NE in 01:45.389
106
- 125 NE in 02:22.834
107
- 150 NE in 03:03.487
108
- 175 NE in 03:31.416
109
- All done with sax in 03:54.540
110
-
111
- C:\Developing\Source\xml-twig\samples>node speed-test.js saxophone
112
- Starting with saxophone...
113
- 25 NE in 00:14.96
114
- 50 NE in 00:31.316
115
- 75 NE in 00:44.478
116
- 100 NE in 01:00.580
117
- 125 NE in 01:21.74
118
- 150 NE in 01:43.881
119
- 175 NE in 01:59.119
120
- All done with saxophone in 02:12.565
121
-
122
- C:\Developing\Source\xml-twig\samples>node speed-test.js saxophone
123
- Starting with saxophone...
124
- 25 NE in 00:14.565
125
- 50 NE in 00:28.947
126
- 75 NE in 00:42.211
127
- 100 NE in 00:58.533
128
- 125 NE in 01:19.194
129
- 150 NE in 01:41.595
130
- 175 NE in 01:57.24
131
- All done with saxophone in 02:10.86
132
-
133
- C:\Developing\Source\xml-twig\samples>node speed-test.js saxophone
134
- Starting with saxophone...
135
- 25 NE in 00:13.307
136
- 50 NE in 00:27.849
137
- 75 NE in 00:41.466
138
- 100 NE in 00:59.190
139
- 125 NE in 01:22.230
140
- 150 NE in 01:44.605
141
- 175 NE in 02:00.299
142
- All done with saxophone in 02:13.447
143
-
144
- C:\Developing\Source\xml-twig\samples>node speed-test.js saxophone
145
- Starting with saxophone...
146
- 25 NE in 00:13.884
147
- 50 NE in 00:28.340
148
- 75 NE in 00:41.720
149
- 100 NE in 00:57.897
150
- 125 NE in 01:19.260
151
- 150 NE in 01:42.974
152
- 175 NE in 01:58.791
153
- All done with saxophone in 02:12.14
154
-
155
- C:\Developing\Source\xml-twig\samples>node speed-test.js saxophone
156
- Starting with saxophone...
157
- 25 NE in 00:13.443
158
- 50 NE in 00:28.99
159
- 75 NE in 00:40.821
160
- 100 NE in 00:56.989
161
- 125 NE in 01:16.787
162
- 150 NE in 01:40.205
163
- 175 NE in 01:55.451
164
- All done with saxophone in 02:08.658