String.prototype.format = function()
{
  return String.format(this, arguments.length == 1 ? arguments[0] : arguments);
};

String.format = function(source, params) {
  var _toString = function(obj, format) {
    var ctor = function(o) {
      if (typeof o == 'number')
        return Number;
      else if (typeof o == 'boolean')
        return Boolean;
      else if (typeof o == 'string')
        return String;
      else
        return o.constructor;
    }(obj);
    var proto = ctor.prototype;
    var formatter = typeof obj != 'string' ? proto ? proto.format || proto.toString : obj.format || obj.toString : obj.toString;
    if (formatter)
      if (typeof format == 'undefined' || format == "") 
        return formatter.call(obj);
      else
        return formatter.call(obj,format);
    else
      return "";
  };
  if ( arguments.length == 1 )
    return function() {
      return String.format.apply( null, [source].concat( Array.prototype.slice.call( arguments, 0 ) ) );
    };
  if ( arguments.length == 2 && typeof params != 'object' && typeof params != 'array')
    params = [ params ];
  if ( arguments.length > 2 ) 
    params = Array.prototype.slice.call(arguments, 1);
  source = source.replace(/\{\{|\}\}|\{([^}: ]+?)(?::([^}]*?))?\}/g, function(match, num, format) {
    if (match == "{{") return "{";
    if (match == "}}") return "}";
    if (typeof params[num] != 'undefined' && params[num] !== null) {
      return _toString(params[num], format);
    } else {
      return "";
    }
  });
  return source;
};

String.prototype.trimStart = function(chars)
{
    return String.trimStart(this, chars);
}
String.prototype.trimEnd = function(chars)
{
    return String.trimEnd(this, chars);
}
//Åñëè íå ðàáîòàåò òðèìÝíä òî çàïóñêàéòå åòîò ìåòîä :) îí áóäåò ðàáîòàòü
String.prototype.trimEnd1 = function(chars) {
    return String.trimEnd(this, chars);
}

String.prototype.trim = function(chars)
{
    return String.trim(this, chars);
}

String.trim = function(str, chars)
{
    return String.trimStart(String.trimEnd(str, chars), chars);
}

String.trimStart = function(str, chars)
{
    chars = chars || " ";

    var charsCount = chars.length;
    var result = str;
    while (result.length >= charsCount && result.substr(0, charsCount) == chars) {
        result = result.substr(charsCount, result.length - charsCount);
    }
    return result;
    //chars = chars || "\\s";
    //return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

String.trimEnd = function(str, chars) {
    chars = chars || ' ';
    var charsCount = chars.length;
    var result = str;
    while (result.length >= charsCount && result.substr(result.length - charsCount, charsCount) == chars) {
        result = result.substr(0, result.length - charsCount);
    }
    return result;
    //chars = chars || '\\s';
    //var re = /((\s*\S+)*)\s*/;
    //var re = new RegExp("((" + chars + "*\S+)*)" + chars + "*", "g");
    //return str.replace(re, "$1");
    //chars = chars || "\\s";
    //return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function isNullOrEmpty(str) {
    if (!str)
        return true;
    for (var i = 0; i < str.length; i++)
        if (" " != str.charAt(i))
        return false;
    return true;
}
