JWT Autorization / Logging in and registering

This commit is contained in:
2020-07-19 14:35:51 +02:00
parent a267dd1f37
commit 9f4f5347d4
279 changed files with 23396 additions and 33 deletions

3
node_modules/translate/.babelrc generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"presets": ["env"]
}

2
node_modules/translate/.env.example generated vendored Normal file
View File

@@ -0,0 +1,2 @@
GOOGLE_KEY=ABCD
YANDEX_KEY=EFGH

1
node_modules/translate/.github/FUNDING.yml generated vendored Normal file
View File

@@ -0,0 +1 @@
custom: https://www.paypal.me/franciscopresencia/19

21
node_modules/translate/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

158
node_modules/translate/README.md generated vendored Normal file
View File

@@ -0,0 +1,158 @@
# Translate
Convert text to different languages on Node.js and the browser. Flexible package and powerful back-end using Google (default) or Yandex:
```js
// async/await. Options can be a language name (ISO 639)
const text = await translate('Hello world', 'es');
console.log(text); // Hola mundo
// Promises with .then(). Options can also be an object
translate('こんにちは世界', { from: 'ja', to: 'es' }).then(text => {
console.log(text); // Hola mundo
});
```
## Getting started
This package can be used in Node.js and on the browser. For the browser we are using `fetch`, so you might want to [polyfill it](https://polyfill.io/v2/docs/) depending on [the browsers you support](https://caniuse.com/#feat=fetch).
To use it in `node.js` first install it:
```bash
npm install translate
```
Then import it to use it:
```js
const translate = require('translate'); // Old school
import translate from 'translate'; // New wave
```
To use it in the browser download the main `translate.min.js` file and include it:
```html
<script src="translate.min.js"></script>
```
Or use the awesome [Jsdelivr **CDN**](https://www.jsdelivr.com/package/npm/translate):
```html
<script src="https://cdn.jsdelivr.net/npm/translate@1/translate.min.js"></script>
```
After including translate the usage is similar for both Node.js and the browser.
## Options
The first parameter is the **string** that you want to translate. Right now only a single string of text is accepted.
The second parameter is the options. It accepts either a `String` of the language to translate **to** or a simple `Object` with these options:
- **`to`**: the string of the language to translate to. It can be in any of the two ISO 639 (1 or 2) or the full name in English like `Spanish`. Defaults to **en**.
- **`from`**: the string of the language to translate to. It can be in any of the two ISO 639 (1 or 2) or the full name in English like `Spanish`. Also defaults to **en**.
- **`cache`**: a `Number` with the milliseconds that each translation should be cached. Leave it undefined to cache it indefinitely (until a server/browser restart).
- **`engine`**: a `String` containing the name of the engine to use for translation. Right now it defaults to `google`. Read more [in the engine section](#engines).
- **`key`**: the API Key for the engine of your choice. Read more [in the engine section](#engines).
Examples:
```js
// Translate from English (default) to Spanish (specified)
const foo = await translate('Hello world', 'es');
// Same as this:
const bar = await translate('Hello world', { to: 'es' });
```
> On both `to` and `from` defaulting to `en`: while I _am_ Spanish and was quite tempted to set this as one of those, English is the main language of the Internet and the main secondary language for those who have a different native language. This is why most of the translations will happen either to or from English.
### Default options
You can change the default options for anything by calling the root library and the option name:
```js
translate.from = 'es';
```
This can be applied to any of the options enumerated above.
## Engines
Several translating engines are available to translate your text:
- **`google`**: ([demo](https://translate.google.com/) | [docs](https://cloud.google.com/translate/docs/)): Google Translate.
- **`yandex`**: ([demo](https://translate.yandex.com/) | [docs](https://tech.yandex.com/translate/) | [API Key](https://translate.yandex.com/developers/keys)): Yandex Translate
> To get the API Key you will be signing some contract with these services; it's your responsibility to follow these and we are not liable if you don't as explained in our MIT License.
Once you get the API key and if you are only going to be using one engine (very likely), we recommend setting this globally for your whole project:
```js
// ... include translate
translate.engine = 'google';
translate.key = 'YOUR-KEY-HERE';
// ... use translate()
```
If you are in Node.js, this likely comes from an environment variable:
```js
// ... include translate
translate.engine = 'google';
translate.key = process.env.TRANSLATE_KEY;
// ... use translate()
```
To pass it per-translation, you can add it to your arguments:
```js
translate('Hello world', { to: 'en', engine: 'google', key: 'YOUR-KEY-HERE' });
```
## Promises
Working with Promises and specially with [async/await](https://ponyfoo.com/articles/understanding-javascript-async-await) reduces [Callback Hell](http://callbackhell.com/). To see it in action, first you'll need an `async` function. Then put your `await` calls inside:
```js
// Browser; jQuery for demonstration purposes
$('#translate').submit(async e => {
e.preventDefault();
const text = $('.text').text();
const spanish = await translate(text, { to: 'es' });
alert(spanish);
});
// Node.js; serverjs.io example for demonstration purposes
const route = async ctx => {
const spanish = await translate(ctx.body, { to: 'es' });
return send(spanish);
};
```
## Authors and thanks
Current package and development: [Francisco Presencia](https://francisco.io/)
Original package and idea: Andrew Lunny (alunny), Marak Squires, Google
Testing in Internet Explorer supported by BrowserStack:
[![BrowserStack logo](https://i.imgur.com/CuCuOkL.png)](https://browserstack.com/)

17
node_modules/translate/data/iso.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
export default [
"aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "ba",
"be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce", "ch", "co",
"cr", "cs", "cu", "cv", "cy", "da", "de", "dv", "dz", "ee", "el", "en", "eo",
"es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr", "fy", "ga", "gd", "gl",
"gn", "gu", "gv", "ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz", "ia",
"id", "ie", "ig", "ii", "ik", "io", "is", "it", "iu", "ja", "jv", "ka", "kg",
"ki", "kj", "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky",
"la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk",
"ml", "mn", "mr", "ms", "mt", "my", "na", "nb", "nd", "ne", "ng", "nl", "nn",
"no", "nr", "nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl", "ps",
"pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si",
"sk", "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta",
"te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty",
"ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh", "yi", "yo", "za",
"zh", "zu"
];

33
node_modules/translate/data/iso2.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
export default {
"aar": "aa", "abk": "ab", "afr": "af", "aka": "ak", "alb": "sq", "amh": "am",
"ara": "ar", "arg": "an", "arm": "hy", "asm": "as", "ava": "av", "ave": "ae",
"aym": "ay", "aze": "az", "bak": "ba", "bam": "bm", "baq": "eu", "bel": "be",
"ben": "bn", "bih": "bh", "bis": "bi", "bos": "bs", "bre": "br", "bul": "bg",
"bur": "my", "cat": "ca", "cha": "ch", "che": "ce", "chi": "zh", "chu": "cu",
"chv": "cv", "cor": "kw", "cos": "co", "cre": "cr", "cze": "cs", "dan": "da",
"div": "dv", "dut": "nl", "dzo": "dz", "eng": "en", "epo": "eo", "est": "et",
"ewe": "ee", "fao": "fo", "fij": "fj", "fin": "fi", "fre": "fr", "fry": "fy",
"ful": "ff", "geo": "ka", "ger": "de", "gla": "gd", "gle": "ga", "glg": "gl",
"glv": "gv", "gre": "el", "grn": "gn", "guj": "gu", "hat": "ht", "hau": "ha",
"heb": "he", "her": "hz", "hin": "hi", "hmo": "ho", "hrv": "hr", "hun": "hu",
"ibo": "ig", "ice": "is", "ido": "io", "iii": "ii", "iku": "iu", "ile": "ie",
"ina": "ia", "ind": "id", "ipk": "ik", "ita": "it", "jav": "jv", "jpn": "ja",
"kal": "kl", "kan": "kn", "kas": "ks", "kau": "kr", "kaz": "kk", "khm": "km",
"kik": "ki", "kin": "rw", "kir": "ky", "kom": "kv", "kon": "kg", "kor": "ko",
"kua": "kj", "kur": "ku", "lao": "lo", "lat": "la", "lav": "lv", "lim": "li",
"lin": "ln", "lit": "lt", "ltz": "lb", "lub": "lu", "lug": "lg", "mac": "mk",
"mah": "mh", "mal": "ml", "mao": "mi", "mar": "mr", "may": "ms", "mlg": "mg",
"mlt": "mt", "mon": "mn", "nau": "na", "nav": "nv", "nbl": "nr", "nde": "nd",
"ndo": "ng", "nep": "ne", "nno": "nn", "nob": "nb", "nor": "no", "nya": "ny",
"oci": "oc", "oji": "oj", "ori": "or", "orm": "om", "oss": "os", "pan": "pa",
"per": "fa", "pli": "pi", "pol": "pl", "por": "pt", "pus": "ps", "que": "qu",
"roh": "rm", "rum": "ro", "run": "rn", "rus": "ru", "sag": "sg", "san": "sa",
"sin": "si", "slo": "sk", "slv": "sl", "sme": "se", "smo": "sm", "sna": "sn",
"snd": "sd", "som": "so", "sot": "st", "spa": "es", "srd": "sc", "srp": "sr",
"ssw": "ss", "sun": "su", "swa": "sw", "swe": "sv", "tah": "ty", "tam": "ta",
"tat": "tt", "tel": "te", "tgk": "tg", "tgl": "tl", "tha": "th", "tib": "bo",
"tir": "ti", "ton": "to", "tsn": "tn", "tso": "ts", "tuk": "tk", "tur": "tr",
"twi": "tw", "uig": "ug", "ukr": "uk", "urd": "ur", "uzb": "uz", "ven": "ve",
"vie": "vi", "vol": "vo", "wel": "cy", "wln": "wa", "wol": "wo", "xho": "xh",
"yid": "yi", "yor": "yo", "zha": "za", "zul": "zu"
}

221
node_modules/translate/data/map.js generated vendored Normal file
View File

@@ -0,0 +1,221 @@
export default {
"afar": "aa",
"abkhazian": "ab",
"afrikaans": "af",
"akan": "ak",
"albanian": "sq",
"amharic": "am",
"arabic": "ar",
"aragonese": "an",
"armenian": "hy",
"assamese": "as",
"avaric": "av",
"avestan": "ae",
"aymara": "ay",
"azerbaijani": "az",
"bashkir": "ba",
"bambara": "bm",
"basque": "eu",
"belarusian": "be",
"bengali": "bn",
"bihari languages": "bh",
"bislama": "bi",
"tibetan": "bo",
"bosnian": "bs",
"breton": "br",
"bulgarian": "bg",
"burmese": "my",
"catalan": "ca",
"valencian": "ca",
"czech": "cs",
"chamorro": "ch",
"chechen": "ce",
"chinese": "zh",
"church slavic": "cu",
"old slavonic": "cu",
"church slavonic": "cu",
"old bulgarian": "cu",
"old church slavonic": "cu",
"chuvash": "cv",
"cornish": "kw",
"corsican": "co",
"cree": "cr",
"welsh": "cy",
"danish": "da",
"german": "de",
"divehi": "dv",
"dhivehi": "dv",
"maldivian": "dv",
"dutch": "nl",
"flemish": "nl",
"dzongkha": "dz",
"greek": "el",
"english": "en",
"esperanto": "eo",
"estonian": "et",
"ewe": "ee",
"faroese": "fo",
"persian": "fa",
"fijian": "fj",
"finnish": "fi",
"french": "fr",
"western frisian": "fy",
"fulah": "ff",
"georgian": "ka",
"gaelic": "gd",
"scottish gaelic": "gd",
"irish": "ga",
"galician": "gl",
"manx": "gv",
"guarani": "gn",
"gujarati": "gu",
"haitian": "ht",
"haitian creole": "ht",
"hausa": "ha",
"hebrew": "he",
"herero": "hz",
"hindi": "hi",
"hiri motu": "ho",
"croatian": "hr",
"hungarian": "hu",
"igbo": "ig",
"icelandic": "is",
"ido": "io",
"sichuan yi": "ii",
"nuosu": "ii",
"inuktitut": "iu",
"interlingue": "ie",
"occidental": "ie",
"interlingua": "ia",
"indonesian": "id",
"inupiaq": "ik",
"italian": "it",
"javanese": "jv",
"japanese": "ja",
"kalaallisut": "kl",
"greenlandic": "kl",
"kannada": "kn",
"kashmiri": "ks",
"kanuri": "kr",
"kazakh": "kk",
"central khmer": "km",
"kikuyu": "ki",
"gikuyu": "ki",
"kinyarwanda": "rw",
"kirghiz": "ky",
"kyrgyz": "ky",
"komi": "kv",
"kongo": "kg",
"korean": "ko",
"kuanyama": "kj",
"kwanyama": "kj",
"kurdish": "ku",
"lao": "lo",
"latin": "la",
"latvian": "lv",
"limburgan": "li",
"limburger": "li",
"limburgish": "li",
"lingala": "ln",
"lithuanian": "lt",
"luxembourgish": "lb",
"letzeburgesch": "lb",
"luba-katanga": "lu",
"ganda": "lg",
"macedonian": "mk",
"marshallese": "mh",
"malayalam": "ml",
"maori": "mi",
"marathi": "mr",
"malay": "ms",
"malagasy": "mg",
"maltese": "mt",
"mongolian": "mn",
"nauru": "na",
"navajo": "nv",
"navaho": "nv",
"ndebele, south": "nr",
"south ndebele": "nr",
"ndebele, north": "nd",
"north ndebele": "nd",
"ndonga": "ng",
"nepali": "ne",
"norwegian nynorsk": "nn",
"nynorsk, norwegian": "nn",
"norwegian bokmål": "nb",
"bokmål, norwegian": "nb",
"norwegian": "no",
"chichewa": "ny",
"chewa": "ny",
"nyanja": "ny",
"occitan": "oc",
"ojibwa": "oj",
"oriya": "or",
"oromo": "om",
"ossetian": "os",
"ossetic": "os",
"panjabi": "pa",
"punjabi": "pa",
"pali": "pi",
"polish": "pl",
"portuguese": "pt",
"pushto": "ps",
"pashto": "ps",
"quechua": "qu",
"romansh": "rm",
"romanian": "ro",
"moldavian": "ro",
"moldovan": "ro",
"rundi": "rn",
"russian": "ru",
"sango": "sg",
"sanskrit": "sa",
"sinhala": "si",
"sinhalese": "si",
"slovak": "sk",
"slovenian": "sl",
"northern sami": "se",
"samoan": "sm",
"shona": "sn",
"sindhi": "sd",
"somali": "so",
"sotho, southern": "st",
"spanish": "es",
"castilian": "es",
"sardinian": "sc",
"serbian": "sr",
"swati": "ss",
"sundanese": "su",
"swahili": "sw",
"swedish": "sv",
"tahitian": "ty",
"tamil": "ta",
"tatar": "tt",
"telugu": "te",
"tajik": "tg",
"tagalog": "tl",
"thai": "th",
"tigrinya": "ti",
"tonga": "to",
"tswana": "tn",
"tsonga": "ts",
"turkmen": "tk",
"turkish": "tr",
"twi": "tw",
"uighur": "ug",
"uyghur": "ug",
"ukrainian": "uk",
"urdu": "ur",
"uzbek": "uz",
"venda": "ve",
"vietnamese": "vi",
"volapük": "vo",
"walloon": "wa",
"wolof": "wo",
"xhosa": "xh",
"yiddish": "yi",
"yoruba": "yo",
"zhuang": "za",
"chuang": "za",
"zulu": "zu"
}

29
node_modules/translate/index.html generated vendored Normal file
View File

@@ -0,0 +1,29 @@
<!-- Small manual front-end test to see it all works -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Translate example</title>
</head>
<body>
<p class="greeting">
Input the key manually in the console like this:
<code>translate.key = 'KEYHERE';</code>
Then call test() from the console.
</p>
<script src="translate.js"></script>
<script>
const test = async () => {
const text = await translate('Hello world', { from: 'en', to: 'es' });
document.querySelector('.greeting').innerText = `Hello world => ${text}`;
console.log('Done! Look at the website :)');
};
</script>
</body>
</html>

192
node_modules/translate/lib/cache.js generated vendored Normal file
View File

@@ -0,0 +1,192 @@
// From https://www.npmjs.com/package/memory-cache (Rollup didn't want to bundle it otherwise)
'use strict';
function Cache () {
var _cache = Object.create(null);
var _hitCount = 0;
var _missCount = 0;
var _size = 0;
var _debug = false;
this.put = function(key, value, time, timeoutCallback) {
if (_debug) {
console.log('caching: %s = %j (@%s)', key, value, time);
}
if (typeof time !== 'undefined' && (typeof time !== 'number' || isNaN(time) || time <= 0)) {
throw new Error('Cache timeout must be a positive number');
} else if (typeof timeoutCallback !== 'undefined' && typeof timeoutCallback !== 'function') {
throw new Error('Cache timeout callback must be a function');
}
var oldRecord = _cache[key];
if (oldRecord) {
clearTimeout(oldRecord.timeout);
} else {
_size++;
}
var record = {
value: value,
expire: time + Date.now()
};
if (!isNaN(record.expire)) {
record.timeout = setTimeout(function() {
_del(key);
if (timeoutCallback) {
timeoutCallback(key, value);
}
}.bind(this), time);
}
_cache[key] = record;
return value;
};
this.del = function(key) {
var canDelete = true;
var oldRecord = _cache[key];
if (oldRecord) {
clearTimeout(oldRecord.timeout);
if (!isNaN(oldRecord.expire) && oldRecord.expire < Date.now()) {
canDelete = false;
}
} else {
canDelete = false;
}
if (canDelete) {
_del(key);
}
return canDelete;
};
function _del(key){
_size--;
delete _cache[key];
}
this.clear = function() {
for (var key in _cache) {
clearTimeout(_cache[key].timeout);
}
_size = 0;
_cache = Object.create(null);
if (_debug) {
_hitCount = 0;
_missCount = 0;
}
};
this.get = function(key) {
var data = _cache[key];
if (typeof data != "undefined") {
if (isNaN(data.expire) || data.expire >= Date.now()) {
if (_debug) _hitCount++;
return data.value;
} else {
// free some space
if (_debug) _missCount++;
_size--;
delete _cache[key];
}
} else if (_debug) {
_missCount++;
}
return null;
};
this.size = function() {
return _size;
};
this.memsize = function() {
var size = 0,
key;
for (key in _cache) {
size++;
}
return size;
};
this.debug = function(bool) {
_debug = bool;
};
this.hits = function() {
return _hitCount;
};
this.misses = function() {
return _missCount;
};
this.keys = function() {
return Object.keys(_cache);
};
this.exportJson = function() {
var plainJsCache = {};
// Discard the `timeout` property.
// Note: JSON doesn't support `NaN`, so convert it to `'NaN'`.
for (var key in _cache) {
var record = _cache[key];
plainJsCache[key] = {
value: record.value,
expire: record.expire || 'NaN',
};
}
return JSON.stringify(plainJsCache);
};
this.importJson = function(jsonToImport, options) {
var cacheToImport = JSON.parse(jsonToImport);
var currTime = Date.now();
var skipDuplicates = options && options.skipDuplicates;
for (var key in cacheToImport) {
if (cacheToImport.hasOwnProperty(key)) {
if (skipDuplicates) {
var existingRecord = _cache[key];
if (existingRecord) {
if (_debug) {
console.log('Skipping duplicate imported key \'%s\'', key);
}
continue;
}
}
var record = cacheToImport[key];
// record.expire could be `'NaN'` if no expiry was set.
// Try to subtract from it; a string minus a number is `NaN`, which is perfectly fine here.
var remainingTime = record.expire - currTime;
if (remainingTime <= 0) {
// Delete any record that might exist with the same key, since this key is expired.
this.del(key);
continue;
}
// Remaining time must now be either positive or `NaN`,
// but `put` will throw an error if we try to give it `NaN`.
remainingTime = remainingTime > 0 ? remainingTime : undefined;
this.put(key, record.value, remainingTime);
}
}
return this.size();
};
}
const exp = new Cache();
exp.Cache = Cache;
export default exp;

10
node_modules/translate/node.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// Small manual test to see that it all works
const translate = require('./translate');
require('dotenv').load();
translate.engine = 'yandex';
translate.key = process.env.YANDEX_KEY;
translate('Hello world', 'es').then(res => {
console.log(res);
});

79
node_modules/translate/package.json generated vendored Normal file
View File

@@ -0,0 +1,79 @@
{
"_from": "translate",
"_id": "translate@1.1.2",
"_inBundle": false,
"_integrity": "sha512-3RlVAzzcNuZ7dDfYk2qsQTxJLSeIQ06bMrYYkBneLHtewV0JGaKSP0GjTKHJn/vYwr18bvHEgdmjfg8B0DFuWw==",
"_location": "/translate",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "translate",
"name": "translate",
"escapedName": "translate",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/translate/-/translate-1.1.2.tgz",
"_shasum": "719665e7f324cfc28619726fc1d97f5a633c37e3",
"_spec": "translate",
"_where": "D:\\WORK\\Menui\\menui_backend",
"author": {
"name": "Francisco Presencia",
"email": "public@francisco.io",
"url": "https://francisco.io/"
},
"bugs": {
"url": "https://github.com/franciscop/translate/issues"
},
"bundleDependencies": false,
"dependencies": {
"node-fetch": "^1.7.3"
},
"deprecated": false,
"description": "Translate text to different languages on node.js and the browser",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-jest": "^21.2.0",
"babel-preset-env": "^1.7.0",
"dotenv": "^4.0.0",
"fetch-mock": "^5.13.1",
"jest": "^23.6.0",
"rollup": "^0.50.0",
"uglify-es": "^3.1.3"
},
"engine": [
"node >=4.0.0"
],
"funding": "https://www.paypal.me/franciscopresencia/19",
"homepage": "https://github.com/franciscop/translate#readme",
"keywords": [
"translate",
"languages",
"i18n",
"internationalization",
"async",
"google",
"yandex"
],
"license": "MIT",
"main": "translate.min.js",
"name": "translate",
"repository": {
"type": "git",
"url": "git+https://github.com/franciscop/translate.git"
},
"scripts": {
"build": "rollup src/index.js -o translate.js --name translate --output.format umd && uglifyjs translate.js -o translate.min.js",
"gzip": "gzip -c translate.min.js | wc -c && echo 'bytes' # Only for Unix",
"start": "npm run watch # Start ~= Start dev",
"test": "jest --coverage --collectCoverageFrom=src/**/*.js --detectOpenHandles",
"watch": "nodemon --exec \"npm run build && npm test && npm run gzip\" --watch src --watch test --watch webpack.config.js --watch package.json"
},
"version": "1.1.2"
}

39
node_modules/translate/src/engines.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
// Translation engines
// Handle different translations differently to allow for extra flexibility
const google = {
needkey: true,
fetch: ({ key, from, to, text }) => [
`https://translation.googleapis.com/language/translate/v2?key=${key}&format=text&source=${from}&target=${to}&q=${encodeURIComponent(text)}`,
{ method: 'POST' }
],
parse: res => res.json().then(body => {
if (body.error) {
throw new Error(body.error.errors[0].message);
}
body = body.data.translations[0];
if (!body) {
throw new Error('Translation not found');
}
return body.translatedText;
})
};
const yandex = {
needkey: true,
fetch: ({ key, from, to, text }) => [
`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${key}&lang=${from}-${to}&text=${encodeURIComponent(text)}`,
{ method: 'POST', body: '' }
],
parse: res => res.json().then(body => {
if (body.code !== 200) {
throw new Error(body.message);
}
return body.text[0];
})
};
export default { google, yandex };

92
node_modules/translate/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,92 @@
// translate.js
// Translate text into different languages;
// Load a language parser to allow for more flexibility in the language choice
import language from "./language";
// Load the default engines for translation
import engines from "./engines";
// Cache the different translations to avoid resending requests
import cache from "../lib/cache";
// Main function
const Translate = function(options = {}) {
if (!(this instanceof Translate)) {
return new Translate(options);
}
const defaults = {
from: "en",
to: "en",
cache: undefined,
language: language,
engines: engines,
engine: "google",
keys: {}
};
const translate = (text, opts = {}) => {
// Load all of the appropriate options (verbose but fast)
// Note: not all of those *should* be documented since some are internal only
if (typeof opts === "string") opts = { to: opts };
opts.text = text;
opts.from = language(opts.from || translate.from);
opts.to = language(opts.to || translate.to);
opts.cache = opts.cache || translate.cache;
opts.engines = opts.engines || {};
opts.engine = opts.engine || translate.engine;
opts.id = opts.id || `${opts.from}:${opts.to}:${opts.engine}:${opts.text}`;
opts.keys = opts.keys || translate.keys || {};
for (let name in translate.keys) {
// The options has stronger preference than the global value
opts.keys[name] = opts.keys[name] || translate.keys[name];
}
opts.key = opts.key || translate.key || opts.keys[opts.engine];
// TODO: validation for few of those
// Use the desired engine
const engine = opts.engines[opts.engine] || translate.engines[opts.engine];
// If it is cached return ASAP
const cached = cache.get(opts.id);
if (cached) return Promise.resolve(cached);
// Target is the same as origin, just return the string
if (opts.to === opts.from) {
return Promise.resolve(opts.text);
}
// Will load only for Node.js and use the native function on the browser
if (typeof fetch === "undefined") {
try {
global.fetch = require("node-fetch");
} catch (error) {
console.warn("Please make sure node-fetch is available");
}
}
if (engine.needkey && !opts.key) {
throw new Error(
`The engine "${opts.engine}" needs a key, please provide it`
);
}
const fetchOpts = engine.fetch(opts);
return fetch(...fetchOpts)
.then(engine.parse)
.then(translated => cache.put(opts.id, translated, opts.cache));
};
for (let key in defaults) {
translate[key] =
typeof options[key] === "undefined" ? defaults[key] : options[key];
}
return translate;
};
// Small hack needed for Webpack/Babel: https://github.com/webpack/webpack/issues/706
const exp = new Translate();
exp.Translate = Translate;
export default exp;

42
node_modules/translate/src/language.js generated vendored Normal file
View File

@@ -0,0 +1,42 @@
// Relevant ISO: ISO 639-1 & ISO 639-2. Google uses the ISO 639-1.
// Valid ISO 639-1 codes
// https://www.loc.gov/standards/iso639-2/php/code_list.php
// Extract these with this code (after loading https://superdom.site/ )
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map((row, i) => `"${row.querySelector('td:nth-child(2)').textContent}", ${i % 12 === 11 ? '\n' : ''}`).join('');
import iso from '../data/iso';
// Parsed from here: https://github.com/wooorm/iso-639-2/blob/master/index.json
import iso2 from '../data/iso2';
// Extract these with this code (after loading https://superdom.site/ ) + a lot of manual clean up
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map(row =>
// ` "${row.querySelector('td:nth-child(3)').textContent.toLowerCase()}": "${row.querySelector('td:nth-child(2)').textContent.toLowerCase()}",`
// ).join('\n');
import map from '../data/map';
// Language parser
// @name: a string to be parsed
// @output: the normalized language string
export default name => {
// Validate the name string
if (typeof name !== 'string') {
throw new Error(`The language must be a string, received ${typeof name}`);
}
// Possible overflow errors
if (name.length > 100) {
throw new Error(`The language must be a string under 100 characters, received ${name.length}`);
}
// Let's work with lowercase for everything
name = name.toLowerCase();
// Pass it through several possible maps to try to find the right one
name = map[name] || iso2[name] || name;
// Make sure we have the correct name or throw
if (!iso.includes(name)) {
throw new Error(`The name "${name}" is not part of the ISO 639-1 and we couldn't automatically parse it :(`);
}
return name;
};

14
node_modules/translate/test/mock.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
// Utility method to mock responses from fetch()
const fetchMock = require('fetch-mock');
module.exports = (url, content, throws) => {
fetchMock.post(url, () => new Promise((resolve, reject) => {
setTimeout(() => {
throws ? reject(content) : resolve(content);
}, 500);
}));
};
module.exports.end = () => {
fetchMock.restore();
};

236
node_modules/translate/test/translate.test.js generated vendored Normal file
View File

@@ -0,0 +1,236 @@
import translate from '../src';
import mock from './mock';
import fs from 'fs';
// Quickly load .env files into the environment
require('dotenv').load();
translate.keys.google = process.env.GOOGLE_KEY || 'fakekey';
translate.keys.yandex = process.env.YANDEX_KEY || 'fakekey';
describe('Main', () => {
beforeEach(() => {
mock(/googleapis.*target=es/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
mock(/googleapis.*target=ja/, { data: { translations: [{ translatedText: 'こんにちは世界'}] } });
});
afterEach(() => mock.end());
it('loads', () => {
expect(translate).toBeDefined();
});
it('returns a promise', () => {
const ret = translate('Hello world');
expect(ret instanceof Promise).toBe(true);
});
it('can translate a simple string', async () => {
const es = await translate('Hello world', { from: 'en', to: 'es' });
expect(es).toMatch(/Hola mundo/i);
const jp = await translate('Hello world', { from: 'en', to: 'ja' });
expect(jp).toBe('こんにちは世界');
});
it('accepts full language names', async () => {
const es = await translate('Hello world', { from: 'English', to: 'Spanish' });
expect(es).toMatch(/Hola mundo/i);
const jp = await translate('Hello world', { from: 'English', to: 'Japanese' });
expect(jp).toBe('こんにちは世界');
});
it('accepts weird casing for language names', async () => {
const es = await translate('Hello world', { from: 'english', to: 'spaNish' });
expect(es).toMatch(/Hola mundo/i);
const jp = await translate('Hello world', { from: 'ENGLISH', to: 'JapAnesE' });
expect(jp).toBe('こんにちは世界');
});
});
let language;
describe('language parsing', () => {
it('loads', () => {
language = translate.language;
expect(language).toBeDefined();
});
it('works with a good language name', () => {
expect(language('Spanish')).toBe('es');
});
it('works with the plain ISO', () => {
expect(language('es')).toBe('es');
expect(language('ja')).toBe('ja');
expect(language('en')).toBe('en');
});
it('works with the alternative ISO 639-2', () => {
expect(language('spa')).toBe('es');
expect(language('jpn')).toBe('ja');
expect(language('eng')).toBe('en');
});
it('works with diferent casing', () => {
expect(language('spanish')).toBe('es');
expect(language('SpANisH')).toBe('es');
expect(language('SPANISH')).toBe('es');
});
it('throws with an invalid language name type', () => {
expect(() => language(20)).toThrow();
});
it('throws with a language name too long', () => {
expect(() => language('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')).toThrow();
});
it('throws with a wrong language name', () => {
expect(() => language('asdfghjddas')).toThrow();
});
it('works with fuzzy strings', () => {
});
});
describe('cache', () => {
beforeEach(() => {
mock(/googleapis.*target=es/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
mock(/googleapis.*target=ja/, { data: { translations: [{ translatedText: 'こんにちは世界'}] } });
});
afterEach(() => mock.end());
const stop = time => new Promise((resolve, reject) => {
setTimeout(resolve, time);
});
it('caches', async () => {
const before = new Date();
await translate('Is this cached?', 'es');
const mid = new Date();
await translate('Is this cached?', 'es');
const after = new Date();
expect(mid - before).toBeLessThan(10000);
expect(mid - before).toBeGreaterThan(100);
expect(after - mid).toBeLessThan(10);
expect(after - mid).toBeGreaterThanOrEqual(0);
});
it('removes cache after the time is out', async () => {
const before = new Date();
await translate('Is this also cached?', { to: 'es', cache: 1000 });
const mid = new Date();
await stop(1100);
await translate('Is this also cached?', { to: 'es' });
const after = new Date();
expect(mid - before).toBeLessThan(10000);
expect(mid - before).toBeGreaterThan(100);
expect(after - mid).toBeLessThan(10000);
expect(after - mid).toBeGreaterThan(100);
});
});
describe('File size', () => {
it('is smaller than 20kb (uncompressed)', () => {
const details = fs.statSync(process.cwd() + '/translate.min.js');
expect(details.size).toBeLessThan(25000);
});
});
describe('Google', () => {
beforeEach(() => {
mock(/googleapi.*error/, { error: { errors: [{ message: 'Google API Error' }] } });
mock(/googleapi.*throw/, { code: 500, message: 'also fails harder' }, true);
mock(/googleapi.*&target=ru/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
});
afterEach(() => mock.end());
it('works', async () => {
const text = await translate('Hello world', { to: 'ru', engine: 'google' });
expect(text).toBe('Hola mundo');
});
it('can handle errors from the API', async () => {
const prom = translate('error', { to: 'es', engine: 'google' });
await expect(prom).rejects.toHaveProperty('message', 'Google API Error');
});
it('can handle errors thrown by fetch()', async () => {
const prom = translate('throw', { to: 'es', engine: 'google' });
await expect(prom).rejects.toHaveProperty('message', 'also fails harder');
});
});
describe('Yandex', () => {
beforeEach(() => {
mock(/yandex.*error/, { code: 500, message: 'it fails' });
mock(/yandex.*throw/, { code: 500, message: 'also fails harder' }, true);
mock(/yandex.*&lang=[a-z]*\-es/, { code: 200, text: ['Hola de Yandex'] });
});
afterEach(() => mock.end());
it('works with a simple request', async () => {
const spanish = await translate('Hello from Yandex', { to: 'es', engine: 'yandex' });
expect(spanish).toMatch(/Hola de Yandex/i);
});
it('can handle errors from the API', async () => {
const prom = translate('error', { to: 'es', engine: 'yandex' });
await expect(prom).rejects.toHaveProperty('message', 'it fails');
});
it('can handle errors thrown by fetch()', async () => {
const prom = translate('throw', { to: 'es', engine: 'yandex' });
await expect(prom).rejects.toHaveProperty('message', 'also fails harder');
});
});
describe('Independent', () => {
it('has independent instances', () => {
const translate2 = new translate.Translate();
translate.keys.madeup = 'a';
translate2.keys.madeup = 'b';
expect(translate.keys.madeup).toBe('a');
expect(translate2.keys.madeup).toBe('b');
});
it('is auto initialized', () => {
let inst = translate.Translate();
expect(inst.from).toBe('en');
inst = new translate.Translate();
expect(inst.from).toBe('en');
});
it('fixed the bug #5', async () => {
// translate.keys = { google: 'abc' };
const options = { to: 'ja', keys: { yandex: 'def' }, engine: 'google' };
// This will wrongly ignore the key for "google"
expect(await translate('Hello world', options)).toBe('こんにちは世界');
})
});
// These cost $ and would need your own keys. Disable otherwise
describe.skip('$$$ Real API tests', () => {
it('works', async () => {
const text = await translate('Hello world', { to: 'fr', engine: 'google' });
expect(text).toMatch(/Hola Mundo/i);
});
});

638
node_modules/translate/translate.js generated vendored Normal file
View File

@@ -0,0 +1,638 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.translate = factory());
}(this, (function () { 'use strict';
var iso = [
"aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "ba",
"be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce", "ch", "co",
"cr", "cs", "cu", "cv", "cy", "da", "de", "dv", "dz", "ee", "el", "en", "eo",
"es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr", "fy", "ga", "gd", "gl",
"gn", "gu", "gv", "ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz", "ia",
"id", "ie", "ig", "ii", "ik", "io", "is", "it", "iu", "ja", "jv", "ka", "kg",
"ki", "kj", "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky",
"la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk",
"ml", "mn", "mr", "ms", "mt", "my", "na", "nb", "nd", "ne", "ng", "nl", "nn",
"no", "nr", "nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl", "ps",
"pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si",
"sk", "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta",
"te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty",
"ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh", "yi", "yo", "za",
"zh", "zu"
];
var iso2 = {
"aar": "aa", "abk": "ab", "afr": "af", "aka": "ak", "alb": "sq", "amh": "am",
"ara": "ar", "arg": "an", "arm": "hy", "asm": "as", "ava": "av", "ave": "ae",
"aym": "ay", "aze": "az", "bak": "ba", "bam": "bm", "baq": "eu", "bel": "be",
"ben": "bn", "bih": "bh", "bis": "bi", "bos": "bs", "bre": "br", "bul": "bg",
"bur": "my", "cat": "ca", "cha": "ch", "che": "ce", "chi": "zh", "chu": "cu",
"chv": "cv", "cor": "kw", "cos": "co", "cre": "cr", "cze": "cs", "dan": "da",
"div": "dv", "dut": "nl", "dzo": "dz", "eng": "en", "epo": "eo", "est": "et",
"ewe": "ee", "fao": "fo", "fij": "fj", "fin": "fi", "fre": "fr", "fry": "fy",
"ful": "ff", "geo": "ka", "ger": "de", "gla": "gd", "gle": "ga", "glg": "gl",
"glv": "gv", "gre": "el", "grn": "gn", "guj": "gu", "hat": "ht", "hau": "ha",
"heb": "he", "her": "hz", "hin": "hi", "hmo": "ho", "hrv": "hr", "hun": "hu",
"ibo": "ig", "ice": "is", "ido": "io", "iii": "ii", "iku": "iu", "ile": "ie",
"ina": "ia", "ind": "id", "ipk": "ik", "ita": "it", "jav": "jv", "jpn": "ja",
"kal": "kl", "kan": "kn", "kas": "ks", "kau": "kr", "kaz": "kk", "khm": "km",
"kik": "ki", "kin": "rw", "kir": "ky", "kom": "kv", "kon": "kg", "kor": "ko",
"kua": "kj", "kur": "ku", "lao": "lo", "lat": "la", "lav": "lv", "lim": "li",
"lin": "ln", "lit": "lt", "ltz": "lb", "lub": "lu", "lug": "lg", "mac": "mk",
"mah": "mh", "mal": "ml", "mao": "mi", "mar": "mr", "may": "ms", "mlg": "mg",
"mlt": "mt", "mon": "mn", "nau": "na", "nav": "nv", "nbl": "nr", "nde": "nd",
"ndo": "ng", "nep": "ne", "nno": "nn", "nob": "nb", "nor": "no", "nya": "ny",
"oci": "oc", "oji": "oj", "ori": "or", "orm": "om", "oss": "os", "pan": "pa",
"per": "fa", "pli": "pi", "pol": "pl", "por": "pt", "pus": "ps", "que": "qu",
"roh": "rm", "rum": "ro", "run": "rn", "rus": "ru", "sag": "sg", "san": "sa",
"sin": "si", "slo": "sk", "slv": "sl", "sme": "se", "smo": "sm", "sna": "sn",
"snd": "sd", "som": "so", "sot": "st", "spa": "es", "srd": "sc", "srp": "sr",
"ssw": "ss", "sun": "su", "swa": "sw", "swe": "sv", "tah": "ty", "tam": "ta",
"tat": "tt", "tel": "te", "tgk": "tg", "tgl": "tl", "tha": "th", "tib": "bo",
"tir": "ti", "ton": "to", "tsn": "tn", "tso": "ts", "tuk": "tk", "tur": "tr",
"twi": "tw", "uig": "ug", "ukr": "uk", "urd": "ur", "uzb": "uz", "ven": "ve",
"vie": "vi", "vol": "vo", "wel": "cy", "wln": "wa", "wol": "wo", "xho": "xh",
"yid": "yi", "yor": "yo", "zha": "za", "zul": "zu"
};
var map = {
"afar": "aa",
"abkhazian": "ab",
"afrikaans": "af",
"akan": "ak",
"albanian": "sq",
"amharic": "am",
"arabic": "ar",
"aragonese": "an",
"armenian": "hy",
"assamese": "as",
"avaric": "av",
"avestan": "ae",
"aymara": "ay",
"azerbaijani": "az",
"bashkir": "ba",
"bambara": "bm",
"basque": "eu",
"belarusian": "be",
"bengali": "bn",
"bihari languages": "bh",
"bislama": "bi",
"tibetan": "bo",
"bosnian": "bs",
"breton": "br",
"bulgarian": "bg",
"burmese": "my",
"catalan": "ca",
"valencian": "ca",
"czech": "cs",
"chamorro": "ch",
"chechen": "ce",
"chinese": "zh",
"church slavic": "cu",
"old slavonic": "cu",
"church slavonic": "cu",
"old bulgarian": "cu",
"old church slavonic": "cu",
"chuvash": "cv",
"cornish": "kw",
"corsican": "co",
"cree": "cr",
"welsh": "cy",
"danish": "da",
"german": "de",
"divehi": "dv",
"dhivehi": "dv",
"maldivian": "dv",
"dutch": "nl",
"flemish": "nl",
"dzongkha": "dz",
"greek": "el",
"english": "en",
"esperanto": "eo",
"estonian": "et",
"ewe": "ee",
"faroese": "fo",
"persian": "fa",
"fijian": "fj",
"finnish": "fi",
"french": "fr",
"western frisian": "fy",
"fulah": "ff",
"georgian": "ka",
"gaelic": "gd",
"scottish gaelic": "gd",
"irish": "ga",
"galician": "gl",
"manx": "gv",
"guarani": "gn",
"gujarati": "gu",
"haitian": "ht",
"haitian creole": "ht",
"hausa": "ha",
"hebrew": "he",
"herero": "hz",
"hindi": "hi",
"hiri motu": "ho",
"croatian": "hr",
"hungarian": "hu",
"igbo": "ig",
"icelandic": "is",
"ido": "io",
"sichuan yi": "ii",
"nuosu": "ii",
"inuktitut": "iu",
"interlingue": "ie",
"occidental": "ie",
"interlingua": "ia",
"indonesian": "id",
"inupiaq": "ik",
"italian": "it",
"javanese": "jv",
"japanese": "ja",
"kalaallisut": "kl",
"greenlandic": "kl",
"kannada": "kn",
"kashmiri": "ks",
"kanuri": "kr",
"kazakh": "kk",
"central khmer": "km",
"kikuyu": "ki",
"gikuyu": "ki",
"kinyarwanda": "rw",
"kirghiz": "ky",
"kyrgyz": "ky",
"komi": "kv",
"kongo": "kg",
"korean": "ko",
"kuanyama": "kj",
"kwanyama": "kj",
"kurdish": "ku",
"lao": "lo",
"latin": "la",
"latvian": "lv",
"limburgan": "li",
"limburger": "li",
"limburgish": "li",
"lingala": "ln",
"lithuanian": "lt",
"luxembourgish": "lb",
"letzeburgesch": "lb",
"luba-katanga": "lu",
"ganda": "lg",
"macedonian": "mk",
"marshallese": "mh",
"malayalam": "ml",
"maori": "mi",
"marathi": "mr",
"malay": "ms",
"malagasy": "mg",
"maltese": "mt",
"mongolian": "mn",
"nauru": "na",
"navajo": "nv",
"navaho": "nv",
"ndebele, south": "nr",
"south ndebele": "nr",
"ndebele, north": "nd",
"north ndebele": "nd",
"ndonga": "ng",
"nepali": "ne",
"norwegian nynorsk": "nn",
"nynorsk, norwegian": "nn",
"norwegian bokmål": "nb",
"bokmål, norwegian": "nb",
"norwegian": "no",
"chichewa": "ny",
"chewa": "ny",
"nyanja": "ny",
"occitan": "oc",
"ojibwa": "oj",
"oriya": "or",
"oromo": "om",
"ossetian": "os",
"ossetic": "os",
"panjabi": "pa",
"punjabi": "pa",
"pali": "pi",
"polish": "pl",
"portuguese": "pt",
"pushto": "ps",
"pashto": "ps",
"quechua": "qu",
"romansh": "rm",
"romanian": "ro",
"moldavian": "ro",
"moldovan": "ro",
"rundi": "rn",
"russian": "ru",
"sango": "sg",
"sanskrit": "sa",
"sinhala": "si",
"sinhalese": "si",
"slovak": "sk",
"slovenian": "sl",
"northern sami": "se",
"samoan": "sm",
"shona": "sn",
"sindhi": "sd",
"somali": "so",
"sotho, southern": "st",
"spanish": "es",
"castilian": "es",
"sardinian": "sc",
"serbian": "sr",
"swati": "ss",
"sundanese": "su",
"swahili": "sw",
"swedish": "sv",
"tahitian": "ty",
"tamil": "ta",
"tatar": "tt",
"telugu": "te",
"tajik": "tg",
"tagalog": "tl",
"thai": "th",
"tigrinya": "ti",
"tonga": "to",
"tswana": "tn",
"tsonga": "ts",
"turkmen": "tk",
"turkish": "tr",
"twi": "tw",
"uighur": "ug",
"uyghur": "ug",
"ukrainian": "uk",
"urdu": "ur",
"uzbek": "uz",
"venda": "ve",
"vietnamese": "vi",
"volapük": "vo",
"walloon": "wa",
"wolof": "wo",
"xhosa": "xh",
"yiddish": "yi",
"yoruba": "yo",
"zhuang": "za",
"chuang": "za",
"zulu": "zu"
};
// Relevant ISO: ISO 639-1 & ISO 639-2. Google uses the ISO 639-1.
// Valid ISO 639-1 codes
// https://www.loc.gov/standards/iso639-2/php/code_list.php
// Extract these with this code (after loading https://superdom.site/ )
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map((row, i) => `"${row.querySelector('td:nth-child(2)').textContent}", ${i % 12 === 11 ? '\n' : ''}`).join('');
// Parsed from here: https://github.com/wooorm/iso-639-2/blob/master/index.json
// Extract these with this code (after loading https://superdom.site/ ) + a lot of manual clean up
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map(row =>
// ` "${row.querySelector('td:nth-child(3)').textContent.toLowerCase()}": "${row.querySelector('td:nth-child(2)').textContent.toLowerCase()}",`
// ).join('\n');
// Language parser
// @name: a string to be parsed
// @output: the normalized language string
var language = name => {
// Validate the name string
if (typeof name !== 'string') {
throw new Error(`The language must be a string, received ${typeof name}`);
}
// Possible overflow errors
if (name.length > 100) {
throw new Error(`The language must be a string under 100 characters, received ${name.length}`);
}
// Let's work with lowercase for everything
name = name.toLowerCase();
// Pass it through several possible maps to try to find the right one
name = map[name] || iso2[name] || name;
// Make sure we have the correct name or throw
if (!iso.includes(name)) {
throw new Error(`The name "${name}" is not part of the ISO 639-1 and we couldn't automatically parse it :(`);
}
return name;
};
// Translation engines
// Handle different translations differently to allow for extra flexibility
const google = {
needkey: true,
fetch: ({ key, from, to, text }) => [
`https://translation.googleapis.com/language/translate/v2?key=${key}&format=text&source=${from}&target=${to}&q=${encodeURIComponent(text)}`,
{ method: 'POST' }
],
parse: res => res.json().then(body => {
if (body.error) {
throw new Error(body.error.errors[0].message);
}
body = body.data.translations[0];
if (!body) {
throw new Error('Translation not found');
}
return body.translatedText;
})
};
const yandex = {
needkey: true,
fetch: ({ key, from, to, text }) => [
`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${key}&lang=${from}-${to}&text=${encodeURIComponent(text)}`,
{ method: 'POST', body: '' }
],
parse: res => res.json().then(body => {
if (body.code !== 200) {
throw new Error(body.message);
}
return body.text[0];
})
};
var engines = { google, yandex };
// From https://www.npmjs.com/package/memory-cache (Rollup didn't want to bundle it otherwise)
'use strict';
function Cache () {
var _cache = Object.create(null);
var _hitCount = 0;
var _missCount = 0;
var _size = 0;
var _debug = false;
this.put = function(key, value, time, timeoutCallback) {
if (_debug) {
console.log('caching: %s = %j (@%s)', key, value, time);
}
if (typeof time !== 'undefined' && (typeof time !== 'number' || isNaN(time) || time <= 0)) {
throw new Error('Cache timeout must be a positive number');
} else if (typeof timeoutCallback !== 'undefined' && typeof timeoutCallback !== 'function') {
throw new Error('Cache timeout callback must be a function');
}
var oldRecord = _cache[key];
if (oldRecord) {
clearTimeout(oldRecord.timeout);
} else {
_size++;
}
var record = {
value: value,
expire: time + Date.now()
};
if (!isNaN(record.expire)) {
record.timeout = setTimeout(function() {
_del(key);
if (timeoutCallback) {
timeoutCallback(key, value);
}
}.bind(this), time);
}
_cache[key] = record;
return value;
};
this.del = function(key) {
var canDelete = true;
var oldRecord = _cache[key];
if (oldRecord) {
clearTimeout(oldRecord.timeout);
if (!isNaN(oldRecord.expire) && oldRecord.expire < Date.now()) {
canDelete = false;
}
} else {
canDelete = false;
}
if (canDelete) {
_del(key);
}
return canDelete;
};
function _del(key){
_size--;
delete _cache[key];
}
this.clear = function() {
for (var key in _cache) {
clearTimeout(_cache[key].timeout);
}
_size = 0;
_cache = Object.create(null);
if (_debug) {
_hitCount = 0;
_missCount = 0;
}
};
this.get = function(key) {
var data = _cache[key];
if (typeof data != "undefined") {
if (isNaN(data.expire) || data.expire >= Date.now()) {
if (_debug) _hitCount++;
return data.value;
} else {
// free some space
if (_debug) _missCount++;
_size--;
delete _cache[key];
}
} else if (_debug) {
_missCount++;
}
return null;
};
this.size = function() {
return _size;
};
this.memsize = function() {
var size = 0,
key;
for (key in _cache) {
size++;
}
return size;
};
this.debug = function(bool) {
_debug = bool;
};
this.hits = function() {
return _hitCount;
};
this.misses = function() {
return _missCount;
};
this.keys = function() {
return Object.keys(_cache);
};
this.exportJson = function() {
var plainJsCache = {};
// Discard the `timeout` property.
// Note: JSON doesn't support `NaN`, so convert it to `'NaN'`.
for (var key in _cache) {
var record = _cache[key];
plainJsCache[key] = {
value: record.value,
expire: record.expire || 'NaN',
};
}
return JSON.stringify(plainJsCache);
};
this.importJson = function(jsonToImport, options) {
var cacheToImport = JSON.parse(jsonToImport);
var currTime = Date.now();
var skipDuplicates = options && options.skipDuplicates;
for (var key in cacheToImport) {
if (cacheToImport.hasOwnProperty(key)) {
if (skipDuplicates) {
var existingRecord = _cache[key];
if (existingRecord) {
if (_debug) {
console.log('Skipping duplicate imported key \'%s\'', key);
}
continue;
}
}
var record = cacheToImport[key];
// record.expire could be `'NaN'` if no expiry was set.
// Try to subtract from it; a string minus a number is `NaN`, which is perfectly fine here.
var remainingTime = record.expire - currTime;
if (remainingTime <= 0) {
// Delete any record that might exist with the same key, since this key is expired.
this.del(key);
continue;
}
// Remaining time must now be either positive or `NaN`,
// but `put` will throw an error if we try to give it `NaN`.
remainingTime = remainingTime > 0 ? remainingTime : undefined;
this.put(key, record.value, remainingTime);
}
}
return this.size();
};
}
const exp$2 = new Cache();
exp$2.Cache = Cache;
// translate.js
// Translate text into different languages;
// Load a language parser to allow for more flexibility in the language choice
// Load the default engines for translation
// Cache the different translations to avoid resending requests
// Main function
const Translate = function(options = {}) {
if (!(this instanceof Translate)) {
return new Translate(options);
}
const defaults = {
from: "en",
to: "en",
cache: undefined,
language: language,
engines: engines,
engine: "google",
keys: {}
};
const translate = (text, opts = {}) => {
// Load all of the appropriate options (verbose but fast)
// Note: not all of those *should* be documented since some are internal only
if (typeof opts === "string") opts = { to: opts };
opts.text = text;
opts.from = language(opts.from || translate.from);
opts.to = language(opts.to || translate.to);
opts.cache = opts.cache || translate.cache;
opts.engines = opts.engines || {};
opts.engine = opts.engine || translate.engine;
opts.id = opts.id || `${opts.from}:${opts.to}:${opts.engine}:${opts.text}`;
opts.keys = opts.keys || translate.keys || {};
for (let name in translate.keys) {
// The options has stronger preference than the global value
opts.keys[name] = opts.keys[name] || translate.keys[name];
}
opts.key = opts.key || translate.key || opts.keys[opts.engine];
// TODO: validation for few of those
// Use the desired engine
const engine = opts.engines[opts.engine] || translate.engines[opts.engine];
// If it is cached return ASAP
const cached = exp$2.get(opts.id);
if (cached) return Promise.resolve(cached);
// Target is the same as origin, just return the string
if (opts.to === opts.from) {
return Promise.resolve(opts.text);
}
// Will load only for Node.js and use the native function on the browser
if (typeof fetch === "undefined") {
try {
global.fetch = require("node-fetch");
} catch (error) {
console.warn("Please make sure node-fetch is available");
}
}
if (engine.needkey && !opts.key) {
throw new Error(
`The engine "${opts.engine}" needs a key, please provide it`
);
}
const fetchOpts = engine.fetch(opts);
return fetch(...fetchOpts)
.then(engine.parse)
.then(translated => exp$2.put(opts.id, translated, opts.cache));
};
for (let key in defaults) {
translate[key] =
typeof options[key] === "undefined" ? defaults[key] : options[key];
}
return translate;
};
// Small hack needed for Webpack/Babel: https://github.com/webpack/webpack/issues/706
const exp = new Translate();
exp.Translate = Translate;
return exp;
})));

1
node_modules/translate/translate.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long