All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.bower_components.cldrjs.dist.cldr.js Maven / Gradle / Ivy

There is a newer version: 0.66.0.1
Show newest version
/**
 * CLDR JavaScript Library v0.4.8
 * http://jquery.com/
 *
 * Copyright 2013 Rafael Xavier de Souza
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2016-11-26T15:03Z
 */
/*!
 * CLDR JavaScript Library v0.4.8 2016-11-26T15:03Z MIT license © Rafael Xavier
 * http://git.io/h4lmVg
 */
(function (root, factory) {

    if (typeof define === "function" && define.amd) {
        // AMD.
        define(factory);
    } else if (typeof module === "object" && typeof module.exports === "object") {
        // Node. CommonJS.
        module.exports = factory();
    } else {
        // Global
        root.Cldr = factory();
    }

}(this, function () {


    var arrayIsArray = Array.isArray || function (obj) {
        return Object.prototype.toString.call(obj) === "[object Array]";
    };


    var pathNormalize = function (path, attributes) {
        if (arrayIsArray(path)) {
            path = path.join("/");
        }
        if (typeof path !== "string") {
            throw new Error("invalid path \"" + path + "\"");
        }
        // 1: Ignore leading slash `/`
        // 2: Ignore leading `cldr/`
        path = path
            .replace(/^\//, "") /* 1 */
            .replace(/^cldr\//, "");
        /* 2 */

        // Replace {attribute}'s
        path = path.replace(/{[a-zA-Z]+}/g, function (name) {
            name = name.replace(/^{([^}]*)}$/, "$1");
            return attributes[name];
        });

        return path.split("/");
    };


    var arraySome = function (array, callback) {
        var i, length;
        if (array.some) {
            return array.some(callback);
        }
        for (i = 0, length = array.length; i < length; i++) {
            if (callback(array[i], i, array)) {
                return true;
            }
        }
        return false;
    };


    /**
     * Return the maximized language id as defined in
     * http://www.unicode.org/reports/tr35/#Likely_Subtags
     * 1. Canonicalize.
     * 1.1 Make sure the input locale is in canonical form: uses the right
     * separator, and has the right casing.
     * TODO Right casing? What df? It seems languages are lowercase, scripts are
     * Capitalized, territory is uppercase. I am leaving this as an exercise to
     * the user.
     *
     * 1.2 Replace any deprecated subtags with their canonical values using the
     *  data in supplemental metadata. Use the first value in the
     * replacement list, if it exists. Language tag replacements may have multiple
     * parts, such as "sh" ➞ "sr_Latn" or mo" ➞ "ro_MD". In such a case, the
     * original script and/or region are retained if there is one. Thus
     * "sh_Arab_AQ" ➞ "sr_Arab_AQ", not "sr_Latn_AQ".
     * TODO What  data?
     *
     * 1.3 If the tag is grandfathered (see  in the supplemental data), then return it.
     * TODO grandfathered?
     *
     * 1.4 Remove the script code 'Zzzz' and the region code 'ZZ' if they occur.
     * 1.5 Get the components of the cleaned-up source tag (languages, scripts,
     * and regions), plus any variants and extensions.
     * 2. Lookup. Lookup each of the following in order, and stop on the first
     * match:
     * 2.1 languages_scripts_regions
     * 2.2 languages_regions
     * 2.3 languages_scripts
     * 2.4 languages
     * 2.5 und_scripts
     * 3. Return
     * 3.1 If there is no match, either return an error value, or the match for
     * "und" (in APIs where a valid language tag is required).
     * 3.2 Otherwise there is a match = languagem_scriptm_regionm
     * 3.3 Let xr = xs if xs is not empty, and xm otherwise.
     * 3.4 Return the language tag composed of languager _ scriptr _ regionr +
     * variants + extensions.
     *
     * @subtags [Array] normalized language id subtags tuple (see init.js).
     */
    var coreLikelySubtags = function (Cldr, cldr, subtags, options) {
        var match, matchFound,
            language = subtags[0],
            script = subtags[1],
            sep = Cldr.localeSep,
            territory = subtags[2],
            variants = subtags.slice(3, 4);
        options = options || {};

        // Skip if (language, script, territory) is not empty [3.3]
        if (language !== "und" && script !== "Zzzz" && territory !== "ZZ") {
            return [language, script, territory].concat(variants);
        }

        // Skip if no supplemental likelySubtags data is present
        if (typeof cldr.get("supplemental/likelySubtags") === "undefined") {
            return;
        }

        // [2]
        matchFound = arraySome([
            [language, script, territory],
            [language, territory],
            [language, script],
            [language],
            ["und", script]
        ], function (test) {
            return match = !(/\b(Zzzz|ZZ)\b/).test(test.join(sep)) /* [1.4] */ && cldr.get(["supplemental/likelySubtags", test.join(sep)]);
        });

        // [3]
        if (matchFound) {
            // [3.2 .. 3.4]
            match = match.split(sep);
            return [
                language !== "und" ? language : match[0],
                script !== "Zzzz" ? script : match[1],
                territory !== "ZZ" ? territory : match[2]
            ].concat(variants);
        } else if (options.force) {
            // [3.1.2]
            return cldr.get("supplemental/likelySubtags/und").split(sep);
        } else {
            // [3.1.1]

        }
    };


    /**
     * Given a locale, remove any fields that Add Likely Subtags would add.
     * http://www.unicode.org/reports/tr35/#Likely_Subtags
     * 1. First get max = AddLikelySubtags(inputLocale). If an error is signaled,
     * return it.
     * 2. Remove the variants from max.
     * 3. Then for trial in {language, language _ region, language _ script}. If
     * AddLikelySubtags(trial) = max, then return trial + variants.
     * 4. If you do not get a match, return max + variants.
     *
     * @maxLanguageId [Array] maxLanguageId tuple (see init.js).
     */
    var coreRemoveLikelySubtags = function (Cldr, cldr, maxLanguageId) {
        var match, matchFound,
            language = maxLanguageId[0],
            script = maxLanguageId[1],
            territory = maxLanguageId[2],
            variants = maxLanguageId[3];

        // [3]
        matchFound = arraySome([
            [[language, "Zzzz", "ZZ"], [language]],
            [[language, "Zzzz", territory], [language, territory]],
            [[language, script, "ZZ"], [language, script]]
        ], function (test) {
            var result = coreLikelySubtags(Cldr, cldr, test[0]);
            match = test[1];
            return result && result[0] === maxLanguageId[0] &&
                result[1] === maxLanguageId[1] &&
                result[2] === maxLanguageId[2];
        });

        if (matchFound) {
            if (variants) {
                match.push(variants);
            }
            return match;
        }

        // [4]
        return maxLanguageId;
    };


    /**
     * subtags( locale )
     *
     * @locale [String]
     */
    var coreSubtags = function (locale) {
        var aux, unicodeLanguageId,
            subtags = [];

        locale = locale.replace(/_/, "-");

        // Unicode locale extensions.
        aux = locale.split("-u-");
        if (aux[1]) {
            aux[1] = aux[1].split("-t-");
            locale = aux[0] + (aux[1][1] ? "-t-" + aux[1][1] : "");
            subtags[4 /* unicodeLocaleExtensions */] = aux[1][0];
        }

        // TODO normalize transformed extensions. Currently, skipped.
        // subtags[ x ] = locale.split( "-t-" )[ 1 ];
        unicodeLanguageId = locale.split("-t-")[0];

        // unicode_language_id = "root"
        //   | unicode_language_subtag
        //     (sep unicode_script_subtag)?
        //     (sep unicode_region_subtag)?
        //     (sep unicode_variant_subtag)* ;
        //
        // Although unicode_language_subtag = alpha{2,8}, I'm using alpha{2,3}. Because, there's no language on CLDR lengthier than 3.
        aux = unicodeLanguageId.match(/^(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)((-([a-zA-Z0-9]{5,8}|[0-9][a-zA-Z0-9]{3}))*)$|^(root)$/);
        if (aux === null) {
            return ["und", "Zzzz", "ZZ"];
        }
        subtags[0 /* language */] = aux[10] /* root */ || aux[2] || "und";
        subtags[1 /* script */] = aux[4] || "Zzzz";
        subtags[2 /* territory */] = aux[6] || "ZZ";
        if (aux[7] && aux[7].length) {
            subtags[3 /* variant */] = aux[7].slice(1) /* remove leading "-" */;
        }

        // 0: language
        // 1: script
        // 2: territory (aka region)
        // 3: variant
        // 4: unicodeLocaleExtensions
        return subtags;
    };


    var arrayForEach = function (array, callback) {
        var i, length;
        if (array.forEach) {
            return array.forEach(callback);
        }
        for (i = 0, length = array.length; i < length; i++) {
            callback(array[i], i, array);
        }
    };


    /**
     * bundleLookup( minLanguageId )
     *
     * @Cldr [Cldr class]
     *
     * @cldr [Cldr instance]
     *
     * @minLanguageId [String] requested languageId after applied remove likely subtags.
     */
    var bundleLookup = function (Cldr, cldr, minLanguageId) {
        var availableBundleMap = Cldr._availableBundleMap,
            availableBundleMapQueue = Cldr._availableBundleMapQueue;

        if (availableBundleMapQueue.length) {
            arrayForEach(availableBundleMapQueue, function (bundle) {
                var existing, maxBundle, minBundle, subtags;
                subtags = coreSubtags(bundle);
                maxBundle = coreLikelySubtags(Cldr, cldr, subtags);
                minBundle = coreRemoveLikelySubtags(Cldr, cldr, maxBundle);
                minBundle = minBundle.join(Cldr.localeSep);
                existing = availableBundleMapQueue[minBundle];
                if (existing && existing.length < bundle.length) {
                    return;
                }
                availableBundleMap[minBundle] = bundle;
            });
            Cldr._availableBundleMapQueue = [];
        }

        return availableBundleMap[minLanguageId] || null;
    };


    var objectKeys = function (object) {
        var i,
            result = [];

        if (Object.keys) {
            return Object.keys(object);
        }

        for (i in object) {
            result.push(i);
        }

        return result;
    };


    var createError = function (code, attributes) {
        var error, message;

        message = code + (attributes && JSON ? ": " + JSON.stringify(attributes) : "");
        error = new Error(message);
        error.code = code;

        // extend( error, attributes );
        arrayForEach(objectKeys(attributes), function (attribute) {
            error[attribute] = attributes[attribute];
        });

        return error;
    };


    var validate = function (code, check, attributes) {
        if (!check) {
            throw createError(code, attributes);
        }
    };


    var validatePresence = function (value, name) {
        validate("E_MISSING_PARAMETER", typeof value !== "undefined", {
            name: name
        });
    };


    var validateType = function (value, name, check, expected) {
        validate("E_INVALID_PAR_TYPE", check, {
            expected: expected,
            name: name,
            value: value
        });
    };


    var validateTypePath = function (value, name) {
        validateType(value, name, typeof value === "string" || arrayIsArray(value), "String or Array");
    };


    /**
     * Function inspired by jQuery Core, but reduced to our use case.
     */
    var isPlainObject = function (obj) {
        return obj !== null && "" + obj === "[object Object]";
    };


    var validateTypePlainObject = function (value, name) {
        validateType(value, name, typeof value === "undefined" || isPlainObject(value), "Plain Object");
    };


    var validateTypeString = function (value, name) {
        validateType(value, name, typeof value === "string", "a string");
    };


    // @path: normalized path
    var resourceGet = function (data, path) {
        var i,
            node = data,
            length = path.length;

        for (i = 0; i < length - 1; i++) {
            node = node[path[i]];
            if (!node) {
                return undefined;
            }
        }
        return node[path[i]];
    };


    /**
     * setAvailableBundles( Cldr, json )
     *
     * @Cldr [Cldr class]
     *
     * @json resolved/unresolved cldr data.
     *
     * Set available bundles queue based on passed json CLDR data. Considers a bundle as any String at /main/{bundle}.
     */
    var coreSetAvailableBundles = function (Cldr, json) {
        var bundle,
            availableBundleMapQueue = Cldr._availableBundleMapQueue,
            main = resourceGet(json, ["main"]);

        if (main) {
            for (bundle in main) {
                if (main.hasOwnProperty(bundle) && bundle !== "root" &&
                    availableBundleMapQueue.indexOf(bundle) === -1) {
                    availableBundleMapQueue.push(bundle);
                }
            }
        }
    };


    var alwaysArray = function (somethingOrArray) {
        return arrayIsArray(somethingOrArray) ? somethingOrArray : [somethingOrArray];
    };


    var jsonMerge = (function () {

        // Returns new deeply merged JSON.
        //
        // Eg.
        // merge( { a: { b: 1, c: 2 } }, { a: { b: 3, d: 4 } } )
        // -> { a: { b: 3, c: 2, d: 4 } }
        //
        // @arguments JSON's
        //
        var merge = function () {
            var destination = {},
                sources = [].slice.call(arguments, 0);
            arrayForEach(sources, function (source) {
                var prop;
                for (prop in source) {
                    if (prop in destination && typeof destination[prop] === "object" && !arrayIsArray(destination[prop])) {

                        // Merge Objects
                        destination[prop] = merge(destination[prop], source[prop]);

                    } else {

                        // Set new values
                        destination[prop] = source[prop];

                    }
                }
            });
            return destination;
        };

        return merge;

    }());


    /**
     * load( Cldr, source, jsons )
     *
     * @Cldr [Cldr class]
     *
     * @source [Object]
     *
     * @jsons [arguments]
     */
    var coreLoad = function (Cldr, source, jsons) {
        var i, j, json;

        validatePresence(jsons[0], "json");

        // Support arbitrary parameters, e.g., `Cldr.load({...}, {...})`.
        for (i = 0; i < jsons.length; i++) {

            // Support array parameters, e.g., `Cldr.load([{...}, {...}])`.
            json = alwaysArray(jsons[i]);

            for (j = 0; j < json.length; j++) {
                validateTypePlainObject(json[j], "json");
                source = jsonMerge(source, json[j]);
                coreSetAvailableBundles(Cldr, json[j]);
            }
        }

        return source;
    };


    var itemGetResolved = function (Cldr, path, attributes) {
        // Resolve path
        var normalizedPath = pathNormalize(path, attributes);

        return resourceGet(Cldr._resolved, normalizedPath);
    };


    /**
     * new Cldr()
     */
    var Cldr = function (locale) {
        this.init(locale);
    };

    // Build optimization hack to avoid duplicating functions across modules.
    Cldr._alwaysArray = alwaysArray;
    Cldr._coreLoad = coreLoad;
    Cldr._createError = createError;
    Cldr._itemGetResolved = itemGetResolved;
    Cldr._jsonMerge = jsonMerge;
    Cldr._pathNormalize = pathNormalize;
    Cldr._resourceGet = resourceGet;
    Cldr._validatePresence = validatePresence;
    Cldr._validateType = validateType;
    Cldr._validateTypePath = validateTypePath;
    Cldr._validateTypePlainObject = validateTypePlainObject;

    Cldr._availableBundleMap = {};
    Cldr._availableBundleMapQueue = [];
    Cldr._resolved = {};

    // Allow user to override locale separator "-" (default) | "_". According to http://www.unicode.org/reports/tr35/#Unicode_language_identifier, both "-" and "_" are valid locale separators (eg. "en_GB", "en-GB"). According to http://unicode.org/cldr/trac/ticket/6786 its usage must be consistent throughout the data set.
    Cldr.localeSep = "-";

    /**
     * Cldr.load( json [, json, ...] )
     *
     * @json [JSON] CLDR data or [Array] Array of @json's.
     *
     * Load resolved cldr data.
     */
    Cldr.load = function () {
        Cldr._resolved = coreLoad(Cldr, Cldr._resolved, arguments);
    };

    /**
     * .init() automatically run on instantiation/construction.
     */
    Cldr.prototype.init = function (locale) {
        var attributes, language, maxLanguageId, minLanguageId, script, subtags, territory, unicodeLocaleExtensions,
            variant,
            sep = Cldr.localeSep,
            unicodeLocaleExtensionsRaw = "";

        validatePresence(locale, "locale");
        validateTypeString(locale, "locale");

        subtags = coreSubtags(locale);

        if (subtags.length === 5) {
            unicodeLocaleExtensions = subtags.pop();
            unicodeLocaleExtensionsRaw = sep + "u" + sep + unicodeLocaleExtensions;
            // Remove trailing null when there is unicodeLocaleExtensions but no variants.
            if (!subtags[3]) {
                subtags.pop();
            }
        }
        variant = subtags[3];

        // Normalize locale code.
        // Get (or deduce) the "triple subtags": language, territory (also aliased as region), and script subtags.
        // Get the variant subtags (calendar, collation, currency, etc).
        // refs:
        // - http://www.unicode.org/reports/tr35/#Field_Definitions
        // - http://www.unicode.org/reports/tr35/#Language_and_Locale_IDs
        // - http://www.unicode.org/reports/tr35/#Unicode_locale_identifier

        // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags.
        maxLanguageId = coreLikelySubtags(Cldr, this, subtags, {force: true}) || subtags;
        language = maxLanguageId[0];
        script = maxLanguageId[1];
        territory = maxLanguageId[2];

        minLanguageId = coreRemoveLikelySubtags(Cldr, this, maxLanguageId).join(sep);

        // Set attributes
        this.attributes = attributes = {
            bundle: bundleLookup(Cldr, this, minLanguageId),

            // Unicode Language Id
            minLanguageId: minLanguageId + unicodeLocaleExtensionsRaw,
            maxLanguageId: maxLanguageId.join(sep) + unicodeLocaleExtensionsRaw,

            // Unicode Language Id Subtabs
            language: language,
            script: script,
            territory: territory,
            region: territory, /* alias */
            variant: variant
        };

        // Unicode locale extensions.
        unicodeLocaleExtensions && ("-" + unicodeLocaleExtensions).replace(/-[a-z]{3,8}|(-[a-z]{2})-([a-z]{3,8})/g, function (attribute, key, type) {

            if (key) {

                // Extension is in the `keyword` form.
                attributes["u" + key] = type;
            } else {

                // Extension is in the `attribute` form.
                attributes["u" + attribute] = true;
            }
        });

        this.locale = locale;
    };

    /**
     * .get()
     */
    Cldr.prototype.get = function (path) {

        validatePresence(path, "path");
        validateTypePath(path, "path");

        return itemGetResolved(Cldr, path, this.attributes);
    };

    /**
     * .main()
     */
    Cldr.prototype.main = function (path) {
        validatePresence(path, "path");
        validateTypePath(path, "path");

        validate("E_MISSING_BUNDLE", this.attributes.bundle !== null, {
            locale: this.locale
        });

        path = alwaysArray(path);
        return this.get(["main/{bundle}"].concat(path));
    };

    return Cldr;


}));




© 2015 - 2024 Weber Informatics LLC | Privacy Policy