(function(h){functionv(a){a.debug&&(f("callbackIfComplete()"),f("totalFiles: "+a.totalFiles),f("filesLoaded: "+a.filesLoaded));a.async&&a.filesLoaded===a.totalFiles&&a.callback&&a.callback()}functionn(a,c){c.debug&&f("loadAndParseFiles");null!==a&&0<a.length?w(a[0],c,function(){a.shift();n(a,c)}):v(c)}functionw(a,c,m){c.debug&&(f("loadAndParseFile('"+a+"')"),f("totalFiles: "+c.totalFiles),f("filesLoaded: "+c.filesLoaded));null!==a&&"undefined"!==typeof a&&h.ajax({url:a,async:c.async,cache:c.cache,
dataType:"text",success:function(e,b){c.debug&&(f("Succeeded in downloading "+a+"."),f(e));x(e,c);m()},error:function(e,b,d){c.debug&&f("Failed to download or parse "+a+". errorThrown: "+d);404===e.status&&--c.totalFiles;m()}})}functionx(a,c){for(var m="",e=a.split(/\n/),b=/(\{\d+})/g,d=/\{(\d+)}/g,k=/(\\u.{4})/ig,f=0,n=e.length;f<n;f++){var l=e[f],l=l.trim();if(0<l.length&&"#"!=l.match("^#")){var p=l.split("=");if(0<p.length){for(var l=decodeURI(p[0]).trim(),g=1==p.length?"":p[1];-1!=g.search(/\\$/);)g=
g.substring(0,g.length-1),g+=e[++f].trimRight();for(var q=2;q<p.length;q++)g+="="+p[q];g=g.trim();if("map"==c.mode||"both"==c.mode)(p=g.match(k))&&p.forEach(function(a){g=g.replace(a,y(a))}),c.namespace?h.i18n.map[c.namespace][l]=g:h.i18n.map[l]=g;if("vars"==c.mode||"both"==c.mode)if(g=g.replace(/"/g,'\\"'),z(l),b.test(g)){var u=!0,r="",t=[];g.split(b).forEach(function(a){!b.test(a)||0!==t.length&&-1!=t.indexOf(a)||(u||(r+=","),r+=a.replace(d,"v$1"),t.push(a),u=!1)});m+=l+"=function("+r+"){";l='"'+
g.replace(d,'"+v$1+"')+'"';m+="return "+l+";};"}else m+=l+'="'+g+'";'}}}eval(m);c.filesLoaded+=1}functionz(a){if(/\./.test(a)){var c="";a=a.split(/\./);for(var m=0,e=a.length;m<e;m++){var b=a[m];0<m&&(c+=".");c+=b;eval("typeof "+c+' == "undefined"')&&eval(c+"={};")}}}functiony(a){var c=[];a=parseInt(a.substr(2),16);0<=a&&a<Math.pow(2,16)&&c.push(a);return c.reduce(function(a,c){return a+String.fromCharCode(c)},"")}h.i18n={};h.i18n.map={};varf=function(a){window.console&&console.log("i18n::"+a)};
h.i18n.properties=function(a){a=h.extend({name:"Messages",language:"",path:"",namespace:null,mode:"vars",cache:!1,debug:!1,encoding:"UTF-8",async:!1,callback:null},a);a.namespace&&"string"==typeof a.namespace&&(a.namespace.match(/^[a-z]*$/)?h.i18n.map[a.namespace]={}:(f("Namespaces can only be lower case letters, a - z"),a.namespace=null));a.path.match(/\/$/)||(a.path+="/");a.language=this.normaliseLanguageCode(a);var c=a.name&&a.name.constructor===Array?a.name:[a.name];a.totalFiles=2*c.length+(5<=
a.language.length?c.length:0);a.debug&&f("totalFiles: "+a.totalFiles);a.filesLoaded=0;c.forEach(function(c){var e=a.path+c+".properties";var b=a.language.substring(0,2);b=a.path+c+"_"+b+".properties";if(5<=a.language.length){var d=a.language.substring(0,5);c=a.path+c+"_"+d+".properties";e=[e,b,c]}else e=[e,b];n(e,a)});a.callback&&!a.async&&a.callback()};h.i18n.prop=function(a){var c=[].slice.call(arguments);if(2==c.length)if(h.isArray(c[1]))var f=c[1];elseif("object"===typeof c[1]){var e=c[1].namespace;var b=c[1].replacements;c.splice(-1,1);b&&Array.prototype.push.apply(c,b)}b=e?h.i18n.map[e][a]:h.i18n.map[a];if(null===b)return"["+(e?e+"#"+a:a)+"]";var d;if("string"==typeof b){for(d=0;-1!=(d=b.indexOf("\\",d));)b="t"==b.charAt(d+1)?b.substring(0,d)+"\t"+b.substring(d+++2):"r"==b.charAt(d+1)?b.substring(0,d)+"\r"+b.substring(d+++2):"n"==b.charAt(d+1)?b.substring(0,d)+"\n"+b.substring(d+++2):"f"==b.charAt(d+1)?b.substring(0,d)+"\f"+b.substring(d+++2):"\\"==b.charAt(d+1)?b.substring(0,d)+"\\"+
b.substring(d+++2):b.substring(0,d)+b.substring(d+1);var k=[];for(d=0;d<b.length;)if("'"==b.charAt(d))if(d==b.length-1)b=b.substring(0,d);elseif("'"==b.charAt(d+1))b=b.substring(0,d)+b.substring(++d);else{for(e=d+2;-1!=(e=b.indexOf("'",e));)if(e==b.length-1||"'"!=b.charAt(e+1)){b=b.substring(0,d)+b.substring(d+1,e)+b.substring(e+1);d=e-1;break}else b=b.substring(0,e)+b.substring(++e);-1==e&&(b=b.substring(0,d)+b.substring(d+1))}elseif("{"==b.charAt(d))if(e=b.indexOf("}",d+1),-1==e)d++;else{var n=parseInt(b.substring(d+1,e));!isNaN(n)&&0<=n?(d=b.substring(0,d),""!==d&&k.push(d),k.push(n),d=0,b=b.substring(e+1)):d=e+1}else d++;""!==b&&k.push(b);b=k;settings.namespace?h.i18n.map[settings.namespace][a]=k:h.i18n.map[a]=k}if(0===b.length)return"";if(1==b.length&&"string"==typeof b[0])return b[0];k="";d=0;for(e=b.length;d<e;d++)k="string"==typeof b[d]?k+b[d]:f&&b[d]<f.length?k+f[b[d]]:!f&&b[d]+1<c.length?k+c[b[d]+1]:k+("{"+b[d]+"}");return k};h.i18n.normaliseLanguageCode=function(a){var c=a.language;if(!c||2>c.length)a.debug&&f("No language supplied. Pulling it from the browser ..."),c=navigator.languages&&0<navigator.languages.length?navigator.languages[0]:navigator.language||navigator.userLanguage||"en",a.debug&&f("Language from browser: "+c);c=c.toLowerCase();c=c.replace(/-/,"_");3<c.length&&(c=c.substring(0,3)+c.substring(3).toUpperCase());return c}})(jQuery);
jquery.i18n.properties.js
/******************************************************************************
* jquery.i18n.properties
*
* Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
* MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
*
* @version 1.2.7
* @url https://github.com/jquery-i18n-properties/jquery-i18n-properties
* @inspiration Localisation assistance for jQuery (http://keith-wood.name/localisation.html)
* by Keith Wood (kbwood{at}iinet.com.au) June 2007
*
*****************************************************************************/(function($){
$.i18n ={};/**
* Map holding bundle keys if mode is 'map' or 'both'. Values of this can also be an
* Object, in which case the key is a namespace.
*/
$.i18n.map ={};vardebug=function(message){
window.console && console.log('i18n::'+ message);};/**
* Load and parse message bundle files (.properties),
* making bundles keys available as javascript variables.
*
* i18n files are named <name>.js, or <name>_<language>.js or <name>_<language>_<country>.js
* Where:
* The <language> argument is a valid ISO Language Code. These codes are the lower-case,
* two-letter codes as defined by ISO-639. You can find a full list of these codes at a
* number of sites, such as: http://www.loc.gov/standards/iso639-2/englangn.html
* The <country> argument is a valid ISO Country Code. These codes are the upper-case,
* two-letter codes as defined by ISO-3166. You can find a full list of these codes at a
* number of sites, such as: http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
*
* Sample usage for a bundles/Messages.properties bundle:
* $.i18n.properties({
* name: 'Messages',
* language: 'en_US',
* path: 'bundles'
* });
* @param name (string/string[], optional) names of file to load (eg, 'Messages' or ['Msg1','Msg2']). Defaults to "Messages"
* @param language (string, optional) language/country code (eg, 'en', 'en_US', 'pt_BR'). if not specified, language reported by the browser will be used instead.
* @param path (string, optional) path of directory that contains file to load
* @param mode (string, optional) whether bundles keys are available as JavaScript variables/functions or as a map (eg, 'vars' or 'map')
* @param debug (boolean, optional) whether debug statements are logged at the console
* @param cache (boolean, optional) whether bundles should be cached by the browser, or forcibly reloaded on each page load. Defaults to false (i.e. forcibly reloaded)
* @param encoding (string, optional) the encoding to request for bundles. Property file resource bundles are specified to be in ISO-8859-1 format. Defaults to UTF-8 for backward compatibility.
* @param callback (function, optional) callback function to be called after script is terminated
*/
$.i18n.properties=function(settings){var defaults ={
name:'Messages',
language:'',
path:'',
namespace:null,
mode:'vars',
cache:false,
debug:false,
encoding:'UTF-8',async:false,
callback:null};
settings = $.extend(defaults, settings);if(settings.namespace &&typeof settings.namespace =='string'){// A namespace has been supplied, initialise it.if(settings.namespace.match(/^[a-z]*$/)){
$.i18n.map[settings.namespace]={};}else{debug('Namespaces can only be lower case letters, a - z');
settings.namespace =null;}}// Ensure a trailing slash on the pathif(!settings.path.match(/\/$/)) settings.path +='/';// Try to ensure that we have at a least a two letter language code
settings.language =this.normaliseLanguageCode(settings);// Ensure an arrayvar files =(settings.name && settings.name.constructor === Array)? settings.name :[settings.name];// A locale is at least a language code which means at least two files per name. If// we also have a country code, thats an extra file per name.
settings.totalFiles =(files.length *2)+((settings.language.length >=5)? files.length :0);if(settings.debug){debug('totalFiles: '+ settings.totalFiles);}
settings.filesLoaded =0;
files.forEach(function(file){var defaultFileName, shortFileName, longFileName, fileNames;// 1. load base (eg, Messages.properties)
defaultFileName = settings.path + file +'.properties';// 2. with language code (eg, Messages_pt.properties)var shortCode = settings.language.substring(0,2);
shortFileName = settings.path + file +'_'+ shortCode +'.properties';// 3. with language code and country code (eg, Messages_pt_BR.properties)if(settings.language.length >=5){var longCode = settings.language.substring(0,5);
longFileName = settings.path + file +'_'+ longCode +'.properties';
fileNames =[defaultFileName, shortFileName, longFileName];}else{
fileNames =[defaultFileName, shortFileName];}loadAndParseFiles(fileNames, settings);});// call callbackif(settings.callback &&!settings.async){
settings.callback();}};// properties/**
* When configured with mode: 'map', allows access to bundle values by specifying its key.
* Eg, jQuery.i18n.prop('com.company.bundles.menu_add')
*/
$.i18n.prop=function(key /* Add parameters as function arguments as necessary */){var args =[].slice.call(arguments);var phvList, namespace;if(args.length ==2){if($.isArray(args[1])){// An array was passed as the second parameter, so assume it is the list of place holder values.
phvList = args[1];}elseif(typeof args[1]==='object'){// Second argument is an options object {namespace: 'mynamespace', replacements: ['egg', 'nog']}
namespace = args[1].namespace;var replacements = args[1].replacements;
args.splice(-1,1);if(replacements){
Array.prototype.push.apply(args, replacements);}}}var value =(namespace)? $.i18n.map[namespace][key]: $.i18n.map[key];if(value ===null){return'['+((namespace)? namespace +'#'+ key : key)+']';}// Place holder replacement/**
* Tested with:
* test.t1=asdf ''{0}''
* test.t2=asdf '{0}' '{1}'{1}'zxcv
* test.t3=This is \"a quote" 'a''{0}''s'd{fgh{ij'
* test.t4="'''{'0}''" {0}{a}
* test.t5="'''{0}'''" {1}
* test.t6=a {1} b {0} c
* test.t7=a 'quoted \\ s\ttringy' \t\t x
*
* Produces:
* test.t1, p1 ==> asdf 'p1'
* test.t2, p1 ==> asdf {0} {1}{1}zxcv
* test.t3, p1 ==> This is "a quote" a'{0}'sd{fgh{ij
* test.t4, p1 ==> "'{0}'" p1{a}
* test.t5, p1 ==> "'{0}'" {1}
* test.t6, p1 ==> a {1} b p1 c
* test.t6, p1, p2 ==> a p2 b p1 c
* test.t6, p1, p2, p3 ==> a p2 b p1 c
* test.t7 ==> a quoted \ s tringy x
*/var i;if(typeof(value)=='string'){// Handle escape characters. Done separately from the tokenizing loop below because escape characters are// active in quoted strings.
i =0;while((i = value.indexOf('\\', i))!=-1){if(value.charAt(i +1)=='t'){
value = value.substring(0, i)+'\t'+ value.substring((i++)+2);// tab}elseif(value.charAt(i +1)=='r'){
value = value.substring(0, i)+'\r'+ value.substring((i++)+2);// return}elseif(value.charAt(i +1)=='n'){
value = value.substring(0, i)+'\n'+ value.substring((i++)+2);// line feed}elseif(value.charAt(i +1)=='f'){
value = value.substring(0, i)+'\f'+ value.substring((i++)+2);// form feed}elseif(value.charAt(i +1)=='\\'){
value = value.substring(0, i)+'\\'+ value.substring((i++)+2);// \}else{
value = value.substring(0, i)+ value.substring(i +1);// Quietly drop the character}}// Lazily convert the string to a list of tokens.var arr =[], j, index;
i =0;while(i < value.length){if(value.charAt(i)=='\''){// Handle quotesif(i == value.length -1){
value = value.substring(0, i);// Silently drop the trailing quote}elseif(value.charAt(i +1)=='\''){
value = value.substring(0, i)+ value.substring(++i);// Escaped quote}else{// Quoted string
j = i +2;while((j = value.indexOf('\'', j))!=-1){if(j == value.length -1|| value.charAt(j +1)!='\''){// Found start and end quotes. Remove them
value = value.substring(0, i)+ value.substring(i +1, j)+ value.substring(j +1);
i = j -1;break;}else{// Found a double quote, reduce to a single quote.
value = value.substring(0, j)+ value.substring(++j);}}if(j ==-1){// There is no end quote. Drop the start quote
value = value.substring(0, i)+ value.substring(i +1);}}}elseif(value.charAt(i)=='{'){// Beginning of an unquoted place holder.
j = value.indexOf('}', i +1);if(j ==-1){
i++;// No end. Process the rest of the line. Java would throw an exception}else{// Add 1 to the index so that it aligns with the function arguments.
index =parseInt(value.substring(i +1, j));if(!isNaN(index)&& index >=0){// Put the line thus far (if it isn't empty) into the arrayvar s = value.substring(0, i);if(s !==""){
arr.push(s);}// Put the parameter reference into the array
arr.push(index);// Start the processing over again starting from the rest of the line.
i =0;
value = value.substring(j +1);}else{
i = j +1;// Invalid parameter. Leave as is.}}}else{
i++;}}// while// Put the remainder of the no-empty line into the array.if(value !==""){
arr.push(value);}
value = arr;// Make the array the value for the entry.if(namespace){
$.i18n.map[settings.namespace][key]= arr;}else{
$.i18n.map[key]= arr;}}if(value.length ===0){return"";}if(value.length ==1&&typeof(value[0])=="string"){return value[0];}var str ="";for(i =0, j = value.length; i < j; i++){if(typeof(value[i])=="string"){
str += value[i];}elseif(phvList && value[i]< phvList.length){// Must be a number
str += phvList[value[i]];}elseif(!phvList && value[i]+1< args.length){
str += args[value[i]+1];}else{
str +="{"+ value[i]+"}";}}return str;};functioncallbackIfComplete(settings){if(settings.debug){debug('callbackIfComplete()');debug('totalFiles: '+ settings.totalFiles);debug('filesLoaded: '+ settings.filesLoaded);}if(settings.async){if(settings.filesLoaded === settings.totalFiles){if(settings.callback){
settings.callback();}}}}functionloadAndParseFiles(fileNames, settings){if(settings.debug)debug('loadAndParseFiles');if(fileNames !==null&& fileNames.length >0){loadAndParseFile(fileNames[0], settings,function(){
fileNames.shift();loadAndParseFiles(fileNames,settings);});}else{callbackIfComplete(settings);}}/** Load and parse .properties files */functionloadAndParseFile(filename, settings, nextFile){if(settings.debug){debug('loadAndParseFile(\''+ filename +'\')');debug('totalFiles: '+ settings.totalFiles);debug('filesLoaded: '+ settings.filesLoaded);}if(filename !==null&&typeof filename !=='undefined'){
$.ajax({
url: filename,async: settings.async,
cache: settings.cache,
dataType:'text',
success:function(data, status){if(settings.debug){debug('Succeeded in downloading '+ filename +'.');debug(data);}parseData(data, settings);nextFile();},
error:function(jqXHR, textStatus, errorThrown){if(settings.debug){debug('Failed to download or parse '+ filename +'. errorThrown: '+ errorThrown);}if(jqXHR.status ===404){
settings.totalFiles -=1;}nextFile();}});}}/** Parse .properties files */functionparseData(data, settings){var parsed ='';var lines = data.split(/\n/);var regPlaceHolder =/(\{\d+})/g;var regRepPlaceHolder =/\{(\d+)}/g;var unicodeRE =/(\\u.{4})/ig;for(var i=0,j=lines.length;i<j;i++){var line = lines[i];
line = line.trim();if(line.length >0&& line.match("^#")!="#"){// skip commentsvar pair = line.split('=');if(pair.length >0){/** Process key & value */var name =decodeURI(pair[0]).trim();var value = pair.length ==1?"": pair[1];// process multi-line valueswhile(value.search(/\\$/)!=-1){
value = value.substring(0, value.length -1);
value += lines[++i].trimRight();}// Put values with embedded '='s back togetherfor(var s =2; s < pair.length; s++){
value +='='+ pair[s];}
value = value.trim();/** Mode: bundle keys in a map */if(settings.mode =='map'|| settings.mode =='both'){// handle unicode chars possibly left outvar unicodeMatches = value.match(unicodeRE);if(unicodeMatches){
unicodeMatches.forEach(function(match){
value = value.replace(match,unescapeUnicode(match));});}// add to mapif(settings.namespace){
$.i18n.map[settings.namespace][name]= value;}else{
$.i18n.map[name]= value;}}/** Mode: bundle keys as vars/functions */if(settings.mode =='vars'|| settings.mode =='both'){
value = value.replace(/"/g,'\\"');// escape quotation mark (")// make sure namespaced key exists (eg, 'some.key')checkKeyNamespace(name);// value with variable substitutionsif(regPlaceHolder.test(value)){var parts = value.split(regPlaceHolder);// process function argsvar first =true;var fnArgs ='';var usedArgs =[];
parts.forEach(function(part){if(regPlaceHolder.test(part)&&(usedArgs.length ===0|| usedArgs.indexOf(part)==-1)){if(!first){
fnArgs +=',';}
fnArgs += part.replace(regRepPlaceHolder,'v$1');
usedArgs.push(part);
first =false;}});
parsed += name +'=function('+ fnArgs +'){';// process function bodyvar fnExpr ='"'+ value.replace(regRepPlaceHolder,'"+v$1+"')+'"';
parsed +='return '+ fnExpr +';'+'};';// simple value}else{
parsed += name +'="'+ value +'";';}}// END: Mode: bundle keys as vars/functions}// END: if(pair.length > 0)}// END: skip comments}eval(parsed);
settings.filesLoaded +=1;}/** Make sure namespace exists (for keys with dots in name) */// TODO key parts that start with numbers quietly fail. i.e. month.short.1=JanfunctioncheckKeyNamespace(key){var regDot =/\./;if(regDot.test(key)){var fullname ='';var names = key.split(/\./);for(var i=0,j=names.length;i<j;i++){var name = names[i];if(i >0){
fullname +='.';}
fullname += name;if(eval('typeof '+ fullname +' == "undefined"')){eval(fullname +'={};');}}}}/** Ensure language code is in the format aa_AA. */
$.i18n.normaliseLanguageCode=function(settings){var lang = settings.language;if(!lang || lang.length <2){if(settings.debug)debug('No language supplied. Pulling it from the browser ...');
lang =(navigator.languages && navigator.languages.length >0)? navigator.languages[0]:(navigator.language || navigator.userLanguage /* IE */||'en');if(settings.debug)debug('Language from browser: '+ lang);}
lang = lang.toLowerCase();
lang = lang.replace(/-/,"_");// some browsers report language as en-US instead of en_USif(lang.length >3){
lang = lang.substring(0,3)+ lang.substring(3).toUpperCase();}return lang;};/** Unescape unicode chars ('\u00e3') */functionunescapeUnicode(str){// unescape unicode codesvar codes =[];var code =parseInt(str.substr(2),16);if(code >=0&& code < Math.pow(2,16)){
codes.push(code);}// convert codes to textreturn codes.reduce(function(acc, val){return acc + String.fromCharCode(val);},'');}})(jQuery);