@funnycode/myclaude 0.1.90 → 0.1.92
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/myclaude.js +35 -25
- package/dist/myclaude.mjs +35 -25
- package/package.json +1 -1
package/dist/myclaude.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// MACRO - build-time constants (injected by build.ts)
|
|
5
5
|
// MACRO injected by build script
|
|
6
6
|
globalThis.MACRO = {
|
|
7
|
-
VERSION: "0.1.
|
|
8
|
-
BUILD_TIME: "2026-07-
|
|
7
|
+
VERSION: "0.1.92",
|
|
8
|
+
BUILD_TIME: "2026-07-17T23:07:28.667Z",
|
|
9
9
|
PACKAGE_URL: "@funnycode/myclaude",
|
|
10
10
|
NATIVE_PACKAGE_URL: "@funnycode/myclaude",
|
|
11
11
|
VERSION_CHANGELOG: '',
|
|
@@ -117484,7 +117484,7 @@ var package_default;
|
|
|
117484
117484
|
var init_package = __esm(() => {
|
|
117485
117485
|
package_default = {
|
|
117486
117486
|
name: "@funnycode/myclaude",
|
|
117487
|
-
version: "0.1.
|
|
117487
|
+
version: "0.1.92",
|
|
117488
117488
|
private: false,
|
|
117489
117489
|
description: "An open-source AI coding assistant in your terminal - powered by Claude",
|
|
117490
117490
|
license: "MIT",
|
|
@@ -210163,7 +210163,7 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
|
|
|
210163
210163
|
processQueue(agentIdOrSessionId);
|
|
210164
210164
|
}
|
|
210165
210165
|
}
|
|
210166
|
-
function processQueue(agentIdOrSessionId) {
|
|
210166
|
+
async function processQueue(agentIdOrSessionId) {
|
|
210167
210167
|
processingQueues.add(agentIdOrSessionId);
|
|
210168
210168
|
const queue = dumpRequestQueue.get(agentIdOrSessionId);
|
|
210169
210169
|
if (!queue || queue.length === 0) {
|
|
@@ -210172,7 +210172,7 @@ function processQueue(agentIdOrSessionId) {
|
|
|
210172
210172
|
return;
|
|
210173
210173
|
}
|
|
210174
210174
|
const callback = queue.shift();
|
|
210175
|
-
callback();
|
|
210175
|
+
await callback();
|
|
210176
210176
|
if (queue.length > 0) {
|
|
210177
210177
|
setImmediate(() => processQueue(agentIdOrSessionId));
|
|
210178
210178
|
} else {
|
|
@@ -210203,14 +210203,17 @@ function addApiRequestToCache(requestData) {
|
|
|
210203
210203
|
function getDumpPromptsPath(agentIdOrSessionId) {
|
|
210204
210204
|
return join48(getClaudeConfigHomeDir(), "dump-prompts", `${agentIdOrSessionId ?? getSessionId()}.jsonl`);
|
|
210205
210205
|
}
|
|
210206
|
-
function appendToFile(filePath, entries) {
|
|
210206
|
+
async function appendToFile(filePath, entries) {
|
|
210207
210207
|
if (entries.length === 0)
|
|
210208
210208
|
return;
|
|
210209
|
-
|
|
210209
|
+
try {
|
|
210210
|
+
await fs11.mkdir(dirname27(filePath), { recursive: true });
|
|
210211
|
+
await fs11.appendFile(filePath, entries.join(`
|
|
210210
210212
|
`) + `
|
|
210211
|
-
`)
|
|
210213
|
+
`);
|
|
210214
|
+
} catch (err2) {
|
|
210212
210215
|
logForDebugging(`dumpPrompts.appendToFile error: ${err2}`, { level: "error" });
|
|
210213
|
-
}
|
|
210216
|
+
}
|
|
210214
210217
|
}
|
|
210215
210218
|
function initFingerprint(req) {
|
|
210216
210219
|
const tools = req.tools;
|
|
@@ -210219,7 +210222,7 @@ function initFingerprint(req) {
|
|
|
210219
210222
|
const toolNames = tools?.map((t) => t.name ?? "").join(",") ?? "";
|
|
210220
210223
|
return `${req.model}|${toolNames}|${sysLen}`;
|
|
210221
210224
|
}
|
|
210222
|
-
function dumpRequest(body, ts, state, filePath) {
|
|
210225
|
+
async function dumpRequest(body, ts, state, filePath) {
|
|
210223
210226
|
try {
|
|
210224
210227
|
const req = jsonParse(body);
|
|
210225
210228
|
addApiRequestToCache(req);
|
|
@@ -210257,7 +210260,7 @@ function dumpRequest(body, ts, state, filePath) {
|
|
|
210257
210260
|
}
|
|
210258
210261
|
}
|
|
210259
210262
|
state.messageCountSeen = messages.length;
|
|
210260
|
-
appendToFile(filePath, entries);
|
|
210263
|
+
await appendToFile(filePath, entries);
|
|
210261
210264
|
} catch (err2) {
|
|
210262
210265
|
logForDebugging(`dumpPrompts.dumpRequest error: ${err2}`, { level: "error" });
|
|
210263
210266
|
}
|
|
@@ -210275,8 +210278,8 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
|
|
|
210275
210278
|
let timestamp;
|
|
210276
210279
|
if (init2?.method === "POST" && init2.body) {
|
|
210277
210280
|
timestamp = new Date().toISOString();
|
|
210278
|
-
enqueueDumpRequest(agentIdOrSessionId, () => {
|
|
210279
|
-
dumpRequest(init2.body, timestamp, state, filePath);
|
|
210281
|
+
enqueueDumpRequest(agentIdOrSessionId, async () => {
|
|
210282
|
+
await dumpRequest(init2.body, timestamp, state, filePath);
|
|
210280
210283
|
});
|
|
210281
210284
|
}
|
|
210282
210285
|
const response = await globalThis.fetch(input, init2);
|
|
@@ -210342,8 +210345,9 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
|
|
|
210342
210345
|
} else {
|
|
210343
210346
|
data = await cloned.json();
|
|
210344
210347
|
}
|
|
210345
|
-
await
|
|
210346
|
-
|
|
210348
|
+
await appendToFile(filePath, [
|
|
210349
|
+
jsonStringify({ type: "response", timestamp, data })
|
|
210350
|
+
]);
|
|
210347
210351
|
} catch (err2) {
|
|
210348
210352
|
try {
|
|
210349
210353
|
logForDebugging(`dumpPrompts.response handler error: ${err2}`, { level: "error" });
|
|
@@ -301130,8 +301134,8 @@ function memoizeWithTTL(fn, ttlMs) {
|
|
|
301130
301134
|
return result;
|
|
301131
301135
|
} catch (error49) {
|
|
301132
301136
|
originalClear();
|
|
301133
|
-
lastCachedAt =
|
|
301134
|
-
|
|
301137
|
+
lastCachedAt = -1;
|
|
301138
|
+
return { success: false };
|
|
301135
301139
|
}
|
|
301136
301140
|
};
|
|
301137
301141
|
wrapped.cache = {
|
|
@@ -301207,11 +301211,13 @@ async function isQualifiedForGrove() {
|
|
|
301207
301211
|
return cachedEntry.grove_enabled;
|
|
301208
301212
|
}
|
|
301209
301213
|
async function fetchAndStoreGroveConfig(accountId) {
|
|
301214
|
+
const mapRelease = await groveConfigMapMutex.acquire();
|
|
301210
301215
|
let mutex = groveConfigMutexes.get(accountId);
|
|
301211
301216
|
if (!mutex) {
|
|
301212
301217
|
mutex = new Mutex;
|
|
301213
301218
|
groveConfigMutexes.set(accountId, mutex);
|
|
301214
301219
|
}
|
|
301220
|
+
mapRelease();
|
|
301215
301221
|
const release = await mutex.acquire();
|
|
301216
301222
|
try {
|
|
301217
301223
|
const result = await getGroveNoticeConfig();
|
|
@@ -301290,7 +301296,7 @@ An update to our Consumer Terms and Privacy Policy will take effect on October 8
|
|
|
301290
301296
|
}
|
|
301291
301297
|
}
|
|
301292
301298
|
}
|
|
301293
|
-
var groveConfigMutexes, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
|
|
301299
|
+
var groveConfigMutexes, groveConfigMapMutex, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
|
|
301294
301300
|
var init_grove = __esm(() => {
|
|
301295
301301
|
init_axios2();
|
|
301296
301302
|
init_memoize();
|
|
@@ -301304,6 +301310,7 @@ var init_grove = __esm(() => {
|
|
|
301304
301310
|
init_log3();
|
|
301305
301311
|
init_async_mutex();
|
|
301306
301312
|
groveConfigMutexes = new Map;
|
|
301313
|
+
groveConfigMapMutex = new Mutex;
|
|
301307
301314
|
GROVE_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
|
|
301308
301315
|
GROVE_API_TIMEOUT_MS = parseInt(process.env.GROVE_API_TIMEOUT_MS ?? "3000", 10);
|
|
301309
301316
|
getGroveSettings = memoizeWithTTL(async () => {
|
|
@@ -453847,14 +453854,16 @@ async function fetchAndStorePassesEligibility() {
|
|
|
453847
453854
|
if (!orgId) {
|
|
453848
453855
|
return null;
|
|
453849
453856
|
}
|
|
453850
|
-
|
|
453851
|
-
|
|
453852
|
-
|
|
453857
|
+
const existingPromise = fetchInProgressMap.get(orgId);
|
|
453858
|
+
if (existingPromise) {
|
|
453859
|
+
logForDebugging(`Passes: Reusing in-flight eligibility fetch for org ${orgId}`);
|
|
453860
|
+
return existingPromise;
|
|
453853
453861
|
}
|
|
453854
453862
|
let resolvePromise;
|
|
453855
|
-
|
|
453863
|
+
const promise3 = new Promise((resolve47) => {
|
|
453856
453864
|
resolvePromise = resolve47;
|
|
453857
453865
|
});
|
|
453866
|
+
fetchInProgressMap.set(orgId, promise3);
|
|
453858
453867
|
(async () => {
|
|
453859
453868
|
try {
|
|
453860
453869
|
const response = await fetchReferralEligibility();
|
|
@@ -453876,10 +453885,10 @@ async function fetchAndStorePassesEligibility() {
|
|
|
453876
453885
|
logError2(error49);
|
|
453877
453886
|
resolvePromise(null);
|
|
453878
453887
|
} finally {
|
|
453879
|
-
|
|
453888
|
+
fetchInProgressMap.delete(orgId);
|
|
453880
453889
|
}
|
|
453881
453890
|
})();
|
|
453882
|
-
return
|
|
453891
|
+
return promise3;
|
|
453883
453892
|
}
|
|
453884
453893
|
async function getCachedOrFetchPassesEligibility() {
|
|
453885
453894
|
if (!shouldCheckForPasses()) {
|
|
@@ -453913,7 +453922,7 @@ async function prefetchPassesEligibility() {
|
|
|
453913
453922
|
}
|
|
453914
453923
|
getCachedOrFetchPassesEligibility().catch(() => {});
|
|
453915
453924
|
}
|
|
453916
|
-
var CACHE_EXPIRATION_MS,
|
|
453925
|
+
var CACHE_EXPIRATION_MS, fetchInProgressMap, CURRENCY_SYMBOLS;
|
|
453917
453926
|
var init_referral = __esm(() => {
|
|
453918
453927
|
init_axios2();
|
|
453919
453928
|
init_oauth();
|
|
@@ -453923,6 +453932,7 @@ var init_referral = __esm(() => {
|
|
|
453923
453932
|
init_log3();
|
|
453924
453933
|
init_api2();
|
|
453925
453934
|
CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
|
|
453935
|
+
fetchInProgressMap = new Map;
|
|
453926
453936
|
CURRENCY_SYMBOLS = {
|
|
453927
453937
|
USD: "$",
|
|
453928
453938
|
EUR: "€",
|
package/dist/myclaude.mjs
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// MACRO - build-time constants (injected by build.ts)
|
|
5
5
|
// MACRO injected by build script
|
|
6
6
|
globalThis.MACRO = {
|
|
7
|
-
VERSION: "0.1.
|
|
8
|
-
BUILD_TIME: "2026-07-
|
|
7
|
+
VERSION: "0.1.92",
|
|
8
|
+
BUILD_TIME: "2026-07-17T23:07:28.667Z",
|
|
9
9
|
PACKAGE_URL: "@funnycode/myclaude",
|
|
10
10
|
NATIVE_PACKAGE_URL: "@funnycode/myclaude",
|
|
11
11
|
VERSION_CHANGELOG: '',
|
|
@@ -117484,7 +117484,7 @@ var package_default;
|
|
|
117484
117484
|
var init_package = __esm(() => {
|
|
117485
117485
|
package_default = {
|
|
117486
117486
|
name: "@funnycode/myclaude",
|
|
117487
|
-
version: "0.1.
|
|
117487
|
+
version: "0.1.92",
|
|
117488
117488
|
private: false,
|
|
117489
117489
|
description: "An open-source AI coding assistant in your terminal - powered by Claude",
|
|
117490
117490
|
license: "MIT",
|
|
@@ -210163,7 +210163,7 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
|
|
|
210163
210163
|
processQueue(agentIdOrSessionId);
|
|
210164
210164
|
}
|
|
210165
210165
|
}
|
|
210166
|
-
function processQueue(agentIdOrSessionId) {
|
|
210166
|
+
async function processQueue(agentIdOrSessionId) {
|
|
210167
210167
|
processingQueues.add(agentIdOrSessionId);
|
|
210168
210168
|
const queue = dumpRequestQueue.get(agentIdOrSessionId);
|
|
210169
210169
|
if (!queue || queue.length === 0) {
|
|
@@ -210172,7 +210172,7 @@ function processQueue(agentIdOrSessionId) {
|
|
|
210172
210172
|
return;
|
|
210173
210173
|
}
|
|
210174
210174
|
const callback = queue.shift();
|
|
210175
|
-
callback();
|
|
210175
|
+
await callback();
|
|
210176
210176
|
if (queue.length > 0) {
|
|
210177
210177
|
setImmediate(() => processQueue(agentIdOrSessionId));
|
|
210178
210178
|
} else {
|
|
@@ -210203,14 +210203,17 @@ function addApiRequestToCache(requestData) {
|
|
|
210203
210203
|
function getDumpPromptsPath(agentIdOrSessionId) {
|
|
210204
210204
|
return join48(getClaudeConfigHomeDir(), "dump-prompts", `${agentIdOrSessionId ?? getSessionId()}.jsonl`);
|
|
210205
210205
|
}
|
|
210206
|
-
function appendToFile(filePath, entries) {
|
|
210206
|
+
async function appendToFile(filePath, entries) {
|
|
210207
210207
|
if (entries.length === 0)
|
|
210208
210208
|
return;
|
|
210209
|
-
|
|
210209
|
+
try {
|
|
210210
|
+
await fs11.mkdir(dirname27(filePath), { recursive: true });
|
|
210211
|
+
await fs11.appendFile(filePath, entries.join(`
|
|
210210
210212
|
`) + `
|
|
210211
|
-
`)
|
|
210213
|
+
`);
|
|
210214
|
+
} catch (err2) {
|
|
210212
210215
|
logForDebugging(`dumpPrompts.appendToFile error: ${err2}`, { level: "error" });
|
|
210213
|
-
}
|
|
210216
|
+
}
|
|
210214
210217
|
}
|
|
210215
210218
|
function initFingerprint(req) {
|
|
210216
210219
|
const tools = req.tools;
|
|
@@ -210219,7 +210222,7 @@ function initFingerprint(req) {
|
|
|
210219
210222
|
const toolNames = tools?.map((t) => t.name ?? "").join(",") ?? "";
|
|
210220
210223
|
return `${req.model}|${toolNames}|${sysLen}`;
|
|
210221
210224
|
}
|
|
210222
|
-
function dumpRequest(body, ts, state, filePath) {
|
|
210225
|
+
async function dumpRequest(body, ts, state, filePath) {
|
|
210223
210226
|
try {
|
|
210224
210227
|
const req = jsonParse(body);
|
|
210225
210228
|
addApiRequestToCache(req);
|
|
@@ -210257,7 +210260,7 @@ function dumpRequest(body, ts, state, filePath) {
|
|
|
210257
210260
|
}
|
|
210258
210261
|
}
|
|
210259
210262
|
state.messageCountSeen = messages.length;
|
|
210260
|
-
appendToFile(filePath, entries);
|
|
210263
|
+
await appendToFile(filePath, entries);
|
|
210261
210264
|
} catch (err2) {
|
|
210262
210265
|
logForDebugging(`dumpPrompts.dumpRequest error: ${err2}`, { level: "error" });
|
|
210263
210266
|
}
|
|
@@ -210275,8 +210278,8 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
|
|
|
210275
210278
|
let timestamp;
|
|
210276
210279
|
if (init2?.method === "POST" && init2.body) {
|
|
210277
210280
|
timestamp = new Date().toISOString();
|
|
210278
|
-
enqueueDumpRequest(agentIdOrSessionId, () => {
|
|
210279
|
-
dumpRequest(init2.body, timestamp, state, filePath);
|
|
210281
|
+
enqueueDumpRequest(agentIdOrSessionId, async () => {
|
|
210282
|
+
await dumpRequest(init2.body, timestamp, state, filePath);
|
|
210280
210283
|
});
|
|
210281
210284
|
}
|
|
210282
210285
|
const response = await globalThis.fetch(input, init2);
|
|
@@ -210342,8 +210345,9 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
|
|
|
210342
210345
|
} else {
|
|
210343
210346
|
data = await cloned.json();
|
|
210344
210347
|
}
|
|
210345
|
-
await
|
|
210346
|
-
|
|
210348
|
+
await appendToFile(filePath, [
|
|
210349
|
+
jsonStringify({ type: "response", timestamp, data })
|
|
210350
|
+
]);
|
|
210347
210351
|
} catch (err2) {
|
|
210348
210352
|
try {
|
|
210349
210353
|
logForDebugging(`dumpPrompts.response handler error: ${err2}`, { level: "error" });
|
|
@@ -301130,8 +301134,8 @@ function memoizeWithTTL(fn, ttlMs) {
|
|
|
301130
301134
|
return result;
|
|
301131
301135
|
} catch (error49) {
|
|
301132
301136
|
originalClear();
|
|
301133
|
-
lastCachedAt =
|
|
301134
|
-
|
|
301137
|
+
lastCachedAt = -1;
|
|
301138
|
+
return { success: false };
|
|
301135
301139
|
}
|
|
301136
301140
|
};
|
|
301137
301141
|
wrapped.cache = {
|
|
@@ -301207,11 +301211,13 @@ async function isQualifiedForGrove() {
|
|
|
301207
301211
|
return cachedEntry.grove_enabled;
|
|
301208
301212
|
}
|
|
301209
301213
|
async function fetchAndStoreGroveConfig(accountId) {
|
|
301214
|
+
const mapRelease = await groveConfigMapMutex.acquire();
|
|
301210
301215
|
let mutex = groveConfigMutexes.get(accountId);
|
|
301211
301216
|
if (!mutex) {
|
|
301212
301217
|
mutex = new Mutex;
|
|
301213
301218
|
groveConfigMutexes.set(accountId, mutex);
|
|
301214
301219
|
}
|
|
301220
|
+
mapRelease();
|
|
301215
301221
|
const release = await mutex.acquire();
|
|
301216
301222
|
try {
|
|
301217
301223
|
const result = await getGroveNoticeConfig();
|
|
@@ -301290,7 +301296,7 @@ An update to our Consumer Terms and Privacy Policy will take effect on October 8
|
|
|
301290
301296
|
}
|
|
301291
301297
|
}
|
|
301292
301298
|
}
|
|
301293
|
-
var groveConfigMutexes, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
|
|
301299
|
+
var groveConfigMutexes, groveConfigMapMutex, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
|
|
301294
301300
|
var init_grove = __esm(() => {
|
|
301295
301301
|
init_axios2();
|
|
301296
301302
|
init_memoize();
|
|
@@ -301304,6 +301310,7 @@ var init_grove = __esm(() => {
|
|
|
301304
301310
|
init_log3();
|
|
301305
301311
|
init_async_mutex();
|
|
301306
301312
|
groveConfigMutexes = new Map;
|
|
301313
|
+
groveConfigMapMutex = new Mutex;
|
|
301307
301314
|
GROVE_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
|
|
301308
301315
|
GROVE_API_TIMEOUT_MS = parseInt(process.env.GROVE_API_TIMEOUT_MS ?? "3000", 10);
|
|
301309
301316
|
getGroveSettings = memoizeWithTTL(async () => {
|
|
@@ -453847,14 +453854,16 @@ async function fetchAndStorePassesEligibility() {
|
|
|
453847
453854
|
if (!orgId) {
|
|
453848
453855
|
return null;
|
|
453849
453856
|
}
|
|
453850
|
-
|
|
453851
|
-
|
|
453852
|
-
|
|
453857
|
+
const existingPromise = fetchInProgressMap.get(orgId);
|
|
453858
|
+
if (existingPromise) {
|
|
453859
|
+
logForDebugging(`Passes: Reusing in-flight eligibility fetch for org ${orgId}`);
|
|
453860
|
+
return existingPromise;
|
|
453853
453861
|
}
|
|
453854
453862
|
let resolvePromise;
|
|
453855
|
-
|
|
453863
|
+
const promise3 = new Promise((resolve47) => {
|
|
453856
453864
|
resolvePromise = resolve47;
|
|
453857
453865
|
});
|
|
453866
|
+
fetchInProgressMap.set(orgId, promise3);
|
|
453858
453867
|
(async () => {
|
|
453859
453868
|
try {
|
|
453860
453869
|
const response = await fetchReferralEligibility();
|
|
@@ -453876,10 +453885,10 @@ async function fetchAndStorePassesEligibility() {
|
|
|
453876
453885
|
logError2(error49);
|
|
453877
453886
|
resolvePromise(null);
|
|
453878
453887
|
} finally {
|
|
453879
|
-
|
|
453888
|
+
fetchInProgressMap.delete(orgId);
|
|
453880
453889
|
}
|
|
453881
453890
|
})();
|
|
453882
|
-
return
|
|
453891
|
+
return promise3;
|
|
453883
453892
|
}
|
|
453884
453893
|
async function getCachedOrFetchPassesEligibility() {
|
|
453885
453894
|
if (!shouldCheckForPasses()) {
|
|
@@ -453913,7 +453922,7 @@ async function prefetchPassesEligibility() {
|
|
|
453913
453922
|
}
|
|
453914
453923
|
getCachedOrFetchPassesEligibility().catch(() => {});
|
|
453915
453924
|
}
|
|
453916
|
-
var CACHE_EXPIRATION_MS,
|
|
453925
|
+
var CACHE_EXPIRATION_MS, fetchInProgressMap, CURRENCY_SYMBOLS;
|
|
453917
453926
|
var init_referral = __esm(() => {
|
|
453918
453927
|
init_axios2();
|
|
453919
453928
|
init_oauth();
|
|
@@ -453923,6 +453932,7 @@ var init_referral = __esm(() => {
|
|
|
453923
453932
|
init_log3();
|
|
453924
453933
|
init_api2();
|
|
453925
453934
|
CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
|
|
453935
|
+
fetchInProgressMap = new Map;
|
|
453926
453936
|
CURRENCY_SYMBOLS = {
|
|
453927
453937
|
USD: "$",
|
|
453928
453938
|
EUR: "€",
|