express-translator
Version:
Translator helper for Express using PO files
1,921 lines (1,786 loc) • 91.1 kB
JavaScript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/**
* @fileoverview Translation object to control client-side of translation.
* @package
* node-gettext
*/
const Gettext = require('node-gettext');
const Client = function({library = {}, country = 'US', language = 'en', domain = 'default'}) {
/* Setup. */
const translator = new Gettext();
translator.addTranslations(`${language}-${country}`, domain, library);
translator.setLocale(`${language}-${country}`);
translator.setTextDomain(domain);
this.translate = (source, {context = '', params = {}} = {}) => {
// Translate string.
let translated = context ?
translator.pgettext(context, source) :
translator.gettext(source);
// Apply dynamical content to string.
Object.entries(params).forEach(([key, value]) => {
translated = translated.replace(new RegExp(key, 'g'), value);
});
return translated;
};
return this;
};
exports = module.exports = Client;
},{"node-gettext":3}],2:[function(require,module,exports){
(function (global){
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** `Object#toString` result references. */
var funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
symbolTag = '[object Symbol]';
/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/,
reLeadingDot = /^\./,
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function getValue(object, key) {
return object == null ? undefined : object[key];
}
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
function isHostObject(value) {
// Many host objects are `Object` objects that can coerce to strings
// despite having improperly defined `toString` methods.
var result = false;
if (value != null && typeof value.toString != 'function') {
try {
result = !!(value + '');
} catch (e) {}
}
return result;
}
/** Used for built-in method references. */
var arrayProto = Array.prototype,
funcProto = Function.prototype,
objectProto = Object.prototype;
/** Used to detect overreaching core-js shims. */
var coreJsData = root['__core-js_shared__'];
/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
return uid ? ('Symbol(src)_1.' + uid) : '';
}());
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** Built-in value references. */
var Symbol = root.Symbol,
splice = arrayProto.splice;
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map'),
nativeCreate = getNative(Object, 'create');
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberOf Hash
*/
function hashClear() {
this.__data__ = nativeCreate ? nativeCreate(null) : {};
}
/**
* Removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function hashDelete(key) {
return this.has(key) && delete this.__data__[key];
}
/**
* Gets the hash value for `key`.
*
* @private
* @name get
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function hashGet(key) {
var data = this.__data__;
if (nativeCreate) {
var result = data[key];
return result === HASH_UNDEFINED ? undefined : result;
}
return hasOwnProperty.call(data, key) ? data[key] : undefined;
}
/**
* Checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function hashHas(key) {
var data = this.__data__;
return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
}
/**
* Sets the hash `key` to `value`.
*
* @private
* @name set
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/
function hashSet(key, value) {
var data = this.__data__;
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
return this;
}
// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberOf ListCache
*/
function listCacheClear() {
this.__data__ = [];
}
/**
* Removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberOf ListCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function listCacheDelete(key) {
var data = this.__data__,
index = assocIndexOf(data, key);
if (index < 0) {
return false;
}
var lastIndex = data.length - 1;
if (index == lastIndex) {
data.pop();
} else {
splice.call(data, index, 1);
}
return true;
}
/**
* Gets the list cache value for `key`.
*
* @private
* @name get
* @memberOf ListCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function listCacheGet(key) {
var data = this.__data__,
index = assocIndexOf(data, key);
return index < 0 ? undefined : data[index][1];
}
/**
* Checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberOf ListCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function listCacheHas(key) {
return assocIndexOf(this.__data__, key) > -1;
}
/**
* Sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberOf ListCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the list cache instance.
*/
function listCacheSet(key, value) {
var data = this.__data__,
index = assocIndexOf(data, key);
if (index < 0) {
data.push([key, value]);
} else {
data[index][1] = value;
}
return this;
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the map.
*
* @private
* @name clear
* @memberOf MapCache
*/
function mapCacheClear() {
this.__data__ = {
'hash': new Hash,
'map': new (Map || ListCache),
'string': new Hash
};
}
/**
* Removes `key` and its value from the map.
*
* @private
* @name delete
* @memberOf MapCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapCacheDelete(key) {
return getMapData(this, key)['delete'](key);
}
/**
* Gets the map value for `key`.
*
* @private
* @name get
* @memberOf MapCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function mapCacheGet(key) {
return getMapData(this, key).get(key);
}
/**
* Checks if a map value for `key` exists.
*
* @private
* @name has
* @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapCacheHas(key) {
return getMapData(this, key).has(key);
}
/**
* Sets the map `key` to `value`.
*
* @private
* @name set
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the map cache instance.
*/
function mapCacheSet(key, value) {
getMapData(this, key).set(key, value);
return this;
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
/**
* The base implementation of `_.get` without support for default values.
*
* @private
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @returns {*} Returns the resolved value.
*/
function baseGet(object, path) {
path = isKey(path, object) ? [path] : castPath(path);
var index = 0,
length = path.length;
while (object != null && index < length) {
object = object[toKey(path[index++])];
}
return (index && index == length) ? object : undefined;
}
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/
function baseIsNative(value) {
if (!isObject(value) || isMasked(value)) {
return false;
}
var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
return pattern.test(toSource(value));
}
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/**
* Casts `value` to a path array if it's not one.
*
* @private
* @param {*} value The value to inspect.
* @returns {Array} Returns the cast property path array.
*/
function castPath(value) {
return isArray(value) ? value : stringToPath(value);
}
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return isKeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : undefined;
}
/**
* Checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value The value to check.
* @param {Object} [object] The object to query keys on.
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
if (isArray(value)) {
return false;
}
var type = typeof value;
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
value == null || isSymbol(value)) {
return true;
}
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
(object != null && value in Object(object));
}
/**
* Checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
*/
function isKeyable(value) {
var type = typeof value;
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
? (value !== '__proto__')
: (value === null);
}
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/
function isMasked(func) {
return !!maskSrcKey && (maskSrcKey in func);
}
/**
* Converts `string` to a property path array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the property path array.
*/
var stringToPath = memoize(function(string) {
string = toString(string);
var result = [];
if (reLeadingDot.test(string)) {
result.push('');
}
string.replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
return result;
});
/**
* Converts `value` to a string key if it's not a string or symbol.
*
* @private
* @param {*} value The value to inspect.
* @returns {string|symbol} Returns the key.
*/
function toKey(value) {
if (typeof value == 'string' || isSymbol(value)) {
return value;
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to process.
* @returns {string} Returns the source code.
*/
function toSource(func) {
if (func != null) {
try {
return funcToString.call(func);
} catch (e) {}
try {
return (func + '');
} catch (e) {}
}
return '';
}
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided, it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
* provided to the memoized function is used as the map cache key. The `func`
* is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
* constructor with one whose instances implement the
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
* method interface of `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to have its output memoized.
* @param {Function} [resolver] The function to resolve the cache key.
* @returns {Function} Returns the new memoized function.
* @example
*
* var object = { 'a': 1, 'b': 2 };
* var other = { 'c': 3, 'd': 4 };
*
* var values = _.memoize(_.values);
* values(object);
* // => [1, 2]
*
* values(other);
* // => [3, 4]
*
* object.a = 2;
* values(object);
* // => [1, 2]
*
* // Modify the result cache.
* values.cache.set(object, ['a', 'b']);
* values(object);
* // => ['a', 'b']
*
* // Replace `_.memoize.Cache`.
* _.memoize.Cache = WeakMap;
*/
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
throw new TypeError(FUNC_ERROR_TEXT);
}
var memoized = function() {
var args = arguments,
key = resolver ? resolver.apply(this, args) : args[0],
cache = memoized.cache;
if (cache.has(key)) {
return cache.get(key);
}
var result = func.apply(this, args);
memoized.cache = cache.set(key, result);
return result;
};
memoized.cache = new (memoize.Cache || MapCache);
return memoized;
}
// Assign cache to `_.memoize`.
memoize.Cache = MapCache;
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {string} Returns the string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined`, the `defaultValue` is returned in its place.
*
* @static
* @memberOf _
* @since 3.7.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
* @returns {*} Returns the resolved value.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.get(object, 'a[0].b.c');
* // => 3
*
* _.get(object, ['a', '0', 'b', 'c']);
* // => 3
*
* _.get(object, 'a.b.c', 'default');
* // => 'default'
*/
function get(object, path, defaultValue) {
var result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
module.exports = get;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],3:[function(require,module,exports){
(function (process){
'use strict';
var get = require('lodash.get');
var plurals = require('./plurals');
module.exports = Gettext;
/**
* Creates and returns a new Gettext instance.
*
* @constructor
* @param {Object} [options] A set of options
* @param {Boolean} options.debug Whether to output debug info into the
* console.
* @return {Object} A Gettext instance
*/
function Gettext(options) {
options = options || {};
this.catalogs = {};
this.locale = '';
this.domain = 'messages';
this.listeners = [];
// Set debug flag
if ('debug' in options) {
this.debug = options.debug === true;
}
else if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV) {
this.debug = process.env.NODE_ENV !== 'production';
}
else {
this.debug = false;
}
}
/**
* Adds an event listener.
*
* @param {String} eventName An event name
* @param {Function} callback An event handler function
*/
Gettext.prototype.on = function(eventName, callback) {
this.listeners.push({
eventName: eventName,
callback: callback
});
};
/**
* Removes an event listener.
*
* @param {String} eventName An event name
* @param {Function} callback A previously registered event handler function
*/
Gettext.prototype.off = function(eventName, callback) {
this.listeners = this.listeners.filter(function(listener) {
return (
listener.eventName === eventName &&
listener.callback === callback
) === false;
});
};
/**
* Emits an event to all registered event listener.
*
* @private
* @param {String} eventName An event name
* @param {any} eventData Data to pass to event listeners
*/
Gettext.prototype.emit = function(eventName, eventData) {
for (var i = 0; i < this.listeners.length; i++) {
var listener = this.listeners[i];
if (listener.eventName === eventName) {
listener.callback(eventData);
}
}
};
/**
* Logs a warning to the console if debug mode is enabled.
*
* @ignore
* @param {String} message A warning message
*/
Gettext.prototype.warn = function(message) {
if (this.debug) {
console.warn(message);
}
this.emit('error', message);
};
/**
* Stores a set of translations in the set of gettext
* catalogs.
*
* @example
* gt.addTranslations('sv-SE', 'messages', translationsObject)
*
* @param {String} locale A locale string
* @param {String} domain A domain name
* @param {Object} translations An object of gettext-parser JSON shape
*/
Gettext.prototype.addTranslations = function(locale, domain, translations) {
if (!this.catalogs[locale]) {
this.catalogs[locale] = {};
}
this.catalogs[locale][domain] = translations;
};
/**
* Sets the locale to get translated messages for.
*
* @example
* gt.setLocale('sv-SE')
*
* @param {String} locale A locale
*/
Gettext.prototype.setLocale = function(locale) {
if (typeof locale !== 'string') {
this.warn(
'You called setLocale() with an argument of type ' + (typeof locale) + '. ' +
'The locale must be a string.'
);
return;
}
if (locale.trim() === '') {
this.warn('You called setLocale() with an empty value, which makes little sense.');
}
if (!this.catalogs[locale]) {
this.warn('You called setLocale() with "' + locale + '", but no translations for that locale has been added.');
}
this.locale = locale;
};
/**
* Sets the default gettext domain.
*
* @example
* gt.setTextDomain('domainname')
*
* @param {String} domain A gettext domain name
*/
Gettext.prototype.setTextDomain = function(domain) {
if (typeof domain !== 'string') {
this.warn(
'You called setTextDomain() with an argument of type ' + (typeof domain) + '. ' +
'The domain must be a string.'
);
return;
}
if (domain.trim() === '') {
this.warn('You called setTextDomain() with an empty `domain` value.');
}
this.domain = domain;
};
/**
* Translates a string using the default textdomain
*
* @example
* gt.gettext('Some text')
*
* @param {String} msgid String to be translated
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.gettext = function(msgid) {
return this.dnpgettext(this.domain, '', msgid);
};
/**
* Translates a string using a specific domain
*
* @example
* gt.dgettext('domainname', 'Some text')
*
* @param {String} domain A gettext domain name
* @param {String} msgid String to be translated
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.dgettext = function(domain, msgid) {
return this.dnpgettext(domain, '', msgid);
};
/**
* Translates a plural string using the default textdomain
*
* @example
* gt.ngettext('One thing', 'Many things', numberOfThings)
*
* @param {String} msgid String to be translated when count is not plural
* @param {String} msgidPlural String to be translated when count is plural
* @param {Number} count Number count for the plural
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.ngettext = function(msgid, msgidPlural, count) {
return this.dnpgettext(this.domain, '', msgid, msgidPlural, count);
};
/**
* Translates a plural string using a specific textdomain
*
* @example
* gt.dngettext('domainname', 'One thing', 'Many things', numberOfThings)
*
* @param {String} domain A gettext domain name
* @param {String} msgid String to be translated when count is not plural
* @param {String} msgidPlural String to be translated when count is plural
* @param {Number} count Number count for the plural
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.dngettext = function(domain, msgid, msgidPlural, count) {
return this.dnpgettext(domain, '', msgid, msgidPlural, count);
};
/**
* Translates a string from a specific context using the default textdomain
*
* @example
* gt.pgettext('sports', 'Back')
*
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.pgettext = function(msgctxt, msgid) {
return this.dnpgettext(this.domain, msgctxt, msgid);
};
/**
* Translates a string from a specific context using s specific textdomain
*
* @example
* gt.dpgettext('domainname', 'sports', 'Back')
*
* @param {String} domain A gettext domain name
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.dpgettext = function(domain, msgctxt, msgid) {
return this.dnpgettext(domain, msgctxt, msgid);
};
/**
* Translates a plural string from a specific context using the default textdomain
*
* @example
* gt.npgettext('sports', 'Back', '%d backs', numberOfBacks)
*
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated when count is not plural
* @param {String} msgidPlural String to be translated when count is plural
* @param {Number} count Number count for the plural
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.npgettext = function(msgctxt, msgid, msgidPlural, count) {
return this.dnpgettext(this.domain, msgctxt, msgid, msgidPlural, count);
};
/**
* Translates a plural string from a specifi context using a specific textdomain
*
* @example
* gt.dnpgettext('domainname', 'sports', 'Back', '%d backs', numberOfBacks)
*
* @param {String} domain A gettext domain name
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated
* @param {String} msgidPlural If no translation was found, return this on count!=1
* @param {Number} count Number count for the plural
* @return {String} Translation or the original string if no translation was found
*/
Gettext.prototype.dnpgettext = function(domain, msgctxt, msgid, msgidPlural, count) {
var defaultTranslation = msgid;
var translation;
var index;
msgctxt = msgctxt || '';
if (!isNaN(count) && count !== 1) {
defaultTranslation = msgidPlural || msgid;
}
translation = this._getTranslation(domain, msgctxt, msgid);
if (translation) {
if (typeof count === 'number') {
var pluralsFunc = plurals[Gettext.getLanguageCode(this.locale)].pluralsFunc;
index = pluralsFunc(count);
if (typeof index === 'boolean') {
index = index ? 1 : 0;
}
} else {
index = 0;
}
return translation.msgstr[index] || defaultTranslation;
}
else {
this.warn('No translation was found for msgid "' + msgid + '" in msgctxt "' + msgctxt + '" and domain "' + domain + '"');
}
return defaultTranslation;
};
/**
* Retrieves comments object for a translation. The comments object
* has the shape `{ translator, extracted, reference, flag, previous }`.
*
* @example
* const comment = gt.getComment('domainname', 'sports', 'Backs')
*
* @private
* @param {String} domain A gettext domain name
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated
* @return {Object} Comments object or false if not found
*/
Gettext.prototype.getComment = function(domain, msgctxt, msgid) {
var translation;
translation = this._getTranslation(domain, msgctxt, msgid);
if (translation) {
return translation.comments || {};
}
return {};
};
/**
* Retrieves translation object from the domain and context
*
* @private
* @param {String} domain A gettext domain name
* @param {String} msgctxt Translation context
* @param {String} msgid String to be translated
* @return {Object} Translation object or false if not found
*/
Gettext.prototype._getTranslation = function(domain, msgctxt, msgid) {
msgctxt = msgctxt || '';
return get(this.catalogs, [this.locale, domain, 'translations', msgctxt, msgid]);
};
/**
* Returns the language code part of a locale
*
* @example
* Gettext.getLanguageCode('sv-SE')
* // -> "sv"
*
* @private
* @param {String} locale A case-insensitive locale string
* @returns {String} A language code
*/
Gettext.getLanguageCode = function(locale) {
return locale.split(/[\-_]/)[0].toLowerCase();
};
/* C-style aliases */
/**
* C-style alias for [setTextDomain](#gettextsettextdomaindomain)
*
* @see Gettext#setTextDomain
*/
Gettext.prototype.textdomain = function(domain) {
if (this.debug) {
console.warn('textdomain(domain) was used to set locales in node-gettext v1. ' +
'Make sure you are using it for domains, and switch to setLocale(locale) if you are not.\n\n ' +
'To read more about the migration from node-gettext v1 to v2, ' +
'see https://github.com/alexanderwallin/node-gettext/#migrating-from-1x-to-2x\n\n' +
'This warning will be removed in the final 2.0.0');
}
this.setTextDomain(domain);
};
/**
* C-style alias for [setLocale](#gettextsetlocalelocale)
*
* @see Gettext#setLocale
*/
Gettext.prototype.setlocale = function(locale) {
this.setLomain(locale);
};
/* Deprecated functions */
/**
* This function will be removed in the final 2.0.0 release.
*
* @deprecated
*/
Gettext.prototype.addTextdomain = function() {
console.error('addTextdomain() is deprecated.\n\n' +
'* To add translations, use addTranslations()\n' +
'* To set the default domain, use setTextDomain() (or its alias textdomain())\n' +
'\n' +
'To read more about the migration from node-gettext v1 to v2, ' +
'see https://github.com/alexanderwallin/node-gettext/#migrating-from-1x-to-2x');
};
}).call(this,require('_process'))
},{"./plurals":4,"_process":5,"lodash.get":2}],4:[function(require,module,exports){
'use strict';
module.exports = {
ach: {
name: 'Acholi',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n > 1)',
pluralsFunc: function(n) {
return (n > 1);
}
},
af: {
name: 'Afrikaans',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
ak: {
name: 'Akan',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n > 1)',
pluralsFunc: function(n) {
return (n > 1);
}
},
am: {
name: 'Amharic',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n > 1)',
pluralsFunc: function(n) {
return (n > 1);
}
},
an: {
name: 'Aragonese',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
ar: {
name: 'Arabic',
examples: [{
plural: 0,
sample: 0
}, {
plural: 1,
sample: 1
}, {
plural: 2,
sample: 2
}, {
plural: 3,
sample: 3
}, {
plural: 4,
sample: 11
}, {
plural: 5,
sample: 100
}],
nplurals: 6,
pluralsText: 'nplurals = 6; plural = (n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5)',
pluralsFunc: function(n) {
return (n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
}
},
arn: {
name: 'Mapudungun',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n > 1)',
pluralsFunc: function(n) {
return (n > 1);
}
},
ast: {
name: 'Asturian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
ay: {
name: 'Aymará',
examples: [{
plural: 0,
sample: 1
}],
nplurals: 1,
pluralsText: 'nplurals = 1; plural = 0',
pluralsFunc: function() {
return 0;
}
},
az: {
name: 'Azerbaijani',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
be: {
name: 'Belarusian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}, {
plural: 2,
sample: 5
}],
nplurals: 3,
pluralsText: 'nplurals = 3; plural = (n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2)',
pluralsFunc: function(n) {
return (n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
},
bg: {
name: 'Bulgarian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
bn: {
name: 'Bengali',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
bo: {
name: 'Tibetan',
examples: [{
plural: 0,
sample: 1
}],
nplurals: 1,
pluralsText: 'nplurals = 1; plural = 0',
pluralsFunc: function() {
return 0;
}
},
br: {
name: 'Breton',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n > 1)',
pluralsFunc: function(n) {
return (n > 1);
}
},
brx: {
name: 'Bodo',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
bs: {
name: 'Bosnian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}, {
plural: 2,
sample: 5
}],
nplurals: 3,
pluralsText: 'nplurals = 3; plural = (n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2)',
pluralsFunc: function(n) {
return (n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
},
ca: {
name: 'Catalan',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
cgg: {
name: 'Chiga',
examples: [{
plural: 0,
sample: 1
}],
nplurals: 1,
pluralsText: 'nplurals = 1; plural = 0',
pluralsFunc: function() {
return 0;
}
},
cs: {
name: 'Czech',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}, {
plural: 2,
sample: 5
}],
nplurals: 3,
pluralsText: 'nplurals = 3; plural = (n === 1 ? 0 : (n >= 2 && n <= 4) ? 1 : 2)',
pluralsFunc: function(n) {
return (n === 1 ? 0 : (n >= 2 && n <= 4) ? 1 : 2);
}
},
csb: {
name: 'Kashubian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}, {
plural: 2,
sample: 5
}],
nplurals: 3,
pluralsText: 'nplurals = 3; plural = (n === 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2)',
pluralsFunc: function(n) {
return (n === 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
}
},
cy: {
name: 'Welsh',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}, {
plural: 2,
sample: 3
}, {
plural: 3,
sample: 8
}],
nplurals: 4,
pluralsText: 'nplurals = 4; plural = (n === 1 ? 0 : n === 2 ? 1 : (n !== 8 && n !== 11) ? 2 : 3)',
pluralsFunc: function(n) {
return (n === 1 ? 0 : n === 2 ? 1 : (n !== 8 && n !== 11) ? 2 : 3);
}
},
da: {
name: 'Danish',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
de: {
name: 'German',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
doi: {
name: 'Dogri',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
dz: {
name: 'Dzongkha',
examples: [{
plural: 0,
sample: 1
}],
nplurals: 1,
pluralsText: 'nplurals = 1; plural = 0',
pluralsFunc: function() {
return 0;
}
},
el: {
name: 'Greek',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
en: {
name: 'English',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
eo: {
name: 'Esperanto',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
es: {
name: 'Spanish',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
et: {
name: 'Estonian',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
eu: {
name: 'Basque',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
fa: {
name: 'Persian',
examples: [{
plural: 0,
sample: 1
}],
nplurals: 1,
pluralsText: 'nplurals = 1; plural = 0',
pluralsFunc: function() {
return 0;
}
},
ff: {
name: 'Fulah',
examples: [{
plural: 0,
sample: 1
}, {
plural: 1,
sample: 2
}],
nplurals: 2,
pluralsText: 'nplurals = 2; plural = (n !== 1)',
pluralsFunc: function(n) {
return (n !== 1);
}
},
fi: {
name: 'Finnish',
examples: [{
plural: 0,
sample: 1
}, {