<commit_before>'use strict';

var Signal = require('signals'),
    request = require('superagent'),
    xtend = require('xtend'),
    queryString = require('query-string');

var opts = null,
    defaults = {
      lang: 'en',
      locales: ['en'],
      directory: '/locales/',
      prefix: '-',
      ext: '.json'
    };

/**
 * i18n
 * @module utils/i18n
 */
module.exports = {

  /**
   * @readonly
   **/
  lang: '',

  /**
   * @readonly
   **/
  translations: null,

  /**
   * @readonly
   **/
  loaded: new Signal(),

  /**
   * //
   * @method load
   **/
  load: function(options) {

    opts = xtend(defaults, options);

    this.lang = getLangUrlParams() ? getLangUrlParams() : getLangBrowser();

    request
      .get(opts.directory + this.lang + opts.ext)
      .end(function(response){

        if(response.ok) {

          this.translations = response.text;
          this.loaded.dispatch();

        } else {
          console.warn('Unable to load i18n file :: ' + this.lang);
        }

      }.bind(this));
  },

  /**
   * //
   * @method toString
   * @return {String} a string representation of the instance.
   **/
  toString: function() {

    return '[utils/I18n (lang='+this.lang+')]';
  }
};

/**
 * //
 * @method getLangBrowser
 * @private
 * @return {String}
 **/
function getLangBrowser() {

  var lang;

  if (navigator.languages) {
    // chrome does not currently set navigator.language correctly https://code.google.com/p/chromium/issues/detail?id=101138
    // but it does set the first element of navigator.languages correctly
    lang = navigator.languages[0];
  } else if (navigator.userLanguage) {
    // IE only
    lang = navigator.userLanguage;
  } else {
    // as of this writing the latest version of firefox + safari set this correctly
    lang = navigator.language;
  }

  return getValidLang(lang, false);

}

/**
 * //
 * @method getLangUrlParams
 * @private
 * @return {String}
 **/
function getLangUrlParams() {

  var params = queryString.parse(location.search);

  if(params && params.lang) {
    return getValidLang(params.lang, true);
  }

  return null;
}

/**
 * //
 * @method getValidLang
 * @private
 * @param {String} lang
 * @param {Boolean} isUrlParams
 * @return {String}
 **/
function getValidLang(lang, isUrlParams) {

  var lr = lang.split('-', 2),
    parentLang = lr[0],
    l = '',
    isValid = false,
    hasRegion = false;

  for (var i = 0, numLocales = opts.locales.length; i < numLocales; i++) {

    if(lang.toLowerCase() === opts.locales[i]) {

      hasRegion = true;
      isValid = true;
      l = lang.toLowerCase();

    } else {

      if(parentLang.toLowerCase() === opts.locales[i] && !hasRegion) {

        isValid = true;
        l =  parentLang.toLowerCase();
      }
    }
  }

  if(isUrlParams) {
    return (isValid) ? l : null;
  } else {
    return (isValid) ? l : opts.lang;
  }
}
<commit_msg>Added default lang (validation)<commit_after>'use strict';

var Signal = require('signals'),
    request = require('superagent'),
    xtend = require('xtend'),
    queryString = require('query-string');

var opts = null,
    defaults = {
      lang: 'en',
      locales: ['en'],
      directory: '/locales/',
      prefix: '-',
      ext: '.json'
    };

/**
 * i18n
 * @module utils/i18n
 */
module.exports = {

  /**
   * @readonly
   **/
  lang: '',

  /**
   * @readonly
   **/
  translations: null,

  /**
   * @readonly
   **/
  loaded: new Signal(),

  /**
   * //
   * @method load
   **/
  load: function(options) {

    opts = xtend(defaults, options);

    this.lang = getLangUrlParams() ? getLangUrlParams() : getLangBrowser();

    request
      .get(opts.directory + this.lang + opts.ext)
      .end(function(response){

        if(response.ok) {

          this.translations = response.text;
          this.loaded.dispatch();

        } else {
          console.warn('Unable to load i18n file :: ' + this.lang);
        }

      }.bind(this));
  },

  /**
   * //
   * @method toString
   * @return {String} a string representation of the instance.
   **/
  toString: function() {

    return '[utils/I18n (lang='+this.lang+')]';
  }
};

/**
 * //
 * @method getLangBrowser
 * @private
 * @return {String}
 **/
function getLangBrowser() {

  var lang;

  if (navigator.languages) {
    // chrome does not currently set navigator.language correctly https://code.google.com/p/chromium/issues/detail?id=101138
    // but it does set the first element of navigator.languages correctly
    lang = navigator.languages[0];
  } else if (navigator.userLanguage) {
    // IE only
    lang = navigator.userLanguage;
  } else {
    // as of this writing the latest version of firefox + safari set this correctly
    lang = navigator.language;
  }

  return getValidLang(lang, false);

}

/**
 * //
 * @method getLangUrlParams
 * @private
 * @return {String}
 **/
function getLangUrlParams() {

  var params = queryString.parse(location.search);

  if(params && params.lang) {
    return getValidLang(params.lang, true);
  }

  return null;
}

/**
 * //
 * @method getValidLang
 * @private
 * @param {String} lang
 * @param {Boolean} isUrlParams
 * @return {String}
 **/
function getValidLang(lang, isUrlParams) {

  if(lang == null) {
    return opts.lang;
  }

  var lr = lang.split('-', 2),
    parentLang = lr[0],
    l = '',
    isValid = false,
    hasRegion = false;

  for (var i = 0, numLocales = opts.locales.length; i < numLocales; i++) {

    if(lang.toLowerCase() === opts.locales[i]) {

      hasRegion = true;
      isValid = true;
      l = lang.toLowerCase();

    } else {

      if(parentLang.toLowerCase() === opts.locales[i] && !hasRegion) {

        isValid = true;
        l =  parentLang.toLowerCase();
      }
    }
  }

  if(isUrlParams) {
    return (isValid) ? l : null;
  } else {
    return (isValid) ? l : opts.lang;
  }
}

{'fraction_non_alphanumeric': 0.16010947656517277, 'fraction_numerical': 0.006158056790968184, 'mean_word_length': 2.433352906635349, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4586293', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1933, 'n_words': 435}