From 3b22d02bf3c1f025a83270ee569225e9714f1ab7 Mon Sep 17 00:00:00 2001 From: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:04:33 +0300 Subject: [PATCH] drop ambiguous bare currency aliases shared across countries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRIORITY only disambiguated USD vs TTD's "доллар". "Manat", "FC", "Som" and "Kwacha" are each shared verbatim between two currencies (AZN/TMT, CDF/KMF, KGS/UZS, MWK/ZMW) and fell to alphabetical code order, so e.g. "100 Manat" always silently priced as AZN even when TMT was meant. Drop the bare alias from the smaller-economy side; its fuller name still works. --- src/engine/edge.test.ts | 20 ++++++++++++++++++++ src/engine/vocab-data.ts | 18 ++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/engine/edge.test.ts b/src/engine/edge.test.ts index b4fc63b..5ebd457 100644 --- a/src/engine/edge.test.ts +++ b/src/engine/edge.test.ts @@ -302,4 +302,24 @@ describe("regression 2026-08-12", () => { const r2 = eng.evaluateDocument("10\n20\n5\nmax").map((x) => x.text); expect(r2).toEqual(["10", "20", "5", "20"]); }); + + function unitIdOf(expr: string): string | null { + const v = eng.evaluateDocument(expr)[0].value; + return v?.kind === "quantity" ? v.unit?.id ?? null : null; + } + it("ambiguous currency aliases resolve to one deliberate currency; the other needs its full name", () => { + expect(unitIdOf("100 Manat")).toBe("AZN"); + expect(unitIdOf("100 Turkmenistan Manat")).toBe("TMT"); + expect(unitIdOf("100 манат")).toBe("AZN"); + expect(unitIdOf("100 туркменский манат")).toBe("TMT"); + expect(unitIdOf("100 FC")).toBe("CDF"); + expect(unitIdOf("100 Comorian Franc")).toBe("KMF"); + // "Som"/"Kwacha" go to the larger economy (UZS/ZMW); the smaller one needs its full name + expect(unitIdOf("100 Som")).toBe("UZS"); + expect(unitIdOf("100 Kyrgyzstani Som")).toBe("KGS"); + expect(unitIdOf("100 Kwacha")).toBe("ZMW"); + expect(unitIdOf("100 Malawian Kwacha")).toBe("MWK"); + expect(unitIdOf("100 квача")).toBe("ZMW"); + expect(unitIdOf("100 малавийская квача")).toBe("MWK"); + }); }); diff --git a/src/engine/vocab-data.ts b/src/engine/vocab-data.ts index 2e22c1a..c4acd00 100644 --- a/src/engine/vocab-data.ts +++ b/src/engine/vocab-data.ts @@ -169,11 +169,13 @@ export const EN: VocabLocale = { "KES.format": "%@ KSh", "KES.variants": "Kenyan Shillings,Kenyan Shilling,KSh", "KGS.format": "%@ sом", - "KGS.variants": "Kyrgyzstani Soms,Kyrgyzstani Som,Soms,Som,sом", + // bare "Som"/"Soms" dropped — UZS (larger economy) owns it; say "Kyrgyzstani Som" for KGS + "KGS.variants": "Kyrgyzstani Soms,Kyrgyzstani Som,sом", "KHR.format": "%@ R.", "KHR.variants": "Cambodian Riel,Riel,៛,Cambodian Riels,Riels", "KMF.format": "%@ FC", - "KMF.variants": "Comorian Francs,Comorian Franc,FC", + // bare "FC" dropped — CDF (Congolese franc, registered first) owns it; say "Comorian Franc" for KMF + "KMF.variants": "Comorian Francs,Comorian Franc", "KPW.format": "₩ %@", "KPW.variants": "North Korean won", "KRW.format": "₩ %@", @@ -221,7 +223,8 @@ export const EN: VocabLocale = { "MVR.format": "Rf %@", "MVR.variants": "Maldivian Rufiyaa,Rufiyaa,Rf", "MWK.format": "%@ MK", - "MWK.variants": "Malawian Kwacha,Kwacha", + // bare "Kwacha" dropped — ZMW (larger economy) owns it; say "Malawian Kwacha" for MWK + "MWK.variants": "Malawian Kwacha", "MXN.format": "$ %@", "MXN.variants": "Mexican Peso,Mexican Pesos", "MYR.format": "RM %@", @@ -301,7 +304,8 @@ export const EN: VocabLocale = { "TJS.format": "%@ TJS", "TJS.variants": "Tajikistani Somoni,Somoni", "TMT.format": "%@ TMT", - "TMT.variants": "Turkmenistan Manat,Manat", + // bare "Manat" dropped — AZN (registered first) owns it; say "Turkmenistan Manat" for TMT + "TMT.variants": "Turkmenistan Manat", "TND.format": "%@ TD", "TND.variants": "Tunisian Dinar,Tunisian Dinars,د.ت,TD", "TOP.format": "T$ %@", @@ -733,7 +737,8 @@ export const RU: VocabLocale = { "MUR.variants": "Маврикийская рупия,Маврикийских рупий,Маврикийских рупиях", "MVR.format": "%@ Rf", "MVR.variants": "Мальдивская руфия,Руфия,Руфий,Руфиях", - "MWK.variants": "Малавийская квача,Малавийских квач,Малавийских квачах,Квача,Квачах", + // bare "Квача"/"Квачах" dropped — ZMW (larger economy) owns them; the fuller phrases stay unambiguous + "MWK.variants": "Малавийская квача,Малавийских квач,Малавийских квачах", "MXN.format": "%@ $", "MXN.variants": "Мексиканских песо,Мексиканское песо", "MYR.format": "%@ RM", @@ -793,7 +798,8 @@ export const RU: VocabLocale = { "THB.variants": "Тайский бат,Бат,Батов,Батах", "TJS.format": "%@ смн.", "TJS.variants": "Таджикский сомони,Сомони", - "TMT.variants": "Туркменский манат,Новый туркменский манат,Манат,Манатов,Туркменских манатов,Маната,Туркменских маната", + // bare "Манат" dropped — AZN owns it; the fuller phrases below stay unambiguous + "TMT.variants": "Туркменский манат,Новый туркменский манат,Манатов,Туркменских манатов,Маната,Туркменских маната", "TND.variants": "Тунисские Динары,Тунисский Динар,Тунисских Динаров,Тунисских Динарах", "TOP.format": "%@ T$", "TOP.variants": "Тонганская паанга,Паанга,Паангах",