Spaces:
Running
Running
| // ============================================================ | |
| // 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; | |
| } | |