if (!console) {
    var console = {
        log: function(){},
        debug: function(){},
        dir: function(){},
        firebug: null
    }
}


(function($) {

jQuery.extend({
    
    jsHttpRequest: function(options)
    {
        var options = jQuery.extend({
            url:     '/',
            data:    {},
            onReady: function(){},
            cache:   true,
            target:  null,
            timeout: 30000
        }, options);
        
        
        var escapeUrl = '';
        $.map(options.url.match(/[а-я]+|[^а-я]+/ig), function(str) {
            escapeUrl += str.match(/[а-я]+/ig) ? str.escapeCyr() : str;
        });
        
        JsHttpRequest.query(
            escapeUrl,
            options.data,
            function(result, text) {

                if (typeof(result._debug) != 'undefined') {
                    console.log(result._debug);
                }
                
                if (typeof(result._trace) != 'undefined') {
                    $.each(result._trace, function(i, message) {
                        console.log(message);
                    });
                }
                
                if (typeof(options.onReady) == 'function') {
                    options.onReady(result, text);
                }
                

            },
            !options.cache
        );
    },
    
    alertZ: function(text, timeout)
    {
    	if (typeof(text) == 'object') {
            $.each(text, function(i, txt) {
                $.alertZ(txt, timeout);
            });
            return;
        }
        
        if (!$('#alertZ-container').length) {
            $('body').append('<div id="alertZ-container"></div>');
        }
        
        var _timeOutHide = function(msgId, timeout) {
            if (typeof($._alertZTimeOutHide) == 'undefined') $._alertZTimeOutHide = [];
            clearTimeout($._alertZTimeOutHide[msgId]);
            $._alertZTimeOutHide[msgId] = setTimeout(function() {
                $('#'+msgId+':not(.alertZ-hover)').fadeOut(1500, function() { $(this).remove(); });
            }, timeout || 10000);
        }
        
        var msgId = ('alertZ-msg-' + Math.random()).replace('.', ''); 
        $('<div class="alertZ-message" id="'+ msgId +'" style="display: none;">'+ text +'<a href="#" onclick="$(this).parent().remove(); return false;" class="alertZ-close"></a></div>')
            .prependTo('#alertZ-container')
            .fadeIn('slow')
            .mouseover(function() {
                $(this).stop().addClass('alertZ-hover').css('opacity', 0.9);
            })
            .mouseout(function() {
                $(this).removeClass('alertZ-hover');
                _timeOutHide(this.id, timeout || 10000);
            });
        
        _timeOutHide(msgId, timeout);
    }
});

jQuery.fn.extend({
    
    serializeHash: function()
    {
        var hash = {};
        $.each(this.serializeArray(), function(i, el) {
            el.name = el.name.replace(/\[\]$/, '');
            
            if (typeof(hash[el.name]) == 'undefined')
                return hash[el.name] = el.value; 
            
            if (!hash[el.name].push)
                hash[el.name] = [hash[el.name]];
            
            hash[el.name].push(el.value);
        });
        return hash;
    },
    
    red: function()
    {
        return $(this).css('border', 'red 1px solid');
    },
    
    removeSlow: function()
    {
        return $(this).animate({ opacity: 'hide', height: 'hide' }, 'slow', null, function(){ $(this).remove(); });
    }
});

$F = function(elm) {
    return $(elm).val();
}

clone = function(object) {
    return $.extend({}, object);
}

differenceOfDays = function(start, end)
{
    start = start.split('.');
    end   = end.split('.');
    start = new Date(start[2], start[1], start[0]);
    end   = new Date(end[2], end[1], end[0]);
    return Math.ceil((end - start) / (1000 * 86400));
}

$.extend(String.prototype, {
    
    /**
     * Транслит руских букв в латинские
     * @param string text
     * @return string
     */
    translit: function () {
        var text   = this;
        var ru_str = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя';
        var en_str = [
        'A','B','V','G','D','E','Jo','Zh','Z','I','Y','K','L','M','N','O','P','R','S','T','U','F',
        'Kh','Ts','Ch','Sh','Shch','','Y','','E','Yu','Ya',
        'a','b','v','g','d','e','jo','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f',
        'kh','ts','ch','sh','shch','','y','','e','yu','ya'];

        for(var i = 0, out = [], count = text.length; i < count; i++) {
            var s = text.charAt(i), n = ru_str.indexOf(s);
            out[out.length] = (n >= 0) ? en_str[n] : s;
        }
        return out.join('');
    },
    
    // подсавляет к числу существительное в соответствующей форме. 
    // например: 3.inciting('турист', 'туриста', 'туристов') -> 3 туриста
    inciting: function(form1, form2, form5)
    {
        var num = Math.abs(parseInt(this));
        var n = num % 100, n1 = num % 10;
        form5 = form5 || form2;
        if (n > 10 && n < 20) return this + ' ' + form5;
        if (n1 > 1 && n1 < 5) return this + ' ' + form2;
        if (n1 == 1) return this + ' ' + form1;
        return this + ' ' + form5;
    },
    
    // делает первый символ с большой буквы, остальные с маленькой. иванов -> Иванов
    capitalize: function()
    {
        return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
    },
    
    // заменяет все символы с 160 по 255-й на соответствующий entitles код. например &#231;
    unicodeToEntitles: function()
    {
        for (var i = 0, output = this, cnt = this.length; i < cnt; i++) {
            if (this.charCodeAt(i) < 160 || this.charCodeAt(i) > 255) continue;
            output = output.replace(this[i], '&#' + this.charCodeAt(i) + ';');
        }
        return output + '';
    },
    
    // переопределение escape, т.к. обычная функция вместо русских букв выдает фигню
    escapeCyr: function()
    {
        var trans = [], ret = [];
        for (var i = 0x410; i <= 0x44F; i++)
            trans[i] = i - 0x350; // А-Яа-я
        trans[0x401] = 0xA8;    // Ё
        trans[0x451] = 0xB8;    // ё
        
        // Составляем массив кодов символов, попутно переводим кириллицу
        for (var i = 0, count = this.length; i < count; i++) {
            var n = this.charCodeAt(i);
            if (typeof trans[n] != 'undefined')
                n = trans[n];
            if (n <= 0xFF)
                ret.push(n);
        }
        return escape(String.fromCharCode.apply(null, ret));
    },
    
    // переопределение unescape, т.к. обычная функция вместо русских букв выдает фигню
    unescapeCyr: function()
    {
        var trans = [], ret = [];
        for (var i = 0x410; i <= 0x44F; i++)
            trans[i] = i - 0x350; // А-Яа-я
        trans[0x401] = 0xA8;    // Ё
        trans[0x451] = 0xB8;    // ё
        
        // Составляем массив кодов символов, попутно переводим кириллицу
        for (var i = 0, count = this.length; i < count; i++) {
            var n = this.charCodeAt(i);
            if (typeof trans[n] != 'undefined')
                n = trans[n];
            if (n <= 0xFF)
                ret.push(n);
        }
        return escape(String.fromCharCode.apply(null, ret));
    }
});

Number.prototype.inciting = String.prototype.inciting;
window.escapeModify = function(str) { return str.escapeCyr(); }

})(jQuery);


/**
 * Плагин для работы с JSON, содержит 2 функции
 * 
 * string = $.toJSON(object);
 * object = $.parseJSON(string, [safeMode]);
 */
(function($){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},s={'array':function(x){var a=['['],b,f,i,l=x.length,v;for(i=0;i<l;i+=1){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a[a.length]=v;b=true}}}a[a.length]=']';return a.join('')},'boolean':function(x){return String(x)},'null':function(x){return"null"},'number':function(x){return isFinite(x)?String(x):'null'},'object':function(x){if(x){if(x instanceof Array){return s.array(x)}var a=['{'],b,f,i,v;for(i in x){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a.push(s.string(i),':',v);b=true}}}a[a.length]='}';return a.join('')}return'null'},'string':function(x){if(/["\\\x00-\x1f]/.test(x)){x=x.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c}c=b.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16)})}return'"'+x+'"'}};$.toJSON=function(v){var f=isNaN(v)?s[typeof v]:s['number'];if(f)return f(v)};$.parseJSON=function(v,safe){if(safe===undefined)safe=$.parseJSON.safe;if(safe&&!/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))return undefined;return eval('('+v+')')};$.parseJSON.safe=false})(jQuery);
