61 Commits

Autor SHA1 Mensagem Data
wellton ac361419b8 Update app.js 2021-05-06 18:58:50 -03:00
Daniel Howard 7985251207 Fixed readme for AjaxIM_v4.0a4. 2014-10-09 15:31:48 -07:00
Daniel Howard 5805778a17 Refactor server for flexibility. 2014-10-09 14:26:31 -07:00
Daniel Howard f522e0874e cookie-parser not needed anymore. 2014-09-24 15:17:02 -07:00
Daniel Howard 58bdceef45 Replace cookies with params because cookies are not cross-domain. 2014-09-24 15:15:58 -07:00
Daniel Howard b20f678a38 Accept URL-encoded GETs and POSTs, too. 2014-09-24 15:10:20 -07:00
Daniel Howard ba32c3b727 Replace homebrew triggerEvent()/onEvent() with jQuery on()/trigger(). 2014-09-24 14:56:31 -07:00
Daniel Howard a6ef421f79 Replace get() and post() calls with request() calls. 2014-09-24 14:29:52 -07:00
Daniel Howard 9f7c470b05 Move get(), post() and request() to be non-static. 2014-09-12 16:30:51 -07:00
Daniel Howard 0a5b025c3e AjaxIM object automatically creates sessionid cookie. 2014-09-12 14:33:49 -07:00
Daniel Howard c75b3d2f31 Store sessionid in store instead of in cookies. 2014-09-12 14:31:46 -07:00
Daniel Howard bb3fc41c32 Remove unneeded build folder. 2014-08-28 14:39:49 -07:00
Daniel Howard 6f05609dab 4.0a3 minified version. 2014-08-28 13:36:46 -07:00
Daniel Howard 0893da7df5 Use >= instead of ^ because other packages do. 2014-08-28 13:08:09 -07:00
Daniel Howard 7658637231 Default chat textarea to 16 pixels. 2014-08-28 13:06:36 -07:00
Daniel Howard 01df091f45 Hide error scrollers by default. 2014-08-28 13:04:30 -07:00
Daniel Howard 9e7ab46683 Hide .imjs-scroll after loading theme. 2014-08-28 11:11:58 -07:00
Daniel Howard 1c3c68c7db Init body-parser with json() call. 2014-08-28 11:09:12 -07:00
Daniel Howard 48f51255a1 Use Socket.IO instead of HTTP when possible. 2014-07-18 15:49:01 -07:00
Daniel Howard 1678ebb345 Refactor to make code more compact. 2014-07-02 15:20:23 -07:00
Daniel Howard acf9bffb7e Detect and create a Socket.IO object. 2014-07-02 15:12:46 -07:00
Daniel Howard dff403f604 Refactor make init cleaner. 2014-07-02 14:40:53 -07:00
Daniel Howard 80d5d177f5 Use hub instead of random numbers to create username and friend's lists. 2014-06-27 16:58:27 -07:00
Daniel Howard 786aec2505 Add new users to friend's list automatically in _friendUpdate(). 2014-06-27 16:42:02 -07:00
Daniel Howard 438ea86155 Fix _friendUpdate() to send correct string to l10n. 2014-06-27 16:40:24 -07:00
Daniel Howard ed404bffcb Add hub as argument #3 to authentication calls. 2014-06-27 15:37:18 -07:00
Daniel Howard 1b1a7a5159 Fix off-by-1 bug in User.close(). 2014-06-27 15:29:58 -07:00
Daniel Howard fd191229a0 Delete and close a session when it is reaped. 2014-06-27 15:04:17 -07:00
Daniel Howard c8747974ee Add User.close() to a session's timer and connections. 2014-06-27 15:02:51 -07:00
Daniel Howard d6caf96690 Remove User.respond() and call jsonp() directly. 2014-06-27 14:07:47 -07:00
Daniel Howard 8b94d6c411 Use bi-directional events system instead of handcrafted messages. 2014-06-20 15:29:17 -07:00
Daniel Howard 5226091385 Fix file format for EGit. 2014-05-13 12:28:15 -07:00
ajaximrpg a89a9f0ac4 Initial import. 2014-05-13 12:23:02 -07:00
Daniel Howard 519ae5c751 Remove obsolete daemon code and cookie pages. 2014-05-09 15:10:17 -07:00
Daniel Howard 014375eea3 Set 'sessionid' cookie automatically. 2014-05-07 16:41:35 -07:00
Daniel Howard e1097a73d5 Fix JSONP. 2014-05-07 16:17:38 -07:00
Daniel Howard 26282c4929 Add charset to suppress browser warning. 2014-05-07 15:51:37 -07:00
Daniel Howard b52aab4136 Replace req.dev with /app URL. 2014-05-02 15:01:20 -07:00
Daniel Howard ad03007044 Fix "status updates before adding listeners" bug. 2014-05-02 14:22:59 -07:00
Daniel Howard b38ba6a3c5 Upgrade jQuery from 1.4.1 to 1.11.0. 2014-05-01 16:09:43 -07:00
Daniel Howard 8c26db802f Use same uid() function on server and client. 2014-05-01 15:29:19 -07:00
Daniel Howard 7a7015078a Fix "all requests marked dev" bug. 2014-05-01 15:14:02 -07:00
Daniel Howard 2742cdd014 Merge branch 'master' of https://github.com/ajaximrpg/AjaxIM.git 2014-04-29 13:44:06 -07:00
ajaximrpg c1d9011d70 Delete .project 2014-04-29 13:41:43 -07:00
Daniel Howard 884e776d3e Update to run on node v0.10.26. 2014-04-29 13:11:13 -07:00
Daniel Howard 677587ca05 Eclipse project. 2013-04-26 12:33:49 -07:00
Daniel Howard d0afe8590d Support JSONP to allow Apache integration. 2013-02-20 12:24:10 -08:00
Daniel Howard 5be7d482e7 Improve cookies.get() to handle both non-JSON values, too. 2013-02-20 12:19:01 -08:00
ajaximrpg ea69a15a62 Merge pull request #52 from mburtscher/patch-1
Allow server to return multiple messages in one response.
2012-10-05 10:05:27 -07:00
ajaximrpg 6899d8e63d Merge pull request #56 from ajaximrpg/master
Upgraded code for node 0.8.9
2012-10-04 12:52:35 -07:00
Daniel Howard c819c7ec43 Fix copyright list formatting. 2012-09-19 12:48:29 -07:00
Daniel Howard 8d2675e328 Update for node 0.8.9. 2012-09-19 12:28:15 -07:00
Daniel Howard c44ec4751d Revise for express and connect package changes and node 0.8.9. 2012-09-19 12:26:31 -07:00
Daniel Howard 9a9bbfef50 Don't pass on listen URL to avoid setHeader() console warning. 2012-09-19 12:20:56 -07:00
Daniel Howard 3be668abaf Limit users to 10 for easier dev demo. 2012-09-19 11:24:44 -07:00
Daniel Howard b98e531bca Use cookie package; connect package no longer supports cookies. 2012-09-19 11:22:32 -07:00
Daniel Howard 02896ecc4a Update format for jade 0.27.4 (node 0.8.9). 2012-09-19 11:19:36 -07:00
Daniel Howard 43289d0d17 Use session storage to stop storing username too long. 2012-09-19 11:18:54 -07:00
Daniel Howard eeac0be514 Show offline users for better demo. 2012-09-19 11:18:14 -07:00
Joshua Gross f00a7fe1c3 Mark project as no longer in active development. 2012-01-09 10:14:45 -05:00
mburtscher eb5a174e3b Allow server to return multiple messages in one response. Quite useful since you generate fewer requests and the implementation on server side is easier ... 2011-07-22 04:34:37 -07:00
27 arquivos alterados com 11068 adições e 7237 exclusões
+21 -29
Ver Arquivo
@@ -10,6 +10,7 @@ community experience.
* Instant communication between connected users
* Robust backend server built on [Node.js](http://nodejs.org)
* Support for [Socket.IO](http://socket.io), JSON and JSONP
* Can be integrated with virtually any existing website
* Seamless authentication
* Works across an entire website, unobtrusively
@@ -20,43 +21,34 @@ community experience.
## Installation
Install `Node.js`:
wget http://nodejs.org/dist/node-v0.2.5.tar.gz
tar xzf node-v0.2.5.tar.gz
cd node-v0.2.5
wget http://nodejs.org/dist/v0.10.32/node-v0.10.32-linux-x86.tar.gz
tar xzf node-v0.10.32-linux-x86.tar.gz
cd node-v0.10.32-linux-x86
./configure
make
make install
Install Node Package Manager (`npm`):
See instructions at http://github.com/isaacs/npm.
Install Ajax IM:
Install `Express.js` and `Connect` (included automatically):
npm install express
Compile the daemon add-on if you plan on letting the server daemonize itself:
cd server/libs/daemon
node-waf configure build
cp build/default/daemon.node .
rm -rf build
## Installation for Development
If you want to test Ajax IM as a standalone app for development, you will need
to install [`Jade`](http://github.com/visionmedia/jade) as well.
To install `Jade`:
npm install jade
unzip AjaxIM_v4.0a4.zip
cd AjaxIM_v4.0a4
npm install
## Starting up the server
Starting the server in _development_ mode is as simple as:
node server/app.js
To start the server in _production_ mode:
EXPRESS_ENV=production node server/app.js
To start the server as a _daemon_ in _production_ mode:
node server/app.js start production
NODE_ENV=production node server/app.js
To start the server using forever with a log file:
npm install forever
forever -l ~/ajaxim.log start ~/AjaxIM_v4.0a4/server/app.js
## Testing it out
@@ -65,24 +57,23 @@ through the included development testing app. The below instructions are
assuming that you have left all default configuration options. If not, please
replace the host/port values with the correct ones.
To get started, first initialize a session cookie by going to:
http://localhost:8000/dev/cookie
To get started, head over to the development page:
Then head over to the development page that will initialize the client:
http://localhost:8000/dev/
That's it!
## More Information
* Follow [endtwist](http://twitter.com/endtwist) on twitter for updates
* Follow [ajaximrpg](http://twitter.com/ajaximrpg) on twitter for updates
* [Google Group](http://groups.google.com/group/ajaxim) for discussion
* [GitHub Wiki](https://github.com/endtwist/AjaxIM/wiki) for guidance
## Node Compatibility
The `master` branch of Ajax IM is compatible with node --version:
v0.2.5
v0.10.32
## Contributing
@@ -220,6 +211,7 @@ Methods:
(The MIT License)
Copyright (c) 2012-2014 [Daniel Howard] (http://www.svexpertise.com)
Copyright (c) 2010 [Joshua Gross](http://www.unwieldy.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
Arquivo binário não exibido.
+23
Ver Arquivo
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax IM</title>
<script src="js/jquery-1.11.1.js" type="text/javascript"></script>
<script src="js/md5.js" type="text/javascript"></script>
<script src="js/store.js" type="text/javascript"></script>
<script src="js/dateformat.js" type="text/javascript"></script>
<script src="js/im.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var u = window.location.href.split("/");
var p = 8000; // Node.js port
u = u[0]+"//"+u[2]+":"+p;
var im = AjaxIM.init({pollServer: u, theme: "themes/default"});
});
</script>
</head>
<body>
Hello.
</body>
</html>
-48
Ver Arquivo
@@ -1,48 +0,0 @@
// Cookies API
var cookies = {
// === {{{AjaxIM.}}}**{{{cookies.set(name, value, days)}}}** ===
//
// Sets a cookie, stringifying the JSON value upon storing it.
//
// ==== Parameters ====
// * {{{name}}} is the cookie name.\\
// * {{{value}}} is the cookie data that you would like to store.\\
// * {{{days}}} is the number of days that the cookie will be stored for.
set: function(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
} else var expires = "";
document.cookie = name + "=" + JSON.stringify(value) + expires + "; path=/";
},
// === {{{AjaxIM.}}}**{{{cookies.get(name)}}}** ===
//
// Gets a cookie, decoding the JSON value before returning the data.
//
// ==== Parameters ====
// * {{{name}}} is the cookie name that you would like to retrieve.
get: function(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) {
var cval = decodeURIComponent(c.substring(nameEQ.length, c.length));
return JSON.parse(cval);
}
}
return null;
},
// === {{{AjaxIM.}}}**{{{cookies.erase(name)}}}** ===
//
// Deletes a cookie.
//
// {{{name}}} is the existing cookie that you would like to delete.
erase: function(name) {
this.set(name, '', -1);
}
};
+351 -212
Ver Arquivo
@@ -47,75 +47,96 @@ AjaxIM = function(options, actions) {
// requests rather than POST requests (such as how the Node.JS Ajax IM
// server works).
this.actions = $.extend({
listen: this.settings.pollServer + '/listen',
send: this.settings.pollServer + '/message',
status: this.settings.pollServer + '/status',
signoff: this.settings.pollServer + '/signoff'
noop: this.settings.pollServer + '/app/noop',
listen: this.settings.pollServer + '/app/listen',
send: this.settings.pollServer + '/app/message',
status: this.settings.pollServer + '/app/status',
signoff: this.settings.pollServer + '/app/signoff'
}, actions);
if (!store.get('sessionid')) {
store.set('sessionid', AjaxIM.uid(40));
}
// If Socket.IO is available, create a socket
self.socket = null;
$.getScript(this.settings.pollServer+'/socket.io/socket.io.js', function(){
self.socket = io(self.settings.pollServer);
self.socket.on('client', function(event) {
event = $.extend(true, {}, event);
self.dispatchEvent(event);
});
var event = {type: 'hello', from: store.get('user')};
self.sendEvent(event, function() {}, function() {});
});
// We load the theme dynamically based on the passed
// settings. If the theme is set to false, we assume
// that the user is going to load it himself.
this.themeLoaded = false;
if(this.settings.theme) {
$('<div>').appendTo('body').load(this.settings.theme + '/theme.html #imjs-bar, .imjs-tooltip',
if (this.settings.theme) {
if(typeof document.createStyleSheet == 'function') {
document.createStyleSheet(this.settings.theme + '/theme.css');
} else {
$('body').append('<link rel="stylesheet" href="' +
this.settings.theme + '/theme.css" />');
}
$('<div>').appendTo('body').load(this.settings.theme +
'/theme.html #imjs-bar, .imjs-tooltip',
function() {
self.themeLoaded = true;
self.setup();
}
);
if(typeof document.createStyleSheet == 'function')
document.createStyleSheet(this.settings.theme + '/theme.css');
else
$('body').append('<link rel="stylesheet" href="' +
this.settings.theme + '/theme.css" />');
} else {
this.themeLoaded = true;
this.setup();
}
// Allow a chatbox to be minimized
$('.imjs-chatbox').live('click', function(e) {
$(document).on('click', '.imjs-chatbox', function(e) {
e.preventDefault();
return false;
});
$('.imjs-chatbox .imjs-minimize').live('click', function() {
$(document).on('click', '.imjs-chatbox .imjs-minimize', function() {
$(this).parents('.imjs-selected').click();
});
// Setup message sending for all chatboxes
$('.imjs-chatbox .imjs-input').live('keydown', function(event) {
$(document).on('keydown', '.imjs-chatbox .imjs-input', function(event) {
var obj = $(this);
if(event.keyCode == 13 && !($.browser.msie && $.browser.version < 8)) {
// if(event.keyCode == 13 && !($.browser.msie && $.browser.version < 8)) {
if(event.keyCode == 13) {
self.send(obj.parents('.imjs-chatbox').data('username'), obj.val());
}
}).live('keyup', function(event) {
}).on('keyup', '.imjs-chatbox .imjs-input', function(event) {
if(event.keyCode == 13) {
if($.browser.msie && $.browser.version < 8) {
// if($.browser.msie && $.browser.version < 8) {
if(false) {
var obj = $(this);
self.send(obj.parents('.imjs-chatbox').data('username'), obj.val());
}
var obj = $(this);
obj.val('');
obj.height(obj.data('height'));
}
}).live('keypress', function(e) {
}).on('keypress', '.imjs-chatbox .imjs-input', function(e) {
var obj = $(this);
if(!($.browser.msie && $.browser.opera)) obj.height(0);
obj.height(0);
if(true) obj.height(0);
if(this.scrollHeight > obj.height() || this.scrollHeight < obj.height()) {
obj.height(this.scrollHeight);
}
});
$('.imjs-msglog').live('click', function() {
$(document).on('click', '.imjs-msglog', function() {
var chatbox = $(this).parents('.imjs-chatbox');
chatbox.find('.imjs-input').focus();
});
// Create a chatbox when a buddylist item is clicked
$('.imjs-friend').live('click', function() {
$(document).on('click', '.imjs-friend', function() {
var chatbox = self._createChatbox($(this).data('friend'));
if(chatbox.parents('.imjs-tab').data('state') != 'active') {
@@ -126,13 +147,16 @@ AjaxIM = function(options, actions) {
chatbox.find('.imjs-input').focus();
if(!(input = chatbox.find('.imjs-input')).data('height')) {
// store the height for resizing later
if (!input.height()) {
input.height(16);
}
input.data('height', input.height());
}
});
// Setup and hide the scrollers
$('.imjs-scroll').css('display', 'none');
$('#imjs-scroll-right').live('click', function() {
$(document).on('click', '#imjs-scroll-right', function() {
var hiddenTab = $(this)
.prevAll('#imjs-bar li.imjs-tab:hidden')
.filter(function() {
@@ -153,7 +177,7 @@ AjaxIM = function(options, actions) {
return false;
});
$('#imjs-scroll-left').live('click', function() {
$(document).on('click', '#imjs-scroll-left', function() {
var hiddenTab = $(this)
.nextAll('#imjs-bar li.imjs-tab:hidden')
.filter(function() {
@@ -176,7 +200,7 @@ AjaxIM = function(options, actions) {
});
// Setup status buttons
$('#imjs-status-panel .imjs-button').live('click', function() {
$(document).on('click', '#imjs-status-panel .imjs-button', function() {
var status = this.id.split('-')[2];
$('#imjs-away-message-text, #imjs-away-message-text-arrow').animate({
@@ -200,8 +224,8 @@ AjaxIM = function(options, actions) {
});
// Allow status message to be changed
$('#imjs-away-message-text')
.live('keyup', (function() {
$(document)
.on('keyup', '#imjs-away-message-text', (function() {
var msg_type_timer = null;
return function() {
@@ -220,7 +244,7 @@ AjaxIM = function(options, actions) {
});
// Setup reconnect button
$('#imjs-reconnect').live('click', function() {
$(document).on('click', '#imjs-reconnect', function() {
self.offline = false;
store.remove(self.username + '-offline');
$('#imjs-reconnect').hide();
@@ -255,6 +279,13 @@ AjaxIM = function(options, actions) {
self._scrollers();
} catch(e) {}
});
// Set up event handling
$(this).on('hello', AjaxIM.onObj(this, this.onHello));
$(this).on('message', AjaxIM.onObj(this, this.onMessage));
$(this).on('status', AjaxIM.onObj(this, this.onStatus));
$(this).on('notice', AjaxIM.onObj(this, this.onNotice));
$(this).on('goodbye', AjaxIM.onObj(this, this.onGoodbye));
} else {
return AjaxIM.init(options);
}
@@ -263,8 +294,10 @@ AjaxIM = function(options, actions) {
$.extend(AjaxIM.prototype, {
// == Main ==
setup: function() {
var self = this;
$(this).trigger('loadComplete');
$('.imjs-scroll').css('display', 'none');
this.initTabBar();
this._scrollers();
@@ -274,7 +307,6 @@ $.extend(AjaxIM.prototype, {
if(this.username && store.get(this.username + '-offline') == true) {
this.offline = true;
var self = this;
setTimeout(function() { self._showReconnect(); }, 0);
return;
}
@@ -282,7 +314,7 @@ $.extend(AjaxIM.prototype, {
if(this.username)
this.storage();
this.listen();
setTimeout(function() { if (!self.socket) self.listen(); }, 2000);
},
// === {{{AjaxIM.}}}**{{{storage()}}}** ===
@@ -340,7 +372,7 @@ $.extend(AjaxIM.prototype, {
var msglog = this.chats[activeTab].find('.imjs-msglog');
msglog[0].scrollTop = msglog[0].scrollHeight;
}
// Set username in Friends list
var header = $('#imjs-friends-panel .imjs-header');
header.html(header.html().replace('{username}', this.username));
@@ -375,14 +407,23 @@ $.extend(AjaxIM.prototype, {
if(this.offline) return;
var self = this;
AjaxIM.get(
self.request(
this.actions.listen,
{},
function(response) {
if(response)
self._parseMessage(response);
'GET',
{type: 'hello', from: store.get('user'), sessionid: store.get('sessionid')},
function(event) {
if($.isArray(event)) {
$.each(event, function(key, event) {
$(self).trigger(event.type, event);
});
}
else if($.isPlainObject(event)) {
$(self).trigger(event.type, event);
}
setTimeout(function() { self.listen(); }, 0);
if (!self.socket) {
setTimeout(function() { self.listen(); }, 0);
}
},
function(error) {
self._notConnected();
@@ -393,67 +434,57 @@ $.extend(AjaxIM.prototype, {
? 1000
: Math.min(self._reconnectIn * 2, 16000);
self._lastReconnect = new Date();
setTimeout(function() { self.listen(); }, self._reconnectIn);
if (!self.socket) {
setTimeout(function() { self.listen(); }, self._reconnectIn);
}
}
);
},
// === //private// {{{AjaxIM.}}}**{{{_parseMessages(messages)}}}** ===
//
_parseMessage: function(message) {
onHello: function(message) {
var self = this;
$(this).trigger('parseMessage', [message]);
this._clearSession();
switch(message.type) {
case 'hello':
this._clearSession();
this.username = message.username;
this.current_status = ['available', ''];
store.set('user', message.username);
store.set(this.username + '-status', this.current_status);
this.username = message.username;
this.current_status = ['available', ''];
store.set('user', message.username);
store.set(this.username + '-status', this.current_status);
$('#imjs-friends').attr('class', 'imjs-available');
$.each(message.friends, function() {
var friend;
if(this.length == 2)
friend = this;
else
friend = [this.toString(), ['offline', '']];
self.addFriend(friend[0], friend[1], 'Friends');
});
store.set(this.username + '-friends', this.friends);
$('#imjs-friends').attr('class', 'imjs-available');
$.each(message.friends, function() {
var friend;
if(this.length == 2)
friend = this;
else
friend = [this.toString(), ['offline', '']];
self.addFriend(friend[0], friend[1], 'Friends');
});
store.set(this.username + '-friends', this.friends);
// Set username in Friends list
var header = $('#imjs-friends-panel .imjs-header');
header.html(header.html().replace('{username}', this.username));
// Set status available
$('#imjs-away-message-text, #imjs-away-message-text-arrow').hide();
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
$('#imjs-button-available').addClass('imjs-toggled');
break;
// Set username in Friends list
var header = $('#imjs-friends-panel .imjs-header');
header.html(header.html().replace('{username}', this.username));
case 'message':
this.incoming(message.user, message.body);
break;
// Set status available
$('#imjs-away-message-text, #imjs-away-message-text-arrow').hide();
$('#imjs-status-panel .imjs-button').removeClass('imjs-toggled');
$('#imjs-button-available').addClass('imjs-toggled');
},
case 'status':
this._friendUpdate(message.user, message.status,
message.message);
this._storeFriends();
break;
onMessage: function(event) {
this.incoming(event.from, event.body);
},
case 'notice':
break;
case 'goodbye':
this._notConnected();
break;
onStatus: function(event) {
this._friendUpdate(event.from, event.status, event.message);
this._storeFriends();
},
default:
break;
}
onNotice: function(event) {
},
onGoodbye: function(event) {
this._notConnected();
},
// === {{{AjaxIM.}}}**{{{incoming(from, message)}}}** ===
@@ -516,8 +547,8 @@ $.extend(AjaxIM.prototype, {
.attr('id', user_id)
.data('friend', username)
.appendTo(group_item.find('ul'));
if(status[0] == 'offline')
user_item.hide();
// if(status[0] == 'offline')
// user_item.hide();
user_item.html(
user_item.html()
.replace('{username}', username)
@@ -622,7 +653,7 @@ $.extend(AjaxIM.prototype, {
this.notification(tab);
}
setTimeout(function() { self._scrollers() }, 0);
setTimeout(function() { self._scrollers(); }, 0);
}
return chatbox;
@@ -837,7 +868,7 @@ $.extend(AjaxIM.prototype, {
var date_stamp_date = date_stamp.find('.imjs-date-date').html(
AjaxIM.l10n[
'chat' + status.toUpperCase() + status.slice(1)
'chat' + status.toUpperCase().slice(0, 1) + status.slice(1)
].replace(/%s/g, friend));
var msglog = this.chats[friend].find('.imjs-msglog');
@@ -845,6 +876,9 @@ $.extend(AjaxIM.prototype, {
msglog[0].scrollTop = msglog[0].scrollHeight;
}
if (!this.friends[friend]) {
this.addFriend(friend, [status, statusMessage], 'Friends');
}
if(this.friends[friend]) {
var friend_id = 'imjs-friend-' + md5.hex(friend + this.friends[friend].group);
$('#' + friend_id).attr('class', 'imjs-friend imjs-' + status);
@@ -876,7 +910,7 @@ $.extend(AjaxIM.prototype, {
if($('#imjs-friends').hasClass('imjs-selected'))
this.activateTab($('#imjs-friends'));
},
_showReconnect: function() {
$('#imjs-reconnect').show();
},
@@ -913,23 +947,17 @@ $.extend(AjaxIM.prototype, {
$(this).trigger('sendingMessage', [username, body]);
AjaxIM.post(
this.actions.send,
{to: username, body: body},
function(result) {
if(result.type == 'success' && result.success == 'sent') {
$(self).trigger('sendMessageSuccessful',
[username, body]);
var event = {type: 'message', from: this.username, to: username, body: body};
this.sendEvent(event, function(result) {
if(result._status.sent) {
$(self).trigger('sendMessageSuccessful', [username, body]);
} else if(result.type == 'error') {
if(result.error == 'not online')
$(self).trigger('sendMessageFailed',
['offline', username, body]);
$(self).trigger('sendMessageFailed', ['offline', username, body]);
else
$(self).trigger('sendMessageFailed',
[result.error, username, body]);
$(self).trigger('sendMessageFailed', [result.error, username, body]);
}
},
function(error) {
}, function(error) {
self._notConnected();
var error = self._addError(
self.chats[username],
@@ -937,11 +965,13 @@ $.extend(AjaxIM.prototype, {
'server is not available. Please ensure ' +
'that you are signed in and try again.');
self._store(error);
$(self).trigger('sendMessageFailed',
['not connected', username, body]);
}
);
});
},
signOff: function() {
this.status('offline', '');
},
// === {{{AjaxIM.}}}**{{{status(s, message)}}}** ===
@@ -976,13 +1006,10 @@ $.extend(AjaxIM.prototype, {
self.offline = true;
$('.imjs-input').attr('disabled', true);
AjaxIM.post(
this.actions.signoff,
{},
function(result) {
if(result.type == 'success')
$(self).trigger('changeStatusSuccessful',
[value, null]);
var event = {type: 'signoff', message: message};
this.sendEvent(event, function(result) {
if(result.type == 'success')
$(self).trigger('changeStatusSuccessful', [value, null]);
},
function(error) {
$(self).trigger('changeStatusFailed',
@@ -990,31 +1017,27 @@ $.extend(AjaxIM.prototype, {
}
);
} else {
AjaxIM.post(
this.actions.status,
{status: value, message: message},
function(result) {
switch(result.type) {
case 'success':
$(self).trigger('changeStatusSuccessful',
[value, message]);
self.current_status = [value, message];
store.set(self.username + '-status',
self.current_status);
break;
case 'error':
default:
$(self).trigger('changeStatusFailed',
[result.e, value, message]);
break;
}
},
function(error) {
$(self).trigger('changeStatusFailed',
['not connected', value, message]);
}
);
var event = {type: 'status', status: value, message: message};
this.sendEvent(event, function(result) {
if(result._status.send) {
$(self).trigger('sendMessageSuccessful', [username, body]);
} else if(result.type == 'error') {
if(result.error == 'not online')
$(self).trigger('sendMessageFailed', ['offline', username, body]);
else
$(self).trigger('sendMessageFailed', [result.error, username, body]);
}
}, function(error) {
self._notConnected();
var error = self._addError(
self.chats[username],
'You are currently not connected or the ' +
'server is not available. Please ensure ' +
'that you are signed in and try again.');
self._store(error);
$(self).trigger('sendMessageFailed',
['not connected', username, body]);
});
}
},
@@ -1045,13 +1068,13 @@ $.extend(AjaxIM.prototype, {
var self = this;
// Set up your standard tab actions
$('.imjs-tab')
.live('click', function() {
$(document)
.on('click', '.imjs-tab', function() {
return self.activateTab.call(self, $(this));
});
$('.imjs-tab .imjs-close')
.live('click', function() {
$(document)
.on('click', '.imjs-tab .imjs-close', function() {
return self.closeTab.call(self, $(this));
});
@@ -1167,13 +1190,16 @@ $.extend(AjaxIM.prototype, {
if(chatbox) {
if((input = chatbox.find('.imjs-input')).length &&
!input.data('height')) {
if(!($.browser.msie && $.browser.opera)) input.height(0);
input.height(0);
if(input[0].scrollHeight > input.height() ||
input[0].scrollHeight < input.height()) {
input.height(input[0].scrollHeight);
}
// store the height for resizing later
if (!input.height()) {
input.height(16);
}
input.data('height', input.height());
}
@@ -1281,8 +1307,8 @@ $.extend(AjaxIM.prototype, {
var tab_pos = tab.position();
if(tab_pos.top >= $('#imjs-bar').height() ||
tab_pos.left < 0 ||
tab_pos.right > $(document).width()) {
tab_pos.left < 0 ||
tab_pos.right > $(document).width()) {
$('.imjs-scroll').css('display', '');
tab.css('display', 'none');
needScrollers = true;
@@ -1311,20 +1337,177 @@ $.extend(AjaxIM.prototype, {
.nextAll('#imjs-bar li.imjs-tab:hidden')
.not('.imjs-default')
.filter(function() {
return $(this).data('state') != 'closed'
return $(this).data('state') != 'closed';
}).length;
var hiddenLeft = $('#imjs-bar li.imjs-tab:visible').eq(0)
.prevAll('#imjs-bar li.imjs-tab:hidden')
.not('.imjs-default')
.filter(function() {
return $(this).data('state') != 'closed'
return $(this).data('state') != 'closed';
}).length;
$('#imjs-scroll-left').html(hiddenLeft);
$('#imjs-scroll-right').html(hiddenRight);
},
unconfirmedEvents: {},
eventId: 1,
createEvent: function() {
var event = {};
event.id = this.eventId++;;
this.unconfirmedEvents[event.id] = evt;
},
sendEvent: function(event, successFunc, failureFunc) {
event.sessionid = store.get('sessionid');
event.id = this.eventId++;
var evt = $.extend({}, event);
evt['_status'] = {
successFunc: successFunc,
failureFunc: failureFunc
};
this.unconfirmedEvents[event.id] = evt;
if (this.socket) {
this.socket.emit('server', event);
} else {
var self = this;
var url = null;
switch (event.type) {
case 'message':
url = this.actions.send;
break;
case 'status':
url = this.actions.status;
break;
case 'signoff':
url = this.actions.signoff;
break;
default:
break;
}
self.request(url, 'POST', event,
function(result) {
if (result) {
for (var e=0; e < result.length; ++e) {
self.dispatchEvent(events[e]);
}
}
},
function(error) {
if (self.unconfirmedEvents[event.id]) {
event = self.unconfirmedEvents[event.id];
event['_status']['sent'] = false;
self.dispatchEvent(event);
}
}
);
}
},
dispatchEvent: function(event) {
if (event.id && this.unconfirmedEvents[event.id]) {
event['_status'] = $.extend({}, this.unconfirmedEvents[event.id]['_status'], event['_status']);
delete this.unconfirmedEvents[event.id];
if (event['_status']['sent']) {
event['_status']['successFunc'](event);
} else {
event['_status']['failureFunc'](event);
}
} else {
$(this).trigger(event.type, event);
}
},
// === {{{AjaxIM.}}}**{{{request(url, data, successFunc, failureFunc)}}}** ===
//
// Wrapper around {{{$.jsonp}}}, the JSON-P library for jQuery, and {{{$.ajax}}},
// jQuery's ajax library. Allows either function to be called, automatically,
// depending on the request's URL array (see {{{AjaxIM.actions}}}).
//
// ==== Parameters ====
// {{{url}}} is the URL of the request.
// {{{data}}} are any arguments that go along with the request.
// {{{success}}} is a callback function called when a request has completed
// without issue.
// {{{_ignore_}}} is simply to provide compatability with {{{$.post}}}.
// {{{failure}}} is a callback function called when a request hasn't not
// completed successfully.
request: function(url, type, data, successFunc, failureFunc, noopurl) {
var self = this;
var errorTypes = ['timeout', 'error', 'notmodified', 'parseerror'];
if(typeof failureFunc != 'function')
failureFunc = function(){};
var jsonp = (url.substring(0, 1) !== '/');
var success = false;
$.ajax({
url: url,
data: data,
dataType: jsonp? 'jsonp': 'json',
type: type,
cache: false,
timeout: 299000
}).done(function(data) {
success = true;
_dbg(JSON.stringify(data));
successFunc(data);
}).fail(function(jqXHR, textStatus) {
_dbg(textStatus);
failureFunc(textStatus);
});
if (jsonp) {
setTimeout(function() {
var failfn = function() {
if (!success) {
var textStatus = 'error';
_dbg(textStatus);
failureFunc(textStatus);
}
};
var noopfn = function() {
var noopdone = false;
var event = {type: 'noop', from: store.get('user'), sessionid: store.get('sessionid')};
$.ajax({
url: self.actions.noop,
data: event,
dataType: 'jsonp',
type: type,
cache: false,
timeout: 299000
}).done(function(data) {
noopdone = true;
if (!success) {
setTimeout(noopfn, 3000);
}
}).fail(function(jqXHR, textStatus) {
// since JSONP, never called
});
setTimeout(function() {
if (!noopdone) {
failfn();
}
}, 3000);
};
noopfn();
}, 3000);
}
// This prevents Firefox from spinning indefinitely
// while it waits for a response.
/*
if(url == 'jsonp' && $.browser.mozilla) {
$.jsonp({
'url': 'about:',
timeout: 0
});
}
*/
}
})
});
// == Static functions and variables ==
//
@@ -1351,64 +1534,6 @@ AjaxIM.init = function(options, actions) {
AjaxIM.client = new AjaxIM(options, actions);
return AjaxIM.client;
}
// === {{{AjaxIM.}}}**{{{request(url, data, successFunc, failureFunc)}}}** ===
//
// Wrapper around {{{$.jsonp}}}, the JSON-P library for jQuery, and {{{$.ajax}}},
// jQuery's ajax library. Allows either function to be called, automatically,
// depending on the request's URL array (see {{{AjaxIM.actions}}}).
//
// ==== Parameters ====
// {{{url}}} is the URL of the request.
// {{{data}}} are any arguments that go along with the request.
// {{{success}}} is a callback function called when a request has completed
// without issue.
// {{{_ignore_}}} is simply to provide compatability with {{{$.post}}}.
// {{{failure}}} is a callback function called when a request hasn't not
// completed successfully.
AjaxIM.post = function(url, data, successFunc, failureFunc) {
AjaxIM.request(url, 'POST', data, successFunc, failureFunc);
};
AjaxIM.get = function(url, data, successFunc, failureFunc) {
AjaxIM.request(url, 'GET', data, successFunc, failureFunc);
};
AjaxIM.request = function(url, type, data, successFunc, failureFunc) {
var errorTypes = ['timeout', 'error', 'notmodified', 'parseerror'];
if(typeof failureFunc != 'function')
failureFunc = function(){};
$.ajax({
url: url,
data: data,
dataType: 'json',
type: type,
cache: false,
timeout: 299000,
success: function(json, textStatus, xhr) {
if('status' in xhr && xhr.status == '0') return;
_dbg(json);
successFunc(json);
},
complete: function(xhr, textStatus) {
if(~errorTypes.indexOf(textStatus) || xhr.status == '0')
failureFunc(textStatus);
}
});
// This prevents Firefox from spinning indefinitely
// while it waits for a response.
/*
if(url == 'jsonp' && $.browser.mozilla) {
$.jsonp({
'url': 'about:',
timeout: 0
});
}
*/
};
// === {{{AjaxIM.}}}**{{{incoming(data)}}}** ===
@@ -1419,13 +1544,27 @@ AjaxIM.request = function(url, type, data, successFunc, failureFunc) {
// //Note:// There are two {{{AjaxIM.incoming()}}} functions. This one is a
// static function called outside of the initialized AjaxIM object; the other
// is only called within the initalized AjaxIM object.
AjaxIM.incoming = function(data) {
AjaxIM.incoming = function(event) {
if(!AjaxIM.client)
return false;
if(data.length)
AjaxIM.client._parseMessages(data);
}
if(event.length)
$(AjaxIM.client).trigger(event.type, event);
};
AjaxIM.uid = function(n){
var chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', nn='';
for(var c=0; c < n; c++){
nn += chars.substr(0|Math.random() * chars.length, 1);
}
return nn;
};
AjaxIM.onObj = function(obj, func) {
return function(evt, event) {
$.proxy(func, obj)(event);
};
};
// === {{{AjaxIM.}}}**{{{l10n}}}** ===
//
@@ -1457,7 +1596,7 @@ AjaxIM.l10n = {
notConnected: 'You are currently not connected or the server is not available. ' +
'Please ensure that you are signed in and try again.',
notConnectedTip: 'You are currently not connected.',
defaultAway: 'I\'m away.'
};
+1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
-22
Ver Arquivo
@@ -1,22 +0,0 @@
/*!
* Ajax IM
* Ajax Instant Messeneger
* http://ajaxim.com/
*
* Copyright 2010, Joshua Gross
* Licensed under the MIT license.
* [License URL]
*
* Includes:
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* v2.1, Copyright 2002, Paul Johnston
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info
*
* Date Format 1.2.3
* http://blog.stevenlevithan.com/archives/date-time-format
* Copyright 2009 Steven Levithan
* MIT license
*/
(function($) {
+10308
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
-6078
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-152
Ver Arquivo
@@ -1,152 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.1
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Mon Jan 25 19:43:33 2010 -0500
*/
(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
-2
Ver Arquivo
@@ -1,2 +0,0 @@
})(jQuery || $);
+9 -1
Ver Arquivo
@@ -3,6 +3,7 @@ var store = (function(){
var api = {},
win = window,
doc = win.document,
sessionStorageName = 'sessionStorage',
localStorageName = 'localStorage',
globalStorageName = 'globalStorage',
storage
@@ -20,7 +21,14 @@ var store = (function(){
return JSON.parse(value)
}
if (localStorageName in win && win[localStorageName]) {
if (sessionStorageName in win && win[sessionStorageName]) {
storage = win[sessionStorageName]
api.set = function(key, val) { storage[key] = serialize(val) }
api.get = function(key) { return deserialize(storage[key]) }
api.remove = function(key) { delete storage[key] }
api.clear = function() { storage.clear() }
} else if (localStorageName in win && win[localStorageName]) {
storage = win[localStorageName]
api.set = function(key, val) { storage[key] = serialize(val) }
api.get = function(key) { return deserialize(storage[key]) }
+1
Ver Arquivo
@@ -269,6 +269,7 @@ ul#imjs-bar {
font-size: 9px;
font-weight: 700;
background-repeat: no-repeat;
display: none;
}
ul#imjs-bar li#imjs-scroll-left {
+17
Ver Arquivo
@@ -0,0 +1,17 @@
{
"name": "AjaxIM",
"description": "instant messaging framework",
"author": "ajaximrpg <ajaximrpg@svexpertise.com>",
"version": "4.0.0",
"dependencies": {
"express": ">= 4.0.0",
"connect": ">= 2.14.0",
"method-override": ">= 1.0.0",
"body-parser": ">= 1.0.0",
"express-error-handler": ">= 0.5.0",
"morgan": ">= 1.0.0",
"cookie": ">= 0.1.0",
"jade": ">= 1.3.0",
"socket.io": ">= 1.0.6"
}
}
+37 -83
Ver Arquivo
@@ -1,5 +1,5 @@
#!/usr/bin/env node
var sys = require('sys'),
var sys = require('util'),
express = require('express'),
packages = require('./libs/packages'),
o_ = require('./libs/utils');
@@ -7,107 +7,59 @@ var sys = require('sys'),
o_.merge(global, require('./settings'));
try { o_.merge(global, require('./settings.local')); } catch(e) {}
try {
var daemon = require('./libs/daemon/daemon'),
start = function() {
daemon.init({
lock: PID_FILE,
stdin: '/dev/null',
stdout: LOG_FILE,
stderr: LOG_FILE,
umask: 0,
chroot: null,
chdir: '.'
});
},
stop = function() {
process.kill(parseInt(require('fs').readFileSync(PID_FILE)));
};
var app = express();
//app.set('env', 'development');
app.use( require('request-param')() )
switch(process.argv[2]) {
case 'stop':
stop();
process.exit(0);
break;
case 'start':
if(process.argv[3])
process.env.EXPRESS_ENV = process.argv[3];
start();
break;
case 'restart':
stop();
start();
process.exit(0);
break;
case 'help':
sys.puts('Usage: node app.js [start|stop|restart]');
process.exit(0);
break;
}
} catch(e) {
sys.puts('Daemon library not found! Please compile ' +
'./libs/daemon/daemon.node if you would like to use it.');
}
var app = express.createServer(
express.methodOverride(),
express.cookieDecoder(),
express.bodyDecoder(),
require('./middleware/im')({
maxAge: 15 * 60 * 1000,
reapInterval: 60 * 1000,
authentication: require('./libs/authentication/' + AUTH_LIBRARY)
})
);
app.use(require('method-override')());
app.use(require('cookie-parser')());;
//app.use(require('body-parser')());;
app.use(require('body-parser').urlencoded({extended: true}));;
app.use(require('body-parser').json());;
app.use(require('./middleware/im')({
maxAge: 15 * 60 * 1000,
reapInterval: 60 * 1000,
authentication: require('./libs/authentication/' + AUTH_LIBRARY)
}));
app.set('root', __dirname);
app.configure('development', function() {
app.set('view engine', 'jade');
if ('development' == app.get('env')) {
app.set('views', __dirname + '/dev/views');
app.stack.unshift({
route: '/dev',
handle: function(req, res, next) {
req.dev = true;
next();
}
});
app.use(express.logger());
app.use('/dev', express.router(require('./dev/app')));
app.use(express.staticProvider(
app.set('view engine', 'jade');
app.use(require("morgan")("dev"));
require('./dev/app')('/dev', app);
app.use(express.static(
require('path').join(__dirname, '../client')));
app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});
app.use(require('express-error-handler')({dumpExceptions: true, showStack: true}));
}
app.listen(APP_PORT, APP_HOST);
// Listener endpoint; handled in middleware
app.get('/listen', function(){});
app.get('/app/listen', function(){});
app.post('/message', function(req, res) {
res.find(req.body['to'], function(user) {
app.use('/app/message', function(req, res) {
res.find(req.param('to'), function(user) {
if(!user)
return res.send(new packages.Error('not online'));
res.message(user, new packages.Message(
req.session.data('username'),
req.body.body
req.param('body')
));
});
});
app.post('/message/typing', function(req, res) {
if(~packages.TYPING_STATES.indexOf('typing' + req.body['state'])) {
res.find(req.body['to'], function(user) {
app.use('/app/message/typing', function(req, res) {
if(~packages.TYPING_STATES.indexOf('typing' + req.param('state'))) {
res.find(req.param('to'), function(user) {
if(user) {
res.message(user, new packages.Status(
req.session.data('username'),
'typing' + req.body.state
'typing' + req.param('state')
));
}
@@ -120,16 +72,18 @@ app.post('/message/typing', function(req, res) {
}
});
app.post('/status', function(req, res) {
if(~packages.STATUSES.indexOf(req.body['status'])) {
res.status(req.body.status, req.body.message);
app.use('/app/status', function(req, res) {
if(~packages.STATUSES.indexOf(req.param('status'))) {
res.status(req.param('status'), req.param('message'));
res.send(new packages.Success('status updated'));
} else {
res.send(new packages.Error('invalid status'));
}
});
app.post('/signoff', function(req, res) {
app.use('/app/signoff', function(req, res) {
res.signOff();
res.send(new packages.Success('goodbye'));
});
console.log('Ajax IM server started...');
+2 -12
Ver Arquivo
@@ -1,16 +1,6 @@
var utils = require('connect/utils');
module.exports = function(app) {
app.get('/', function(req, res) {
module.exports = function(route, app) {
app.get(route+'/', function(req, res) {
res.render('chat', {
locals: {}
});
});
app.get('/cookie', function(req, res) {
res.send('cookie set', {
'Set-Cookie': utils.serializeCookie('sessionid', utils.uid(),
{path: '/'})
});
});
};
+11 -11
Ver Arquivo
@@ -1,13 +1,13 @@
!!! 5
html
doctype html
html(lang="en")
head
title Ajax IM
script(src: '/js/jquery-1.4.1.js', type: 'text/javascript')
script(src: '/js/md5.js', type: 'text/javascript')
script(src: '/js/store.js', type: 'text/javascript')
script(src: '/js/cookies.js', type: 'text/javascript')
script(src: '/js/dateformat.js', type: 'text/javascript')
script(src: '/js/im.js', type: 'text/javascript')
script(type: 'text/javascript')
| $(function(){var im = AjaxIM.init({theme: "/themes/default"});});
body Hello.
script(src='/js/jquery-1.11.1.js', type='text/javascript')
script(src='/js/md5.js', type='text/javascript')
script(src='/js/store.js', type='text/javascript')
script(src='/js/dateformat.js', type='text/javascript')
script(src='/js/im.js', type='text/javascript')
script(type='text/javascript').
$(function(){var im = AjaxIM.init({theme: "/themes/default"});});
body.
Hello.
+50 -21
Ver Arquivo
@@ -1,24 +1,53 @@
// Cookie that stores the session ID
// Will be set as request.sessionID in `authenticate` and `friends` functions
exports.cookie = 'sessionid';
var o_ = require('../../utils');
var User = require('../../../middleware/im/user');
exports.authenticate = function(request, callback) {
// Verify user based on request.
// On failure, redirect user to auth form
exports.authenticate = function(store, event, callback) {
// remove authentication from event
var sessionid = event.sessionid;
delete event.sessionid;
callback({
username: 'username' + Math.floor(Math.random() * 1000),
displayname: 'John Smith',
otherinfo: 'any other relevant key/values'
});
// find the user
var user = event.from? store.sessions[event.from]: undefined;
// create, validate or reject user
if (user) {
// found the user so check authentication
if (sessionid && (sessionid === user.data('sessionid'))) {
event.from = user.data('username');
callback(event, user);
} else {
event._status = {sent: false, e: 'not authenticated'};
callback(event);
}
} else if (event.type == 'hello') {
store.find('sessionid', sessionid, function(user) {
if (user) {
// relogin as same user
event.from = user.data('username');
callback(event, user);
} else {
// if no username requested, assign user name
if (!event.from) {
event.from = 'username' + (++store.uid);
}
// everybody is your friend!
var friends = o_.values(store.sessions).map(function(friend) {
return friend.data('username');
});
// you're even friends with yourself!
friends.push(event.from);
// create new user
user = new User(store, {
username: event.from,
sessionid: sessionid,
displayname: 'John Smith',
otherinfo: 'any other relevant key/values'
}, friends);
callback(event, user);
}
});
} else {
event._status = {sent: false, e: 'not authenticated'};
callback(event);
}
};
exports.friends = function(request, data, callback) {
// Create a friends list based on given user data
callback([
'username1',
'username2',
'username3'
]);
};
-301
Ver Arquivo
@@ -1,301 +0,0 @@
/*
* Daemon.node
*** A node.JS addon that allows creating Unix/Linux Daemons in pure Javascript.
*** Copyright 2010 (c) <arthur@norgic.com>
* Under MIT License. See LICENSE file.
*/
#include <node/node.h>
#include <v8.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define PID_MAXLEN 10
using namespace v8;
// Go through special routines to become a daemon.
// if successful, returns daemon's PID
Handle<Value> Start(const Arguments& args) {
pid_t pid;
pid = fork();
if(pid > 0) exit(0);
if(pid < 0) exit(1);
// Can be changed after with process.umaks
umask(0);
setsid();
// Can be changed with process.chdir
chdir("/");
return Integer::New(getpid());
}
// Close Standard IN/OUT/ERR Streams
Handle<Value> CloseIO(const Arguments& args) {
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
// File-lock to make sure that only one instance of daemon is running.. also for storing PID
/* lock ( filename )
*** filename: a path to a lock-file.
*** Note: if filename doesn't exist, it will be created when function is called.
*/
Handle<Value> LockD(const Arguments& args) {
if(!args[0]->IsString())
return Boolean::New(false);
String::Utf8Value data(args[0]->ToString());
char pid_str[PID_MAXLEN+1];
int lfp = open(*data, O_RDWR | O_CREAT, 0640);
if(lfp < 0) exit(1);
if(lockf(lfp, F_TLOCK, 0) < 0) exit(0);
int len = snprintf(pid_str, PID_MAXLEN, "%d", getpid());
write(lfp, pid_str, len);
return Boolean::New(true);
}
class StreamPtr : public node::ObjectWrap
{
public:
explicit StreamPtr(FILE** fpp, const char *pmode);
~StreamPtr();
static Handle<Value> Open(const Arguments& args);
static Handle<Value> Close(const Arguments& args);
static Handle<Value> Redirect(const Arguments& args);
static void Initialize(Handle<Object> target);
static Handle<Value> New(const Arguments& args);
FILE** stream;
const char *mode;
private:
static Persistent<FunctionTemplate> constructor_template;
};
Persistent<FunctionTemplate> StreamPtr::constructor_template;
StreamPtr::StreamPtr(FILE** fpp, const char *pmode)
: stream(fpp)
, mode( pmode )
{
}
StreamPtr::~StreamPtr()
{
fclose(*stream);
}
Handle<Value> StreamPtr::Open(const Arguments& args)
{
HandleScope scope;
StreamPtr *fp = ObjectWrap::Unwrap<StreamPtr>(args.This());
char *new_file = *String::Utf8Value(args[0]->ToString());
*fp->stream = fopen(new_file, fp->mode);
// return if the creation of the new FILE* was successful;
return Boolean::New( *fp->stream != NULL );
}
Handle<Value> StreamPtr::Close(const Arguments& args)
{
HandleScope handle_scope;
StreamPtr *fp = ObjectWrap::Unwrap<StreamPtr>(args.This());
assert( fp && "object had no InternalField" );
int ret = fclose(*fp->stream);
return Boolean::New(ret == 0);
}
Handle<Value> StreamPtr::Redirect(const Arguments& args)
{
HandleScope scope;
if (Close(args)->ToBoolean()->Value())
{
return Open(args);
} else {
return Boolean::New(false);
}
}
Persistent<Object> stdin_obj;
Persistent<Object> stdout_obj;
Persistent<Object> stderr_obj;
void StreamPtr::Initialize(Handle<Object> target)
{
HandleScope scope;
Local<FunctionTemplate> file_pointer = FunctionTemplate::New(StreamPtr::New);
constructor_template = Persistent<FunctionTemplate>::New(file_pointer);
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "open", StreamPtr::Open);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", StreamPtr::Close);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "sendTo", StreamPtr::Redirect);
// Although we could expose the prototype directly, I see no reason to, as it's not
// very useful for anything other than the intended purpose.
//target->Set(String::NewSymbol("StreamPtr"), constructor_template->GetFunction());
stdin_obj = Persistent<Object>::New( constructor_template->GetFunction()->NewInstance() );
Handle<External> stdin_ptr = External::New( new StreamPtr( &stdin, "r" ) );
stdin_obj->SetInternalField(0, stdin_ptr);
target->Set(String::NewSymbol("stdin"), stdin_obj);
stdout_obj = Persistent<Object>::New( constructor_template->GetFunction()->NewInstance() );
Handle<External> stdout_ptr = External::New( new StreamPtr( &stdout, "w" ) );
stdout_obj->SetInternalField(0, stdout_ptr);
target->Set(String::NewSymbol("stdout"), stdout_obj);
stderr_obj = Persistent<Object>::New( constructor_template->GetFunction()->NewInstance() );
Handle<External> stderr_ptr = External::New( new StreamPtr( &stderr, "w" ) );
stderr_obj->SetInternalField(0, stderr_ptr);
target->Set(String::NewSymbol("stderr"), stderr_obj);
}
Handle<Value> StreamPtr::New(const Arguments& args)
{
HandleScope scope;
return scope.Close(args.This());
}
/* The default object:
* {
* "fork": true,
* "lock": "daemon.pid"
* "stdout": null,
* "stderr": null,
* "stdin": null,
* "umask": 0,
* "chroot": null,
* "chdir": ".",
* }
*/
#define SET_DEFAULT(obj, name, value) \
do { \
Local<String> str_##name = String::New(#name); \
if( !obj->Has( str_##name ) ) \
obj->Set( str_##name, (value) ); \
} while (0)
static inline void setDefaults(Handle<Object> &arg)
{
HandleScope scope;
SET_DEFAULT( arg, fork, Boolean::New(true) );
SET_DEFAULT( arg, lock, String::New("daemon.pid") );
SET_DEFAULT( arg, stdin, Null() );
SET_DEFAULT( arg, stdout, Null() );
SET_DEFAULT( arg, stderr, Null() );
SET_DEFAULT( arg, umask, Integer::New(0) );
SET_DEFAULT( arg, chroot, Null() );
SET_DEFAULT( arg, chdir, String::New(".") );
//SET_DEFAULT( arg, close_fds, Boolean::New(false) );
//SET_DEFAULT( arg, catch_signals, Boolean::New(false) );
}
#undef SET_DEFAULT
Handle<Value> Init(const Arguments& args)
{
HandleScope scope;
Local<Object> arg = args[0]->ToObject();
setDefaults( arg );
pid_t pid = 0;
if( arg->Get( String::New("fork") )->IsTrue() )
{
pid = fork();
if(pid > 0) exit(0);
if(pid < 0) exit(1);
}
if( !arg->Get( String::New("lock") )->IsNull() )
{
Local<String> file = arg->Get( String::New( "lock" ) )->ToString();
String::Utf8Value data(file);
char pid_str[PID_MAXLEN+1];
int lfp = open(*data, O_RDWR | O_CREAT, 0640);
if(lfp < 0) exit(1);
if(lockf(lfp, F_TLOCK, 0) < 0) exit(0);
int len = snprintf(pid_str, PID_MAXLEN, "%d", getpid());
write(lfp, pid_str, len);
}
if( arg->Get( String::New("stdin") )->IsNull() )
{
Local<Function> close = Function::Cast( *stdin_obj->Get( String::New("close") ) );
close->Call( stdin_obj, 0, NULL );
} else {
Local<Function> send_to = Function::Cast( *stdin_obj->Get( String::New("sendTo") ) );
Local<Value> string_arg = arg->Get( String::New("stdin") );
send_to->Call( stdin_obj, 1, &string_arg );
}
if( arg->Get( String::New("stdout") )->IsNull() )
{
Local<Function> close = Function::Cast( *stdout_obj->Get( String::New("close") ) );
close->Call( stdout_obj, 0, NULL );
} else {
Local<Function> send_to = Function::Cast( *stdout_obj->Get( String::New("sendTo") ) );
Local<Value> string_arg = arg->Get( String::New("stdout") );
send_to->Call( stdout_obj, 1, &string_arg );
}
if( arg->Get( String::New("stderr") )->IsNull() )
{
Local<Function> close = Function::Cast( *stderr_obj->Get( String::New("close") ) );
close->Call( stderr_obj, 0, NULL );
} else {
Local<Function> send_to = Function::Cast( *stderr_obj->Get( String::New("sendTo") ) );
Local<Value> string_arg = arg->Get( String::New("stderr") );
send_to->Call( stderr_obj, 1, &string_arg );
}
Local<Integer> umask_arg = arg->Get( String::New("umask") )->ToInteger();
umask( umask_arg->Value() );
if( !arg->Get( String::New("chroot") )->IsNull() )
{
char* dir = *String::AsciiValue( arg->Get( String::New("chroot") ) );
chroot( dir );
}
if( !arg->Get( String::New("chdir") )->IsNull() )
{
char* dir = *String::AsciiValue( arg->Get( String::New("chdir") ) );
chdir( dir );
}
return Integer::New(pid);
}
extern "C" void init(Handle<Object> target) {
HandleScope scope;
target->Set(String::New("start"), FunctionTemplate::New(Start)->GetFunction());
target->Set(String::New("lock"), FunctionTemplate::New(LockD)->GetFunction());
target->Set(String::New("closeIO"), FunctionTemplate::New(CloseIO)->GetFunction());
target->Set(String::New("init"), FunctionTemplate::New(Init)->GetFunction());
StreamPtr::Initialize(target);
}
-15
Ver Arquivo
@@ -1,15 +0,0 @@
srcdir = "."
blddir = "build"
VERSION = "0.0.1"
def set_options(opt):
opt.tool_options("compiler_cxx")
def configure(conf):
conf.check_tool("compiler_cxx")
conf.check_tool("node_addon")
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
obj.target = "daemon"
obj.source = "daemon.cc"
-86
Ver Arquivo
@@ -1,88 +1,2 @@
var sys = require('sys');
var Package = function() {};
Package.prototype._sanitize = function(content) {
// strip HTML
return content.replace(/<(.|\n)*?>/g, '');
};
var Error = exports.Error = function(error) {
this.error = error;
};
sys.inherits(Error, Package);
Error.prototype.toJSON = function() {
return {
type: 'error',
error: this.error
};
};
var Success = exports.Success = function(success) {
this.success = success;
};
sys.inherits(Success, Package);
Success.prototype.toJSON = function() {
return {
type: 'success',
success: this.success
};
};
var Message = exports.Message = function(from, body) {
this.from = from;
this.body = body;
};
sys.inherits(Message, Package);
Message.prototype.toJSON = function() {
return {
type: 'message',
user: this.from,
body: this._sanitize(this.body)
};
};
var Notice = exports.Notice = function(username, info) {
this.username = username;
this.info = info;
};
sys.inherits(Notice, Package);
Notice.prototype.toJSON = function() {
return {
type: 'notice',
user: this.username,
info: this.info
};
};
exports.TYPING_STATES = ['typing+', 'typing~', 'typing-'];
exports.STATUSES = ['available', 'away', 'idle'];
var Status = exports.Status = function(username, status, message) {
var statuses = exports.STATUSES + exports.TYPING_STATES;
this.username = username;
this.status = -~statuses.indexOf(status) ? status : statuses[0];
this.message = message;
};
sys.inherits(Status, Package);
Status.prototype.toJSON = function() {
return {
type: 'status',
user: this.username,
status: this.status,
message: this._sanitize(this.message || '')
};
};
var Offline = exports.Offline = function(username) {
this.username = username;
};
sys.inherits(Offline, Package);
Offline.prototype.toJSON = function() {
// A special type of status
return {
type: 'status',
user: this.username,
status: 'offline',
message: ''
};
};
+15
Ver Arquivo
@@ -9,6 +9,21 @@ module.exports = o_ = {
a[keys[i]] = b[keys[i]];
return a;
},
extend: function() {
var o = {};
for (var a=0; a < arguments.length; ++a) {
this.merge(o, arguments[a]);
}
return o;
},
deletekey: function(o, key) {
if (o.hasOwnProperty(key)) {
delete o[key];
}
return o;
},
values: function(obj) {
if(typeof obj == 'array')
+64 -43
Ver Arquivo
@@ -1,67 +1,88 @@
var url = require('url'),
Hub = require('./im/hub');
Hub = require('./im/hub'),
packages = require('../libs/packages'),
o_ = require('../libs/utils');
module.exports = function setupHub(options) {
options = options || {};
store = new Hub(options);
var store = new Hub(options);
return function session(req, res, next) {
return {store: store, session: function session(req, res, next) {
req.sessionStore = store;
req.sessionID = req.cookies[options.authentication.cookie];
if(!req.cookies) {
next(new Error('session requires cookieDecoder to work properly'));
return;
}
if(req.dev) {
next();
return;
}
// create the event object
req.event = o_.extend({}, req.query, req.body, req.params);
o_.deletekey(req.event, 'callback');
o_.deletekey(req.event, '_');
if(req.sessionID) {
store.get(req, function(err, sess) {
if(err) {
next(err);
req.event.reply = function(status) {
if (status) {
this._status = status;
}
delete this.reply;
res.jsonp(this);
};
var unauthenticated = function() {
req.event.reply({sent: false, e: 'unauthenticated'});
};
// set event handlers to unauthenticated by default
res.message = res.typing = res.status = res.signOff = unauthenticated;
if(url.parse(req.url).pathname.substring(0, 5) === '/app/') {
store.get(req.event, function(event, user) {
if(!user) {
next();
return;
}
if(!sess) {
next(new Error(JSON.stringify({
type: 'error',
error: 'not authenticated'})));
return;
}
sess.touch();
if(url.parse(req.url).pathname === '/listen') {
user.touch();
if(url.parse(req.url).pathname === '/app/listen') {
req.connection.setTimeout(5 * 60 * 1000);
sess.listener(res);
store.set(req.sessionID, sess);
user.listener(res);
store.set(user.data('username'), user);
if(msg = sess.message_queue.shift())
sess._send.apply(sess, msg);
if(msg = user.message_queue.shift()) {
user._send.apply(user, msg);
}
} else {
sess.connection = res;
req.event.from = user.data('username');
}
req.session = sess;
res.find = store.find.bind(store);
res.message = function(to, package) {
store.message(req.session, to, package);
res.message = function() {
user.message(req.event);
};
res.status = function(value, message) {
req.session.status(value, message);
res.typing = function() {
if(~packages.TYPING_STATES.indexOf('typing' + req.event.state)) {
store.find('username', req.event.to, function(to) {
if(to) {
req.event.status = 'typing' + req.event.state;
user.message(req.event);
} else {
// Typing updates do not receive confirmations,
// as they are not important enough.
req.event.reply({sent: true});
}
});
} else {
req.event.reply({sent: false, e: 'invalid state'});
}
};
res.status = function() {
user.status(req.event);
};
res.signOff = function() {
user.signOff(req.event);
};
res.signOff = function() { store.signOff(req.sessionID); };
next();
if(url.parse(req.url).pathname !== '/app/listen') {
next();
}
});
} else {
next(new Error(JSON.stringify({
type: 'error',
error: 'not authenticated'})));
next();
}
};
}};
};
+63 -73
Ver Arquivo
@@ -5,6 +5,7 @@ var events = require('events'),
User = require('./user');
var Hub = module.exports = function Hub(options) {
this.uid = 0;
this.events = new events.EventEmitter();
this.auth = options.authentication;
this.sessions = {};
@@ -14,19 +15,19 @@ var Hub = module.exports = function Hub(options) {
if(this.reapInterval !== -1) {
setInterval(function(self) {
self.reap(self.maxAge);
self.reapCheck(self.maxAge);
}, this.reapInterval, this);
}
this.events.addListener('update', o_.bind(function(package) {
var _package = package.toJSON();
if(package.type == 'status' && package.status == 'offline') {
this.events.addListener('update', o_.bind(function(event) {
if(event.type == 'status' && event.status == 'offline') {
var sids = Object.keys(this.sessions), sid, sess;
for(sid in this.sessions) {
sess = this.sessions[sid];
if(sess.data('username') == package.username) {
if(sess.listeners.length)
sess.send(200, {type: 'goodbye'});
if (sess.data('username') == event.from) {
if (sess.listeners.length) {
sess.send({type: 'goodbye'});
}
delete this.sessions[sid];
break;
}
@@ -35,60 +36,56 @@ var Hub = module.exports = function Hub(options) {
}, this));
};
Hub.prototype.destroy = function(sid, fn) {
this.set(sid, null, fn);
};
Hub.prototype.reap = function(ms) {
var threshold = +new Date - ms,
sids = Object.keys(this.sessions);
Hub.prototype.reapCheck = function(ms) {
var threshold = +new Date - ms;
var sids = Object.keys(this.sessions);
for(var i = 0, len = sids.length; i < len; ++i) {
var sid = sids[i], sess = this.sessions[sid];
if(sess.lastAccess < threshold) {
this.events.emit('update', new packages.Offline(sess.data('username')));
var sid = sids[i];
if(this.sessions[sid].lastAccess < threshold) {
this.reap(sid);
}
}
};
Hub.prototype.get = function(req, fn) {
if(this.sessions[req.sessionID]) {
fn(null, this.sessions[req.sessionID]);
} else {
this.auth.authenticate(req, o_.bind(function(data) {
if(data) {
var session = new User(req.sessionID, data);
this.set(req.sessionID, session);
Hub.prototype.reap = function(sid) {
var sess = this.sessions[sid];
console.log('reaping '+sess.data('username'));
var event = {type: 'status', from: sess.data('username'), status: 'offline', message: ''};
this.events.emit('update', event);
delete this.sessions[sid];
sess.close();
};
this.auth.friends(req, data, o_.bind(function(friends) {
var friends_copy = friends.slice();
o_.values(this.sessions).filter(function(friend) {
return ~friends.indexOf(friend.data('username'));
}).forEach(function(friend) {
var username = friend.data('username');
friends_copy[friends_copy.indexOf(username)] =
[username, friend.status()];
}, this);
session._friends(friends_copy);
session.events.addListener('status',
o_.bind(function(value, message) {
this.events.emit(
'update',
new packages.Status(session.data('username'),
value,
message)
);
}, this));
this.events.addListener('update',
o_.bind(session.receivedUpdate, session));
this.set(req.sessionID, session);
fn(null, session);
}, this));
} else {
fn();
Hub.prototype.get = function(event, fn, socket) {
this.auth.authenticate(this, event, o_.bind(function(event, user) {
if (user) {
if (socket) {
user.socketio = socket;
}
}, this));
}
if (this.sessions[user.data('username')]) {
fn(event, user);
return;
}
this.set(user.data('username'), user);
var friends = user.friends;
var friends_copy = friends.slice();
o_.values(this.sessions).filter(function(friend) {
return ~friends.indexOf(friend.data('username'));
}).forEach(function(friend) {
var username = friend.data('username');
friends_copy[friends_copy.indexOf(username)] = [username, friend.status()];
}, this);
user._friends(friends_copy);
user.events.addListener('status', o_.bind(function(value, message) {
var event = {type: 'status', from: user.data('username'), status: value, message: message};
this.events.emit('update', event);
}, this));
this.events.addListener('update', o_.bind(user.receivedUpdate, user));
fn(event, user);
} else {
fn(event);
}
}, this));
};
Hub.prototype.set = function(sid, sess, fn) {
@@ -96,11 +93,11 @@ Hub.prototype.set = function(sid, sess, fn) {
fn && fn();
};
Hub.prototype.find = function(username, fn) {
Hub.prototype.find = function(key, value, fn) {
for(var sid in this.sessions) {
var session = this.sessions[sid],
sess_username = session.data('username');
if(sess_username == username) {
var session = this.sessions[sid];
var user_value = session.data(key);
if (user_value == value) {
fn(session);
return;
}
@@ -108,19 +105,12 @@ Hub.prototype.find = function(username, fn) {
fn(false);
};
Hub.prototype.message = function(from, to, package) {
try {
package.user = from;
to.send(package);
from.respond(new packages.Success('sent'));
} catch(e) {
from.respond(new packages.Error(e.description));
}
};
Hub.prototype.signOff = function(sid) {
if(sid in this.sessions)
this.events.emit('update',
new packages.Offline(
this.sessions[sid].data('username')));
Hub.prototype.dispatch = function(event) {
this.find('username', event.from, function(from) {
if (from) {
from.dispatch(event);
} else {
event.reply({sent: false, e: 'not authenticated'});
}
});
};
+90 -46
Ver Arquivo
@@ -2,32 +2,50 @@ var events = require('events'),
packages = require('../../libs/packages'),
o_ = require('../../libs/utils');
var User = module.exports = function(id, data) {
this.id = id;
var User = module.exports = function(store, data, friends) {
this.store = store;
this.connection = null;
this.listeners = [];
this.message_queue = [];
this.convos = {};
this._data = data;
this.friends = friends;
this.events = new events.EventEmitter();
this.status(packages.STATUSES[0], '');
this._status = packages.STATUSES[0];
this._status_message = '';
setInterval(o_.bind(this._expireConns, this), 500);
this.interval = setInterval(o_.bind(this._expireConns, this), 500);
};
User.prototype.receivedUpdate = function(package) {
if(this.friends.indexOf(package.username))
this.send(package);
User.prototype.close = function() {
clearInterval(this.interval);
var conn,
noop = JSON.stringify({type: 'noop'}),
noop_headers = {
'Content-Type': 'application/json',
'Content-Length': noop.length
};
for(var i = this.listeners.length-1; i >= 0; i--) {
conn = this.listeners[i].connection;
this.listeners[i].writeHead(200, noop_headers);
this.listeners[i].end(noop);
}
};
User.prototype.receivedUpdate = function(event) {
event = o_.extend({}, event);
event.to = this.data('username');
if(this.friends.indexOf(event.from))
this.send(event);
};
User.prototype._friends = function(friends) {
this.friends = friends;
this.send(JSON.stringify({
this.send({
type: 'hello',
username: this.data('username'),
friends: friends
}));
});
};
User.prototype._expireConns = function() {
@@ -52,49 +70,37 @@ User.prototype.listener = function(conn) {
this.listeners.push(conn);
};
User.prototype.respond = function(code, message, callback) {
this._send('connection', code, message, callback);
User.prototype.send = function(event) {
this._send('listener', event);
};
User.prototype.send = function(code, message, callback) {
this._send('listener', code, message, callback);
};
User.prototype._send = function(type, code, message, callback) {
if(!message && typeof code != 'number') {
callback = message;
message = code;
code = 200;
}
if(typeof message != 'string')
message = JSON.stringify(message);
if(type == 'connection' && this.connection) {
this.connection.writeHead(code || 200, {
'Content-Type': 'application/json',
'Content-Length': message.length
});
this.connection.end(message);
User.prototype._send = function(type, event, res) {
if (this.socketio) {
var id = event.id;
if (event.id) {
delete event.id;
}
this.socketio.emit('client', event);
if (id) {
event.id = id;
}
} else if(type == 'connection') {
// end a regular connection with a response
res.jsonp(event);
} else {
// end a long-polling connection with an event
if(!this.listeners.length)
return this.message_queue.push(arguments);
var cx = this.listeners.slice(), conn;
this.listeners = [];
while(conn = cx.shift()) {
conn.writeHead(code || 200, {
'Content-Type': 'application/json',
'Content-Length': message.length
});
conn.end(message);
conn.jsonp(event);
}
if(callback) callback();
}
};
User.prototype.data = function(key, def) {
if(key == 'id') return this.id;
return this._data[key] || this['_' + key] ||
(typeof this[key] != 'function' && this[key]) ||
def || false;
@@ -104,11 +110,49 @@ User.prototype.touch = function() {
this.lastAccess = +new Date;
};
User.prototype.status = function(value, message) {
if(!value)
return this._status;
this._status = value;
this._status_message = message;
this.events.emit('status', value, message);
User.prototype.message = function(event) {
var self = this;
try {
self.store.find('username', event.to, function(to) {
if(to) {
to.send(event);
event.reply({sent: true});
} else {
event.reply({sent: false, e: 'not online'});
}
});
} catch(e) {
event.reply({sent: false, e: e.description});
}
};
User.prototype.status = function(event) {
if (!event) {
return this._status;
}
this._status = event.status;
this._status_message = event.message;
this.events.emit('status', event.status, event.message);
if (event.reply) {
event.reply({sent: true});
}
};
User.prototype.signOff = function(event) {
event.status = 'offline';
this.store.events.emit('update', event);
event.reply({sent: true});
};
User.prototype.dispatch = function(event) {
if (event.type == 'message') {
this.message(event);
} else if (event.type == 'status') {
this.status(event);
} else if (event.type == 'signoff') {
this.signOff(event);
} else {
event.reply({sent: false, e: 'invalid event type'});
}
};
+1 -2
Ver Arquivo
@@ -1,8 +1,7 @@
// == Server Configuration ==
//
// This is the configuration file for the Node.js Ajax IM server. Here, you
// can set which ports will be used for the public and internal servers,
// as well as other settings such as the session cookie name and expiration.
// can set which ports will be used for the public and internal servers.
// === Host and Port ===
//