File size: 6,149 Bytes
91111e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// ============================================================
// Unit Conversion Adapter — Chuyển đổi đơn vị đo lường
// Phụ thuộc: currentLang, _adapterPath
// ============================================================

var CONVERSION_FACTORS = {
    length: { m: 1, km: 1000, cm: 0.01, mm: 0.001, mile: 1609.344, yard: 0.9144, foot: 0.3048, inch: 0.0254 },
    mass: { kg: 1, g: 0.001, mg: 0.000001, pound: 0.453592, ounce: 0.0283495 }
};

var TEMPERATURE_UNITS = {
    celsius: 'celsius', c: 'celsius',
    fahrenheit: 'fahrenheit', f: 'fahrenheit',
    kelvin: 'kelvin', k: 'kelvin'
};

function convertTemperature(value, from, to) {
    if (from === to) return value;
    var celsius;
    if (from === 'celsius') celsius = value;
    else if (from === 'fahrenheit') celsius = (value - 32) * 5 / 9;
    else celsius = value - 273.15;

    if (to === 'celsius') return celsius;
    if (to === 'fahrenheit') return (celsius * 9 / 5) + 32;
    return celsius + 273.15;
}

function convertUnit(value, fromUnit, toUnit) {
    var from = String(fromUnit).toLowerCase().trim();
    var to = String(toUnit).toLowerCase().trim();
    if (from === to) return value;

    var fromTemp = TEMPERATURE_UNITS[from];
    var toTemp = TEMPERATURE_UNITS[to];
    if (fromTemp && toTemp) return convertTemperature(value, fromTemp, toTemp);
    if (fromTemp || toTemp) return null;

    var categories = Object.keys(CONVERSION_FACTORS);
    for (var i = 0; i < categories.length; i++) {
        var factors = CONVERSION_FACTORS[categories[i]];
        if (factors[from] !== undefined && factors[to] !== undefined) {
            return value * (factors[from] / factors[to]);
        }
    }
    return null;
}

function parseConversionRequest(input, lang) {
    if (typeof input !== 'string' || input.trim().length === 0) return null;
    var text = input.trim();

    var separators;
    if (lang === 'ja') separators = ['に変換', 'は何', 'を'];
    else if (lang === 'en') separators = ['convert', ' to ', ' in '];
    else separators = [' sang ', ' ra '];

    for (var i = 0; i < separators.length; i++) {
        var sep = separators[i];
        var idx = text.toLowerCase().indexOf(sep.toLowerCase());
        if (idx === -1) continue;

        var leftPart = text.substring(0, idx).trim();
        var rightPart = text.substring(idx + sep.length).trim();
        if (leftPart.length === 0 || rightPart.length === 0) continue;

        var leftMatch = leftPart.match(/(-?\d+(?:\.\d+)?)\s*(.+)/);
        if (!leftMatch) continue;

        var value = parseFloat(leftMatch[1]);
        var fromUnit = leftMatch[2].trim().toLowerCase();
        var toUnit = rightPart.trim().toLowerCase();
        if (isNaN(value)) continue;

        return { value: value, from: fromUnit, to: toUnit };
    }
    return null;
}

function getSupportedUnits() {
    var units = [];
    var categories = Object.keys(CONVERSION_FACTORS);
    for (var i = 0; i < categories.length; i++) {
        units = units.concat(Object.keys(CONVERSION_FACTORS[categories[i]]));
    }
    units = units.concat(['celsius', 'fahrenheit', 'kelvin', 'c', 'f', 'k']);
    return units.join(', ');
}

function unitConversionAdapter(rs, args) {
    _adapterPath.push('unit_conversion');
    var input = (args || []).join(' ').trim();
    var lang = currentLang || 'vi';

    if (input.length === 0) {
        if (lang === 'en') return 'Please provide a conversion request (e.g., "5 km to m").';
        if (lang === 'ja') return '変換リクエストを入力してください(例: 「5 km を m」)。';
        return 'Vui lòng nhập yêu cầu chuyển đổi (ví dụ: "5 km sang m").';
    }

    var parsed = parseConversionRequest(input, lang);
    if (!parsed) {
        if (lang === 'en') return 'Invalid syntax. Example: "5 km to m", "100 fahrenheit to celsius".';
        if (lang === 'ja') return '構文が無効です。例: 「5 km を m」、「100 fahrenheit を celsius」。';
        return 'Cú pháp không hợp lệ. Ví dụ: "5 km sang m", "100 fahrenheit sang celsius".';
    }

    var allUnits = {};
    var categories = Object.keys(CONVERSION_FACTORS);
    for (var i = 0; i < categories.length; i++) {
        var catUnits = Object.keys(CONVERSION_FACTORS[categories[i]]);
        for (var j = 0; j < catUnits.length; j++) allUnits[catUnits[j]] = true;
    }
    var tempKeys = Object.keys(TEMPERATURE_UNITS);
    for (var t = 0; t < tempKeys.length; t++) allUnits[tempKeys[t]] = true;

    if (!allUnits[parsed.from.toLowerCase()] || !allUnits[parsed.to.toLowerCase()]) {
        var supported = getSupportedUnits();
        if (lang === 'en') return 'Unsupported unit. Supported units: ' + supported;
        if (lang === 'ja') return 'サポートされていない単位です。対応単位: ' + supported;
        return 'Đơn vị không được hỗ trợ. Các đơn vị hỗ trợ: ' + supported;
    }

    var result = convertUnit(parsed.value, parsed.from.toLowerCase(), parsed.to.toLowerCase());
    if (result === null) {
        var supported2 = getSupportedUnits();
        if (lang === 'en') return 'Cannot convert between incompatible units. Supported units: ' + supported2;
        if (lang === 'ja') return '互換性のない単位間の変換はできません。対応単位: ' + supported2;
        return 'Không thể chuyển đổi giữa các đơn vị không tương thích. Các đơn vị hỗ trợ: ' + supported2;
    }

    var resultStr = Number.isInteger(result) ? String(result) : result.toFixed(4).replace(/\.?0+$/, '');
    return parsed.value + ' ' + parsed.from + ' = ' + resultStr + ' ' + parsed.to;
}

// Node/test: export to globalThis
if (typeof module !== 'undefined' && module.exports) {
    globalThis.CONVERSION_FACTORS = CONVERSION_FACTORS;
    globalThis.TEMPERATURE_UNITS = TEMPERATURE_UNITS;
    globalThis.convertTemperature = convertTemperature;
    globalThis.convertUnit = convertUnit;
    globalThis.parseConversionRequest = parseConversionRequest;
    globalThis.getSupportedUnits = getSupportedUnits;
    globalThis.unitConversionAdapter = unitConversionAdapter;
}