@bithumb-official/bithumb-mcp 0.1.16 → 0.1.17
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/dist/index.js +77 -847
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,710 +9,12 @@ import { createHash, createHmac, randomUUID } from "crypto";
|
|
|
9
9
|
import fs from "fs";
|
|
10
10
|
import path from "path";
|
|
11
11
|
import os from "os";
|
|
12
|
-
import {
|
|
13
|
-
import { join } from "path";
|
|
12
|
+
import { mkdirSync, appendFileSync } from "fs";
|
|
14
13
|
import { homedir } from "os";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { existsSync, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "fs";
|
|
17
16
|
import { homedir as homedir2 } from "os";
|
|
18
|
-
|
|
19
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
20
|
-
function getLineColFromPtr(string, ptr) {
|
|
21
|
-
let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
|
|
22
|
-
return [lines.length, lines.pop().length + 1];
|
|
23
|
-
}
|
|
24
|
-
function makeCodeBlock(string, line, column) {
|
|
25
|
-
let lines = string.split(/\r\n|\n|\r/g);
|
|
26
|
-
let codeblock = "";
|
|
27
|
-
let numberLen = (Math.log10(line + 1) | 0) + 1;
|
|
28
|
-
for (let i = line - 1; i <= line + 1; i++) {
|
|
29
|
-
let l = lines[i - 1];
|
|
30
|
-
if (!l)
|
|
31
|
-
continue;
|
|
32
|
-
codeblock += i.toString().padEnd(numberLen, " ");
|
|
33
|
-
codeblock += ": ";
|
|
34
|
-
codeblock += l;
|
|
35
|
-
codeblock += "\n";
|
|
36
|
-
if (i === line) {
|
|
37
|
-
codeblock += " ".repeat(numberLen + column + 2);
|
|
38
|
-
codeblock += "^\n";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return codeblock;
|
|
42
|
-
}
|
|
43
|
-
var TomlError = class extends Error {
|
|
44
|
-
line;
|
|
45
|
-
column;
|
|
46
|
-
codeblock;
|
|
47
|
-
constructor(message, options) {
|
|
48
|
-
const [line, column] = getLineColFromPtr(options.toml, options.ptr);
|
|
49
|
-
const codeblock = makeCodeBlock(options.toml, line, column);
|
|
50
|
-
super(`Invalid TOML document: ${message}
|
|
51
|
-
|
|
52
|
-
${codeblock}`, options);
|
|
53
|
-
this.line = line;
|
|
54
|
-
this.column = column;
|
|
55
|
-
this.codeblock = codeblock;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/util.js
|
|
60
|
-
function isEscaped(str, ptr) {
|
|
61
|
-
let i = 0;
|
|
62
|
-
while (str[ptr - ++i] === "\\")
|
|
63
|
-
;
|
|
64
|
-
return --i && i % 2;
|
|
65
|
-
}
|
|
66
|
-
function indexOfNewline(str, start = 0, end = str.length) {
|
|
67
|
-
let idx = str.indexOf("\n", start);
|
|
68
|
-
if (str[idx - 1] === "\r")
|
|
69
|
-
idx--;
|
|
70
|
-
return idx <= end ? idx : -1;
|
|
71
|
-
}
|
|
72
|
-
function skipComment(str, ptr) {
|
|
73
|
-
for (let i = ptr; i < str.length; i++) {
|
|
74
|
-
let c = str[i];
|
|
75
|
-
if (c === "\n")
|
|
76
|
-
return i;
|
|
77
|
-
if (c === "\r" && str[i + 1] === "\n")
|
|
78
|
-
return i + 1;
|
|
79
|
-
if (c < " " && c !== " " || c === "\x7F") {
|
|
80
|
-
throw new TomlError("control characters are not allowed in comments", {
|
|
81
|
-
toml: str,
|
|
82
|
-
ptr
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return str.length;
|
|
87
|
-
}
|
|
88
|
-
function skipVoid(str, ptr, banNewLines, banComments) {
|
|
89
|
-
let c;
|
|
90
|
-
while (1) {
|
|
91
|
-
while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
|
|
92
|
-
ptr++;
|
|
93
|
-
if (banComments || c !== "#")
|
|
94
|
-
break;
|
|
95
|
-
ptr = skipComment(str, ptr);
|
|
96
|
-
}
|
|
97
|
-
return ptr;
|
|
98
|
-
}
|
|
99
|
-
function skipUntil(str, ptr, sep, end, banNewLines = false) {
|
|
100
|
-
if (!end) {
|
|
101
|
-
ptr = indexOfNewline(str, ptr);
|
|
102
|
-
return ptr < 0 ? str.length : ptr;
|
|
103
|
-
}
|
|
104
|
-
for (let i = ptr; i < str.length; i++) {
|
|
105
|
-
let c = str[i];
|
|
106
|
-
if (c === "#") {
|
|
107
|
-
i = indexOfNewline(str, i);
|
|
108
|
-
} else if (c === sep) {
|
|
109
|
-
return i + 1;
|
|
110
|
-
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
111
|
-
return i;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
throw new TomlError("cannot find end of structure", {
|
|
115
|
-
toml: str,
|
|
116
|
-
ptr
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
function getStringEnd(str, seek) {
|
|
120
|
-
let first = str[seek];
|
|
121
|
-
let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
|
|
122
|
-
seek += target.length - 1;
|
|
123
|
-
do
|
|
124
|
-
seek = str.indexOf(target, ++seek);
|
|
125
|
-
while (seek > -1 && first !== "'" && isEscaped(str, seek));
|
|
126
|
-
if (seek > -1) {
|
|
127
|
-
seek += target.length;
|
|
128
|
-
if (target.length > 1) {
|
|
129
|
-
if (str[seek] === first)
|
|
130
|
-
seek++;
|
|
131
|
-
if (str[seek] === first)
|
|
132
|
-
seek++;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return seek;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/date.js
|
|
139
|
-
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
140
|
-
var TomlDate = class _TomlDate extends Date {
|
|
141
|
-
#hasDate = false;
|
|
142
|
-
#hasTime = false;
|
|
143
|
-
#offset = null;
|
|
144
|
-
constructor(date) {
|
|
145
|
-
let hasDate = true;
|
|
146
|
-
let hasTime = true;
|
|
147
|
-
let offset = "Z";
|
|
148
|
-
if (typeof date === "string") {
|
|
149
|
-
let match = date.match(DATE_TIME_RE);
|
|
150
|
-
if (match) {
|
|
151
|
-
if (!match[1]) {
|
|
152
|
-
hasDate = false;
|
|
153
|
-
date = `0000-01-01T${date}`;
|
|
154
|
-
}
|
|
155
|
-
hasTime = !!match[2];
|
|
156
|
-
hasTime && date[10] === " " && (date = date.replace(" ", "T"));
|
|
157
|
-
if (match[2] && +match[2] > 23) {
|
|
158
|
-
date = "";
|
|
159
|
-
} else {
|
|
160
|
-
offset = match[3] || null;
|
|
161
|
-
date = date.toUpperCase();
|
|
162
|
-
if (!offset && hasTime)
|
|
163
|
-
date += "Z";
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
date = "";
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
super(date);
|
|
170
|
-
if (!isNaN(this.getTime())) {
|
|
171
|
-
this.#hasDate = hasDate;
|
|
172
|
-
this.#hasTime = hasTime;
|
|
173
|
-
this.#offset = offset;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
isDateTime() {
|
|
177
|
-
return this.#hasDate && this.#hasTime;
|
|
178
|
-
}
|
|
179
|
-
isLocal() {
|
|
180
|
-
return !this.#hasDate || !this.#hasTime || !this.#offset;
|
|
181
|
-
}
|
|
182
|
-
isDate() {
|
|
183
|
-
return this.#hasDate && !this.#hasTime;
|
|
184
|
-
}
|
|
185
|
-
isTime() {
|
|
186
|
-
return this.#hasTime && !this.#hasDate;
|
|
187
|
-
}
|
|
188
|
-
isValid() {
|
|
189
|
-
return this.#hasDate || this.#hasTime;
|
|
190
|
-
}
|
|
191
|
-
toISOString() {
|
|
192
|
-
let iso = super.toISOString();
|
|
193
|
-
if (this.isDate())
|
|
194
|
-
return iso.slice(0, 10);
|
|
195
|
-
if (this.isTime())
|
|
196
|
-
return iso.slice(11, 23);
|
|
197
|
-
if (this.#offset === null)
|
|
198
|
-
return iso.slice(0, -1);
|
|
199
|
-
if (this.#offset === "Z")
|
|
200
|
-
return iso;
|
|
201
|
-
let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
|
|
202
|
-
offset = this.#offset[0] === "-" ? offset : -offset;
|
|
203
|
-
let offsetDate = new Date(this.getTime() - offset * 6e4);
|
|
204
|
-
return offsetDate.toISOString().slice(0, -1) + this.#offset;
|
|
205
|
-
}
|
|
206
|
-
static wrapAsOffsetDateTime(jsDate, offset = "Z") {
|
|
207
|
-
let date = new _TomlDate(jsDate);
|
|
208
|
-
date.#offset = offset;
|
|
209
|
-
return date;
|
|
210
|
-
}
|
|
211
|
-
static wrapAsLocalDateTime(jsDate) {
|
|
212
|
-
let date = new _TomlDate(jsDate);
|
|
213
|
-
date.#offset = null;
|
|
214
|
-
return date;
|
|
215
|
-
}
|
|
216
|
-
static wrapAsLocalDate(jsDate) {
|
|
217
|
-
let date = new _TomlDate(jsDate);
|
|
218
|
-
date.#hasTime = false;
|
|
219
|
-
date.#offset = null;
|
|
220
|
-
return date;
|
|
221
|
-
}
|
|
222
|
-
static wrapAsLocalTime(jsDate) {
|
|
223
|
-
let date = new _TomlDate(jsDate);
|
|
224
|
-
date.#hasDate = false;
|
|
225
|
-
date.#offset = null;
|
|
226
|
-
return date;
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/primitive.js
|
|
231
|
-
var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
232
|
-
var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
233
|
-
var LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
234
|
-
var ESCAPE_REGEX = /^[0-9a-f]{2,8}$/i;
|
|
235
|
-
var ESC_MAP = {
|
|
236
|
-
b: "\b",
|
|
237
|
-
t: " ",
|
|
238
|
-
n: "\n",
|
|
239
|
-
f: "\f",
|
|
240
|
-
r: "\r",
|
|
241
|
-
e: "\x1B",
|
|
242
|
-
'"': '"',
|
|
243
|
-
"\\": "\\"
|
|
244
|
-
};
|
|
245
|
-
function parseString(str, ptr = 0, endPtr = str.length) {
|
|
246
|
-
let isLiteral = str[ptr] === "'";
|
|
247
|
-
let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1];
|
|
248
|
-
if (isMultiline) {
|
|
249
|
-
endPtr -= 2;
|
|
250
|
-
if (str[ptr += 2] === "\r")
|
|
251
|
-
ptr++;
|
|
252
|
-
if (str[ptr] === "\n")
|
|
253
|
-
ptr++;
|
|
254
|
-
}
|
|
255
|
-
let tmp = 0;
|
|
256
|
-
let isEscape;
|
|
257
|
-
let parsed = "";
|
|
258
|
-
let sliceStart = ptr;
|
|
259
|
-
while (ptr < endPtr - 1) {
|
|
260
|
-
let c = str[ptr++];
|
|
261
|
-
if (c === "\n" || c === "\r" && str[ptr] === "\n") {
|
|
262
|
-
if (!isMultiline) {
|
|
263
|
-
throw new TomlError("newlines are not allowed in strings", {
|
|
264
|
-
toml: str,
|
|
265
|
-
ptr: ptr - 1
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
} else if (c < " " && c !== " " || c === "\x7F") {
|
|
269
|
-
throw new TomlError("control characters are not allowed in strings", {
|
|
270
|
-
toml: str,
|
|
271
|
-
ptr: ptr - 1
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (isEscape) {
|
|
275
|
-
isEscape = false;
|
|
276
|
-
if (c === "x" || c === "u" || c === "U") {
|
|
277
|
-
let code = str.slice(ptr, ptr += c === "x" ? 2 : c === "u" ? 4 : 8);
|
|
278
|
-
if (!ESCAPE_REGEX.test(code)) {
|
|
279
|
-
throw new TomlError("invalid unicode escape", {
|
|
280
|
-
toml: str,
|
|
281
|
-
ptr: tmp
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
try {
|
|
285
|
-
parsed += String.fromCodePoint(parseInt(code, 16));
|
|
286
|
-
} catch {
|
|
287
|
-
throw new TomlError("invalid unicode escape", {
|
|
288
|
-
toml: str,
|
|
289
|
-
ptr: tmp
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
} else if (isMultiline && (c === "\n" || c === " " || c === " " || c === "\r")) {
|
|
293
|
-
ptr = skipVoid(str, ptr - 1, true);
|
|
294
|
-
if (str[ptr] !== "\n" && str[ptr] !== "\r") {
|
|
295
|
-
throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
|
|
296
|
-
toml: str,
|
|
297
|
-
ptr: tmp
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
ptr = skipVoid(str, ptr);
|
|
301
|
-
} else if (c in ESC_MAP) {
|
|
302
|
-
parsed += ESC_MAP[c];
|
|
303
|
-
} else {
|
|
304
|
-
throw new TomlError("unrecognized escape sequence", {
|
|
305
|
-
toml: str,
|
|
306
|
-
ptr: tmp
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
sliceStart = ptr;
|
|
310
|
-
} else if (!isLiteral && c === "\\") {
|
|
311
|
-
tmp = ptr - 1;
|
|
312
|
-
isEscape = true;
|
|
313
|
-
parsed += str.slice(sliceStart, tmp);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return parsed + str.slice(sliceStart, endPtr - 1);
|
|
317
|
-
}
|
|
318
|
-
function parseValue(value, toml, ptr, integersAsBigInt) {
|
|
319
|
-
if (value === "true")
|
|
320
|
-
return true;
|
|
321
|
-
if (value === "false")
|
|
322
|
-
return false;
|
|
323
|
-
if (value === "-inf")
|
|
324
|
-
return -Infinity;
|
|
325
|
-
if (value === "inf" || value === "+inf")
|
|
326
|
-
return Infinity;
|
|
327
|
-
if (value === "nan" || value === "+nan" || value === "-nan")
|
|
328
|
-
return NaN;
|
|
329
|
-
if (value === "-0")
|
|
330
|
-
return integersAsBigInt ? 0n : 0;
|
|
331
|
-
let isInt = INT_REGEX.test(value);
|
|
332
|
-
if (isInt || FLOAT_REGEX.test(value)) {
|
|
333
|
-
if (LEADING_ZERO.test(value)) {
|
|
334
|
-
throw new TomlError("leading zeroes are not allowed", {
|
|
335
|
-
toml,
|
|
336
|
-
ptr
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
value = value.replace(/_/g, "");
|
|
340
|
-
let numeric = +value;
|
|
341
|
-
if (isNaN(numeric)) {
|
|
342
|
-
throw new TomlError("invalid number", {
|
|
343
|
-
toml,
|
|
344
|
-
ptr
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
if (isInt) {
|
|
348
|
-
if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
|
|
349
|
-
throw new TomlError("integer value cannot be represented losslessly", {
|
|
350
|
-
toml,
|
|
351
|
-
ptr
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
if (isInt || integersAsBigInt === true)
|
|
355
|
-
numeric = BigInt(value);
|
|
356
|
-
}
|
|
357
|
-
return numeric;
|
|
358
|
-
}
|
|
359
|
-
const date = new TomlDate(value);
|
|
360
|
-
if (!date.isValid()) {
|
|
361
|
-
throw new TomlError("invalid value", {
|
|
362
|
-
toml,
|
|
363
|
-
ptr
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
return date;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/extract.js
|
|
370
|
-
function sliceAndTrimEndOf(str, startPtr, endPtr) {
|
|
371
|
-
let value = str.slice(startPtr, endPtr);
|
|
372
|
-
let commentIdx = value.indexOf("#");
|
|
373
|
-
if (commentIdx > -1) {
|
|
374
|
-
skipComment(str, commentIdx);
|
|
375
|
-
value = value.slice(0, commentIdx);
|
|
376
|
-
}
|
|
377
|
-
return [value.trimEnd(), commentIdx];
|
|
378
|
-
}
|
|
379
|
-
function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
380
|
-
if (depth === 0) {
|
|
381
|
-
throw new TomlError("document contains excessively nested structures. aborting.", {
|
|
382
|
-
toml: str,
|
|
383
|
-
ptr
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
let c = str[ptr];
|
|
387
|
-
if (c === "[" || c === "{") {
|
|
388
|
-
let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
|
|
389
|
-
if (end) {
|
|
390
|
-
endPtr2 = skipVoid(str, endPtr2);
|
|
391
|
-
if (str[endPtr2] === ",")
|
|
392
|
-
endPtr2++;
|
|
393
|
-
else if (str[endPtr2] !== end) {
|
|
394
|
-
throw new TomlError("expected comma or end of structure", {
|
|
395
|
-
toml: str,
|
|
396
|
-
ptr: endPtr2
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return [value, endPtr2];
|
|
401
|
-
}
|
|
402
|
-
let endPtr;
|
|
403
|
-
if (c === '"' || c === "'") {
|
|
404
|
-
endPtr = getStringEnd(str, ptr);
|
|
405
|
-
let parsed = parseString(str, ptr, endPtr);
|
|
406
|
-
if (end) {
|
|
407
|
-
endPtr = skipVoid(str, endPtr);
|
|
408
|
-
if (str[endPtr] && str[endPtr] !== "," && str[endPtr] !== end && str[endPtr] !== "\n" && str[endPtr] !== "\r") {
|
|
409
|
-
throw new TomlError("unexpected character encountered", {
|
|
410
|
-
toml: str,
|
|
411
|
-
ptr: endPtr
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
endPtr += +(str[endPtr] === ",");
|
|
415
|
-
}
|
|
416
|
-
return [parsed, endPtr];
|
|
417
|
-
}
|
|
418
|
-
endPtr = skipUntil(str, ptr, ",", end);
|
|
419
|
-
let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ","));
|
|
420
|
-
if (!slice[0]) {
|
|
421
|
-
throw new TomlError("incomplete key-value declaration: no value specified", {
|
|
422
|
-
toml: str,
|
|
423
|
-
ptr
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
if (end && slice[1] > -1) {
|
|
427
|
-
endPtr = skipVoid(str, ptr + slice[1]);
|
|
428
|
-
endPtr += +(str[endPtr] === ",");
|
|
429
|
-
}
|
|
430
|
-
return [
|
|
431
|
-
parseValue(slice[0], str, ptr, integersAsBigInt),
|
|
432
|
-
endPtr
|
|
433
|
-
];
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/struct.js
|
|
437
|
-
var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
|
438
|
-
function parseKey(str, ptr, end = "=") {
|
|
439
|
-
let dot = ptr - 1;
|
|
440
|
-
let parsed = [];
|
|
441
|
-
let endPtr = str.indexOf(end, ptr);
|
|
442
|
-
if (endPtr < 0) {
|
|
443
|
-
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
444
|
-
toml: str,
|
|
445
|
-
ptr
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
do {
|
|
449
|
-
let c = str[ptr = ++dot];
|
|
450
|
-
if (c !== " " && c !== " ") {
|
|
451
|
-
if (c === '"' || c === "'") {
|
|
452
|
-
if (c === str[ptr + 1] && c === str[ptr + 2]) {
|
|
453
|
-
throw new TomlError("multiline strings are not allowed in keys", {
|
|
454
|
-
toml: str,
|
|
455
|
-
ptr
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
let eos = getStringEnd(str, ptr);
|
|
459
|
-
if (eos < 0) {
|
|
460
|
-
throw new TomlError("unfinished string encountered", {
|
|
461
|
-
toml: str,
|
|
462
|
-
ptr
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
dot = str.indexOf(".", eos);
|
|
466
|
-
let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
467
|
-
let newLine = indexOfNewline(strEnd);
|
|
468
|
-
if (newLine > -1) {
|
|
469
|
-
throw new TomlError("newlines are not allowed in keys", {
|
|
470
|
-
toml: str,
|
|
471
|
-
ptr: ptr + dot + newLine
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
if (strEnd.trimStart()) {
|
|
475
|
-
throw new TomlError("found extra tokens after the string part", {
|
|
476
|
-
toml: str,
|
|
477
|
-
ptr: eos
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
if (endPtr < eos) {
|
|
481
|
-
endPtr = str.indexOf(end, eos);
|
|
482
|
-
if (endPtr < 0) {
|
|
483
|
-
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
484
|
-
toml: str,
|
|
485
|
-
ptr
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
parsed.push(parseString(str, ptr, eos));
|
|
490
|
-
} else {
|
|
491
|
-
dot = str.indexOf(".", ptr);
|
|
492
|
-
let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
493
|
-
if (!KEY_PART_RE.test(part)) {
|
|
494
|
-
throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
|
|
495
|
-
toml: str,
|
|
496
|
-
ptr
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
parsed.push(part.trimEnd());
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
} while (dot + 1 && dot < endPtr);
|
|
503
|
-
return [parsed, skipVoid(str, endPtr + 1, true, true)];
|
|
504
|
-
}
|
|
505
|
-
function parseInlineTable(str, ptr, depth, integersAsBigInt) {
|
|
506
|
-
let res = {};
|
|
507
|
-
let seen = /* @__PURE__ */ new Set();
|
|
508
|
-
let c;
|
|
509
|
-
ptr++;
|
|
510
|
-
while ((c = str[ptr++]) !== "}" && c) {
|
|
511
|
-
if (c === ",") {
|
|
512
|
-
throw new TomlError("expected value, found comma", {
|
|
513
|
-
toml: str,
|
|
514
|
-
ptr: ptr - 1
|
|
515
|
-
});
|
|
516
|
-
} else if (c === "#")
|
|
517
|
-
ptr = skipComment(str, ptr);
|
|
518
|
-
else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
|
|
519
|
-
let k;
|
|
520
|
-
let t = res;
|
|
521
|
-
let hasOwn = false;
|
|
522
|
-
let [key, keyEndPtr] = parseKey(str, ptr - 1);
|
|
523
|
-
for (let i = 0; i < key.length; i++) {
|
|
524
|
-
if (i)
|
|
525
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
526
|
-
k = key[i];
|
|
527
|
-
if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
|
|
528
|
-
throw new TomlError("trying to redefine an already defined value", {
|
|
529
|
-
toml: str,
|
|
530
|
-
ptr
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
if (!hasOwn && k === "__proto__") {
|
|
534
|
-
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (hasOwn) {
|
|
538
|
-
throw new TomlError("trying to redefine an already defined value", {
|
|
539
|
-
toml: str,
|
|
540
|
-
ptr
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
|
|
544
|
-
seen.add(value);
|
|
545
|
-
t[k] = value;
|
|
546
|
-
ptr = valueEndPtr;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (!c) {
|
|
550
|
-
throw new TomlError("unfinished table encountered", {
|
|
551
|
-
toml: str,
|
|
552
|
-
ptr
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
return [res, ptr];
|
|
556
|
-
}
|
|
557
|
-
function parseArray(str, ptr, depth, integersAsBigInt) {
|
|
558
|
-
let res = [];
|
|
559
|
-
let c;
|
|
560
|
-
ptr++;
|
|
561
|
-
while ((c = str[ptr++]) !== "]" && c) {
|
|
562
|
-
if (c === ",") {
|
|
563
|
-
throw new TomlError("expected value, found comma", {
|
|
564
|
-
toml: str,
|
|
565
|
-
ptr: ptr - 1
|
|
566
|
-
});
|
|
567
|
-
} else if (c === "#")
|
|
568
|
-
ptr = skipComment(str, ptr);
|
|
569
|
-
else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
|
|
570
|
-
let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
|
|
571
|
-
res.push(e[0]);
|
|
572
|
-
ptr = e[1];
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
if (!c) {
|
|
576
|
-
throw new TomlError("unfinished array encountered", {
|
|
577
|
-
toml: str,
|
|
578
|
-
ptr
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
return [res, ptr];
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/parse.js
|
|
585
|
-
function peekTable(key, table, meta, type) {
|
|
586
|
-
let t = table;
|
|
587
|
-
let m = meta;
|
|
588
|
-
let k;
|
|
589
|
-
let hasOwn = false;
|
|
590
|
-
let state;
|
|
591
|
-
for (let i = 0; i < key.length; i++) {
|
|
592
|
-
if (i) {
|
|
593
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
594
|
-
m = (state = m[k]).c;
|
|
595
|
-
if (type === 0 && (state.t === 1 || state.t === 2)) {
|
|
596
|
-
return null;
|
|
597
|
-
}
|
|
598
|
-
if (state.t === 2) {
|
|
599
|
-
let l = t.length - 1;
|
|
600
|
-
t = t[l];
|
|
601
|
-
m = m[l].c;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
k = key[i];
|
|
605
|
-
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
|
|
606
|
-
return null;
|
|
607
|
-
}
|
|
608
|
-
if (!hasOwn) {
|
|
609
|
-
if (k === "__proto__") {
|
|
610
|
-
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
611
|
-
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
612
|
-
}
|
|
613
|
-
m[k] = {
|
|
614
|
-
t: i < key.length - 1 && type === 2 ? 3 : type,
|
|
615
|
-
d: false,
|
|
616
|
-
i: 0,
|
|
617
|
-
c: {}
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
state = m[k];
|
|
622
|
-
if (state.t !== type && !(type === 1 && state.t === 3)) {
|
|
623
|
-
return null;
|
|
624
|
-
}
|
|
625
|
-
if (type === 2) {
|
|
626
|
-
if (!state.d) {
|
|
627
|
-
state.d = true;
|
|
628
|
-
t[k] = [];
|
|
629
|
-
}
|
|
630
|
-
t[k].push(t = {});
|
|
631
|
-
state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
|
|
632
|
-
}
|
|
633
|
-
if (state.d) {
|
|
634
|
-
return null;
|
|
635
|
-
}
|
|
636
|
-
state.d = true;
|
|
637
|
-
if (type === 1) {
|
|
638
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
639
|
-
} else if (type === 0 && hasOwn) {
|
|
640
|
-
return null;
|
|
641
|
-
}
|
|
642
|
-
return [k, t, state.c];
|
|
643
|
-
}
|
|
644
|
-
function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
|
|
645
|
-
let res = {};
|
|
646
|
-
let meta = {};
|
|
647
|
-
let tbl = res;
|
|
648
|
-
let m = meta;
|
|
649
|
-
for (let ptr = skipVoid(toml, 0); ptr < toml.length; ) {
|
|
650
|
-
if (toml[ptr] === "[") {
|
|
651
|
-
let isTableArray = toml[++ptr] === "[";
|
|
652
|
-
let k = parseKey(toml, ptr += +isTableArray, "]");
|
|
653
|
-
if (isTableArray) {
|
|
654
|
-
if (toml[k[1] - 1] !== "]") {
|
|
655
|
-
throw new TomlError("expected end of table declaration", {
|
|
656
|
-
toml,
|
|
657
|
-
ptr: k[1] - 1
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
k[1]++;
|
|
661
|
-
}
|
|
662
|
-
let p = peekTable(
|
|
663
|
-
k[0],
|
|
664
|
-
res,
|
|
665
|
-
meta,
|
|
666
|
-
isTableArray ? 2 : 1
|
|
667
|
-
/* Type.EXPLICIT */
|
|
668
|
-
);
|
|
669
|
-
if (!p) {
|
|
670
|
-
throw new TomlError("trying to redefine an already defined table or value", {
|
|
671
|
-
toml,
|
|
672
|
-
ptr
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
m = p[2];
|
|
676
|
-
tbl = p[1];
|
|
677
|
-
ptr = k[1];
|
|
678
|
-
} else {
|
|
679
|
-
let k = parseKey(toml, ptr);
|
|
680
|
-
let p = peekTable(
|
|
681
|
-
k[0],
|
|
682
|
-
tbl,
|
|
683
|
-
m,
|
|
684
|
-
0
|
|
685
|
-
/* Type.DOTTED */
|
|
686
|
-
);
|
|
687
|
-
if (!p) {
|
|
688
|
-
throw new TomlError("trying to redefine an already defined table or value", {
|
|
689
|
-
toml,
|
|
690
|
-
ptr
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
let v = extractValue(toml, k[1], void 0, maxDepth, integersAsBigInt);
|
|
694
|
-
p[1][p[0]] = v[0];
|
|
695
|
-
ptr = v[1];
|
|
696
|
-
}
|
|
697
|
-
ptr = skipVoid(toml, ptr, true);
|
|
698
|
-
if (toml[ptr] && toml[ptr] !== "\n" && toml[ptr] !== "\r") {
|
|
699
|
-
throw new TomlError("each key-value declaration must be followed by an end-of-line", {
|
|
700
|
-
toml,
|
|
701
|
-
ptr
|
|
702
|
-
});
|
|
703
|
-
}
|
|
704
|
-
ptr = skipVoid(toml, ptr);
|
|
705
|
-
}
|
|
706
|
-
return res;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// ../core/dist/index.js
|
|
710
|
-
import { mkdirSync as mkdirSync2, appendFileSync } from "fs";
|
|
711
|
-
import { homedir as homedir3 } from "os";
|
|
712
|
-
import { join as join3 } from "path";
|
|
713
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
714
|
-
import { homedir as homedir4 } from "os";
|
|
715
|
-
import { join as join4 } from "path";
|
|
17
|
+
import { join as join2 } from "path";
|
|
716
18
|
import * as fs2 from "fs";
|
|
717
19
|
import * as path2 from "path";
|
|
718
20
|
import * as os2 from "os";
|
|
@@ -1628,14 +930,14 @@ function registerTradeTools() {
|
|
|
1628
930
|
{
|
|
1629
931
|
name: "trade_get_order",
|
|
1630
932
|
module: "trade",
|
|
1631
|
-
description:
|
|
933
|
+
description: '\uAC1C\uBCC4(\uB2E8\uAC74) \uC8FC\uBB38\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. Get a SINGLE order by order_id or client_order_id. Use when: you have exactly one order identifier. Do NOT use: for multiple orders at once \u2014 do NOT call this repeatedly. Pass all identifiers to trade_get_orders (order_ids/client_order_ids arrays) in a single call instead. Example call: {"order_id":"C0101..."}',
|
|
1632
934
|
isWrite: false,
|
|
1633
935
|
inputSchema: {
|
|
1634
936
|
type: "object",
|
|
1635
937
|
properties: {
|
|
1636
|
-
|
|
938
|
+
order_id: {
|
|
1637
939
|
type: "string",
|
|
1638
|
-
description: "Order
|
|
940
|
+
description: "Order ID"
|
|
1639
941
|
},
|
|
1640
942
|
client_order_id: {
|
|
1641
943
|
type: "string",
|
|
@@ -1649,7 +951,7 @@ function registerTradeTools() {
|
|
|
1649
951
|
const response = await context.client.privateGet(
|
|
1650
952
|
"/v1/order",
|
|
1651
953
|
compactObject({
|
|
1652
|
-
uuid: readString(args, "
|
|
954
|
+
uuid: readString(args, "order_id"),
|
|
1653
955
|
client_order_id: readString(args, "client_order_id")
|
|
1654
956
|
}),
|
|
1655
957
|
privateRateLimit("trade_get_order")
|
|
@@ -1661,7 +963,7 @@ function registerTradeTools() {
|
|
|
1661
963
|
{
|
|
1662
964
|
name: "trade_get_orders",
|
|
1663
965
|
module: "trade",
|
|
1664
|
-
description:
|
|
966
|
+
description: '\uC8FC\uBB38 \uB9AC\uC2A4\uD2B8/\uBCF5\uC218 \uC8FC\uBB38\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. Get orders \u2014 fetch MULTIPLE specific orders in one call via order_ids/client_order_ids (arrays), or list by market/state filters. Use when: the user gives two or more order numbers, or wants a filtered list. Do NOT use trade_get_order repeatedly for multiple ids \u2014 pass them all here in one call. Note: the server defaults to state=wait when omitted, so to fetch done/cancel orders (e.g. by order_ids) set states explicitly, e.g. states=["wait","done","cancel"]. The auto-order state (watch) CANNOT be mixed with general states (wait/done/cancel); query it separately with state=watch. state and states cannot be used together. Example call: {"order_ids":["C0101...","C0102..."],"states":["wait","done","cancel"]}',
|
|
1665
967
|
isWrite: false,
|
|
1666
968
|
inputSchema: {
|
|
1667
969
|
type: "object",
|
|
@@ -1678,12 +980,12 @@ function registerTradeTools() {
|
|
|
1678
980
|
states: {
|
|
1679
981
|
type: "array",
|
|
1680
982
|
items: { type: "string" },
|
|
1681
|
-
description:
|
|
983
|
+
description: 'Multiple order state filters. Constraints: general states (wait/done/cancel) and the auto-order state (watch) CANNOT be mixed in one query; state and states cannot be used together. If omitted, the server defaults to state=wait \u2014 pass states=["wait","done","cancel"] to include done/cancel orders.'
|
|
1682
984
|
},
|
|
1683
|
-
|
|
985
|
+
order_ids: {
|
|
1684
986
|
type: "array",
|
|
1685
987
|
items: { type: "string" },
|
|
1686
|
-
description: "
|
|
988
|
+
description: "Fetch multiple specific orders by order ID in one call (batch lookup). Pass all order IDs here instead of calling trade_get_order repeatedly."
|
|
1687
989
|
},
|
|
1688
990
|
client_order_ids: {
|
|
1689
991
|
type: "array",
|
|
@@ -1713,7 +1015,7 @@ function registerTradeTools() {
|
|
|
1713
1015
|
market: readString(args, "market"),
|
|
1714
1016
|
state: readString(args, "state"),
|
|
1715
1017
|
states: readStringArray(args, "states"),
|
|
1716
|
-
uuids: readStringArray(args, "
|
|
1018
|
+
uuids: readStringArray(args, "order_ids"),
|
|
1717
1019
|
client_order_ids: readStringArray(args, "client_order_ids"),
|
|
1718
1020
|
page: readNumber(args, "page"),
|
|
1719
1021
|
limit: readNumber(args, "limit"),
|
|
@@ -2025,27 +1327,11 @@ async function checkApiReachability(baseUrl) {
|
|
|
2025
1327
|
};
|
|
2026
1328
|
}
|
|
2027
1329
|
}
|
|
2028
|
-
function checkAuthentication() {
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
if (accessKey && secretKey) {
|
|
2032
|
-
return { name: "Authentication", status: "pass", message: "API keys configured via environment variables" };
|
|
1330
|
+
function checkAuthentication(hasAuth) {
|
|
1331
|
+
if (hasAuth) {
|
|
1332
|
+
return { name: "Authentication", status: "pass", message: "API keys configured (--access-key/--secret-key flags or BITHUMB_ACCESS_KEY/BITHUMB_SECRET_KEY env vars)" };
|
|
2033
1333
|
}
|
|
2034
|
-
|
|
2035
|
-
if (existsSync(tomlPath)) {
|
|
2036
|
-
return { name: "Authentication", status: "pass", message: "config.toml found (credentials may be in profile)" };
|
|
2037
|
-
}
|
|
2038
|
-
if (accessKey || secretKey) {
|
|
2039
|
-
return { name: "Authentication", status: "fail", message: "Partial credentials: set both BITHUMB_ACCESS_KEY and BITHUMB_SECRET_KEY" };
|
|
2040
|
-
}
|
|
2041
|
-
return { name: "Authentication", status: "fail", message: "No credentials found (set env vars or create ~/.bithumb/config.toml)" };
|
|
2042
|
-
}
|
|
2043
|
-
function checkTomlConfig() {
|
|
2044
|
-
const tomlPath = join(homedir(), ".bithumb", "config.toml");
|
|
2045
|
-
if (existsSync(tomlPath)) {
|
|
2046
|
-
return { name: "TOML Config", status: "pass", message: `Found ${tomlPath}` };
|
|
2047
|
-
}
|
|
2048
|
-
return { name: "TOML Config", status: "fail", message: `Not found: ${tomlPath} (optional \u2014 use 'setup' command to create)` };
|
|
1334
|
+
return { name: "Authentication", status: "fail", message: "No credentials found. Set --access-key/--secret-key flags or BITHUMB_ACCESS_KEY/BITHUMB_SECRET_KEY env vars." };
|
|
2049
1335
|
}
|
|
2050
1336
|
function checkModules(enabledModules) {
|
|
2051
1337
|
return {
|
|
@@ -2092,7 +1378,7 @@ function registerDiagnoseTools() {
|
|
|
2092
1378
|
{
|
|
2093
1379
|
name: "system_diagnose",
|
|
2094
1380
|
module: "system",
|
|
2095
|
-
description: "Run diagnostic checks on the Bithumb Trade Kit configuration. Checks API reachability, authentication,
|
|
1381
|
+
description: "Run diagnostic checks on the Bithumb Trade Kit configuration. Checks API reachability, authentication, and module status.",
|
|
2096
1382
|
isWrite: false,
|
|
2097
1383
|
inputSchema: {
|
|
2098
1384
|
type: "object",
|
|
@@ -2101,10 +1387,10 @@ function registerDiagnoseTools() {
|
|
|
2101
1387
|
handler: async (_args, context) => {
|
|
2102
1388
|
const baseUrl = context?.config?.baseUrl ?? BITHUMB_API_BASE_URL;
|
|
2103
1389
|
const modules = context?.config?.modules ?? [];
|
|
1390
|
+
const hasAuth = context?.config?.hasAuth ?? false;
|
|
2104
1391
|
const checks = [];
|
|
2105
1392
|
checks.push(await checkApiReachability(baseUrl));
|
|
2106
|
-
checks.push(checkAuthentication());
|
|
2107
|
-
checks.push(checkTomlConfig());
|
|
1393
|
+
checks.push(checkAuthentication(hasAuth));
|
|
2108
1394
|
checks.push(checkModules(modules));
|
|
2109
1395
|
const passed = checks.filter((c) => c.status === "pass").length;
|
|
2110
1396
|
const total = checks.length;
|
|
@@ -2146,7 +1432,7 @@ function registerTwapTools() {
|
|
|
2146
1432
|
},
|
|
2147
1433
|
frequency: {
|
|
2148
1434
|
type: "string",
|
|
2149
|
-
enum: ["
|
|
1435
|
+
enum: ["15", "20", "30", "60", "120"],
|
|
2150
1436
|
description: "\uC8FC\uBB38 \uAC04\uACA9(\uCD08)"
|
|
2151
1437
|
},
|
|
2152
1438
|
volume: {
|
|
@@ -2190,7 +1476,7 @@ function registerTwapTools() {
|
|
|
2190
1476
|
type: "string",
|
|
2191
1477
|
description: "\uAC70\uB798 \uB300\uC0C1 \uD398\uC5B4\uC758 \uACE0\uC720 \uC2EC\uBCFC (\uC608\uC2DC: KRW-BTC)"
|
|
2192
1478
|
},
|
|
2193
|
-
|
|
1479
|
+
order_ids: {
|
|
2194
1480
|
type: "array",
|
|
2195
1481
|
items: { type: "string" },
|
|
2196
1482
|
description: "TWAP \uC8FC\uBB38 ID \uBAA9\uB85D"
|
|
@@ -2222,7 +1508,7 @@ function registerTwapTools() {
|
|
|
2222
1508
|
"/v1/twap",
|
|
2223
1509
|
compactObject({
|
|
2224
1510
|
market: readString(args, "market"),
|
|
2225
|
-
uuids: readStringArray(args, "
|
|
1511
|
+
uuids: readStringArray(args, "order_ids"),
|
|
2226
1512
|
state: readString(args, "state"),
|
|
2227
1513
|
next_key: readString(args, "next_key"),
|
|
2228
1514
|
limit: readNumber(args, "limit"),
|
|
@@ -2310,7 +1596,7 @@ function registerWithdrawTools() {
|
|
|
2310
1596
|
type: "string",
|
|
2311
1597
|
description: "Currency symbol, e.g. BTC"
|
|
2312
1598
|
},
|
|
2313
|
-
|
|
1599
|
+
withdrawal_id: {
|
|
2314
1600
|
type: "string",
|
|
2315
1601
|
description: "Withdrawal unique ID"
|
|
2316
1602
|
},
|
|
@@ -2327,7 +1613,7 @@ function registerWithdrawTools() {
|
|
|
2327
1613
|
"/v1/withdraw",
|
|
2328
1614
|
compactObject({
|
|
2329
1615
|
currency: requireString(args, "currency"),
|
|
2330
|
-
uuid: readString(args, "
|
|
1616
|
+
uuid: readString(args, "withdrawal_id"),
|
|
2331
1617
|
txid: readString(args, "txid")
|
|
2332
1618
|
}),
|
|
2333
1619
|
privateRateLimit("withdraw_get")
|
|
@@ -2353,10 +1639,10 @@ function registerWithdrawTools() {
|
|
|
2353
1639
|
enum: ["PROCESSING", "DONE", "CANCELED"],
|
|
2354
1640
|
description: "Withdrawal state filter"
|
|
2355
1641
|
},
|
|
2356
|
-
|
|
1642
|
+
withdrawal_ids: {
|
|
2357
1643
|
type: "array",
|
|
2358
1644
|
items: { type: "string" },
|
|
2359
|
-
description: "Filter by withdrawal
|
|
1645
|
+
description: "Filter by withdrawal IDs"
|
|
2360
1646
|
},
|
|
2361
1647
|
txids: {
|
|
2362
1648
|
type: "array",
|
|
@@ -2386,7 +1672,7 @@ function registerWithdrawTools() {
|
|
|
2386
1672
|
compactObject({
|
|
2387
1673
|
currency: readString(args, "currency"),
|
|
2388
1674
|
state: readString(args, "state"),
|
|
2389
|
-
uuids: readStringArray(args, "
|
|
1675
|
+
uuids: readStringArray(args, "withdrawal_ids"),
|
|
2390
1676
|
txids: readStringArray(args, "txids"),
|
|
2391
1677
|
limit: readNumber(args, "limit"),
|
|
2392
1678
|
page: readNumber(args, "page"),
|
|
@@ -2411,10 +1697,10 @@ function registerWithdrawTools() {
|
|
|
2411
1697
|
enum: ["PROCESSING", "DONE", "CANCELED"],
|
|
2412
1698
|
description: "Withdrawal state filter"
|
|
2413
1699
|
},
|
|
2414
|
-
|
|
1700
|
+
withdrawal_ids: {
|
|
2415
1701
|
type: "array",
|
|
2416
1702
|
items: { type: "string" },
|
|
2417
|
-
description: "Filter by withdrawal
|
|
1703
|
+
description: "Filter by withdrawal IDs"
|
|
2418
1704
|
},
|
|
2419
1705
|
txids: {
|
|
2420
1706
|
type: "array",
|
|
@@ -2443,7 +1729,7 @@ function registerWithdrawTools() {
|
|
|
2443
1729
|
"/v1/withdraws/krw",
|
|
2444
1730
|
compactObject({
|
|
2445
1731
|
state: readString(args, "state"),
|
|
2446
|
-
uuids: readStringArray(args, "
|
|
1732
|
+
uuids: readStringArray(args, "withdrawal_ids"),
|
|
2447
1733
|
txids: readStringArray(args, "txids"),
|
|
2448
1734
|
limit: readNumber(args, "limit"),
|
|
2449
1735
|
page: readNumber(args, "page"),
|
|
@@ -2622,7 +1908,7 @@ function registerDepositTools() {
|
|
|
2622
1908
|
{
|
|
2623
1909
|
name: "deposit_get",
|
|
2624
1910
|
module: "deposit",
|
|
2625
|
-
description: '\uAC1C\uBCC4 \uC785\uAE08\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. Get a single deposit by currency +
|
|
1911
|
+
description: '\uAC1C\uBCC4 \uC785\uAE08\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. Get a single deposit by currency + deposit_id (or single txid). Use when: you have a specific deposit_id and want the full record. Do NOT use: to search by txid list \u2014 use deposit_get_list with txids (array) instead. Example call: {"currency":"BTC","deposit_id":"12345678-...."}',
|
|
2626
1912
|
isWrite: false,
|
|
2627
1913
|
inputSchema: {
|
|
2628
1914
|
type: "object",
|
|
@@ -2631,9 +1917,9 @@ function registerDepositTools() {
|
|
|
2631
1917
|
type: "string",
|
|
2632
1918
|
description: "Currency symbol, e.g. BTC"
|
|
2633
1919
|
},
|
|
2634
|
-
|
|
1920
|
+
deposit_id: {
|
|
2635
1921
|
type: "string",
|
|
2636
|
-
description: "Deposit
|
|
1922
|
+
description: "Deposit ID"
|
|
2637
1923
|
},
|
|
2638
1924
|
txid: {
|
|
2639
1925
|
type: "string",
|
|
@@ -2648,7 +1934,7 @@ function registerDepositTools() {
|
|
|
2648
1934
|
"/v1/deposit",
|
|
2649
1935
|
compactObject({
|
|
2650
1936
|
currency: requireString(args, "currency"),
|
|
2651
|
-
uuid: readString(args, "
|
|
1937
|
+
uuid: readString(args, "deposit_id"),
|
|
2652
1938
|
txid: readString(args, "txid")
|
|
2653
1939
|
}),
|
|
2654
1940
|
privateRateLimit("deposit_get")
|
|
@@ -2673,10 +1959,10 @@ function registerDepositTools() {
|
|
|
2673
1959
|
type: "string",
|
|
2674
1960
|
description: "Deposit state filter"
|
|
2675
1961
|
},
|
|
2676
|
-
|
|
1962
|
+
deposit_ids: {
|
|
2677
1963
|
type: "array",
|
|
2678
1964
|
items: { type: "string" },
|
|
2679
|
-
description: "Filter by deposit
|
|
1965
|
+
description: "Filter by deposit IDs"
|
|
2680
1966
|
},
|
|
2681
1967
|
txids: {
|
|
2682
1968
|
type: "array",
|
|
@@ -2705,7 +1991,7 @@ function registerDepositTools() {
|
|
|
2705
1991
|
compactObject({
|
|
2706
1992
|
currency: readString(args, "currency"),
|
|
2707
1993
|
state: readString(args, "state"),
|
|
2708
|
-
uuids: readStringArray(args, "
|
|
1994
|
+
uuids: readStringArray(args, "deposit_ids"),
|
|
2709
1995
|
txids: readStringArray(args, "txids"),
|
|
2710
1996
|
limit: readNumber(args, "limit"),
|
|
2711
1997
|
page: readNumber(args, "page"),
|
|
@@ -2729,10 +2015,10 @@ function registerDepositTools() {
|
|
|
2729
2015
|
type: "string",
|
|
2730
2016
|
description: "Deposit state: PROCESSING, ACCEPTED, CANCELED"
|
|
2731
2017
|
},
|
|
2732
|
-
|
|
2018
|
+
deposit_ids: {
|
|
2733
2019
|
type: "array",
|
|
2734
2020
|
items: { type: "string" },
|
|
2735
|
-
description: "Filter by deposit
|
|
2021
|
+
description: "Filter by deposit IDs"
|
|
2736
2022
|
},
|
|
2737
2023
|
txids: {
|
|
2738
2024
|
type: "array",
|
|
@@ -2760,7 +2046,7 @@ function registerDepositTools() {
|
|
|
2760
2046
|
"/v1/deposits/krw",
|
|
2761
2047
|
compactObject({
|
|
2762
2048
|
state: readString(args, "state"),
|
|
2763
|
-
uuids: readStringArray(args, "
|
|
2049
|
+
uuids: readStringArray(args, "deposit_ids"),
|
|
2764
2050
|
txids: readStringArray(args, "txids"),
|
|
2765
2051
|
limit: readNumber(args, "limit"),
|
|
2766
2052
|
page: readNumber(args, "page"),
|
|
@@ -2922,41 +2208,19 @@ function toMcpTool(tool) {
|
|
|
2922
2208
|
}
|
|
2923
2209
|
};
|
|
2924
2210
|
}
|
|
2925
|
-
function configFilePath() {
|
|
2926
|
-
return join2(homedir2(), ".bithumb", "config.toml");
|
|
2927
|
-
}
|
|
2928
|
-
function readFullConfig() {
|
|
2929
|
-
const path3 = configFilePath();
|
|
2930
|
-
if (!existsSync2(path3)) return { profiles: {} };
|
|
2931
|
-
const raw = readFileSync(path3, "utf-8");
|
|
2932
|
-
try {
|
|
2933
|
-
return parse(raw);
|
|
2934
|
-
} catch (err) {
|
|
2935
|
-
throw new ConfigError(
|
|
2936
|
-
`Failed to parse ${path3}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2937
|
-
"Check TOML syntax in your config file, or delete and re-create it."
|
|
2938
|
-
);
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
function readTomlProfile(profileName) {
|
|
2942
|
-
const config = readFullConfig();
|
|
2943
|
-
const name = profileName ?? config.default_profile ?? "default";
|
|
2944
|
-
return config.profiles?.[name] ?? {};
|
|
2945
|
-
}
|
|
2946
2211
|
function loadConfig(options) {
|
|
2947
|
-
const
|
|
2948
|
-
const
|
|
2949
|
-
const secretKey = process.env.BITHUMB_SECRET_KEY?.trim() ?? toml.secret_key;
|
|
2212
|
+
const accessKey = options?.accessKey?.trim() || process.env.BITHUMB_ACCESS_KEY?.trim();
|
|
2213
|
+
const secretKey = options?.secretKey?.trim() || process.env.BITHUMB_SECRET_KEY?.trim();
|
|
2950
2214
|
const hasAuth = Boolean(accessKey && secretKey);
|
|
2951
2215
|
const partialAuth = Boolean(accessKey) || Boolean(secretKey);
|
|
2952
2216
|
if (partialAuth && !hasAuth) {
|
|
2953
2217
|
throw new ConfigError(
|
|
2954
2218
|
"Partial API credentials.",
|
|
2955
|
-
"Set both
|
|
2219
|
+
"Set both access and secret keys via --access-key/--secret-key flags or BITHUMB_ACCESS_KEY/BITHUMB_SECRET_KEY env vars."
|
|
2956
2220
|
);
|
|
2957
2221
|
}
|
|
2958
|
-
const baseUrl = (process.env.BITHUMB_API_BASE_URL?.trim() ??
|
|
2959
|
-
const rawTimeout = process.env.BITHUMB_TIMEOUT_MS ? Number(process.env.BITHUMB_TIMEOUT_MS) :
|
|
2222
|
+
const baseUrl = (process.env.BITHUMB_API_BASE_URL?.trim() ?? BITHUMB_API_BASE_URL).replace(/\/+$/, "");
|
|
2223
|
+
const rawTimeout = process.env.BITHUMB_TIMEOUT_MS ? Number(process.env.BITHUMB_TIMEOUT_MS) : 15e3;
|
|
2960
2224
|
if (!Number.isFinite(rawTimeout) || rawTimeout <= 0) {
|
|
2961
2225
|
throw new ConfigError(
|
|
2962
2226
|
"Invalid timeout.",
|
|
@@ -3027,18 +2291,21 @@ var TradeLogger = class {
|
|
|
3027
2291
|
logDir;
|
|
3028
2292
|
minLevel;
|
|
3029
2293
|
verbose;
|
|
2294
|
+
emitToStderr;
|
|
3030
2295
|
constructor(minLevelOrOptions) {
|
|
3031
2296
|
if (typeof minLevelOrOptions === "string") {
|
|
3032
|
-
this.logDir =
|
|
2297
|
+
this.logDir = join(homedir(), ".bithumb", "logs");
|
|
3033
2298
|
this.minLevel = minLevelOrOptions;
|
|
3034
2299
|
this.verbose = false;
|
|
2300
|
+
this.emitToStderr = true;
|
|
3035
2301
|
} else {
|
|
3036
|
-
this.logDir = minLevelOrOptions?.logDir ??
|
|
2302
|
+
this.logDir = minLevelOrOptions?.logDir ?? join(homedir(), ".bithumb", "logs");
|
|
3037
2303
|
this.minLevel = minLevelOrOptions?.minLevel ?? "info";
|
|
3038
2304
|
this.verbose = minLevelOrOptions?.verbose ?? false;
|
|
2305
|
+
this.emitToStderr = minLevelOrOptions?.emitToStderr ?? true;
|
|
3039
2306
|
}
|
|
3040
2307
|
try {
|
|
3041
|
-
|
|
2308
|
+
mkdirSync(this.logDir, { recursive: true });
|
|
3042
2309
|
} catch {
|
|
3043
2310
|
}
|
|
3044
2311
|
}
|
|
@@ -3071,24 +2338,24 @@ var TradeLogger = class {
|
|
|
3071
2338
|
...meta ? redactSensitive(meta) : {}
|
|
3072
2339
|
};
|
|
3073
2340
|
const line = JSON.stringify(entry);
|
|
3074
|
-
if (this.verbose || level === "error") {
|
|
2341
|
+
if (this.emitToStderr && (this.verbose || level === "error")) {
|
|
3075
2342
|
process.stderr.write(`[${level}] ${message}
|
|
3076
2343
|
`);
|
|
3077
2344
|
}
|
|
3078
2345
|
try {
|
|
3079
|
-
const filePath =
|
|
2346
|
+
const filePath = join(this.logDir, `trade-${todayDateString()}.log`);
|
|
3080
2347
|
appendFileSync(filePath, line + "\n", "utf8");
|
|
3081
2348
|
} catch {
|
|
3082
2349
|
}
|
|
3083
2350
|
}
|
|
3084
2351
|
};
|
|
3085
|
-
var CACHE_DIR =
|
|
3086
|
-
var CACHE_FILE =
|
|
2352
|
+
var CACHE_DIR = join2(homedir2(), ".bithumb");
|
|
2353
|
+
var CACHE_FILE = join2(CACHE_DIR, "update-check.json");
|
|
3087
2354
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
3088
2355
|
function isNewerVersion(current, latest) {
|
|
3089
|
-
const
|
|
3090
|
-
const cur =
|
|
3091
|
-
const lat =
|
|
2356
|
+
const parse = (v) => v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
|
|
2357
|
+
const cur = parse(current);
|
|
2358
|
+
const lat = parse(latest);
|
|
3092
2359
|
for (let i = 0; i < Math.max(cur.length, lat.length); i++) {
|
|
3093
2360
|
const c = cur[i] ?? 0;
|
|
3094
2361
|
const l = lat[i] ?? 0;
|
|
@@ -3113,8 +2380,8 @@ async function fetchLatestVersion(packageName) {
|
|
|
3113
2380
|
}
|
|
3114
2381
|
function readCache() {
|
|
3115
2382
|
try {
|
|
3116
|
-
if (!
|
|
3117
|
-
const raw =
|
|
2383
|
+
if (!existsSync(CACHE_FILE)) return null;
|
|
2384
|
+
const raw = readFileSync(CACHE_FILE, "utf8");
|
|
3118
2385
|
return JSON.parse(raw);
|
|
3119
2386
|
} catch {
|
|
3120
2387
|
return null;
|
|
@@ -3122,10 +2389,10 @@ function readCache() {
|
|
|
3122
2389
|
}
|
|
3123
2390
|
function writeCache(data) {
|
|
3124
2391
|
try {
|
|
3125
|
-
if (!
|
|
3126
|
-
|
|
2392
|
+
if (!existsSync(CACHE_DIR)) {
|
|
2393
|
+
mkdirSync2(CACHE_DIR, { recursive: true });
|
|
3127
2394
|
}
|
|
3128
|
-
|
|
2395
|
+
writeFileSync(CACHE_FILE, JSON.stringify(data), "utf8");
|
|
3129
2396
|
} catch {
|
|
3130
2397
|
}
|
|
3131
2398
|
}
|
|
@@ -3233,7 +2500,6 @@ function buildEntry(client, args) {
|
|
|
3233
2500
|
}
|
|
3234
2501
|
function buildArgs(options) {
|
|
3235
2502
|
const args = [];
|
|
3236
|
-
if (options.profile) args.push("--profile", options.profile);
|
|
3237
2503
|
args.push("--modules", options.modules ?? "all");
|
|
3238
2504
|
return args;
|
|
3239
2505
|
}
|
|
@@ -3261,13 +2527,12 @@ function mergeJsonConfig(configPath, serverName, entry) {
|
|
|
3261
2527
|
}
|
|
3262
2528
|
function printSetupUsage() {
|
|
3263
2529
|
process.stdout.write(
|
|
3264
|
-
`Usage: bithumb setup --client <client> [--
|
|
2530
|
+
`Usage: bithumb setup --client <client> [--modules <list>]
|
|
3265
2531
|
|
|
3266
2532
|
Clients:
|
|
3267
2533
|
` + SUPPORTED_CLIENTS.map((id) => ` ${id.padEnd(16)} ${CLIENT_NAMES[id]}`).join("\n") + `
|
|
3268
2534
|
|
|
3269
2535
|
Options:
|
|
3270
|
-
--profile <name> Profile from ${configFilePath()} (default: uses default_profile)
|
|
3271
2536
|
--modules <list> Comma-separated modules or "all" (default: all)
|
|
3272
2537
|
`
|
|
3273
2538
|
);
|
|
@@ -3276,7 +2541,7 @@ function runSetup(options) {
|
|
|
3276
2541
|
const { client } = options;
|
|
3277
2542
|
const name = CLIENT_NAMES[client];
|
|
3278
2543
|
const args = buildArgs(options);
|
|
3279
|
-
const serverName =
|
|
2544
|
+
const serverName = "bithumb-mcp";
|
|
3280
2545
|
if (client === "claude-code") {
|
|
3281
2546
|
const claudeArgs = [
|
|
3282
2547
|
"mcp",
|
|
@@ -3434,13 +2699,16 @@ Options:
|
|
|
3434
2699
|
--no-log Disable audit logging
|
|
3435
2700
|
--log-level <level> Log level: error, warn, info, debug (default: info)
|
|
3436
2701
|
--verbose Enable verbose request logging to stderr
|
|
3437
|
-
--
|
|
2702
|
+
--access-key <key> Bithumb API access key (overrides BITHUMB_ACCESS_KEY env var)
|
|
2703
|
+
--secret-key <key> Bithumb API secret key (overrides BITHUMB_SECRET_KEY env var)
|
|
3438
2704
|
--help Show this help message
|
|
3439
2705
|
--version Show version
|
|
3440
2706
|
|
|
3441
|
-
Credentials (environment variables):
|
|
2707
|
+
Credentials (environment variables, recommended):
|
|
3442
2708
|
BITHUMB_ACCESS_KEY Bithumb API access key
|
|
3443
2709
|
BITHUMB_SECRET_KEY Bithumb API secret key
|
|
2710
|
+
(Keys may also be passed via --access-key/--secret-key, but flags can be visible
|
|
2711
|
+
in the process list \u2014 prefer env vars for sensitive credentials.)
|
|
3444
2712
|
|
|
3445
2713
|
Other Environment Variables:
|
|
3446
2714
|
BITHUMB_API_BASE_URL Optional API base URL override (default: https://api.bithumb.com)
|
|
@@ -3456,7 +2724,8 @@ function parseCli() {
|
|
|
3456
2724
|
"no-log": { type: "boolean", default: false },
|
|
3457
2725
|
"log-level": { type: "string", default: "info" },
|
|
3458
2726
|
verbose: { type: "boolean", default: false },
|
|
3459
|
-
|
|
2727
|
+
"access-key": { type: "string" },
|
|
2728
|
+
"secret-key": { type: "string" },
|
|
3460
2729
|
help: { type: "boolean", default: false },
|
|
3461
2730
|
version: { type: "boolean", default: false }
|
|
3462
2731
|
},
|
|
@@ -3468,7 +2737,8 @@ function parseCli() {
|
|
|
3468
2737
|
noLog: parsed.values["no-log"] ?? false,
|
|
3469
2738
|
logLevel: parsed.values["log-level"] ?? "info",
|
|
3470
2739
|
verbose: parsed.values.verbose ?? false,
|
|
3471
|
-
|
|
2740
|
+
accessKey: parsed.values["access-key"],
|
|
2741
|
+
secretKey: parsed.values["secret-key"],
|
|
3472
2742
|
help: parsed.values.help ?? false,
|
|
3473
2743
|
version: parsed.values.version ?? false
|
|
3474
2744
|
};
|
|
@@ -3479,7 +2749,6 @@ async function main() {
|
|
|
3479
2749
|
args: process.argv.slice(3),
|
|
3480
2750
|
options: {
|
|
3481
2751
|
client: { type: "string" },
|
|
3482
|
-
profile: { type: "string" },
|
|
3483
2752
|
modules: { type: "string" },
|
|
3484
2753
|
help: { type: "boolean", default: false }
|
|
3485
2754
|
},
|
|
@@ -3497,7 +2766,6 @@ async function main() {
|
|
|
3497
2766
|
}
|
|
3498
2767
|
runSetup({
|
|
3499
2768
|
client: setupArgs.values.client,
|
|
3500
|
-
profile: setupArgs.values.profile,
|
|
3501
2769
|
modules: setupArgs.values.modules
|
|
3502
2770
|
});
|
|
3503
2771
|
return;
|
|
@@ -3517,7 +2785,8 @@ async function main() {
|
|
|
3517
2785
|
modules: cli.modules,
|
|
3518
2786
|
readOnly: cli.readOnly,
|
|
3519
2787
|
verbose: cli.verbose,
|
|
3520
|
-
|
|
2788
|
+
accessKey: cli.accessKey,
|
|
2789
|
+
secretKey: cli.secretKey,
|
|
3521
2790
|
clientType: "mcp"
|
|
3522
2791
|
});
|
|
3523
2792
|
const logger = cli.noLog ? void 0 : new TradeLogger(cli.logLevel);
|
|
@@ -3534,43 +2803,4 @@ main().catch((error) => {
|
|
|
3534
2803
|
export {
|
|
3535
2804
|
main
|
|
3536
2805
|
};
|
|
3537
|
-
/*! Bundled license information:
|
|
3538
|
-
|
|
3539
|
-
smol-toml/dist/error.js:
|
|
3540
|
-
smol-toml/dist/util.js:
|
|
3541
|
-
smol-toml/dist/date.js:
|
|
3542
|
-
smol-toml/dist/primitive.js:
|
|
3543
|
-
smol-toml/dist/extract.js:
|
|
3544
|
-
smol-toml/dist/struct.js:
|
|
3545
|
-
smol-toml/dist/parse.js:
|
|
3546
|
-
smol-toml/dist/stringify.js:
|
|
3547
|
-
smol-toml/dist/index.js:
|
|
3548
|
-
(*!
|
|
3549
|
-
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3550
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
3551
|
-
*
|
|
3552
|
-
* Redistribution and use in source and binary forms, with or without
|
|
3553
|
-
* modification, are permitted provided that the following conditions are met:
|
|
3554
|
-
*
|
|
3555
|
-
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
3556
|
-
* list of conditions and the following disclaimer.
|
|
3557
|
-
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
3558
|
-
* this list of conditions and the following disclaimer in the
|
|
3559
|
-
* documentation and/or other materials provided with the distribution.
|
|
3560
|
-
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
3561
|
-
* may be used to endorse or promote products derived from this software without
|
|
3562
|
-
* specific prior written permission.
|
|
3563
|
-
*
|
|
3564
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
3565
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
3566
|
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
3567
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
3568
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
3569
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
3570
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
3571
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
3572
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
3573
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3574
|
-
*)
|
|
3575
|
-
*/
|
|
3576
2806
|
//# sourceMappingURL=index.js.map
|