ezmedicationinput 0.1.43 → 0.1.45

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/i18n.js DELETED
@@ -1,899 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.THAI_SITE_TRANSLATIONS = exports.getRegisteredSigTranslations = exports.registerSigTranslation = void 0;
4
- exports.registerSigLocalization = registerSigLocalization;
5
- exports.getRegisteredSigLocalizations = getRegisteredSigLocalizations;
6
- exports.resolveSigLocalization = resolveSigLocalization;
7
- exports.resolveSigTranslation = resolveSigTranslation;
8
- const types_1 = require("./types");
9
- const timing_summary_1 = require("./timing-summary");
10
- const REGISTERED_LOCALIZATIONS = new Map();
11
- function registerSigLocalization(localization) {
12
- REGISTERED_LOCALIZATIONS.set(localization.locale.toLowerCase(), localization);
13
- }
14
- function getRegisteredSigLocalizations() {
15
- return Array.from(REGISTERED_LOCALIZATIONS.values());
16
- }
17
- function resolveSigLocalization(locale, config) {
18
- var _a, _b, _c, _d, _e, _f, _g;
19
- const normalizedLocale = (_a = config === null || config === void 0 ? void 0 : config.locale) !== null && _a !== void 0 ? _a : locale;
20
- const targetKey = normalizedLocale === null || normalizedLocale === void 0 ? void 0 : normalizedLocale.toLowerCase();
21
- const base = targetKey ? REGISTERED_LOCALIZATIONS.get(targetKey) : undefined;
22
- const inherited = (config === null || config === void 0 ? void 0 : config.inherit)
23
- ? REGISTERED_LOCALIZATIONS.get(config.inherit.toLowerCase())
24
- : undefined;
25
- if (!base && !inherited && !config) {
26
- return undefined;
27
- }
28
- const resolvedLocale = (_f = (_e = (_d = (_c = (_b = config === null || config === void 0 ? void 0 : config.locale) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.inherit) !== null && _c !== void 0 ? _c : base === null || base === void 0 ? void 0 : base.locale) !== null && _d !== void 0 ? _d : inherited === null || inherited === void 0 ? void 0 : inherited.locale) !== null && _e !== void 0 ? _e : targetKey) !== null && _f !== void 0 ? _f : "custom";
29
- const result = {
30
- locale: resolvedLocale
31
- };
32
- if (base === null || base === void 0 ? void 0 : base.formatShort) {
33
- result.formatShort = base.formatShort;
34
- }
35
- if (base === null || base === void 0 ? void 0 : base.formatLong) {
36
- result.formatLong = base.formatLong;
37
- }
38
- if (inherited === null || inherited === void 0 ? void 0 : inherited.formatShort) {
39
- result.formatShort = inherited.formatShort;
40
- }
41
- if (inherited === null || inherited === void 0 ? void 0 : inherited.formatLong) {
42
- result.formatLong = inherited.formatLong;
43
- }
44
- if ((config === null || config === void 0 ? void 0 : config.formatShort) !== undefined) {
45
- result.formatShort = config.formatShort;
46
- }
47
- if ((config === null || config === void 0 ? void 0 : config.formatLong) !== undefined) {
48
- result.formatLong = config.formatLong;
49
- }
50
- if (!result.formatShort && !result.formatLong) {
51
- return (_g = base !== null && base !== void 0 ? base : inherited) !== null && _g !== void 0 ? _g : result;
52
- }
53
- return result;
54
- }
55
- registerSigLocalization({
56
- locale: "en",
57
- formatShort: ({ defaultText }) => defaultText,
58
- formatLong: ({ defaultText }) => defaultText
59
- });
60
- exports.registerSigTranslation = registerSigLocalization;
61
- exports.getRegisteredSigTranslations = getRegisteredSigLocalizations;
62
- function resolveSigTranslation(locale, config) {
63
- return resolveSigLocalization(locale, config);
64
- }
65
- function createThaiLocalization() {
66
- return {
67
- locale: "th",
68
- formatShort: ({ internal }) => formatShortThai(internal),
69
- formatLong: ({ internal, groupMealTimingsByRelation, includeTimesPerDaySummary }) => formatLongThai(internal, {
70
- groupMealTimingsByRelation,
71
- includeTimesPerDaySummary
72
- })
73
- };
74
- }
75
- registerSigLocalization(createThaiLocalization());
76
- // Thai formatting helpers
77
- const ROUTE_SHORT = {
78
- [types_1.RouteCode["Oral route"]]: "PO",
79
- [types_1.RouteCode["Sublingual route"]]: "SL",
80
- [types_1.RouteCode["Buccal route"]]: "BUC",
81
- [types_1.RouteCode["Respiratory tract route (qualifier value)"]]: "INH",
82
- [types_1.RouteCode["Nasal route"]]: "IN",
83
- [types_1.RouteCode["Topical route"]]: "TOP",
84
- [types_1.RouteCode["Transdermal route"]]: "TD",
85
- [types_1.RouteCode["Subcutaneous route"]]: "SC",
86
- [types_1.RouteCode["Intramuscular route"]]: "IM",
87
- [types_1.RouteCode["Intravenous route"]]: "IV",
88
- [types_1.RouteCode["Per rectum"]]: "PR",
89
- [types_1.RouteCode["Per vagina"]]: "PV",
90
- [types_1.RouteCode["Ophthalmic route"]]: "OPH",
91
- [types_1.RouteCode["Otic route"]]: "OT",
92
- [types_1.RouteCode["Intravitreal route (qualifier value)"]]: "IVT"
93
- };
94
- const WHEN_TEXT_THAI = {
95
- [types_1.EventTiming["Before Sleep"]]: "ก่อนนอน",
96
- [types_1.EventTiming["Before Meal"]]: "ก่อนอาหาร",
97
- [types_1.EventTiming["Before Breakfast"]]: "ก่อนอาหารเช้า",
98
- [types_1.EventTiming["Before Lunch"]]: "ก่อนอาหารกลางวัน",
99
- [types_1.EventTiming["Before Dinner"]]: "ก่อนอาหารเย็น",
100
- [types_1.EventTiming["After Meal"]]: "หลังอาหาร",
101
- [types_1.EventTiming["After Breakfast"]]: "หลังอาหารเช้า",
102
- [types_1.EventTiming["After Lunch"]]: "หลังอาหารกลางวัน",
103
- [types_1.EventTiming["After Dinner"]]: "หลังอาหารเย็น",
104
- [types_1.EventTiming.Meal]: "พร้อมอาหาร",
105
- [types_1.EventTiming.Breakfast]: "พร้อมอาหารเช้า",
106
- [types_1.EventTiming.Lunch]: "พร้อมอาหารกลางวัน",
107
- [types_1.EventTiming.Dinner]: "พร้อมอาหารเย็น",
108
- [types_1.EventTiming.Morning]: "ตอนเช้า",
109
- [types_1.EventTiming["Early Morning"]]: "เช้าตรู่",
110
- [types_1.EventTiming["Late Morning"]]: "สาย",
111
- [types_1.EventTiming.Noon]: "ตอนเที่ยง",
112
- [types_1.EventTiming.Afternoon]: "ตอนบ่าย",
113
- [types_1.EventTiming["Early Afternoon"]]: "บ่ายต้น",
114
- [types_1.EventTiming["Late Afternoon"]]: "บ่ายแก่",
115
- [types_1.EventTiming.Evening]: "ตอนเย็น",
116
- [types_1.EventTiming["Early Evening"]]: "หัวค่ำ",
117
- [types_1.EventTiming["Late Evening"]]: "ดึก",
118
- [types_1.EventTiming.Night]: "ตอนกลางคืน",
119
- [types_1.EventTiming.Wake]: "หลังตื่นนอน",
120
- [types_1.EventTiming["After Sleep"]]: "หลังจากนอน",
121
- [types_1.EventTiming.Immediate]: "ทันที"
122
- };
123
- const DAY_NAMES_THAI = {
124
- mon: "วันจันทร์",
125
- tue: "วันอังคาร",
126
- wed: "วันพุธ",
127
- thu: "วันพฤหัสบดี",
128
- fri: "วันศุกร์",
129
- sat: "วันเสาร์",
130
- sun: "วันอาทิตย์"
131
- };
132
- const TH_TIMES_PER_DAY = {
133
- 1: "วันละครั้ง",
134
- 2: "วันละ 2 ครั้ง",
135
- 3: "วันละ 3 ครั้ง",
136
- 4: "วันละ 4 ครั้ง"
137
- };
138
- exports.THAI_SITE_TRANSLATIONS = {
139
- eye: "ตา",
140
- eyes: "ตา",
141
- "right eye": "ตาขวา",
142
- "left eye": "ตาซ้าย",
143
- "both eyes": "ตาทั้งสองข้าง",
144
- "bilateral eyes": "ตาทั้งสองข้าง",
145
- "right ear": "หูขวา",
146
- "left ear": "หูซ้าย",
147
- "both ears": "หูทั้งสองข้าง",
148
- "bilateral ears": "หูทั้งสองข้าง",
149
- ear: "หู",
150
- ears: "หูทั้งสองข้าง",
151
- nostril: "รูจมูก",
152
- nostrils: "รูจมูกทั้งสองข้าง",
153
- "right nostril": "รูจมูกขวา",
154
- "left nostril": "รูจมูกซ้าย",
155
- "both nostrils": "รูจมูกทั้งสองข้าง",
156
- "left naris": "รูจมูกซ้าย",
157
- "right naris": "รูจมูกขวา",
158
- nares: "รูจมูกทั้งสองข้าง",
159
- "anterior nares": "รูจมูกด้านหน้า",
160
- nose: "จมูก",
161
- mouth: "ปาก",
162
- tongue: "ลิ้น",
163
- tongues: "ลิ้น",
164
- "right arm": "แขนขวา",
165
- "left arm": "แขนซ้าย",
166
- "both arms": "แขนทั้งสองข้าง",
167
- arm: "แขน",
168
- "upper arm": "ต้นแขน",
169
- "left upper arm": "ต้นแขนซ้าย",
170
- "right upper arm": "ต้นแขนขวา",
171
- "bilateral arms": "แขนทั้งสองข้าง",
172
- "right leg": "ขาขวา",
173
- "left leg": "ขาซ้าย",
174
- "both legs": "ขาทั้งสองข้าง",
175
- leg: "ขา",
176
- "lower leg": "ขาส่วนล่าง",
177
- "left lower leg": "ขาส่วนล่างซ้าย",
178
- "right lower leg": "ขาส่วนล่างขวา",
179
- "bilateral legs": "ขาทั้งสองข้าง",
180
- "right hand": "มือขวา",
181
- "left hand": "มือซ้าย",
182
- "both hands": "มือทั้งสองข้าง",
183
- hand: "มือ",
184
- hands: "มือทั้งสองข้าง",
185
- "right foot": "เท้าขวา",
186
- "left foot": "เท้าซ้าย",
187
- "both feet": "เท้าทั้งสองข้าง",
188
- foot: "เท้า",
189
- feet: "เท้า",
190
- abdomen: "ช่องท้อง",
191
- abdominal: "ช่องท้อง",
192
- belly: "ท้อง",
193
- back: "แผ่นหลัง",
194
- scalp: "หนังศีรษะ",
195
- face: "ใบหน้า",
196
- cheek: "แก้ม",
197
- cheeks: "แก้มทั้งสองข้าง",
198
- forehead: "หน้าผาก",
199
- chin: "คาง",
200
- neck: "คอ",
201
- forearm: "ปลายแขน",
202
- "left forearm": "ปลายแขนซ้าย",
203
- "right forearm": "ปลายแขนขวา",
204
- shoulder: "ไหล่",
205
- shoulders: "ไหล่ทั้งสองข้าง",
206
- thigh: "ต้นขา",
207
- thighs: "ต้นขาทั้งสองข้าง",
208
- "left thigh": "ต้นขาซ้าย",
209
- "right thigh": "ต้นขาขวา",
210
- gum: "เหงือก",
211
- gums: "เหงือก",
212
- tooth: "ฟัน",
213
- teeth: "ฟัน",
214
- buttock: "สะโพก",
215
- buttocks: "สะโพกทั้งสองข้าง",
216
- gluteal: "สะโพก",
217
- glute: "สะโพก",
218
- "left buttock": "สะโพกซ้าย",
219
- "left gluteal": "สะโพกซ้าย",
220
- "right buttock": "สะโพกขวา",
221
- "right gluteal": "สะโพกขวา",
222
- muscle: "กล้ามเนื้อ",
223
- muscles: "กล้ามเนื้อทั้งหมด",
224
- vein: "หลอดเลือดดำ",
225
- veins: "หลอดเลือดดำทั้งหมด",
226
- vagina: "ช่องคลอด",
227
- vaginal: "บริเวณช่องคลอด",
228
- penis: "อวัยวะเพศชาย",
229
- penile: "บริเวณอวัยวะเพศชาย",
230
- rectum: "ไส้ตรง",
231
- rectal: "บริเวณทวารหนัก",
232
- anus: "ทวารหนัก",
233
- perineum: "ฝีเย็บ",
234
- skin: "ผิวหนัง",
235
- hair: "เส้นผม"
236
- };
237
- const DEFAULT_THAI_ROUTE_GRAMMAR = { verb: "ใช้" };
238
- const THAI_ROUTE_GRAMMAR = {
239
- [types_1.RouteCode["Oral route"]]: { verb: "รับประทาน", routePhrase: "ทางปาก" },
240
- [types_1.RouteCode["Sublingual route"]]: { verb: "อมใต้ลิ้น", routePhrase: "ใต้ลิ้น" },
241
- [types_1.RouteCode["Buccal route"]]: { verb: "อมกระพุ้งแก้ม", routePhrase: "ที่กระพุ้งแก้ม" },
242
- [types_1.RouteCode["Respiratory tract route (qualifier value)"]]: {
243
- verb: "สูด",
244
- sitePreposition: "ที่"
245
- },
246
- [types_1.RouteCode["Nasal route"]]: {
247
- verb: "พ่น",
248
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางจมูก"),
249
- sitePreposition: "ที่"
250
- },
251
- [types_1.RouteCode["Topical route"]]: {
252
- verb: "ทา",
253
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "บริเวณผิวหนัง"),
254
- sitePreposition: "บริเวณ"
255
- },
256
- [types_1.RouteCode["Transdermal route"]]: {
257
- verb: "ติด",
258
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "แบบแผ่นแปะผิวหนัง"),
259
- sitePreposition: "บริเวณ"
260
- },
261
- [types_1.RouteCode["Subcutaneous route"]]: {
262
- verb: "ฉีด",
263
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าใต้ผิวหนัง"),
264
- sitePreposition: "ที่"
265
- },
266
- [types_1.RouteCode["Intramuscular route"]]: {
267
- verb: "ฉีด",
268
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้ากล้ามเนื้อ"),
269
- sitePreposition: "ที่"
270
- },
271
- [types_1.RouteCode["Intravenous route"]]: {
272
- verb: "ฉีด",
273
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าหลอดเลือดดำ"),
274
- sitePreposition: "ที่"
275
- },
276
- [types_1.RouteCode["Per rectum"]]: {
277
- verb: "สอด",
278
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางทวารหนัก"),
279
- sitePreposition: "ที่"
280
- },
281
- [types_1.RouteCode["Per vagina"]]: {
282
- verb: "สอด",
283
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางช่องคลอด"),
284
- sitePreposition: "ที่"
285
- },
286
- [types_1.RouteCode["Ophthalmic route"]]: {
287
- verb: "หยอด",
288
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ที่ดวงตา"),
289
- sitePreposition: "ที่"
290
- },
291
- [types_1.RouteCode["Otic route"]]: {
292
- verb: "หยอด",
293
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ที่หู"),
294
- sitePreposition: "ที่"
295
- },
296
- [types_1.RouteCode["Intravitreal route (qualifier value)"]]: {
297
- verb: "ฉีด",
298
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าดวงตา"),
299
- sitePreposition: "ที่"
300
- }
301
- };
302
- function resolveRouteGrammarThai(internal) {
303
- var _a, _b, _c;
304
- if (internal.routeCode && THAI_ROUTE_GRAMMAR[internal.routeCode]) {
305
- return (_a = THAI_ROUTE_GRAMMAR[internal.routeCode]) !== null && _a !== void 0 ? _a : DEFAULT_THAI_ROUTE_GRAMMAR;
306
- }
307
- const grammar = grammarFromRouteTextThai(internal.routeText);
308
- if (grammar) {
309
- return grammar;
310
- }
311
- if (((_b = internal.unit) === null || _b === void 0 ? void 0 : _b.trim().toLowerCase()) === "puff") {
312
- return (_c = THAI_ROUTE_GRAMMAR[types_1.RouteCode["Respiratory tract route (qualifier value)"]]) !== null && _c !== void 0 ? _c : DEFAULT_THAI_ROUTE_GRAMMAR;
313
- }
314
- return DEFAULT_THAI_ROUTE_GRAMMAR;
315
- }
316
- function grammarFromRouteTextThai(text) {
317
- if (!text)
318
- return undefined;
319
- const normalized = text.trim().toLowerCase();
320
- if (!normalized)
321
- return undefined;
322
- if (normalized.includes("mouth") || normalized.includes("oral")) {
323
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Oral route"]];
324
- }
325
- if (normalized.includes("ophthalm")) {
326
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Ophthalmic route"]];
327
- }
328
- if (normalized.includes("intravitreal")) {
329
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intravitreal route (qualifier value)"]];
330
- }
331
- if (normalized.includes("topical")) {
332
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Topical route"]];
333
- }
334
- if (normalized.includes("transdermal")) {
335
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Transdermal route"]];
336
- }
337
- if (normalized.includes("subcutaneous") || normalized === "sc" || normalized === "sq") {
338
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Subcutaneous route"]];
339
- }
340
- if (normalized.includes("intramuscular") || normalized === "im") {
341
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intramuscular route"]];
342
- }
343
- if (normalized.includes("intravenous") || normalized === "iv") {
344
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intravenous route"]];
345
- }
346
- if (normalized.includes("nasal")) {
347
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Nasal route"]];
348
- }
349
- if (normalized.includes("inhal")) {
350
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Respiratory tract route (qualifier value)"]];
351
- }
352
- return undefined;
353
- }
354
- function formatDoseThaiShort(internal) {
355
- if (internal.doseRange) {
356
- const { low, high } = internal.doseRange;
357
- const base = `${stripTrailingZero(low)}-${stripTrailingZero(high)}`;
358
- if (internal.unit) {
359
- return `${base} ${formatUnitThai(internal.unit, high, "short")}`;
360
- }
361
- return base;
362
- }
363
- if (internal.dose !== undefined) {
364
- const amount = stripTrailingZero(internal.dose);
365
- if (internal.unit) {
366
- return `${amount} ${formatUnitThai(internal.unit, internal.dose, "short")}`;
367
- }
368
- return amount;
369
- }
370
- return undefined;
371
- }
372
- function formatDoseThaiLong(internal) {
373
- if (internal.doseRange) {
374
- const { low, high } = internal.doseRange;
375
- if (internal.unit) {
376
- const unit = formatUnitThai(internal.unit, high, "long");
377
- return `ครั้งละ ${stripTrailingZero(low)} ถึง ${stripTrailingZero(high)} ${unit}`;
378
- }
379
- return `ครั้งละ ${stripTrailingZero(low)} ถึง ${stripTrailingZero(high)}`;
380
- }
381
- if (internal.dose !== undefined) {
382
- if (internal.unit) {
383
- const unit = formatUnitThai(internal.unit, internal.dose, "long");
384
- return `ครั้งละ ${stripTrailingZero(internal.dose)} ${unit}`;
385
- }
386
- return `ครั้งละ ${stripTrailingZero(internal.dose)}`;
387
- }
388
- return undefined;
389
- }
390
- function formatUnitThai(unit, value, style) {
391
- const lower = unit.toLowerCase();
392
- const quantity = Math.abs(value);
393
- const mapping = {
394
- tab: { short: "เม็ด", long: "เม็ด" },
395
- tablet: { short: "เม็ด", long: "เม็ด" },
396
- cap: { short: "แคปซูล", long: "แคปซูล" },
397
- capsule: { short: "แคปซูล", long: "แคปซูล" },
398
- ml: { short: "มล.", long: "มิลลิลิตร" },
399
- milliliter: { short: "มล.", long: "มิลลิลิตร" },
400
- milliliters: { short: "มล.", long: "มิลลิลิตร" },
401
- mg: { short: "มก.", long: "มิลลิกรัม" },
402
- mcg: { short: "ไมโครกรัม", long: "ไมโครกรัม" },
403
- ug: { short: "ไมโครกรัม", long: "ไมโครกรัม" },
404
- puff: { short: "พัฟ", long: "พัฟ" },
405
- puffs: { short: "พัฟ", long: "พัฟ" },
406
- spray: { short: "พ่น", long: "พ่น" },
407
- sprays: { short: "พ่น", long: "พ่น" },
408
- drop: { short: "หยด", long: "หยด" },
409
- drops: { short: "หยด", long: "หยด" },
410
- patch: { short: "แผ่น", long: "แผ่นแปะ" },
411
- patches: { short: "แผ่น", long: "แผ่นแปะ" },
412
- suppository: { short: "ยาเหน็บ", long: "ยาเหน็บ" },
413
- suppositories: { short: "ยาเหน็บ", long: "ยาเหน็บ" }
414
- };
415
- const entry = mapping[lower];
416
- if (entry) {
417
- return style === "short" ? entry.short : entry.long;
418
- }
419
- return unit;
420
- }
421
- function describeFrequencyThai(internal) {
422
- const { frequency, frequencyMax, period, periodMax, periodUnit, timingCode } = internal;
423
- if (frequency !== undefined &&
424
- frequencyMax !== undefined &&
425
- periodUnit === types_1.FhirPeriodUnit.Day &&
426
- (!period || period === 1)) {
427
- if (frequency === 1 && frequencyMax === 1) {
428
- return "วันละครั้ง";
429
- }
430
- if (frequency === 1 && frequencyMax === 2) {
431
- return "วันละ 1 ถึง 2 ครั้ง";
432
- }
433
- return `วันละ ${stripTrailingZero(frequency)} ถึง ${stripTrailingZero(frequencyMax)} ครั้ง`;
434
- }
435
- if (frequency && periodUnit === types_1.FhirPeriodUnit.Day && (!period || period === 1)) {
436
- const dailyText = TH_TIMES_PER_DAY[frequency];
437
- if (dailyText) {
438
- return dailyText;
439
- }
440
- return `วันละ ${stripTrailingZero(frequency)} ครั้ง`;
441
- }
442
- if (periodUnit === types_1.FhirPeriodUnit.Hour && period) {
443
- if (periodMax && periodMax !== period) {
444
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} ชั่วโมง`;
445
- }
446
- return `ทุก ${stripTrailingZero(period)} ชั่วโมง`;
447
- }
448
- if (periodUnit === types_1.FhirPeriodUnit.Day && period && period !== 1) {
449
- if (period === 2 && (!periodMax || periodMax === 2)) {
450
- return "วันเว้นวัน";
451
- }
452
- if (periodMax && periodMax !== period) {
453
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} วัน`;
454
- }
455
- return `ทุก ${stripTrailingZero(period)} วัน`;
456
- }
457
- if (periodUnit === types_1.FhirPeriodUnit.Week && period) {
458
- if (period === 1 && (!periodMax || periodMax === 1)) {
459
- return "สัปดาห์ละครั้ง";
460
- }
461
- if (periodMax && periodMax !== period) {
462
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} สัปดาห์`;
463
- }
464
- return `ทุก ${stripTrailingZero(period)} สัปดาห์`;
465
- }
466
- if (periodUnit === types_1.FhirPeriodUnit.Month && period) {
467
- if (period === 1 && (!periodMax || periodMax === 1)) {
468
- return "เดือนละครั้ง";
469
- }
470
- if (periodMax && periodMax !== period) {
471
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} เดือน`;
472
- }
473
- return `ทุก ${stripTrailingZero(period)} เดือน`;
474
- }
475
- if (timingCode) {
476
- const map = {
477
- BID: "วันละ 2 ครั้ง",
478
- TID: "วันละ 3 ครั้ง",
479
- QID: "วันละ 4 ครั้ง",
480
- QD: "วันละครั้ง",
481
- QOD: "วันเว้นวัน",
482
- Q6H: "ทุก 6 ชั่วโมง",
483
- Q8H: "ทุก 8 ชั่วโมง",
484
- WK: "สัปดาห์ละครั้ง",
485
- MO: "เดือนละครั้ง"
486
- };
487
- const value = map[timingCode.toUpperCase()];
488
- if (value) {
489
- return value;
490
- }
491
- }
492
- if (frequency && periodUnit === undefined && period === undefined) {
493
- if (frequency === 1)
494
- return "ครั้งเดียว";
495
- return `${stripTrailingZero(frequency)} ครั้ง`;
496
- }
497
- return undefined;
498
- }
499
- function describeFrequencyCountThai(count) {
500
- if (!count || count <= 0) {
501
- return undefined;
502
- }
503
- const dailyText = TH_TIMES_PER_DAY[count];
504
- if (dailyText) {
505
- return dailyText;
506
- }
507
- return `วันละ ${stripTrailingZero(count)} ครั้ง`;
508
- }
509
- function joinMealNamesThai(parts) {
510
- if (parts.length === 0) {
511
- return "";
512
- }
513
- if (parts.length === 1) {
514
- return parts[0];
515
- }
516
- if (parts.length === 2) {
517
- return `${parts[0]} และ${parts[1]}`;
518
- }
519
- let text = parts[0];
520
- for (let i = 1; i < parts.length - 1; i += 1) {
521
- text += ` ${parts[i]}`;
522
- }
523
- return `${text} และ${parts[parts.length - 1]}`;
524
- }
525
- function summarizeMealTimingGroupThai(group) {
526
- const relationText = {
527
- before: "ก่อนอาหาร",
528
- after: "หลังอาหาร",
529
- with: "พร้อมอาหาร"
530
- };
531
- const mealText = {
532
- breakfast: "เช้า",
533
- lunch: "กลางวัน",
534
- dinner: "เย็น"
535
- };
536
- const meals = [];
537
- for (let i = 0; i < group.meals.length; i += 1) {
538
- meals.push(mealText[group.meals[i]]);
539
- }
540
- return `${relationText[group.relation]}${joinMealNamesThai(meals)}`;
541
- }
542
- function collectWhenPhrasesThai(internal, options) {
543
- if (!internal.when.length) {
544
- return [];
545
- }
546
- const unique = [];
547
- const seen = new Set();
548
- let hasSpecificAfter = false;
549
- let hasSpecificBefore = false;
550
- let hasSpecificWith = false;
551
- for (const code of internal.when) {
552
- if (!seen.has(code)) {
553
- seen.add(code);
554
- unique.push(code);
555
- if (code === types_1.EventTiming["After Breakfast"] ||
556
- code === types_1.EventTiming["After Lunch"] ||
557
- code === types_1.EventTiming["After Dinner"]) {
558
- hasSpecificAfter = true;
559
- }
560
- if (code === types_1.EventTiming["Before Breakfast"] ||
561
- code === types_1.EventTiming["Before Lunch"] ||
562
- code === types_1.EventTiming["Before Dinner"]) {
563
- hasSpecificBefore = true;
564
- }
565
- if (code === types_1.EventTiming.Breakfast ||
566
- code === types_1.EventTiming.Lunch ||
567
- code === types_1.EventTiming.Dinner) {
568
- hasSpecificWith = true;
569
- }
570
- }
571
- }
572
- const filtered = [];
573
- for (let i = 0; i < unique.length; i += 1) {
574
- const code = unique[i];
575
- if (code === types_1.EventTiming["After Meal"] && hasSpecificAfter) {
576
- continue;
577
- }
578
- if (code === types_1.EventTiming["Before Meal"] && hasSpecificBefore) {
579
- continue;
580
- }
581
- if (code === types_1.EventTiming.Meal && hasSpecificWith) {
582
- continue;
583
- }
584
- filtered.push(code);
585
- }
586
- const mealGroup = (0, timing_summary_1.getMealTimingGroup)(filtered, options);
587
- if (mealGroup) {
588
- const groupedCodes = new Set(mealGroup.codes);
589
- const phrases = [];
590
- let insertedGroup = false;
591
- for (let i = 0; i < filtered.length; i += 1) {
592
- const code = filtered[i];
593
- if (groupedCodes.has(code)) {
594
- if (!insertedGroup) {
595
- phrases.push(summarizeMealTimingGroupThai(mealGroup));
596
- insertedGroup = true;
597
- }
598
- continue;
599
- }
600
- const text = WHEN_TEXT_THAI[code];
601
- if (text) {
602
- phrases.push(text);
603
- }
604
- }
605
- return phrases;
606
- }
607
- const phrases = [];
608
- for (let i = 0; i < filtered.length; i += 1) {
609
- const text = WHEN_TEXT_THAI[filtered[i]];
610
- if (text) {
611
- phrases.push(text);
612
- }
613
- }
614
- return phrases;
615
- }
616
- function joinWithAndThai(parts) {
617
- if (!parts.length) {
618
- return "";
619
- }
620
- if (parts.length === 1) {
621
- return parts[0];
622
- }
623
- if (parts.length === 2) {
624
- return `${parts[0]} และ ${parts[1]}`;
625
- }
626
- return `${parts.slice(0, -1).join(", ")} และ ${parts[parts.length - 1]}`;
627
- }
628
- function combineFrequencyAndEventsThai(frequency, events) {
629
- if (!frequency) {
630
- if (!events.length) {
631
- return {};
632
- }
633
- return { event: joinWithAndThai(events) };
634
- }
635
- if (!events.length) {
636
- return { frequency };
637
- }
638
- if (events.length === 1 && events[0] === "ก่อนนอน") {
639
- if (frequency.includes("วันละ")) {
640
- return { frequency: `${frequency} และ ${events[0]}` };
641
- }
642
- }
643
- return { frequency, event: joinWithAndThai(events) };
644
- }
645
- function isOralRouteThai(internal) {
646
- var _a;
647
- if (internal.routeCode === types_1.RouteCode["Oral route"]) {
648
- return true;
649
- }
650
- const text = (_a = internal.routeText) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase();
651
- if (!text) {
652
- return false;
653
- }
654
- return (text === "po" ||
655
- text === "oral" ||
656
- text.includes("mouth") ||
657
- text.includes("per os"));
658
- }
659
- function buildRoutePhraseThai(internal, grammar, hasSite) {
660
- var _a;
661
- if (grammar.verb === "รับประทาน" && isOralRouteThai(internal)) {
662
- return undefined;
663
- }
664
- if (typeof grammar.routePhrase === "function") {
665
- return grammar.routePhrase({ hasSite, internal });
666
- }
667
- if (typeof grammar.routePhrase === "string") {
668
- return grammar.routePhrase;
669
- }
670
- const text = (_a = internal.routeText) === null || _a === void 0 ? void 0 : _a.trim();
671
- if (!text) {
672
- return undefined;
673
- }
674
- const normalized = text.toLowerCase();
675
- if (normalized.startsWith("by ") || normalized.startsWith("per ") || normalized.startsWith("via ")) {
676
- return text;
677
- }
678
- if (normalized === "oral") {
679
- return "ทางปาก";
680
- }
681
- if (normalized === "intravenous") {
682
- return "เข้าหลอดเลือดดำ";
683
- }
684
- if (normalized === "intramuscular") {
685
- return "เข้ากล้ามเนื้อ";
686
- }
687
- if (normalized === "subcutaneous") {
688
- return "เข้าใต้ผิวหนัง";
689
- }
690
- if (normalized === "topical") {
691
- return "บริเวณผิวหนัง";
692
- }
693
- if (normalized === "transdermal") {
694
- return "แบบแผ่นแปะผิวหนัง";
695
- }
696
- if (normalized === "intranasal" || normalized === "nasal") {
697
- return "ทางจมูก";
698
- }
699
- if (normalized.includes("inhal")) {
700
- return undefined;
701
- }
702
- return text;
703
- }
704
- function formatSiteThai(internal, grammar) {
705
- var _a, _b;
706
- const text = (_a = internal.siteText) === null || _a === void 0 ? void 0 : _a.trim();
707
- if (!text) {
708
- return undefined;
709
- }
710
- const translated = translateSiteThai(text);
711
- const preposition = (_b = grammar.sitePreposition) !== null && _b !== void 0 ? _b : "ที่";
712
- const separator = /^[\u0E00-\u0E7F]/.test(translated) ? "" : " ";
713
- return `${preposition}${separator}${translated}`.trim();
714
- }
715
- function translateSiteThai(site) {
716
- var _a;
717
- const normalized = site.trim().toLowerCase().replace(/\s+/g, " ");
718
- if (!normalized) {
719
- return site;
720
- }
721
- return (_a = exports.THAI_SITE_TRANSLATIONS[normalized]) !== null && _a !== void 0 ? _a : site;
722
- }
723
- function describeDayOfWeekThai(internal) {
724
- if (!internal.dayOfWeek.length) {
725
- return undefined;
726
- }
727
- const days = internal.dayOfWeek
728
- .map((d) => { var _a; return (_a = DAY_NAMES_THAI[d]) !== null && _a !== void 0 ? _a : undefined; })
729
- .filter((d) => Boolean(d));
730
- if (!days.length) {
731
- return undefined;
732
- }
733
- return `ใน${joinWithAndThai(days)}`;
734
- }
735
- function formatAsNeededThai(internal) {
736
- var _a, _b;
737
- if (!internal.asNeeded) {
738
- return undefined;
739
- }
740
- if (internal.asNeededReason) {
741
- const translation = (_b = (_a = internal.asNeededReasonCoding) === null || _a === void 0 ? void 0 : _a.i18n) === null || _b === void 0 ? void 0 : _b.th;
742
- return `ใช้เมื่อจำเป็นสำหรับ ${translation || internal.asNeededReason}`;
743
- }
744
- return "ใช้เมื่อจำเป็น";
745
- }
746
- function formatShortThai(internal) {
747
- var _a;
748
- const parts = [];
749
- const dose = formatDoseThaiShort(internal);
750
- if (dose) {
751
- parts.push(dose);
752
- }
753
- if (internal.routeCode) {
754
- const short = ROUTE_SHORT[internal.routeCode];
755
- if (short) {
756
- parts.push(short);
757
- }
758
- else if (internal.routeText) {
759
- parts.push(internal.routeText);
760
- }
761
- }
762
- else if (internal.routeText) {
763
- parts.push(internal.routeText);
764
- }
765
- const timing = describeFrequencyThai(internal);
766
- if (timing) {
767
- parts.push(timing);
768
- }
769
- else if (internal.timingCode) {
770
- parts.push(internal.timingCode);
771
- }
772
- else if (internal.period && internal.periodUnit) {
773
- const base = stripTrailingZero(internal.period);
774
- const qualifier = internal.periodMax && internal.periodMax !== internal.period
775
- ? `${base}-${stripTrailingZero(internal.periodMax)}`
776
- : base;
777
- parts.push(`Q${qualifier}${internal.periodUnit.toUpperCase()}`);
778
- }
779
- if (internal.when.length) {
780
- const events = collectWhenPhrasesThai(internal);
781
- if (events.length) {
782
- parts.push(events.join(" "));
783
- }
784
- }
785
- if ((_a = internal.timeOfDay) === null || _a === void 0 ? void 0 : _a.length) {
786
- const times = internal.timeOfDay.map((t) => t.slice(0, 5)).join(",");
787
- parts.push(times);
788
- }
789
- if (internal.dayOfWeek.length) {
790
- const days = internal.dayOfWeek
791
- .map((d) => { var _a, _b; return (_b = (_a = DAY_NAMES_THAI[d]) === null || _a === void 0 ? void 0 : _a.replace(/^วัน/, "")) !== null && _b !== void 0 ? _b : d; })
792
- .join(",");
793
- parts.push(days);
794
- }
795
- if (internal.count !== undefined) {
796
- parts.push(`x${stripTrailingZero(internal.count)}`);
797
- }
798
- const asNeeded = formatAsNeededThai(internal);
799
- if (asNeeded) {
800
- parts.push(asNeeded);
801
- }
802
- return parts.filter(Boolean).join(" ");
803
- }
804
- function formatLongThai(internal, options) {
805
- var _a, _b, _c;
806
- const grammar = resolveRouteGrammarThai(internal);
807
- const dosePart = (_a = formatDoseThaiLong(internal)) !== null && _a !== void 0 ? _a : "ยา";
808
- const sitePart = formatSiteThai(internal, grammar);
809
- const routePart = buildRoutePhraseThai(internal, grammar, Boolean(sitePart));
810
- const frequencyPart = (_b = describeFrequencyThai(internal)) !== null && _b !== void 0 ? _b : describeFrequencyCountThai((0, timing_summary_1.inferDailyOccurrenceCount)(internal, options));
811
- const eventParts = collectWhenPhrasesThai(internal, options);
812
- if ((_c = internal.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) {
813
- const timeStrings = [];
814
- for (const time of internal.timeOfDay) {
815
- const parts = time.split(":");
816
- const h = parseInt(parts[0], 10);
817
- const m = parseInt(parts[1], 10);
818
- const displayM = m < 10 ? `0${m}` : `${m}`;
819
- const displayH = h < 10 ? `0${h}` : `${h}`;
820
- timeStrings.push(`${displayH}:${displayM}`);
821
- }
822
- if (timeStrings.length > 0) {
823
- eventParts.push(`เวลา ${timeStrings.join(", ")}`);
824
- }
825
- }
826
- const timing = combineFrequencyAndEventsThai(frequencyPart, eventParts);
827
- const dayPart = describeDayOfWeekThai(internal);
828
- const countPart = internal.count !== undefined
829
- ? `จำนวน ${stripTrailingZero(internal.count)} ครั้ง`
830
- : undefined;
831
- const asNeeded = formatAsNeededThai(internal);
832
- const segments = [dosePart];
833
- if (routePart) {
834
- segments.push(routePart);
835
- }
836
- if (timing.frequency) {
837
- segments.push(timing.frequency);
838
- }
839
- if (timing.event) {
840
- segments.push(timing.event);
841
- }
842
- if (dayPart) {
843
- segments.push(dayPart);
844
- }
845
- if (countPart) {
846
- segments.push(countPart);
847
- }
848
- if (asNeeded) {
849
- segments.push(asNeeded);
850
- }
851
- if (sitePart) {
852
- segments.push(sitePart);
853
- }
854
- const body = segments.filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
855
- if (!body) {
856
- const instructionText = formatAdditionalInstructionsThai(internal);
857
- if (!instructionText) {
858
- return `${grammar.verb}.`;
859
- }
860
- return `${grammar.verb}. ${instructionText}`.trim();
861
- }
862
- const instructionText = formatAdditionalInstructionsThai(internal);
863
- const baseSentence = `${grammar.verb} ${body}.`;
864
- return instructionText ? `${baseSentence} ${instructionText}` : baseSentence;
865
- }
866
- function formatAdditionalInstructionsThai(internal) {
867
- var _a;
868
- if (!((_a = internal.additionalInstructions) === null || _a === void 0 ? void 0 : _a.length)) {
869
- return undefined;
870
- }
871
- const phrases = internal.additionalInstructions
872
- .map((instruction) => {
873
- var _a, _b, _c;
874
- const translation = (_b = (_a = instruction.coding) === null || _a === void 0 ? void 0 : _a.i18n) === null || _b === void 0 ? void 0 : _b.th;
875
- if (translation)
876
- return translation;
877
- const original = instruction.text || ((_c = instruction.coding) === null || _c === void 0 ? void 0 : _c.display);
878
- if (!original)
879
- return undefined;
880
- return original.trim();
881
- })
882
- .filter((text) => Boolean(text))
883
- .map((text) => text.trim())
884
- .filter((text) => text.length > 0);
885
- if (!phrases.length) {
886
- return undefined;
887
- }
888
- return phrases
889
- .map((phrase) => (/[.!?]$/.test(phrase) ? phrase : `${phrase}.`))
890
- .join(" ")
891
- .trim();
892
- }
893
- function stripTrailingZero(value) {
894
- const text = value.toString();
895
- if (text.includes(".")) {
896
- return text.replace(/\.0+$/, "").replace(/0+$/, "");
897
- }
898
- return text;
899
- }