/* global */
var PTM		= {};
var PTMObj 	= null;

PTM = jQuery.Class.create({
    init: function(){
	  $().pngFix();
    },
	target: function(url){
    	if(this.strpos(url,'http:') === 0){
    		window.open(url);
    	}else{
    		window.location=url;
    	}
	},
	sendMailTo: function(a,b,e){
		$(e).html('<a href="mailto:' + a + '@' + b + '">' + a + '@' + b + '</a>');
	},
	getWidth: function (text){ // to get the actual width of the text with css etc
		var spanElement = document.createElement('span');
		spanElement.style.whiteSpace = 'nowrap';
		spanElement.innerHTML = text;
		document.body.appendChild(spanElement);
		var width = spanElement.offsetWidth;
		document.body.removeChild(spanElement);
	
		return width;
	},
	exists: function(el){
		return jQuery(el).length>0;
	},
    strpos: function( haystack, needle, offset){
	    // Finds position of first occurrence of a string within another  
	    // 
	    // version: 905.1314
	    // discuss at: http://phpjs.org/functions/strpos
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Onno Marsman    
	    // +   bugfixed by: Daniel Esteban
	    // *     example 1: strpos('Kevin van Zonneveld', 'e', 5);
	    // *     returns 1: 14
	    var i = (haystack+'').indexOf(needle, (offset ? offset : 0));
	    return i === -1 ? false : i;
	},
	strtolower: function (str) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Onno Marsman
	    // *     example 1: strtolower('Kevin van Zonneveld');
	    // *     returns 1: 'kevin van zonneveld'

	    return (str+'').toLowerCase();
	},
	json_encode: function (mixed_val) {
	    // Returns the JSON representation of a value  
	    // 
	    // version: 906.1806
	    // discuss at: http://phpjs.org/functions/json_encode
	    // +      original by: Public Domain (http://www.json.org/json2.js)
	    // + reimplemented by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // + improved by: T.J. Leahy
	    // *     example 1: json_encode(['e', {pluribus: 'unum'}]);
	    // *     returns 1: '[\n    "e",\n    {\n    "pluribus": "unum"\n}\n]'
	    /*
	        http://www.JSON.org/json2.js
	        2008-11-19
	        Public Domain.
	        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
	        See http://www.JSON.org/js.html
	    */
	    //var json = $(this).window.JSON;
		try {var json = JSON;}catch(e){var json = {};}
	    if (typeof json === 'object' && typeof json.stringify === 'function') {
	        return json.stringify(mixed_val);
	    }

	    var value = mixed_val;

	    var quote = function (string) {
	        var escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
	        var meta = {    // table of character substitutions
	            '\b': '\\b',
	            '\t': '\\t',
	            '\n': '\\n',
	            '\f': '\\f',
	            '\r': '\\r',
	            '"' : '\\"',
	            '\\': '\\\\'
	        };

	        escapable.lastIndex = 0;
	        return escapable.test(string) ?
	        '"' + string.replace(escapable, function (a) {
	            var c = meta[a];
	            return typeof c === 'string' ? c :
	            '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
	        }) + '"' :
	        '"' + string + '"';
	    };

	    var str = function(key, holder) {
	        var gap = '';
	        var indent = '    ';
	        var i = 0;          // The loop counter.
	        var k = '';          // The member key.
	        var v = '';          // The member value.
	        var length = 0;
	        var mind = gap;
	        var partial = [];
	        var value = holder[key];

	        // If the value has a toJSON method, call it to obtain a replacement value.
	        if (value && typeof value === 'object' &&
	            typeof value.toJSON === 'function') {
	            value = value.toJSON(key);
	        }
	        
	        // What happens next depends on the value's type.
	        switch (typeof value) {
	            case 'string':
	                return quote(value);

	            case 'number':
	                // JSON numbers must be finite. Encode non-finite numbers as null.
	                return isFinite(value) ? String(value) : 'null';

	            case 'boolean':
	            case 'null':
	                // If the value is a boolean or null, convert it to a string. Note:
	                // typeof null does not produce 'null'. The case is included here in
	                // the remote chance that this gets fixed someday.

	                return String(value);

	            case 'object':
	                // If the type is 'object', we might be dealing with an object or an array or
	                // null.
	                // Due to a specification blunder in ECMAScript, typeof null is 'object',
	                // so watch out for that case.
	                if (!value) {
	                    return 'null';
	                }

	                // Make an array to hold the partial results of stringifying this object value.
	                gap += indent;
	                partial = [];

	                // Is the value an array?
	                if (Object.prototype.toString.apply(value) === '[object Array]') {
	                    // The value is an array. Stringify every element. Use null as a placeholder
	                    // for non-JSON values.

	                    length = value.length;
	                    for (i = 0; i < length; i += 1) {
	                        partial[i] = str(i, value) || 'null';
	                    }

	                    // Join all of the elements together, separated with commas, and wrap them in
	                    // brackets.
	                    v = partial.length === 0 ? '[]' :
	                    gap ? '[\n' + gap +
	                    partial.join(',\n' + gap) + '\n' +
	                    mind + ']' :
	                    '[' + partial.join(',') + ']';
	                    gap = mind;
	                    return v;
	                }

	                // Iterate through all of the keys in the object.
	                for (k in value) {
	                    if (Object.hasOwnProperty.call(value, k)) {
	                        v = str(k, value);
	                        if (v) {
	                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
	                        }
	                    }
	                }

	                // Join all of the member texts together, separated with commas,
	                // and wrap them in braces.
	                v = partial.length === 0 ? '{}' :
	                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
	                mind + '}' : '{' + partial.join(',') + '}';
	                gap = mind;
	                return v;
	        }
	    };

	    // Make a fake root object containing our value under the key of ''.
	    // Return the result of stringifying the value.
	    return str('', {
	        '': value
	    });
	},
	is_null: function  (mixed_var) {
	    // Returns true if variable is null  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/is_null
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: is_null('23');
	    // *     returns 1: false
	    // *     example 2: is_null(null);
	    // *     returns 2: true
	    return ( mixed_var === null );
	},
	is_undefined: function (mixed_var) {
		return ( typeof mixed_var == 'undefined' );
	},
	empty: function (mixed_var) {
	    // !No description available for empty. @php.js developers: Please update the function summary text file.
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/empty
	    // +   original by: Philippe Baumann
	    // +      input by: Onno Marsman
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: LH
	    // +   improved by: Onno Marsman
	    // +   improved by: Francesco
	    // +   improved by: Marc Jansen
	    // *     example 1: empty(null);
	    // *     returns 1: true
	    // *     example 2: empty(undefined);
	    // *     returns 2: true
	    // *     example 3: empty([]);
	    // *     returns 3: true
	    // *     example 4: empty({});
	    // *     returns 4: true
	    // *     example 5: empty({'aFunc' : function () { alert('humpty'); } });
	    // *     returns 5: false
	    
	    var key;
	    
	    if (mixed_var === "" ||
	        mixed_var === 0 ||
	        mixed_var === "0" ||
	        mixed_var === null ||
	        mixed_var === false ||
	        mixed_var === undefined
	    ){
	        return true;
	    }

	    if (typeof mixed_var == 'object') {
	        for (key in mixed_var) {
	            return false;
	        }
	        return true;
	    }

	    return false;
	},
	isset: function() {
	    // !No description available for isset. @php.js developers: Please update the function summary text file.
	    // 
	    // version: 905.1001
	    // discuss at: http://phpjs.org/functions/isset
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: FremyCompany
	    // +   improved by: Onno Marsman
	    // *     example 1: isset( undefined, true);
	    // *     returns 1: false
	    // *     example 2: isset( 'Kevin van Zonneveld' );
	    // *     returns 2: true
	    
	    var a=arguments, l=a.length, i=0;
	    
	    if (l===0) {
	        throw new Error('Empty isset'); 
	    }
	    
	    while (i!==l) {
	        if (typeof(a[i])=='undefined' || a[i]===null) { 
	            return false; 
	        } else { 
	            i++; 
	        }
	    }
	    return true;
	},
	str_replace: function(search, replace, subject, count) {
	    // Replaces all occurrences of search in haystack with replace  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/str_replace
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Gabriel Paderni
	    // +   improved by: Philip Peterson
	    // +   improved by: Simon Willison (http://simonwillison.net)
	    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
	    // +   bugfixed by: Anton Ongson
	    // +      input by: Onno Marsman
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    tweaked by: Onno Marsman
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   input by: Oleg Eremeev
	    // +   improved by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Oleg Eremeev
	    // %          note 1: The count parameter must be passed as a string in order
	    // %          note 1:  to find a global variable in which the result will be given
	    // *     example 1: str_replace(' ', '.', 'Kevin van Zonneveld');
	    // *     returns 1: 'Kevin.van.Zonneveld'
	    // *     example 2: str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
	    // *     returns 2: 'hemmo, mars'
	    var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
	            f = [].concat(search),
	            r = [].concat(replace),
	            s = subject,
	            ra = r instanceof Array, sa = s instanceof Array;
	    s = [].concat(s);
	    if (count) {
	        this.window[count] = 0;
	    }

	    for (i=0, sl=s.length; i < sl; i++) {
	        if (s[i] === '') {
	            continue;
	        }
	        for (j=0, fl=f.length; j < fl; j++) {
	            temp = s[i]+'';
	            repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
	            s[i] = (temp).split(f[j]).join(repl);
	            if (count && s[i] !== temp) {
	                this.window[count] += (temp.length-s[i].length)/f[j].length;}
	        }
	    }
	    return sa ? s : s[0];
	},
	explode: function(delimiter, string, limit) {
	    // Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned.  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/explode
	    // +     original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +     improved by: kenneth
	    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +     improved by: d3x
	    // +     bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: explode(' ', 'Kevin van Zonneveld');
	    // *     returns 1: {0: 'Kevin', 1: 'van', 2: 'Zonneveld'}
	    // *     example 2: explode('=', 'a=bc=d', 2);
	    // *     returns 2: ['a', 'bc=d']
	 
	    var emptyArray = { 0: '' };
	    
	    // third argument is not required
	    if ( arguments.length < 2 ||
	        typeof arguments[0] == 'undefined' ||
	        typeof arguments[1] == 'undefined' )
	    {
	        return null;
	    }
	 
	    if ( delimiter === '' ||
	        delimiter === false ||
	        delimiter === null )
	    {
	        return false;
	    }
	 
	    if ( typeof delimiter == 'function' ||
	        typeof delimiter == 'object' ||
	        typeof string == 'function' ||
	        typeof string == 'object' )
	    {
	        return emptyArray;
	    }
	 
	    if ( delimiter === true ) {
	        delimiter = '1';
	    }
	    
	    if (!limit) {
	        return string.toString().split(delimiter.toString());
	    } else {
	        // support for limit argument
	        var splitted = string.toString().split(delimiter.toString());
	        var partA = splitted.splice(0, limit - 1);
	        var partB = splitted.join(delimiter.toString());
	        partA.push(partB);
	        return partA;
	    }
	},
	implode: function (glue, pieces) {
	    // Joins array elements placing glue string between items and return one string  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/implode
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Waldo Malqui Silva
	    // *     example 1: implode(' ', ['Kevin', 'van', 'Zonneveld']);
	    // *     returns 1: 'Kevin van Zonneveld'
	    return ( ( pieces instanceof Array ) ? pieces.join( glue ) : pieces );
	},
	basename: function (path, suffix) {
	    // Returns the filename component of the path  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/basename
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Ash Searle (http://hexmen.com/blog/)
	    // +   improved by: Lincoln Ramsay
	    // +   improved by: djmix
	    // *     example 1: basename('/www/site/home.htm', '.htm');
	    // *     returns 1: 'home'
	    var b = path.replace(/^.*[\/\\]/g, '');
	    
	    if (typeof(suffix) == 'string' && b.substr(b.length-suffix.length) == suffix) {
	        b = b.substr(0, b.length-suffix.length);
	    }
	    
	    return b;
	},
	in_array: function  (needle, haystack, argStrict) {
	    // Checks if the given value exists in the array  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/in_array
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: vlado houba
	    // *     example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);
	    // *     returns 1: true
	    // *     example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
	    // *     returns 2: false
	    // *     example 3: in_array(1, ['1', '2', '3']);
	    // *     returns 3: true
	    // *     example 3: in_array(1, ['1', '2', '3'], false);
	    // *     returns 3: true
	    // *     example 4: in_array(1, ['1', '2', '3'], true);
	    // *     returns 4: false
	    var key = '', strict = !!argStrict;

	    if (strict) {
	        for (key in haystack) {
	            if (haystack[key] === needle) {
	                return true;
	            }
	        }
	    } else {
	        for (key in haystack) {
	            if (haystack[key] == needle) {
	                return true;
	            }
	        }
	    }

	    return false;
	},
	array_flip: function  (trans) {
	    // Return array with key <-> value flipped  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/array_flip
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: array_flip( {a: 1, b: 1, c: 2} );
	    // *     returns 1: {1: 'b', 2: 'c'}
	    var key, tmp_ar = {};

	    for (key in trans) {
	        tmp_ar[trans[key]] = key;
	    }

	    return tmp_ar;
	},
	array_pop: function  (array) {
	    // Pops an element off the end of the array  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/array_pop
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: array_pop([0,1,2]);
	    // *     returns 1: 2
	    // *     example 2: data = {firstName: 'Kevin', surName: 'van Zonneveld'};
	    // *     example 2: lastElem = array_pop(data);
	    // *     returns 2: 'van Zonneveld'
	    // *     results 2: data == {firstName: 'Kevin'}
	    var key = '', cnt = 0;

	    if (array.hasOwnProperty('length')) {
	        // Indexed
	        if (!array.length){
	            // Done popping, are we?
	            return null;
	        }
	        return array.pop();
	    } else {
	        // Associative
	        for (key in array) {
	            cnt++;
	        }
	        if (cnt) {
	            delete(array[key]);
	            return array[key];
	        } else {
	            return null;
	        }
	    }
	},
	array_splice: function(arr, offst, lgth, replacement) {
	    // Removes the elements designated by offset and length and replace them with supplied array  
	    // 
	    // version: 905.3122
	    // discuss at: http://phpjs.org/functions/array_splice
	    // +   original by: Brett Zamir (http://brett-zamir.me)
	    // %        note 1: Order does get shifted in associative array input with numeric indices,
	    // %        note 1: since PHP behavior doesn't preserve keys, but I understand order is not reliable anyways
	    // -    depends on: is_int
	    // *     example 1: input = {4: "red", 'abc': "green", 2: "blue", 'dud': "yellow"};
	    // *     example 1: array_splice(input, 2);
	    // *     returns 1: {0: "blue", 'dud': "yellow"}
	    // *     results 1: input == {'abc':"green", 0:"red"}
	    // *     example 2: input = ["red", "green", "blue", "yellow"];
	    // *     example 2: array_splice(input, 3, 0, "purple");
	    // *     returns 2: []
	    // *     results 2: input == ["red", "green", "blue", "purple", "yellow"]
	    // *     example 3: input = ["red", "green", "blue", "yellow"]
	    // *     example 3: array_splice(input, -1, 1, ["black", "maroon"]);
	    // *     returns 3: ["yellow"]
	    // *     results 3: input == ["red", "green", "blue", "black", "maroon"]
	    
	    var checkToUpIndices = function (arr, ct, key) {
	        // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
	        // increment all subsequent (skipping current key, since we need its value below) until find unused)
	        if (arr[ct] !== undefined) {
	            var tmp = ct;
	            ct += 1;
	            if (ct === key) {
	                ct += 1;
	            }
	            ct = checkToUpIndices(arr, ct, key);
	            arr[ct] = arr[tmp];
	            delete arr[tmp];
	        }
	        return ct;
	    };

	    if (replacement === null || (replacement && !(typeof replacement === 'object'))) {
	        replacement = [replacement];
	    }
	    if (lgth === undefined) {
	        lgth = offst >= 0 ? arr.length - offst : -offst;
	    } else if (lgth < 0) {
	        lgth = (offst >= 0 ? arr.length - offst : -offst)  + lgth;
	    }

	    if (!(arr instanceof Array)) {
	        /*if (arr.length !== undefined) { // Deal with array-like objects as input
	        delete arr.length;
	        }*/
	        var lgt = 0, ct = -1, rmvd = [], rmvdObj = {}, repl_ct=-1, int_ct=-1;
	        var returnArr = true, rmvd_ct = 0, rmvd_lgth = 0, key = '';
	        // rmvdObj.length = 0;
	        for (key in arr) { // Can do arr.__count__ in some browsers
	            lgt += 1;
	        }
	        offst = (offst >= 0) ? offst : lgt + offst;
	        for (key in arr) {
	            ct += 1;
	            if (ct < offst) {
	                if (this.is_int(key)) {
	                    int_ct += 1;
	                    if (parseInt(key, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
	                        continue;
	                    }
	                    checkToUpIndices(arr, int_ct, key); // Deal with situation, e.g.,
	                    // if encounter index 4 and try to set it to 0, but 0 exists later in loop
	                    arr[int_ct] = arr[key];
	                    delete arr[key];
	                }
	                continue;
	            }
	            if (returnArr && this.is_int(key)) {
	                rmvd.push(arr[key]);
	                rmvdObj[rmvd_ct++] = arr[key]; // PHP starts over here too
	            } else {
	                rmvdObj[key] = arr[key];
	                returnArr    = false;
	            }
	            rmvd_lgth += 1;
	            // rmvdObj.length += 1;

	            if (replacement && replacement[++repl_ct]) {
	                arr[key] = replacement[repl_ct];
	            } else {
	                delete arr[key];
	            }
	        }
	        // arr.length = lgt - rmvd_lgth + (replacement ? replacement.length : 0); // Make (back) into an array-like object
	        return returnArr ? rmvd : rmvdObj;
	    }

	    if (replacement) {
	    	replacement.unshift(offst, lgth);
	        return Array.prototype.splice.apply(arr, replacement);
	    }
	    return arr.splice(offst, lgth);
	},
	array_filter: function  (arr, func) {
	    var retObj, k, type = 'array';
	    func_set = 0;
	    
	    if(this.isset(func))
	    	func_set = 1;
	    // Check for 'length'
	    if(arr.length === undefined){
	    	type = 'hashed_array';
	    }
	    if(type == 'hashed_array'){
	    	retObj = {};
		    for (k in arr) {
		    	if(func_set){
			        if (func(arr[k])) {
			            retObj[k] = arr[k];
			        }
		    	}else{
		    		if(this.is_null(arr[k]))
		    			continue;
		    		retObj[k] = arr[k];
		    	}
		    }
	    }else{ // MODIFIED by CoffeeHarmony
	    	retObj = [];
	    	for(i=0;i<arr.length;++i){
	    		if(func_set){
			        if (func(arr[i])) {
			            retObj[i] = arr[i];
			        }
		    	}else{
		    		if(!this.is_null(arr[i])){
		    			retObj[retObj.length] = arr[i];
		    		}
		    	}
	    	}
	    }
	    return retObj;
	},
	trim: function(str, charlist) {
	    // Strips whitespace from the beginning and end of a string  
	    // 
	    // version: 905.1001
	    // discuss at: http://phpjs.org/functions/trim
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: mdsjack (http://www.mdsjack.bo.it)
	    // +   improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
	    // +      input by: Erkekjetter
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: DxGx
	    // +   improved by: Steven Levithan (http://blog.stevenlevithan.com)
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // *     example 1: trim('    Kevin van Zonneveld    ');
	    // *     returns 1: 'Kevin van Zonneveld'
	    // *     example 2: trim('Hello World', 'Hdle');
	    // *     returns 2: 'o Wor'
	    // *     example 3: trim(16, 1);
	    // *     returns 3: 6
	    var whitespace, l = 0, i = 0;
	    str += '';
	    
	    if (!charlist) {
	        // default list
	        whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
	    } else {
	        // preg_quote custom list
	        charlist += '';
	        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
	    }
	    
	    l = str.length;
	    for (i = 0; i < l; i++) {
	        if (whitespace.indexOf(str.charAt(i)) === -1) {
	            str = str.substring(i);
	            break;
	        }
	    }
	    
	    l = str.length;
	    for (i = l - 1; i >= 0; i--) {
	        if (whitespace.indexOf(str.charAt(i)) === -1) {
	            str = str.substring(0, i + 1);
	            break;
	        }
	    }
	    
	    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
	},
	microtime: function (get_as_float) {
	    // Returns either a string or a float containing the current time in seconds and microseconds  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/microtime
	    // +   original by: Paulo Ricardo F. Santos
	    // *     example 1: timeStamp = microtime(true);
	    // *     results 1: timeStamp > 1000000000 && timeStamp < 2000000000
	    var now = new Date().getTime() / 1000;
	    var s = parseInt(now, 10);

	    return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
	},
	utf8_decode:function ( str_data ) {
	    // Converts a UTF-8 encoded string to ISO-8859-1  
	    // 
	    // version: 905.3122
	    // discuss at: http://phpjs.org/functions/utf8_decode
	    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	    // +      input by: Aman Gupta
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Norman "zEh" Fuchs
	    // +   bugfixed by: hitwork
	    // +   bugfixed by: Onno Marsman
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // *     example 1: utf8_decode('Kevin van Zonneveld');
	    // *     returns 1: 'Kevin van Zonneveld'
	    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
	    
	    str_data += '';
	    
	    while ( i < str_data.length ) {
	        c1 = str_data.charCodeAt(i);
	        if (c1 < 128) {
	            tmp_arr[ac++] = String.fromCharCode(c1);
	            i++;
	        } else if ((c1 > 191) && (c1 < 224)) {
	            c2 = str_data.charCodeAt(i+1);
	            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
	            i += 2;
	        } else {
	            c2 = str_data.charCodeAt(i+1);
	            c3 = str_data.charCodeAt(i+2);
	            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
	            i += 3;
	        }
	    }

	    return tmp_arr.join('');
	},
	utf8_encode:function  ( argString ) {
	    // Encodes an ISO-8859-1 string to UTF-8  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/utf8_encode
	    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: sowberry
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // +   improved by: Yves Sucaet
	    // +   bugfixed by: Onno Marsman
	    // *     example 1: utf8_encode('Kevin van Zonneveld');
	    // *     returns 1: 'Kevin van Zonneveld'
	    var string = (argString+'').replace(/\r\n/g, "\n").replace(/\r/g, "\n");

	    var utftext = "";
	    var start, end;
	    var stringl = 0;

	    start = end = 0;
	    stringl = string.length;
	    for (var n = 0; n < stringl; n++) {
	        var c1 = string.charCodeAt(n);
	        var enc = null;

	        if (c1 < 128) {
	            end++;
	        } else if (c1 > 127 && c1 < 2048) {
	            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
	        } else {
	            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
	        }
	        if (enc !== null) {
	            if (end > start) {
	                utftext += string.substring(start, end);
	            }
	            utftext += enc;
	            start = end = n+1;
	        }
	    }

	    if (end > start) {
	        utftext += string.substring(start, string.length);
	    }

	    return utftext;
	},
	md5: function  (str) {
	    // Calculate the md5 hash of a string  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/md5
	    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	    // + namespaced by: Michael White (http://getsprink.com)
	    // +    tweaked by: Jack
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // -    depends on: utf8_encode
	    // *     example 1: md5('Kevin van Zonneveld');
	    // *     returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
	    var xl;

	    var rotateLeft = function (lValue, iShiftBits) {
	        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
	    };

	    var addUnsigned = function (lX,lY) {
	        var lX4,lY4,lX8,lY8,lResult;
	        lX8 = (lX & 0x80000000);
	        lY8 = (lY & 0x80000000);
	        lX4 = (lX & 0x40000000);
	        lY4 = (lY & 0x40000000);
	        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
	        if (lX4 & lY4) {
	            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
	        }
	        if (lX4 | lY4) {
	            if (lResult & 0x40000000) {
	                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
	            } else {
	                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
	            }
	        } else {
	            return (lResult ^ lX8 ^ lY8);
	        }
	    };

	    var _F = function (x,y,z) { return (x & y) | ((~x) & z); };
	    var _G = function (x,y,z) { return (x & z) | (y & (~z)); };
	    var _H = function (x,y,z) { return (x ^ y ^ z); };
	    var _I = function (x,y,z) { return (y ^ (x | (~z))); };

	    var _FF = function (a,b,c,d,x,s,ac) {
	        a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
	        return addUnsigned(rotateLeft(a, s), b);
	    };

	    var _GG = function (a,b,c,d,x,s,ac) {
	        a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
	        return addUnsigned(rotateLeft(a, s), b);
	    };

	    var _HH = function (a,b,c,d,x,s,ac) {
	        a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
	        return addUnsigned(rotateLeft(a, s), b);
	    };

	    var _II = function (a,b,c,d,x,s,ac) {
	        a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
	        return addUnsigned(rotateLeft(a, s), b);
	    };

	    var convertToWordArray = function (str) {
	        var lWordCount;
	        var lMessageLength = str.length;
	        var lNumberOfWords_temp1=lMessageLength + 8;
	        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
	        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
	        var lWordArray=new Array(lNumberOfWords-1);
	        var lBytePosition = 0;
	        var lByteCount = 0;
	        while ( lByteCount < lMessageLength ) {
	            lWordCount = (lByteCount-(lByteCount % 4))/4;
	            lBytePosition = (lByteCount % 4)*8;
	            lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount)<<lBytePosition));
	            lByteCount++;
	        }
	        lWordCount = (lByteCount-(lByteCount % 4))/4;
	        lBytePosition = (lByteCount % 4)*8;
	        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
	        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
	        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
	        return lWordArray;
	    };

	    var wordToHex = function (lValue) {
	        var wordToHexValue="",wordToHexValue_temp="",lByte,lCount;
	        for (lCount = 0;lCount<=3;lCount++) {
	            lByte = (lValue>>>(lCount*8)) & 255;
	            wordToHexValue_temp = "0" + lByte.toString(16);
	            wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length-2,2);
	        }
	        return wordToHexValue;
	    };

	    var x=[],
	        k,AA,BB,CC,DD,a,b,c,d,
	        S11=7, S12=12, S13=17, S14=22,
	        S21=5, S22=9 , S23=14, S24=20,
	        S31=4, S32=11, S33=16, S34=23,
	        S41=6, S42=10, S43=15, S44=21;

	    str = this.utf8_encode(str);
	    x = convertToWordArray(str);
	    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
	    
	    xl = x.length;
	    for (k=0;k<xl;k+=16) {
	        AA=a; BB=b; CC=c; DD=d;
	        a=_FF(a,b,c,d,x[k+0], S11,0xD76AA478);
	        d=_FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
	        c=_FF(c,d,a,b,x[k+2], S13,0x242070DB);
	        b=_FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
	        a=_FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
	        d=_FF(d,a,b,c,x[k+5], S12,0x4787C62A);
	        c=_FF(c,d,a,b,x[k+6], S13,0xA8304613);
	        b=_FF(b,c,d,a,x[k+7], S14,0xFD469501);
	        a=_FF(a,b,c,d,x[k+8], S11,0x698098D8);
	        d=_FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
	        c=_FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
	        b=_FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
	        a=_FF(a,b,c,d,x[k+12],S11,0x6B901122);
	        d=_FF(d,a,b,c,x[k+13],S12,0xFD987193);
	        c=_FF(c,d,a,b,x[k+14],S13,0xA679438E);
	        b=_FF(b,c,d,a,x[k+15],S14,0x49B40821);
	        a=_GG(a,b,c,d,x[k+1], S21,0xF61E2562);
	        d=_GG(d,a,b,c,x[k+6], S22,0xC040B340);
	        c=_GG(c,d,a,b,x[k+11],S23,0x265E5A51);
	        b=_GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
	        a=_GG(a,b,c,d,x[k+5], S21,0xD62F105D);
	        d=_GG(d,a,b,c,x[k+10],S22,0x2441453);
	        c=_GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
	        b=_GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
	        a=_GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
	        d=_GG(d,a,b,c,x[k+14],S22,0xC33707D6);
	        c=_GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
	        b=_GG(b,c,d,a,x[k+8], S24,0x455A14ED);
	        a=_GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
	        d=_GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
	        c=_GG(c,d,a,b,x[k+7], S23,0x676F02D9);
	        b=_GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
	        a=_HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
	        d=_HH(d,a,b,c,x[k+8], S32,0x8771F681);
	        c=_HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
	        b=_HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
	        a=_HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
	        d=_HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
	        c=_HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
	        b=_HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
	        a=_HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
	        d=_HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
	        c=_HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
	        b=_HH(b,c,d,a,x[k+6], S34,0x4881D05);
	        a=_HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
	        d=_HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
	        c=_HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
	        b=_HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
	        a=_II(a,b,c,d,x[k+0], S41,0xF4292244);
	        d=_II(d,a,b,c,x[k+7], S42,0x432AFF97);
	        c=_II(c,d,a,b,x[k+14],S43,0xAB9423A7);
	        b=_II(b,c,d,a,x[k+5], S44,0xFC93A039);
	        a=_II(a,b,c,d,x[k+12],S41,0x655B59C3);
	        d=_II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
	        c=_II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
	        b=_II(b,c,d,a,x[k+1], S44,0x85845DD1);
	        a=_II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
	        d=_II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
	        c=_II(c,d,a,b,x[k+6], S43,0xA3014314);
	        b=_II(b,c,d,a,x[k+13],S44,0x4E0811A1);
	        a=_II(a,b,c,d,x[k+4], S41,0xF7537E82);
	        d=_II(d,a,b,c,x[k+11],S42,0xBD3AF235);
	        c=_II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
	        b=_II(b,c,d,a,x[k+9], S44,0xEB86D391);
	        a=addUnsigned(a,AA);
	        b=addUnsigned(b,BB);
	        c=addUnsigned(c,CC);
	        d=addUnsigned(d,DD);
	    }

	    var temp = wordToHex(a)+wordToHex(b)+wordToHex(c)+wordToHex(d);

	    return temp.toLowerCase();
	},
	latLngAdjust:function(X,Y,x,y,z,w){
		var offset=268435456;
		var radius=offset/Math.PI;

		function LToX(x)
		{
			return Math.round(offset+radius*x*Math.PI/180);
		}

		function LToY(y)
		{
			return Math.round(offset-radius*Math.log((1+Math.sin(y*Math.PI/180))/(1-Math.sin(y*Math.PI/180)))/2);
		}

		function XToL(x)
		{
			return ((Math.round(x)-offset)/radius)*180/Math.PI;
		}

		function YToL(y)
		{
			return (Math.PI/2-2*Math.atan(Math.exp((Math.round(y)-offset)/radius)))*180/Math.PI;
		}

		if (w)
		{
			return {x:(LToX(X)-LToX(x))>>(21-z),y:(LToY(Y)-LToY(y))>>(21-z)};
		}

		else
		{
			return {x:XToL(LToX(x)+(X<<(21-z))),y:YToL(LToY(y)+(Y<<(21-z)))};
		}
	},
	latLngXYToLL: function (X,Y,x,y,z){
//		X = X pixel offset of new map center from old map center
//		Y = Y pixel offset of new map center from old map center
//		x = Longitude of map center
//		y = Latitude  of map center
//		z = Zoom level

//		result.x = Longitude of adjusted map center
//		result.y = Latitude  of adjusted map center

		return this.latLngAdjust(X,Y,x,y,z,0);
	},


	latLngLLToXY:function (X,Y,x,y,z){
//		X = Longitude of marker center
//		Y = Latitude  of marker center
//		x = Longitude of map center
//		y = Latitude  of map center
//		z = Zoom level

//		result.x = X pixel offset of marker center from map center
//		result.y = Y pixel offset of marker center from map center
		return this.latLngAdjust(X,Y,x,y,z,1);
	},
	htmlspecialchars: function  (string, quote_style, charset, double_encode) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Mirek Slugen
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Nathan
	    // +   bugfixed by: Arno
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Ratheous
	    // +      input by: Mailfaker (http://www.weedem.fr/)
	    // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: felix
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // %        note 1: charset argument not supported
	    // *     example 1: htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
	    // *     returns 1: '&lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;'
	    // *     example 2: htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']);
	    // *     returns 2: 'ab"c&#039;d'
	    // *     example 3: htmlspecialchars("my "&entity;" is still here", null, null, false);
	    // *     returns 3: 'my &quot;&entity;&quot; is still here'

	    var optTemp = 0, i = 0, noquotes= false;
	    if (typeof quote_style === 'undefined' || quote_style === null) {
	        quote_style = 2;
	    }
	    string = string.toString();
	    if (double_encode !== false) { // Put this first to avoid double-encoding
	        string = string.replace(/&/g, '&amp;');
	    }
	    string = string.replace(/</g, '&lt;').replace(/>/g, '&gt;');

	    var OPTS = {
	        'ENT_NOQUOTES': 0,
	        'ENT_HTML_QUOTE_SINGLE' : 1,
	        'ENT_HTML_QUOTE_DOUBLE' : 2,
	        'ENT_COMPAT': 2,
	        'ENT_QUOTES': 3,
	        'ENT_IGNORE' : 4
	    };
	    if (quote_style === 0) {
	        noquotes = true;
	    }
	    if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
	        quote_style = [].concat(quote_style);
	        for (i=0; i < quote_style.length; i++) {
	            // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
	            if (OPTS[quote_style[i]] === 0) {
	                noquotes = true;
	            }
	            else if (OPTS[quote_style[i]]) {
	                optTemp = optTemp | OPTS[quote_style[i]];
	            }
	        }
	        quote_style = optTemp;
	    }
	    if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
	        string = string.replace(/'/g, '&#039;');
	    }
	    if (!noquotes) {
	        string = string.replace(/"/g, '&quot;');
	    }

	    return string;
	},
	htmlspecialchars_decode: function  (string, quote_style) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Mirek Slugen
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Mateusz "loonquawl" Zalega
	    // +      input by: ReverseSyntax
	    // +      input by: Slawomir Kaniecki
	    // +      input by: Scott Cariss
	    // +      input by: Francois
	    // +   bugfixed by: Onno Marsman
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Ratheous
	    // +      input by: Mailfaker (http://www.weedem.fr/)
	    // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // *     example 1: htmlspecialchars_decode("<p>this -&gt; &quot;</p>", 'ENT_NOQUOTES');
	    // *     returns 1: '<p>this -> &quot;</p>'
	    // *     example 2: htmlspecialchars_decode("&amp;quot;");
	    // *     returns 2: '&quot;'

	    var optTemp = 0, i = 0, noquotes= false;
	    if (typeof quote_style === 'undefined') {
	        quote_style = 2;
	    }
	    string = string.toString().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
	    var OPTS = {
	        'ENT_NOQUOTES': 0,
	        'ENT_HTML_QUOTE_SINGLE' : 1,
	        'ENT_HTML_QUOTE_DOUBLE' : 2,
	        'ENT_COMPAT': 2,
	        'ENT_QUOTES': 3,
	        'ENT_IGNORE' : 4
	    };
	    if (quote_style === 0) {
	        noquotes = true;
	    }
	    if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
	        quote_style = [].concat(quote_style);
	        for (i=0; i < quote_style.length; i++) {
	            // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
	            if (OPTS[quote_style[i]] === 0) {
	                noquotes = true;
	            }
	            else if (OPTS[quote_style[i]]) {
	                optTemp = optTemp | OPTS[quote_style[i]];
	            }
	        }
	        quote_style = optTemp;
	    }
	    if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
	        string = string.replace(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
	        // string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
	    }
	    if (!noquotes) {
	        string = string.replace(/&quot;/g, '"');
	    }
	    // Put this in last place to avoid escape being double-decoded
	    string = string.replace(/&amp;/g, '&');

	    return string;
	},
	get_html_translation_table: function  (table, quote_style) {
	    // Returns the internal translation table used by htmlspecialchars and htmlentities  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/get_html_translation_table
	    // +   original by: Philip Peterson
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: noname
	    // +   bugfixed by: Alex
	    // +   bugfixed by: Marco
	    // +   bugfixed by: madipta
	    // +   improved by: KELAN
	    // +   improved by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Frank Forte
	    // +   bugfixed by: T.Wild
	    // +      input by: Ratheous
	    // %          note: It has been decided that we're not going to add global
	    // %          note: dependencies to php.js, meaning the constants are not
	    // %          note: real constants, but strings instead. Integers are also supported if someone
	    // %          note: chooses to create the constants themselves.
	    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
	    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
	    
	    var entities = {}, hash_map = {}, decimal = 0, symbol = '';
	    var constMappingTable = {}, constMappingQuoteStyle = {};
	    var useTable = {}, useQuoteStyle = {};
	    
	    // Translate arguments
	    constMappingTable[0]      = 'HTML_SPECIALCHARS';
	    constMappingTable[1]      = 'HTML_ENTITIES';
	    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
	    constMappingQuoteStyle[2] = 'ENT_COMPAT';
	    constMappingQuoteStyle[3] = 'ENT_QUOTES';

	    useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
	    useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';

	    if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
	        throw new Error("Table: "+useTable+' not supported');
	        // return false;
	    }

	    entities['38'] = '&amp;';
	    if (useTable === 'HTML_ENTITIES') {
	        entities['160'] = '&nbsp;';
	        entities['161'] = '&iexcl;';
	        entities['162'] = '&cent;';
	        entities['163'] = '&pound;';
	        entities['164'] = '&curren;';
	        entities['165'] = '&yen;';
	        entities['166'] = '&brvbar;';
	        entities['167'] = '&sect;';
	        entities['168'] = '&uml;';
	        entities['169'] = '&copy;';
	        entities['170'] = '&ordf;';
	        entities['171'] = '&laquo;';
	        entities['172'] = '&not;';
	        entities['173'] = '&shy;';
	        entities['174'] = '&reg;';
	        entities['175'] = '&macr;';
	        entities['176'] = '&deg;';
	        entities['177'] = '&plusmn;';
	        entities['178'] = '&sup2;';
	        entities['179'] = '&sup3;';
	        entities['180'] = '&acute;';
	        entities['181'] = '&micro;';
	        entities['182'] = '&para;';
	        entities['183'] = '&middot;';
	        entities['184'] = '&cedil;';
	        entities['185'] = '&sup1;';
	        entities['186'] = '&ordm;';
	        entities['187'] = '&raquo;';
	        entities['188'] = '&frac14;';
	        entities['189'] = '&frac12;';
	        entities['190'] = '&frac34;';
	        entities['191'] = '&iquest;';
	        entities['192'] = '&Agrave;';
	        entities['193'] = '&Aacute;';
	        entities['194'] = '&Acirc;';
	        entities['195'] = '&Atilde;';
	        entities['196'] = '&Auml;';
	        entities['197'] = '&Aring;';
	        entities['198'] = '&AElig;';
	        entities['199'] = '&Ccedil;';
	        entities['200'] = '&Egrave;';
	        entities['201'] = '&Eacute;';
	        entities['202'] = '&Ecirc;';
	        entities['203'] = '&Euml;';
	        entities['204'] = '&Igrave;';
	        entities['205'] = '&Iacute;';
	        entities['206'] = '&Icirc;';
	        entities['207'] = '&Iuml;';
	        entities['208'] = '&ETH;';
	        entities['209'] = '&Ntilde;';
	        entities['210'] = '&Ograve;';
	        entities['211'] = '&Oacute;';
	        entities['212'] = '&Ocirc;';
	        entities['213'] = '&Otilde;';
	        entities['214'] = '&Ouml;';
	        entities['215'] = '&times;';
	        entities['216'] = '&Oslash;';
	        entities['217'] = '&Ugrave;';
	        entities['218'] = '&Uacute;';
	        entities['219'] = '&Ucirc;';
	        entities['220'] = '&Uuml;';
	        entities['221'] = '&Yacute;';
	        entities['222'] = '&THORN;';
	        entities['223'] = '&szlig;';
	        entities['224'] = '&agrave;';
	        entities['225'] = '&aacute;';
	        entities['226'] = '&acirc;';
	        entities['227'] = '&atilde;';
	        entities['228'] = '&auml;';
	        entities['229'] = '&aring;';
	        entities['230'] = '&aelig;';
	        entities['231'] = '&ccedil;';
	        entities['232'] = '&egrave;';
	        entities['233'] = '&eacute;';
	        entities['234'] = '&ecirc;';
	        entities['235'] = '&euml;';
	        entities['236'] = '&igrave;';
	        entities['237'] = '&iacute;';
	        entities['238'] = '&icirc;';
	        entities['239'] = '&iuml;';
	        entities['240'] = '&eth;';
	        entities['241'] = '&ntilde;';
	        entities['242'] = '&ograve;';
	        entities['243'] = '&oacute;';
	        entities['244'] = '&ocirc;';
	        entities['245'] = '&otilde;';
	        entities['246'] = '&ouml;';
	        entities['247'] = '&divide;';
	        entities['248'] = '&oslash;';
	        entities['249'] = '&ugrave;';
	        entities['250'] = '&uacute;';
	        entities['251'] = '&ucirc;';
	        entities['252'] = '&uuml;';
	        entities['253'] = '&yacute;';
	        entities['254'] = '&thorn;';
	        entities['255'] = '&yuml;';
	    }

	    if (useQuoteStyle !== 'ENT_NOQUOTES') {
	        entities['34'] = '&quot;';
	    }
	    if (useQuoteStyle === 'ENT_QUOTES') {
	        entities['39'] = '&#39;';
	    }
	    entities['60'] = '&lt;';
	    entities['62'] = '&gt;';


	    // ascii decimals to real symbols
	    for (decimal in entities) {
	        symbol = String.fromCharCode(decimal);
	        hash_map[symbol] = entities[decimal];
	    }
	    
	    return hash_map;
	},
	html_entity_decode: function  (string, quote_style) {
	    // Convert all HTML entities to their applicable characters  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/html_entity_decode
	    // +   original by: john (http://www.jd-tech.net)
	    // +      input by: ger
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Onno Marsman
	    // +   improved by: marc andreu
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Ratheous
	    // -    depends on: get_html_translation_table
	    // *     example 1: html_entity_decode('Kevin &amp; van Zonneveld');
	    // *     returns 1: 'Kevin & van Zonneveld'
	    // *     example 2: html_entity_decode('&amp;lt;');
	    // *     returns 2: '&lt;'
	    var hash_map = {}, symbol = '', tmp_str = '', entity = '';
	    tmp_str = string.toString();
	    if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
	        return false;
	    }
	    
	    for (symbol in hash_map) {
	        entity = hash_map[symbol];
	        tmp_str = tmp_str.split(entity).join(symbol);
	    }
	    //tmp_str = tmp_str.split('&#039;').join("'"); // MODIFIED by CoffeeHarmony (original line)
	    // MODIFIED by CoffeeHarmony
	    var that_single_quote = this.strpos(tmp_str, '&#39;');
	    if(that_single_quote!==false){
	    	var tmp_front 	= this.substr(tmp_str,0,that_single_quote-1);
	    	var tmp_end  	= this.substr(tmp_str,(that_single_quote+5),tmp_str.length);
	    	tmp_str = tmp_front+'\''+tmp_end;
	    }
	    // END modification
	    return tmp_str;
	},
	substr:function  (f_string, f_start, f_length) {
	    // Returns part of a string  
	    // 
	    // version: 908.406
	    // discuss at: http://phpjs.org/functions/substr
	    // +     original by: Martijn Wieringa
	    // +     bugfixed by: T.Wild
	    // +      tweaked by: Onno Marsman
	    // *       example 1: substr('abcdef', 0, -1);
	    // *       returns 1: 'abcde'
	    // *       example 2: substr(2, 0, -6);
	    // *       returns 2: ''
	    f_string += '';

	    if (f_start < 0) {
	        f_start += f_string.length;
	    }

	    if (f_length == undefined) {
	        f_length = f_string.length;
	    } else if (f_length < 0){
	        f_length += f_string.length;
	    } else {
	        f_length += f_start;
	    }

	    if (f_length < f_start) {
	        f_length = f_start;
	    }

	    return f_string.substring(f_start, f_length);
	},
	htmlentities:function  (string, quote_style) {
	    // Convert all applicable characters to HTML entities  
	    // 
	    // version: 907.503
	    // discuss at: http://phpjs.org/functions/htmlentities
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: nobbler
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Ratheous
	    // -    depends on: get_html_translation_table
	    // *     example 1: htmlentities('Kevin & van Zonneveld');
	    // *     returns 1: 'Kevin &amp; van Zonneveld'
	    // *     example 2: htmlentities("foo'bar","ENT_QUOTES");
	    // *     returns 2: 'foo&#039;bar'
	    var hash_map = {}, symbol = '', tmp_str = '', entity = '';
	    tmp_str = string.toString();
	    
	    if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
	        return false;
	    }
	    hash_map["'"] = '&#039;';
	    for (symbol in hash_map) {
	        entity = hash_map[symbol];
	        tmp_str = tmp_str.split(symbol).join(entity);
	    }
	    
	    return tmp_str;
	},
	strip_tags: function (str, allowed_tags) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: Luke Godfrey
	    // +      input by: Pul
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Onno Marsman
	    // +      input by: Alex
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Marc Palau
	    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +      input by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Eric Nagel
	    // +      input by: Bobby Drake
	    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: Tomasz Wesolowski
	    // *     example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
	    // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
	    // *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
	    // *     returns 2: '<p>Kevin van Zonneveld</p>'
	    // *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
	    // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
	    // *     example 4: strip_tags('1 < 5 5 > 1');
	    // *     returns 4: '1 < 5 5 > 1'

	    var key = '', allowed = false;
	    var matches = [];
	    var allowed_array = [];
	    var allowed_tag = '';
	    var i = 0;
	    var k = '';
	    var html = '';

	    var replacer = function (search, replace, str) {
	        return str.split(search).join(replace);
	    };

	    // Build allowes tags associative array
	    if (allowed_tags) {
	        allowed_array = allowed_tags.match(/([a-zA-Z0-9]+)/gi);
	    }

	    str += '';

	    // Match tags
	    matches = str.match(/(<\/?[\S][^>]*>)/gi);

	    // Go through all HTML tags
	    for (key in matches) {
	        if (isNaN(key)) {
	            // IE7 Hack
	            continue;
	        }

	        // Save HTML tag
	        html = matches[key].toString();

	        // Is tag not in allowed list? Remove from str!
	        allowed = false;

	        // Go through all allowed tags
	        for (k in allowed_array) {
	            // Init
	            allowed_tag = allowed_array[k];
	            i = -1;

	            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
	            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
	            if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}

	            // Determine
	            if (i == 0) {
	                allowed = true;
	                break;
	            }
	        }

	        if (!allowed) {
	            str = replacer(html, "", str); // Custom replace. No regexing
	        }
	    }

	    return str;
	}
});

$().ready(function () {
	PTMObj = new PTM();
});