You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

859 lines
29 KiB

import { __awaiter, __generator } from 'tslib';
import { request as request$2 } from 'http';
import { request as request$1 } from 'https';
import { parse } from 'url';
import { stringify } from 'querystring';
import { createHash } from 'crypto';
/** 反转对象 */
function invert (obj) {
var result = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
result[obj[key]] = key;
}
}
return result;
}
var root = 'https://fanyi.baidu.com';
// 写死一个 Cookie 供 Node.js 端使用;浏览器端自带这个 Cookie 所以无需处理
var Cookie = 'BAIDUID=0F8E1A72A51EE47B7CA0A81711749C00:FG=1;';
/**
* 百度支持的语种到百度自定义的语种名的映射,去掉了文言文。
* @see http://api.fanyi.baidu.com/api/trans/product/apidoc#languageList
*/
var standard2custom = {
en: 'en',
th: 'th',
ru: 'ru',
pt: 'pt',
el: 'el',
nl: 'nl',
pl: 'pl',
bg: 'bul',
et: 'est',
da: 'dan',
fi: 'fin',
cs: 'cs',
ro: 'rom',
sl: 'slo',
sv: 'swe',
hu: 'hu',
de: 'de',
it: 'it',
'zh-CN': 'zh',
'zh-TW': 'cht',
// 'zh-HK': 'yue',
ja: 'jp',
ko: 'kor',
es: 'spa',
fr: 'fra',
ar: 'ara'
};
/** 百度自定义的语种名到标准语种名的映射 */
var custom2standard = invert(standard2custom);
/**
* 安全的获取一个变量上指定路径的值。
* TODO: 使用 noshjs 代替
*/
function getValue (obj, pathArray, defaultValue) {
if (obj == null)
return defaultValue;
if (typeof pathArray === 'string') {
pathArray = [pathArray];
}
var value = obj;
for (var i = 0; i < pathArray.length; i += 1) {
var key = pathArray[i];
value = value[key];
if (value == null) {
return defaultValue;
}
}
return value;
}
function getError (code, msg) {
var e = new Error(msg);
e.code = code;
return e;
}
function request (options) {
var _a = options.method, method = _a === void 0 ? 'get' : _a;
var urlObj = parse(options.url, true);
var qs = stringify(Object.assign(urlObj.query, options.query));
var headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
};
var body;
if (method === 'post') {
switch (options.type) {
case 'form':
headers['Content-Type'] =
'application/x-www-form-urlencoded; charset=UTF-8';
body = stringify(options.body);
break;
case 'json':
default:
headers['Content-Type'] = 'application/json; charset=UTF-8';
body = JSON.stringify(options.body);
break;
}
headers['Content-Length'] = String(Buffer.byteLength(body));
}
Object.assign(headers, options.headers);
var httpOptions = {
hostname: urlObj.hostname,
method: method,
path: urlObj.pathname + '?' + qs,
headers: headers,
auth: urlObj.auth,
timeout: options.timeout || 5000
};
var responseType = options.responseType || 'json';
return new Promise(function (resolve, reject) {
var req = (urlObj.protocol === 'https:' ? request$1 : request$2)(httpOptions, function (res) {
// 内置的翻译接口都以 200 作为响应码,所以不是 200 的一律视为错误
if (res.statusCode !== 200) {
reject(getError("API_SERVER_ERROR" /* API_SERVER_ERROR */));
return;
}
res.setEncoding('utf8');
var rawData = '';
res.on('data', function (chunk) {
rawData += chunk;
});
res.on('end', function () {
// Node.js 端只支持 json,其余都作为 text 处理
if (responseType === 'json') {
try {
resolve(JSON.parse(rawData));
}
catch (e) {
// 与浏览器端保持一致,在无法解析成 json 时报错
reject(getError("API_SERVER_ERROR" /* API_SERVER_ERROR */));
}
}
else {
resolve(rawData);
}
});
});
req.on('timeout', function () {
req.abort();
reject(getError("NETWORK_TIMEOUT" /* NETWORK_TIMEOUT */, '查询超时'));
});
req.on('error', function (e) {
reject(getError("NETWORK_ERROR" /* NETWORK_ERROR */, e.message));
});
req.end(body);
});
}
// tslint:disable
var C = null;
/**
* 从百度网页翻译中复制过来的计算签名的代码
* @param text 要查询的文本
* @param seed 从 ./seed.ts 获取到的 seed
*/
function sign (text, seed) {
var o = text.length;
o > 30 &&
(text =
'' +
text.substr(0, 10) +
text.substr(Math.floor(o / 2) - 5, 10) +
text.substr(-10, 10));
var t = null !== C ? C : (C = seed || '') || '';
for (var e = t.split('.'), h = Number(e[0]) || 0, i = Number(e[1]) || 0, d = [], f = 0, g = 0; g < text.length; g++) {
var m = text.charCodeAt(g);
128 > m
? (d[f++] = m)
: (2048 > m
? (d[f++] = (m >> 6) | 192)
: (55296 === (64512 & m) &&
g + 1 < text.length &&
56320 === (64512 & text.charCodeAt(g + 1))
? ((m =
65536 + ((1023 & m) << 10) + (1023 & text.charCodeAt(++g))),
(d[f++] = (m >> 18) | 240),
(d[f++] = ((m >> 12) & 63) | 128))
: (d[f++] = (m >> 12) | 224),
(d[f++] = ((m >> 6) & 63) | 128)),
(d[f++] = (63 & m) | 128));
}
for (var S = h, u = '+-a^+6', l = '+-3^+b+-f', s = 0; s < d.length; s++)
(S += d[s]), (S = a(S, u));
return ((S = a(S, l)),
(S ^= i),
0 > S && (S = (2147483647 & S) + 2147483648),
(S %= 1e6),
S.toString() + '.' + (S ^ h));
}
function a(r, o) {
for (var t = 0; t < o.length - 2; t += 3) {
var a = o.charAt(t + 2);
(a = a >= 'a' ? a.charCodeAt(0) - 87 : Number(a)),
(a = '+' === o.charAt(t + 1) ? r >>> a : r << a),
(r = '+' === o.charAt(t) ? (r + a) & 4294967295 : r ^ a);
}
return r;
}
var seedReg = /window\.gtk\s=\s'([^']+)';/;
var tokenReg = /token:\s'([^']+)'/;
var headers = {
// 鸡贼的百度,需要带上 BAIDUUID 才会返回正确的 token;请求接口时也需要带上相同的 Cookie。
// 在浏览器端应该不需要做额外设置,因为浏览器会自动保存 cookie,然后请求接口时自动带上。
// 换了一个 IP 地址后也能用相同的 Cookie 请求,不过不清楚过期了是否还能继续用。
Cookie: Cookie
}
;
function getSeed () {
return __awaiter(this, void 0, void 0, function () {
var html, seed, token;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, request({
url: 'https://fanyi.baidu.com',
headers: headers,
responseType: 'text'
})];
case 1:
html = _a.sent();
seed = html.match(seedReg);
if (seed) {
token = html.match(tokenReg);
if (token) {
return [2 /*return*/, {
seed: seed[1],
token: token[1]
}];
}
}
// 如果不能正确解析出 seed 和 token,则视为服务器错误
throw getError("API_SERVER_ERROR" /* API_SERVER_ERROR */);
}
});
});
}
/**
* 获取查询百度网页翻译接口所需的 token 和 sign
* @param text 要查询的文本
*/
function sign$1 (text) {
return __awaiter(this, void 0, void 0, function () {
var _a, seed, token;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, getSeed()];
case 1:
_a = _b.sent(), seed = _a.seed, token = _a.token;
return [2 /*return*/, {
token: token,
sign: sign(text, seed)
}];
}
});
});
}
function detect (options) {
return __awaiter(this, void 0, void 0, function () {
var query, body, iso689lang;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
query = (typeof options === 'string' ? options : options.text).slice(0, 73);
return [4 /*yield*/, request({
method: 'post',
url: root + '/langdetect',
body: {
query: query
},
type: 'form'
})];
case 1:
body = _a.sent();
if (body.error === 0) {
iso689lang = custom2standard[body.lan];
if (iso689lang)
return [2 /*return*/, iso689lang];
}
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
}
});
});
}
/**
* 生成百度语音地址
* @param text 要朗读的文本
* @param lang 文本的语种,使用百度自定义的语种名称
*/
function getAudioURI(text, lang) {
return (root +
("/gettts?lan=" + lang + "&text=" + encodeURIComponent(text) + "&spd=3&source=web"));
}
/**
* 获取指定文本的网络语音地址
*/
function audio (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, from, lang;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.from, from = _b === void 0 ? undefined : _b;
if (!!from) return [3 /*break*/, 2];
return [4 /*yield*/, detect(text)];
case 1:
from = _c.sent();
_c.label = 2;
case 2:
if (from === 'en-GB') {
lang = 'uk';
}
else {
lang = standard2custom[from];
if (!lang)
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
}
return [2 /*return*/, getAudioURI(text, lang)];
}
});
});
}
var headers$1 = {
'X-Requested-With': 'XMLHttpRequest',
Cookie: Cookie
}
;
function translate (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, _b, from, _c, to, text, customFromLang, customToLang, _d, _e, _f, _g, _h, _j, _k;
return __generator(this, function (_l) {
switch (_l.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, _b = _a.from, from = _b === void 0 ? undefined : _b, _c = _a.to, to = _c === void 0 ? undefined : _c, text = _a.text;
if (!!from) return [3 /*break*/, 2];
return [4 /*yield*/, detect(text)];
case 1:
from = _l.sent();
_l.label = 2;
case 2:
if (!to) {
to = from.startsWith('zh') ? 'en' : 'zh-CN';
}
customFromLang = standard2custom[from];
customToLang = standard2custom[to];
if (!customFromLang || !customToLang) {
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
}
_d = transformRaw;
_e = [text];
_f = request;
_g = {
url: root + '/v2transapi',
type: 'form',
method: 'post'
};
_j = (_h = Object).assign;
_k = [{
from: customFromLang,
to: customToLang,
query: text,
transtype: 'translang',
simple_means_flag: 3
}];
return [4 /*yield*/, sign$1(text)];
case 3: return [4 /*yield*/, _f.apply(void 0, [(_g.body = _j.apply(_h, _k.concat([_l.sent()])),
_g.headers = headers$1,
_g)])];
case 4: return [2 /*return*/, _d.apply(void 0, _e.concat([_l.sent()]))];
}
});
});
}
function transformRaw(text, body) {
var transResult = body.trans_result;
var customFrom = getValue(transResult, 'from');
var customTo = getValue(transResult, 'to');
var result = {
text: text,
raw: body,
link: root + ("/#" + customFrom + "/" + customTo + "/" + encodeURIComponent(text)),
from: custom2standard[customFrom],
to: custom2standard[customTo]
};
var symbols = getValue(body, [
'dict_result',
'simple_means',
'symbols',
'0'
]);
if (symbols) {
// 解析音标
var phonetic = [];
var ph_am = symbols.ph_am, ph_en = symbols.ph_en;
if (ph_am) {
phonetic.push({
name: '美',
ttsURI: getAudioURI(text, 'en'),
value: ph_am
});
}
if (ph_en) {
phonetic.push({
name: '英',
ttsURI: getAudioURI(text, 'en-GB'),
value: ph_en
});
}
if (phonetic.length) {
result.phonetic = phonetic;
}
// 解析词典数据
try {
result.dict = symbols.parts.map(function (part) {
return (part.part ? part.part + ' ' : '') + part.means.join(';');
});
}
catch (e) { }
}
// 解析普通的翻译结果
try {
result.result = transResult.data.map(function (d) { return d.dst; });
}
catch (e) { }
if (!result.dict && !result.result) {
throw getError("API_SERVER_ERROR" /* API_SERVER_ERROR */);
}
return result;
}
var index = /*#__PURE__*/Object.freeze({
__proto__: null,
translate: translate,
detect: detect,
audio: audio
});
function getRoot(com) {
return 'https://translate.google.c' + (com ? 'om' : 'n');
}
var window = {
TKK: '0'
};
var yr = null;
var xr = function(a, b) {
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = 'a' <= d ? d.charCodeAt(0) - 87 : Number(d),
d = '+' == b.charAt(c + 1) ? a >>> d : a << d;
a = '+' == b.charAt(c) ? (a + d) & 4294967295 : a ^ d;
}
return a
};
function sM(a) {
var b;
if (null !== yr) {
b = yr;
} else {
b = (yr = window.TKK || '') || '';
}
var d = b.split('.');
b = Number(d[0]) || 0;
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var l = a.charCodeAt(g);
128 > l
? (e[f++] = l)
: (2048 > l
? (e[f++] = (l >> 6) | 192)
: (55296 == (l & 64512) &&
g + 1 < a.length &&
56320 == (a.charCodeAt(g + 1) & 64512)
? ((l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023)),
(e[f++] = (l >> 18) | 240),
(e[f++] = ((l >> 12) & 63) | 128))
: (e[f++] = (l >> 12) | 224),
(e[f++] = ((l >> 6) & 63) | 128)),
(e[f++] = (l & 63) | 128));
}
a = b;
for (f = 0; f < e.length; f++) (a += e[f]), (a = xr(a, '+-a^+6'));
a = xr(a, '+-3^+b+-f');
a ^= Number(d[1]) || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1e6;
return a.toString() + '.' + (a ^ b)
}
/**
* 代码来自 https://github.com/matheuss/google-translate-token
* 做了一些修改以适应本项目
*/
function updateTKK(com) {
return __awaiter(this, void 0, void 0, function () {
var now, html, code;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
now = Math.floor(Date.now() / 3600000);
if (Number(window.TKK.split('.')[0]) === now) {
return [2 /*return*/];
}
return [4 /*yield*/, request({
url: getRoot(com),
responseType: 'text'
})];
case 1:
html = _a.sent();
code = html.match(/tkk:'(\d+\.\d+)'/);
if (code) {
window.TKK = code[1];
}
return [2 /*return*/];
}
});
});
}
function sign$2 (text, com) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, updateTKK(com)];
case 1:
_a.sent();
return [2 /*return*/, sM(text)];
}
});
});
}
function detect$1 (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, com, result, _c, _d, _e, src;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.com, com = _b === void 0 ? false : _b;
_c = request;
_d = {
url: getRoot(com) + '/translate_a/single'
};
_e = {
client: 'webapp',
sl: 'auto',
tl: 'zh-CN',
hl: 'zh-CN',
ssel: '3',
tsel: '0',
kc: '0'
};
return [4 /*yield*/, sign$2(text, com)];
case 1: return [4 /*yield*/, _c.apply(void 0, [(_d.query = (_e.tk = _f.sent(),
_e.q = text,
_e),
_d)])];
case 2:
result = _f.sent();
src = result && result[2];
if (src)
return [2 /*return*/, src];
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
}
});
});
}
function audio$1 (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, from, _c, com, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.from, from = _b === void 0 ? '' : _b, _c = _a.com, com = _c === void 0 ? false : _c;
if (!!from) return [3 /*break*/, 2];
return [4 /*yield*/, detect$1(text)];
case 1:
from = _e.sent();
_e.label = 2;
case 2:
_d = getRoot(com) + "/translate_tts?ie=UTF-8&q=" + encodeURIComponent(text) + "&tl=" + from + "&total=1&idx=0&textlen=" + text.length + "&tk=";
return [4 /*yield*/, sign$2(text, com)];
case 3: return [2 /*return*/, _d + (_e.sent()) + "&client=webapp&prev=input"];
}
});
});
}
function translate$1 (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, com, _c, from, _d, to, _e, _f, _g, _h;
return __generator(this, function (_j) {
switch (_j.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.com, com = _b === void 0 ? false : _b, _c = _a.from, from = _c === void 0 ? '' : _c, _d = _a.to, to = _d === void 0 ? '' : _d;
if (!!from) return [3 /*break*/, 2];
return [4 /*yield*/, detect$1(options)];
case 1:
from = _j.sent();
_j.label = 2;
case 2:
if (!to) {
to = from.startsWith('zh') ? 'en' : 'zh-CN';
}
_e = transformRaw$1;
_f = request;
_g = {
url: getRoot(com) + '/translate_a/single'
};
_h = {
client: 'webapp',
sl: from,
tl: to,
hl: 'zh-CN',
dt: ['at', 'bd', 'ex', 'ld', 'md', 'qca', 'rw', 'rm', 'ss', 't'],
otf: '2',
ssel: '3',
tsel: '0',
kc: '6'
};
return [4 /*yield*/, sign$2(text, com)];
case 3: return [4 /*yield*/, _f.apply(void 0, [(_g.query = (_h.tk = _j.sent(),
_h.q = text,
_h),
_g)])];
case 4: return [2 /*return*/, _e.apply(void 0, [_j.sent(),
{
from: from,
to: to,
com: com,
text: text
}])];
}
});
});
}
function transformRaw$1(body, queryObj) {
var text = queryObj.text, com = queryObj.com, to = queryObj.to;
var googleFrom = body[2];
var result = {
text: text,
raw: body,
from: googleFrom,
to: to,
link: getRoot(com) + "/#view=home&op=translate&sl=" + googleFrom + "&tl=" + to + "&text=" + encodeURIComponent(text)
};
try {
result.dict = body[1].map(function (arr) {
return arr[0] + ':' + arr[1].join(',');
});
}
catch (e) { }
try {
result.result = body[0]
.map(function (arr) { return arr[0]; })
.filter(function (x) { return x; })
.map(function (x) { return x.trim(); });
}
catch (e) { }
return result;
}
var index$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
detect: detect$1,
audio: audio$1,
translate: translate$1
});
function md5 (text) {
return createHash('md5')
.update(text)
.digest('hex');
}
var client = 'fanyideskweb';
var navigatorAppVersion = '5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
;
var bv = md5(navigatorAppVersion);
/**
* 有道翻译接口的签名算法
* @param text
*/
function sign$3 (text) {
var ts = Date.now() + '';
var salt = ts + parseInt(10 * Math.random() + '', 10);
return {
client: client,
ts: ts,
bv: bv,
salt: salt,
sign: md5(client + text + salt + 'mmbP%A-r6U3Nw(n]BjuEU')
};
}
var standard2custom$1 = {
en: 'en',
ru: 'ru',
pt: 'pt',
es: 'es',
'zh-CN': 'zh-CHS',
ja: 'ja',
ko: 'ko',
fr: 'fr'
};
var custom2standard$1 = invert(standard2custom$1);
var link = 'http://fanyi.youdao.com';
var translateAPI = link + '/translate_o?smartresult=dict&smartresult=rule';
// 有道跟百度一样,通过添加一个 Cookie 鉴别请求是否来自网页
var headers$2 = { Referer: link, Cookie: 'OUTFOX_SEARCH_USER_ID=-1799202939@10.168.8.64' }
;
function webAPI (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, from, _c, to, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.from, from = _b === void 0 ? '' : _b, _c = _a.to, to = _c === void 0 ? '' : _c;
text = text.slice(0, 5000);
if (from) {
from = standard2custom$1[from];
}
else {
from = 'AUTO';
}
if (to) {
to = standard2custom$1[to];
}
else {
to = 'AUTO';
}
// 有道网页翻译的接口的语种与目标语种中必须有一个是中文,或者两个都是 AUTO
if (!((from === 'AUTO' && to === 'AUTO') ||
(from === 'zh-CHS' || to === 'zh-CHS'))) {
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
}
_d = transformRaw$2;
return [4 /*yield*/, request({
method: 'post',
url: translateAPI,
type: 'form',
body: Object.assign({
i: text,
from: from,
to: to,
smartresult: 'dict',
doctype: 'json',
version: '2.1',
keyfrom: 'fanyi.web',
action: 'FY_BY_REALTIME',
typoResult: 'false'
}, sign$3(text)),
headers: headers$2
})];
case 1: return [2 /*return*/, _d.apply(void 0, [_e.sent(),
text])];
}
});
});
}
function transformRaw$2(body, text) {
if (body.errorCode !== 0) {
throw getError("API_SERVER_ERROR" /* API_SERVER_ERROR */);
}
var _a = body.type.split('2'), from = _a[0], to = _a[1];
from = custom2standard$1[from];
to = custom2standard$1[to];
var smartResult = body.smartResult;
var result = {
raw: body,
text: text,
from: from,
to: to,
link: smartResult
? "https://dict.youdao.com/search?q=" + encodeURIComponent(text) + "&keyfrom=fanyi.smartResult"
: "http://fanyi.youdao.com/translate?i=" + encodeURIComponent(text)
};
if (smartResult) {
try {
result.dict = smartResult.entries.filter(function (s) { return s; }).map(function (s) { return s.trim(); });
}
catch (e) { }
}
try {
result.result = body.translateResult.map(function (part) {
return part.map(function (o) { return o.tgt.trim(); }).join('');
});
}
catch (e) { }
return result;
}
function detect$2 (options) {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, webAPI(typeof options === 'string' ? options : options.text)];
case 1:
result = _a.sent();
return [2 /*return*/, result.from];
}
});
});
}
var standard2custom$2 = {
en: 'eng',
ja: 'jap',
ko: 'ko',
fr: 'fr'
};
function audio$2 (options) {
return __awaiter(this, void 0, void 0, function () {
var _a, text, _b, from, voiceLang;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a = typeof options === 'string' ? { text: options } : options, text = _a.text, _b = _a.from, from = _b === void 0 ? '' : _b;
if (!!from) return [3 /*break*/, 2];
return [4 /*yield*/, detect$2(text)];
case 1:
from = _c.sent();
_c.label = 2;
case 2:
voiceLang = standard2custom$2[from];
if (!voiceLang)
throw getError("UNSUPPORTED_LANG" /* UNSUPPORTED_LANG */);
return [2 /*return*/, "http://tts.youdao.com/fanyivoice?word=" + encodeURIComponent(text) + "&le=" + voiceLang + "&keyfrom=speaker-target"];
}
});
});
}
var index$2 = /*#__PURE__*/Object.freeze({
__proto__: null,
detect: detect$2,
audio: audio$2,
translate: webAPI
});
export { index as baidu, index$1 as google, index$2 as youdao };