@sc-voice/tools 1.1.0
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/LICENSE +21 -0
- package/README.md +70 -0
- package/index.mjs +31 -0
- package/package.json +38 -0
- package/src/defines.mjs +9 -0
- package/src/math/fraction.mjs +94 -0
- package/src/text/aligner.mjs +562 -0
- package/src/text/bilara-path.mjs +84 -0
- package/src/text/ebt-doc.mjs +124 -0
- package/src/text/legacy-doc.mjs +80 -0
- package/src/text/merkle-json.mjs +264 -0
- package/src/text/sutta-central-id.mjs +362 -0
- package/src/text/unicode.mjs +370 -0
- package/src/text/word-space.mjs +213 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { SuttaCentralId } from './sutta-central-id.mjs';
|
|
2
|
+
|
|
3
|
+
let privateCtor = false;
|
|
4
|
+
|
|
5
|
+
const INHERITED_KEYS = [
|
|
6
|
+
'lang', 'author', 'author_uid', 'wordSpace'
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const HDR_KEY = '__header__';
|
|
10
|
+
|
|
11
|
+
export class EbtDoc {
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
const msg = 'E4c.ctor:';
|
|
14
|
+
if (!privateCtor) {
|
|
15
|
+
throw new Error(`${msg} create()!`);
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(this, '_scids', {
|
|
18
|
+
writable: true,
|
|
19
|
+
value: undefined,
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(this, 'parent', {
|
|
22
|
+
writable: true,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
Object.assign(this, opts);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static create(opts = {}) {
|
|
29
|
+
const msg = 'E4c.create:';
|
|
30
|
+
let { suid, bilaraPath, segMap = {}, parent = {} } = opts;
|
|
31
|
+
if (segMap == null) {
|
|
32
|
+
throw new Error(`${msg} segMap?`);
|
|
33
|
+
}
|
|
34
|
+
if (typeof segMap === 'string' || segMap instanceof Buffer) {
|
|
35
|
+
segMap = JSON.parse(segMap);
|
|
36
|
+
}
|
|
37
|
+
let args = INHERITED_KEYS.reduce(
|
|
38
|
+
(a, k) => {
|
|
39
|
+
a[k] = opts[k] || parent[k];
|
|
40
|
+
return a;
|
|
41
|
+
},
|
|
42
|
+
{ bilaraPath, parent, segMap, suid },
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
privateCtor = true;
|
|
46
|
+
let ebtDoc = new EbtDoc(args);
|
|
47
|
+
privateCtor = false;
|
|
48
|
+
|
|
49
|
+
return ebtDoc;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static fromBilaraString(str, parent) {
|
|
53
|
+
const msg = 'E4c.fromBilaraString:';
|
|
54
|
+
let json = JSON.parse(str);
|
|
55
|
+
let { [HDR_KEY]: header } = json;
|
|
56
|
+
let { suid, bilaraPath } = header;
|
|
57
|
+
let scids = Object.keys(json).filter((k) => k !== HDR_KEY);
|
|
58
|
+
let segMap = scids.reduce((a, scid) => {
|
|
59
|
+
a[scid] = json[scid];
|
|
60
|
+
return a;
|
|
61
|
+
}, {});
|
|
62
|
+
let args = Object.keys(header).reduce(
|
|
63
|
+
(a, k) => {
|
|
64
|
+
a[k] = header[k];
|
|
65
|
+
return a;
|
|
66
|
+
},
|
|
67
|
+
{ suid, bilaraPath, scids, segMap, parent },
|
|
68
|
+
);
|
|
69
|
+
return EbtDoc.create(args);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
scids() {
|
|
73
|
+
let { _scids } = this;
|
|
74
|
+
if (_scids == null) {
|
|
75
|
+
_scids = Object.keys(this.segMap);
|
|
76
|
+
_scids.sort(SuttaCentralId.compareLow);
|
|
77
|
+
this._scids = _scids;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return _scids;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
segments() {
|
|
84
|
+
return this.scids().map((scid) => ({
|
|
85
|
+
scid,
|
|
86
|
+
[this.lang]: this.segMap[scid] || '',
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
toBilaraString() {
|
|
91
|
+
const msg = 'E4c.toBilaraString:';
|
|
92
|
+
let { segMap, parent } = this;
|
|
93
|
+
let scids = this.scids();
|
|
94
|
+
let keys = Object.keys(this);
|
|
95
|
+
let headerKeys = keys.filter((k) => {
|
|
96
|
+
switch (k) {
|
|
97
|
+
case 'segMap':
|
|
98
|
+
return false;
|
|
99
|
+
case 'parent':
|
|
100
|
+
return false;
|
|
101
|
+
default:
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
let header = headerKeys.reduce((a, k) => {
|
|
107
|
+
let v = this[k];
|
|
108
|
+
if (parent[k] !== v) {
|
|
109
|
+
a[k] = v;
|
|
110
|
+
}
|
|
111
|
+
return a;
|
|
112
|
+
}, {});
|
|
113
|
+
|
|
114
|
+
let json = scids.reduce(
|
|
115
|
+
(a, scid) => {
|
|
116
|
+
a[scid] = segMap[scid];
|
|
117
|
+
return a;
|
|
118
|
+
},
|
|
119
|
+
{ [HDR_KEY]: header },
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return JSON.stringify(json, null, 2);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
let privateCtor = false;
|
|
2
|
+
|
|
3
|
+
const HTML_FILTER = (() => {
|
|
4
|
+
let prefixes = [
|
|
5
|
+
'<!DOCTYPE',
|
|
6
|
+
'<html',
|
|
7
|
+
'<head',
|
|
8
|
+
'</html',
|
|
9
|
+
'<meta',
|
|
10
|
+
'<title',
|
|
11
|
+
'</head',
|
|
12
|
+
'<body',
|
|
13
|
+
'</body',
|
|
14
|
+
'<article',
|
|
15
|
+
'</article',
|
|
16
|
+
].join('|');
|
|
17
|
+
let pat = `^(${prefixes}).*> *$`;
|
|
18
|
+
return new RegExp(pat);
|
|
19
|
+
})();
|
|
20
|
+
|
|
21
|
+
export class LegacyDoc {
|
|
22
|
+
constructor(opts = {}) {
|
|
23
|
+
const msg = 'LegacyDoc.ctor:';
|
|
24
|
+
if (!privateCtor) {
|
|
25
|
+
throw new Error(`${msg} use LegacyDoc.create()`);
|
|
26
|
+
}
|
|
27
|
+
Object.assign(this, opts);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static filterHtml(line) {
|
|
31
|
+
if (HTML_FILTER.test(line)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static create(rawDoc) {
|
|
39
|
+
const msg = 'LegacyDoc.create:';
|
|
40
|
+
if (typeof legacy === 'string') {
|
|
41
|
+
legacy = JSON.parse(legacy);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let { uid, lang, title, author, author_uid, text } = rawDoc;
|
|
45
|
+
|
|
46
|
+
let para;
|
|
47
|
+
let lines = text.filter((line) => !HTML_FILTER.test(line));
|
|
48
|
+
lines = lines
|
|
49
|
+
.join(' ')
|
|
50
|
+
.replace(/<\/p> */g, '')
|
|
51
|
+
.replace(/<h.*sutta-title.>(.*)<\/h1> /, '$1')
|
|
52
|
+
.split('<p>');
|
|
53
|
+
let footer = [];
|
|
54
|
+
lines.forEach((line, i) => {
|
|
55
|
+
if (/<footer>/.test(line)) {
|
|
56
|
+
let f = line.replace(/.*<footer>(.*)<.footer>.*/, '$1');
|
|
57
|
+
footer.push(f);
|
|
58
|
+
lines[i] = line.replace(/<footer>.*<.footer>/, '');
|
|
59
|
+
}
|
|
60
|
+
lines[i] = lines[i].trim();
|
|
61
|
+
});
|
|
62
|
+
footer = footer.join(' ');
|
|
63
|
+
|
|
64
|
+
let opts = {
|
|
65
|
+
uid,
|
|
66
|
+
lang,
|
|
67
|
+
title,
|
|
68
|
+
author,
|
|
69
|
+
author_uid,
|
|
70
|
+
footer,
|
|
71
|
+
lines,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
privateCtor = true;
|
|
75
|
+
let ldoc = new LegacyDoc(opts);
|
|
76
|
+
privateCtor = false;
|
|
77
|
+
|
|
78
|
+
return ldoc;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// Supercedes NPM package merkle-json
|
|
2
|
+
// BEGIN http://www.myersdaily.org/joseph/javascript/md5.js
|
|
3
|
+
function md5cycle(x, k) {
|
|
4
|
+
let a = x[0],
|
|
5
|
+
b = x[1],
|
|
6
|
+
c = x[2],
|
|
7
|
+
d = x[3];
|
|
8
|
+
|
|
9
|
+
a = ff(a, b, c, d, k[0], 7, -680876936);
|
|
10
|
+
d = ff(d, a, b, c, k[1], 12, -389564586);
|
|
11
|
+
c = ff(c, d, a, b, k[2], 17, 606105819);
|
|
12
|
+
b = ff(b, c, d, a, k[3], 22, -1044525330);
|
|
13
|
+
a = ff(a, b, c, d, k[4], 7, -176418897);
|
|
14
|
+
d = ff(d, a, b, c, k[5], 12, 1200080426);
|
|
15
|
+
c = ff(c, d, a, b, k[6], 17, -1473231341);
|
|
16
|
+
b = ff(b, c, d, a, k[7], 22, -45705983);
|
|
17
|
+
a = ff(a, b, c, d, k[8], 7, 1770035416);
|
|
18
|
+
d = ff(d, a, b, c, k[9], 12, -1958414417);
|
|
19
|
+
c = ff(c, d, a, b, k[10], 17, -42063);
|
|
20
|
+
b = ff(b, c, d, a, k[11], 22, -1990404162);
|
|
21
|
+
a = ff(a, b, c, d, k[12], 7, 1804603682);
|
|
22
|
+
d = ff(d, a, b, c, k[13], 12, -40341101);
|
|
23
|
+
c = ff(c, d, a, b, k[14], 17, -1502002290);
|
|
24
|
+
b = ff(b, c, d, a, k[15], 22, 1236535329);
|
|
25
|
+
|
|
26
|
+
a = gg(a, b, c, d, k[1], 5, -165796510);
|
|
27
|
+
d = gg(d, a, b, c, k[6], 9, -1069501632);
|
|
28
|
+
c = gg(c, d, a, b, k[11], 14, 643717713);
|
|
29
|
+
b = gg(b, c, d, a, k[0], 20, -373897302);
|
|
30
|
+
a = gg(a, b, c, d, k[5], 5, -701558691);
|
|
31
|
+
d = gg(d, a, b, c, k[10], 9, 38016083);
|
|
32
|
+
c = gg(c, d, a, b, k[15], 14, -660478335);
|
|
33
|
+
b = gg(b, c, d, a, k[4], 20, -405537848);
|
|
34
|
+
a = gg(a, b, c, d, k[9], 5, 568446438);
|
|
35
|
+
d = gg(d, a, b, c, k[14], 9, -1019803690);
|
|
36
|
+
c = gg(c, d, a, b, k[3], 14, -187363961);
|
|
37
|
+
b = gg(b, c, d, a, k[8], 20, 1163531501);
|
|
38
|
+
a = gg(a, b, c, d, k[13], 5, -1444681467);
|
|
39
|
+
d = gg(d, a, b, c, k[2], 9, -51403784);
|
|
40
|
+
c = gg(c, d, a, b, k[7], 14, 1735328473);
|
|
41
|
+
b = gg(b, c, d, a, k[12], 20, -1926607734);
|
|
42
|
+
|
|
43
|
+
a = hh(a, b, c, d, k[5], 4, -378558);
|
|
44
|
+
d = hh(d, a, b, c, k[8], 11, -2022574463);
|
|
45
|
+
c = hh(c, d, a, b, k[11], 16, 1839030562);
|
|
46
|
+
b = hh(b, c, d, a, k[14], 23, -35309556);
|
|
47
|
+
a = hh(a, b, c, d, k[1], 4, -1530992060);
|
|
48
|
+
d = hh(d, a, b, c, k[4], 11, 1272893353);
|
|
49
|
+
c = hh(c, d, a, b, k[7], 16, -155497632);
|
|
50
|
+
b = hh(b, c, d, a, k[10], 23, -1094730640);
|
|
51
|
+
a = hh(a, b, c, d, k[13], 4, 681279174);
|
|
52
|
+
d = hh(d, a, b, c, k[0], 11, -358537222);
|
|
53
|
+
c = hh(c, d, a, b, k[3], 16, -722521979);
|
|
54
|
+
b = hh(b, c, d, a, k[6], 23, 76029189);
|
|
55
|
+
a = hh(a, b, c, d, k[9], 4, -640364487);
|
|
56
|
+
d = hh(d, a, b, c, k[12], 11, -421815835);
|
|
57
|
+
c = hh(c, d, a, b, k[15], 16, 530742520);
|
|
58
|
+
b = hh(b, c, d, a, k[2], 23, -995338651);
|
|
59
|
+
|
|
60
|
+
a = ii(a, b, c, d, k[0], 6, -198630844);
|
|
61
|
+
d = ii(d, a, b, c, k[7], 10, 1126891415);
|
|
62
|
+
c = ii(c, d, a, b, k[14], 15, -1416354905);
|
|
63
|
+
b = ii(b, c, d, a, k[5], 21, -57434055);
|
|
64
|
+
a = ii(a, b, c, d, k[12], 6, 1700485571);
|
|
65
|
+
d = ii(d, a, b, c, k[3], 10, -1894986606);
|
|
66
|
+
c = ii(c, d, a, b, k[10], 15, -1051523);
|
|
67
|
+
b = ii(b, c, d, a, k[1], 21, -2054922799);
|
|
68
|
+
a = ii(a, b, c, d, k[8], 6, 1873313359);
|
|
69
|
+
d = ii(d, a, b, c, k[15], 10, -30611744);
|
|
70
|
+
c = ii(c, d, a, b, k[6], 15, -1560198380);
|
|
71
|
+
b = ii(b, c, d, a, k[13], 21, 1309151649);
|
|
72
|
+
a = ii(a, b, c, d, k[4], 6, -145523070);
|
|
73
|
+
d = ii(d, a, b, c, k[11], 10, -1120210379);
|
|
74
|
+
c = ii(c, d, a, b, k[2], 15, 718787259);
|
|
75
|
+
b = ii(b, c, d, a, k[9], 21, -343485551);
|
|
76
|
+
|
|
77
|
+
x[0] = add32(a, x[0]);
|
|
78
|
+
x[1] = add32(b, x[1]);
|
|
79
|
+
x[2] = add32(c, x[2]);
|
|
80
|
+
x[3] = add32(d, x[3]);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function cmn(q, a, b, x, s, t) {
|
|
84
|
+
a = add32(add32(a, q), add32(x, t));
|
|
85
|
+
return add32((a << s) | (a >>> (32 - s)), b);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function ff(a, b, c, d, x, s, t) {
|
|
89
|
+
return cmn((b & c) | (~b & d), a, b, x, s, t);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function gg(a, b, c, d, x, s, t) {
|
|
93
|
+
return cmn((b & d) | (c & ~d), a, b, x, s, t);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function hh(a, b, c, d, x, s, t) {
|
|
97
|
+
return cmn(b ^ c ^ d, a, b, x, s, t);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function ii(a, b, c, d, x, s, t) {
|
|
101
|
+
return cmn(c ^ (b | ~d), a, b, x, s, t);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function md51(s) {
|
|
105
|
+
//txt = '';
|
|
106
|
+
let n = s.length,
|
|
107
|
+
state = [1732584193, -271733879, -1732584194, 271733878],
|
|
108
|
+
i;
|
|
109
|
+
for (i = 64; i <= s.length; i += 64) {
|
|
110
|
+
md5cycle(state, md5blk(s.substring(i - 64, i)));
|
|
111
|
+
}
|
|
112
|
+
s = s.substring(i - 64);
|
|
113
|
+
let tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
114
|
+
for (i = 0; i < s.length; i++)
|
|
115
|
+
tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
|
|
116
|
+
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
|
|
117
|
+
if (i > 55) {
|
|
118
|
+
md5cycle(state, tail);
|
|
119
|
+
for (i = 0; i < 16; i++) tail[i] = 0;
|
|
120
|
+
}
|
|
121
|
+
tail[14] = n * 8;
|
|
122
|
+
md5cycle(state, tail);
|
|
123
|
+
return state;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* there needs to be support for Unicode here,
|
|
127
|
+
* unless we pretend that we can redefine the MD-5
|
|
128
|
+
* algorithm for multi-byte characters (perhaps
|
|
129
|
+
* by adding every four 16-bit characters and
|
|
130
|
+
* shortening the sum to 32 bits). Otherwise
|
|
131
|
+
* I suggest performing MD-5 as if every character
|
|
132
|
+
* was two bytes--e.g., 0040 0025 = @%--but then
|
|
133
|
+
* how will an ordinary MD-5 sum be matched?
|
|
134
|
+
* There is no way to standardize text to something
|
|
135
|
+
* like UTF-8 before transformation; speed cost is
|
|
136
|
+
* utterly prohibitive. The JavaScript standard
|
|
137
|
+
* itself needs to look at this: it should start
|
|
138
|
+
* providing access to strings as preformed UTF-8
|
|
139
|
+
* 8-bit unsigned value arrays.
|
|
140
|
+
**/
|
|
141
|
+
function md5blk(s) {
|
|
142
|
+
/* I figured global was faster. */
|
|
143
|
+
let md5blks = [],
|
|
144
|
+
i; /* Andy King said do it this way. */
|
|
145
|
+
for (i = 0; i < 64; i += 4) {
|
|
146
|
+
md5blks[i >> 2] =
|
|
147
|
+
s.charCodeAt(i) +
|
|
148
|
+
(s.charCodeAt(i + 1) << 8) +
|
|
149
|
+
(s.charCodeAt(i + 2) << 16) +
|
|
150
|
+
(s.charCodeAt(i + 3) << 24);
|
|
151
|
+
}
|
|
152
|
+
return md5blks;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const hex_chr = '0123456789abcdef'.split('');
|
|
156
|
+
|
|
157
|
+
function rhex(n) {
|
|
158
|
+
let s = '',
|
|
159
|
+
j = 0;
|
|
160
|
+
for (; j < 4; j++)
|
|
161
|
+
s +=
|
|
162
|
+
hex_chr[(n >> (j * 8 + 4)) & 0x0f] +
|
|
163
|
+
hex_chr[(n >> (j * 8)) & 0x0f];
|
|
164
|
+
return s;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function hex(x) {
|
|
168
|
+
for (let i = 0; i < x.length; i++) x[i] = rhex(x[i]);
|
|
169
|
+
return x.join('');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function md5(s) {
|
|
173
|
+
return hex(md51(s));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* this function is much faster,
|
|
177
|
+
* so if possible we use it. Some IEs
|
|
178
|
+
* are the only ones I know of that
|
|
179
|
+
* need the idiotic second function,
|
|
180
|
+
* generated by an if clause. */
|
|
181
|
+
|
|
182
|
+
function add32(a, b) {
|
|
183
|
+
return (a + b) & 0xffffffff;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
|
|
187
|
+
function add32(x, y) {
|
|
188
|
+
let lsw = (x & 0xffff) + (y & 0xffff),
|
|
189
|
+
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
|
190
|
+
return (msw << 16) | (lsw & 0xffff);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// END http://www.myersdaily.org/joseph/javascript/md5.js
|
|
194
|
+
|
|
195
|
+
export class MerkleJson {
|
|
196
|
+
constructor(opts = {}) {
|
|
197
|
+
this.hashTag = opts.hashTag || 'merkleHash';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
hash(value, cached = true) {
|
|
201
|
+
if (typeof value === 'string') {
|
|
202
|
+
return md5(value);
|
|
203
|
+
} else if (value instanceof Array) {
|
|
204
|
+
let acc = '';
|
|
205
|
+
acc = value.reduce((a, v) => a + this.hash(v, cached), acc);
|
|
206
|
+
return this.hash(acc, cached);
|
|
207
|
+
} else if (typeof value === 'number') {
|
|
208
|
+
value = value + '';
|
|
209
|
+
return this.hash(value);
|
|
210
|
+
} else if (value instanceof Date) {
|
|
211
|
+
return this.hash(value.toJSON());
|
|
212
|
+
} else if (value === false) {
|
|
213
|
+
return this.hash('false');
|
|
214
|
+
} else if (value === true) {
|
|
215
|
+
return this.hash('true');
|
|
216
|
+
} else if (value === null) {
|
|
217
|
+
return this.hash('null');
|
|
218
|
+
} else if (value === undefined) {
|
|
219
|
+
return this.hash('undefined');
|
|
220
|
+
} else if (typeof value === 'function') {
|
|
221
|
+
return this.hash(value.toString());
|
|
222
|
+
} else if (typeof value === 'object') {
|
|
223
|
+
if (cached && value[this.hashTag]) {
|
|
224
|
+
return value[this.hashTag];
|
|
225
|
+
}
|
|
226
|
+
let keys = Object.keys(value).sort();
|
|
227
|
+
let acc = keys.reduce((a, k) => {
|
|
228
|
+
return k === this.hashTag
|
|
229
|
+
? a
|
|
230
|
+
: a + k + ':' + this.hash(value[k]) + ',';
|
|
231
|
+
}, '');
|
|
232
|
+
return this.hash(acc);
|
|
233
|
+
}
|
|
234
|
+
throw new Error('hash() not supported:' + typeof value);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
stringify(value) {
|
|
238
|
+
if (value instanceof Array) {
|
|
239
|
+
let body = value.reduce((a, v) => {
|
|
240
|
+
return a
|
|
241
|
+
? `${a},${this.stringify(v)}`
|
|
242
|
+
: `${this.stringify(v)}`;
|
|
243
|
+
}, '');
|
|
244
|
+
return `[${body}]`;
|
|
245
|
+
} else if (value instanceof Date) {
|
|
246
|
+
return `"${value.toJSON()}"`;
|
|
247
|
+
} else if (value === null) {
|
|
248
|
+
return JSON.stringify(value);
|
|
249
|
+
} else if (typeof value === 'object') {
|
|
250
|
+
if (typeof value.toJSON === 'function') {
|
|
251
|
+
value = JSON.parse(JSON.stringify(value));
|
|
252
|
+
}
|
|
253
|
+
let keys = Object.keys(value).sort();
|
|
254
|
+
let body = keys.reduce((a, k) => {
|
|
255
|
+
return a
|
|
256
|
+
? `${a},"${k}":${this.stringify(value[k])}`
|
|
257
|
+
: `"${k}":${this.stringify(value[k])}`;
|
|
258
|
+
}, '');
|
|
259
|
+
return `{${body}}`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return JSON.stringify(value);
|
|
263
|
+
}
|
|
264
|
+
} // class MerkleJson
|