commit all new-style code so it can be versioned, NB: this is in a

broken state currently.
This commit is contained in:
Damien Churchill 2009-04-21 21:41:18 +00:00
parent e1e45753de
commit 1157fc1eeb
41 changed files with 4060 additions and 2406 deletions

View File

@ -0,0 +1,361 @@
/*
Script: deluge-connections.js
Contains all objects and functions related to the connection manager.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
var hostRenderer = function(value, p, r) {
return value + ':' + r.data['port']
}
Ext.deluge.ConnectionManager = Ext.extend(Ext.Window, {
layout: 'fit',
width: 300,
height: 220,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Connection Manager'),
iconCls: 'x-deluge-connect-window-icon',
initComponent: function() {
Ext.deluge.ConnectionManager.superclass.initComponent.call(this);
this.on({
'hide': this.onHide,
'show': this.onShow
});
Deluge.Events.on('login', this.onLogin, this);
Deluge.Events.on('logout', this.onLogout, this);
this.addButton(_('Close'), this.onClose, this);
this.addButton(_('Connect'), this.onConnect, this);
this.grid = this.add({
xtype: 'grid',
store: new Ext.data.SimpleStore({
fields: [
{name: 'status', mapping: 3},
{name: 'host', mapping: 1},
{name: 'port', mapping: 2},
{name: 'version', mapping: 4}
],
id: 0
}),
columns: [{
header: _('Status'),
width: 65,
sortable: true,
renderer: fplain,
dataIndex: 'status'
}, {
id:'host',
header: _('Host'),
width: 150,
sortable: true,
renderer: hostRenderer,
dataIndex: 'host'
}, {
header: _('Version'),
width: 75,
sortable: true,
renderer: fplain,
dataIndex: 'version'
}],
stripeRows: true,
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
'rowselect': {fn: this.onSelect, scope: this}
}
}),
autoExpandColumn: 'host',
deferredRender:false,
autoScroll:true,
margins: '0 0 0 0',
bbar: new Ext.Toolbar({
items: [
{
id: 'add',
cls: 'x-btn-text-icon',
text: _('Add'),
icon: '/icons/add.png',
handler: this.onAdd,
scope: this
}, {
id: 'remove',
cls: 'x-btn-text-icon',
text: _('Remove'),
icon: '/icons/remove.png',
handler: this.onRemove,
scope: this
}, '->', {
id: 'stop',
cls: 'x-btn-text-icon',
text: _('Stop Daemon'),
icon: '/icons/error.png',
handler: this.onStop,
scope: this
}
]
})
});
},
disconnect: function() {
Deluge.Events.fire('disconnect');
},
runCheck: function(callback, scope) {
callback = callback || this.onGetHosts;
scope = scope || this;
Deluge.Client.web.get_hosts({
success: callback,
scope: scope
});
},
onAdd: function(button, e) {
//Deluge.Connections.Add.show();
},
onAddHost: function() {
var form = Deluge.Connections.Add.items.first();
var host = form.items.get('host').getValue();
var port = form.items.get('port').getValue();
var username = form.items.get('username').getValue();
var password = form.items.get('_password').getValue();
Deluge.Client.web.add_host(host, port, username, password, {
onSuccess: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: "Unable to add host: " + result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
this.runCheck();
}
Deluge.Connections.Add.hide();
}
});
},
onAddWindowHide: function() {
// Tidy up the form to ensure all the values are default.
var form = Deluge.Connections.Add.items.first();
form.items.get('host').reset();
form.items.get('port').reset();
form.items.get('username').reset();
form.items.get('_password').reset();
},
onClose: function(e) {
if (this.running) window.clearInterval(this.running);
this.hide();
},
onConnect: function(e) {
var selected = this.grid.getSelectionModel().getSelected();
if (!selected) return;
if (selected.get('status') == _('Connected')) {
Deluge.Client.web.disconnect({
success: function(result) {
this.runCheck();
Deluge.Events.fire('disconnect');
},
scope: this
});
} else {
var id = selected.id;
Deluge.Client.web.connect(id, {
success: function(methods) {
Deluge.Client.reloadMethods();
Deluge.Events.fire('connect');
}
});
if (this.running) window.clearInterval(this.running);
this.hide();
}
},
onGetHosts: function(hosts) {
this.grid.getStore().loadData(hosts);
var selection = this.grid.getSelectionModel();
selection.selectRow(this.selectedRow);
},
onLogin: function() {
Deluge.Client.web.connected({
success: function(connected) {
if (connected) {
Deluge.Events.fire('connect');
} else {
this.show();
}
},
scope: this
});
},
onLogout: function() {
this.disconnect();
this.hide();
},
onRemove: function(button) {
var connection = Deluge.Connections.Grid.getSelectionModel().getSelected();
Deluge.Client.web.remove_host(connection.id, {
onSuccess: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
Deluge.Connections.Grid.store.remove(connection);
}
}
});
},
onSelect: function(selModel, rowIndex, record) {
this.selectedRow = rowIndex;
var button = this.buttons[1];
if (record.get('status') == _('Connected')) {
button.setText(_('Disconnect'));
} else {
button.setText(_('Connect'));
}
},
onShow: function() {
this.runCheck();
this.running = window.setInterval(this.runCheck, 2000);
},
onStop: function(button, e) {
var connection = this.grid.getSelectionModel().getSelected();
Deluge.Client.web.stop_daemon(connection.id, {
success: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
}
}
});
}
});
Deluge.ConnectionManager = new Ext.deluge.ConnectionManager();
})();
/*Deluge.Connections = {
loginShow: function() {
},
,
}
Deluge.Connections.Store ;
Deluge.Connections.Grid = new Ext.grid.GridPanel();
Deluge.Connections.Add = new Ext.Window({
layout: 'fit',
width: 300,
height: 195,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Add Connection'),
iconCls: 'x-deluge-add-window-icon',
items: [new Ext.form.FormPanel({
defaultType: 'textfield',
id: 'connectionAddForm',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Host'),
id: 'host',
name: 'host',
anchor: '100%',
listeners: {}
},{
fieldLabel: _('Port'),
id: 'port',
xtype: 'uxspinner',
ctCls: 'x-form-uxspinner',
name: 'port',
strategy: Ext.ux.form.Spinner.NumberStrategy(),
value: '58846',
anchor: '50%',
listeners: {}
}, {
fieldLabel: _('Username'),
id: 'username',
name: 'username',
anchor: '100%',
listeners: {}
},{
fieldLabel: _('Password'),
anchor: '100%',
id: '_password',
name: '_password',
inputType: 'password'
}]
})],
buttons: [{
text: _('Close'),
handler: function() {
Deluge.Connections.Add.hide();
}
},{
text: _('Add'),
handler: Deluge.Connections.onAddHost
}],
listeners: {
'hide': Deluge.Connections.onAddWindowHide
}
});*/

View File

@ -0,0 +1,79 @@
/*
Script: Deluge.Details.Details.js
The details tab displayed in the details panel.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
Ext.deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
title: _('Details'),
cls: 'x-deluge-status',
onRender: function(ct, position) {
Ext.deluge.details.DetailsTab.superclass.onRender.call(this, ct, position);
this.load({
url: '/render/tab_details.html',
text: _('Loading') + '...'
});
this.getUpdater().on('update', this.onPanelUpdate, this);
},
clear: function() {
if (!this.fields) return;
for (var k in this.fields) {
this.fields[k].innerHTML = '';
}
},
update: function(torrentId) {
if (!this.fields) this.getFields();
Deluge.Client.core.get_torrent_status(torrentId, Deluge.Keys.Details, {
success: this.onRequestComplete,
scope: this,
torrentId: torrentId
});
},
onPanelUpdate: function(el, response) {
this.fields = {};
Ext.each(Ext.query('dd', this.body.dom), function(field) {
this.fields[field.className] = field;
}, this);
},
onRequestComplete: function(torrent, options) {
var data = {
torrent_name: torrent.name,
hash: options.torrentId,
path: torrent.save_path,
size: fsize(torrent.total_size),
files: torrent.num_files,
status: torrent.tracker_status,
tracker: torrent.tracker,
comment: torrent.comment
};
for (var field in this.fields) {
this.fields[field].innerHTML = data[field];
}
}
});
Deluge.Details.add(new Ext.deluge.details.DetailsTab());
})();

View File

View File

View File

@ -0,0 +1,109 @@
/*
Script: Deluge.Details.Status.js
The status tab displayed in the details panel.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
Ext.deluge.details.StatusTab = Ext.extend(Ext.Panel, {
title: _('Status'),
onRender: function(ct, position) {
Ext.deluge.details.StatusTab.superclass.onRender.call(this, ct, position);
this.progressBar = this.add({
xtype: 'fullprogressbar',
cls: 'x-deluge-status-progressbar'
});
this.status = this.add({
cls: 'x-deluge-status',
border: false,
listeners: {
'render': {
fn: function(panel) {
panel.load({
url: '/render/tab_status.html',
text: _('Loading') + '...'
});
panel.getUpdater().on('update', this.onPanelUpdate, this);
},
scope: this
}
}
});
},
clear: function() {
if (!this.fields) return;
this.progressBar.updateProgress(0, ' ');
for (var k in this.fields) {
this.fields[k].innerHTML = '';
}
},
update: function(torrentId) {
if (!this.fields) this.getFields();
Deluge.Client.core.get_torrent_status(torrentId, Deluge.Keys.Status, {
success: this.onRequestComplete,
scope: this
});
},
onPanelUpdate: function(el, response) {
this.fields = {};
Ext.each(Ext.query('dd', this.status.body.dom), function(field) {
this.fields[field.className] = field;
}, this);
},
onRequestComplete: function(status) {
seeders = status.total_seeds > -1 ? status.num_seeds + ' (' + status.total_seeds + ')' : status.num_seeds
peers = status.total_peers > -1 ? status.num_peers + ' (' + status.total_peers + ')' : status.num_peers
var data = {
downloaded: fsize(status.total_done) + ' (' + fsize(status.total_payload_download) + ')',
uploaded: fsize(status.total_uploaded) + ' (' + fsize(status.total_payload_upload) + ')',
share: status.ratio.toFixed(3),
announce: ftime(status.next_announce),
tracker_status: status.tracker_status,
downspeed: fspeed(status.download_payload_rate),
upspeed: fspeed(status.upload_payload_rate),
eta: ftime(status.eta),
pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
seeders: seeders,
peers: peers,
avail: status.distributed_copies.toFixed(3),
active_time: ftime(status.active_time),
seeding_time: ftime(status.seeding_time),
seed_rank: status.seed_rank,
auto_managed: 'False',
time_added: fdate(status.time_added)
}
if (status.is_auto_managed) {data.auto_managed = 'True'}
for (var field in this.fields) {
this.fields[field].innerHTML = data[field];
}
var text = status.state + ' ' + status.progress.toFixed(2) + '%';
this.progressBar.updateProgress(status.progress, text);
}
});
Deluge.Details.add(new Ext.deluge.details.StatusTab());
})();

View File

@ -22,184 +22,63 @@ Copyright:
Boston, MA 02110-1301, USA.
*/
Deluge.Details = {
clear: function() {
this.Panel.items.each(function(item) {
if (item.clear) item.clear();
});
},
update: function(tab) {
var torrent = Deluge.Torrents.getSelected();
if (!torrent) return;
(function() {
Ext.namespace('Ext.deluge.details');
Ext.deluge.details.TabPanel = Ext.extend(Ext.TabPanel, {
tab = tab || this.Panel.getActiveTab();
if (tab.update) {
tab.update(torrent.id);
}
},
onRender: function(panel) {
Deluge.Torrents.on('rowclick', this.onTorrentsClick.bindWithEvent(this));
constructor: function(config) {
config = Ext.apply({
region: 'south',
split: true,
height: 220,
minSize: 100,
collapsible: true,
margins: '0 5 5 5',
activeTab: 0
}, config);
Ext.deluge.details.TabPanel.superclass.constructor.call(this, config);
},
var selModel = Deluge.Torrents.getSelectionModel();
selModel.on('selectionchange', function(selModel) {
if (!selModel.hasSelection()) {
this.clear.delay(10, this);
}
}.bindWithEvent(this));
Deluge.Events.on('disconnect', this.clear.bind(this));
},
onTabChange: function(panel, tab) {
this.update(tab);
},
onTorrentsClick: function(grid, rowIndex, e) {
this.update();
}
}
Deluge.Details.Status = {
onRender: function(panel) {
this.panel = panel;
this.progressBar = new Ext.ux.FullProgressBar({
id: 'pbar-status',
cls: 'deluge-status-progressbar'
});
this.panel.add(this.progressBar);
this.panel.add({
id: 'status-details',
cls: 'deluge-status',
border: false,
listeners: {'render': Deluge.Details.Status.onStatusRender}
});
this.panel.update = this.update.bind(this);
this.panel.clear = this.clear.bind(this);
},
onStatusRender: function(panel) {
this.status = panel;
this.status.load({
url: '/render/tab_status.html',
text: _('Loading') + '...'
});
},
onRequestComplete: function(status) {
seeders = status.total_seeds > -1 ? status.num_seeds + ' (' + status.total_seeds + ')' : status.num_seeds
peers = status.total_peers > -1 ? status.num_peers + ' (' + status.total_peers + ')' : status.num_peers
var data = {
downloaded: fsize(status.total_done) + ' (' + fsize(status.total_payload_download) + ')',
uploaded: fsize(status.total_uploaded) + ' (' + fsize(status.total_payload_upload) + ')',
share: status.ratio.toFixed(3),
announce: ftime(status.next_announce),
tracker_status: status.tracker_status,
downspeed: fspeed(status.download_payload_rate),
upspeed: fspeed(status.upload_payload_rate),
eta: ftime(status.eta),
pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
seeders: seeders,
peers: peers,
avail: status.distributed_copies.toFixed(3),
active_time: ftime(status.active_time),
seeding_time: ftime(status.seeding_time),
seed_rank: status.seed_rank,
auto_managed: 'False',
time_added: fdate(status.time_added)
clear: function() {
this.items.each(function(panel) {
if (panel.clear) panel.clear();
});
},
update: function(tab) {
var torrent = Deluge.Torrents.getSelected();
if (!torrent) return;
tab = tab || this.getActiveTab();
if (tab.update) tab.update(torrent.id);
},
/* Event Handlers */
// We need to add the events in onRender since Deluge.Torrents hasn't
// been created yet.
onRender: function(ct, position) {
Ext.deluge.details.TabPanel.superclass.onRender.call(this, ct, position);
Deluge.Events.on('disconnect', this.clear, this);
Deluge.Torrents.on('rowclick', this.onTorrentsClick, this);
Deluge.Torrents.getSelectionModel().on('selectionchange', function(selModel) {
if (!selModel.hasSelection()) this.clear();
}, this);
},
onTabChange: function(panel, tab) {
this.update(tab);
},
onTorrentsClick: function(grid, rowIndex, e) {
this.update();
}
if (status.is_auto_managed) {data.auto_managed = 'True'}
this.fields.each(function(value, key) {
value.set('text', data[key]);
}, this);
var text = status.state + ' ' + status.progress.toFixed(2) + '%';
this.progressBar.updateProgress(status.progress, text);
},
getFields: function() {
var panel = this.panel.items.get('status-details');
this.fields = new Hash();
$(panel.body.dom).getElements('dd').each(function(item) {
this.fields[item.getProperty('class')] = item;
}, this);
},
update: function(torrentId) {
if (!this.fields) this.getFields();
Deluge.Client.core.get_torrent_status(torrentId, Deluge.Keys.Status, {
onSuccess: this.onRequestComplete.bind(this)
});
},
clear: function() {
if (!this.fields) return;
this.progressBar.updateProgress(0, ' ');
this.fields.each(function(value, key) {
value.set('text', '');
}, this);
}
}
Deluge.Details.Details = {
onRender: function(panel) {
this.panel = panel;
panel.load({
url: '/render/tab_details.html',
text: _('Loading') + '...',
callback: this.onLoaded.bindWithEvent(this)
});
this.doUpdate = false;
this.panel.update = this.update.bind(this);
this.panel.clear = this.clear.bind(this);
},
onLoaded: function() {
this.getFields();
this.doUpdate = true;
if (Deluge.Details.Panel.getActiveTab() == this.panel) {
Deluge.Details.update(this.panel);
}
},
onRequestComplete: function(torrent, torrentId) {
var data = {
torrent_name: torrent.name,
hash: torrentId,
path: torrent.save_path,
size: fsize(torrent.total_size),
files: torrent.num_files,
status: torrent.tracker_status,
tracker: torrent.tracker,
comment: torrent.comment
};
this.fields.each(function(value, key) {
value.set('text', data[key]);
}, this);
},
getFields: function() {
this.fields = new Hash();
$(this.panel.body.dom.firstChild).getElements('dd').each(function(item) {
this.fields[item.getProperty('class')] = item;
}, this);
},
update: function(torrentId) {
if (!this.doUpdate) return;
if (!this.fields) this.getFields();
Deluge.Client.core.get_torrent_status(torrentId, Deluge.Keys.Details, {
onSuccess: this.onRequestComplete.bindWithEvent(this, torrentId)
});
},
clear: function() {
if (!this.fields) return;
this.fields.each(function(value, key) {
value.set('text', '');
}, this);
}
}
});
Deluge.Details = new Ext.deluge.details.TabPanel();
})();
/*
Deluge.Details.Files = {
onRender: function(panel) {
this.panel = panel;
@ -440,23 +319,8 @@ Deluge.Details.Peers.Store = new Ext.data.SimpleStore({
});
Deluge.Details.Panel = new Ext.TabPanel({
region: 'south',
split: true,
height: 220,
minSize: 100,
collapsible: true,
margins: '0 5 5 5',
activeTab: 0,
,
items: [{
id: 'status',
title: _('Status'),
listeners: {
'render': {
fn: Deluge.Details.Status.onRender,
scope: Deluge.Details.Status
}
}
}, {
id: 'details',
title: _('Details'),
cls: 'deluge-status',
@ -708,4 +572,4 @@ Deluge.Details.Panel = new Ext.TabPanel({
'render': {fn: Deluge.Details.onRender, scope: Deluge.Details},
'tabchange': {fn: Deluge.Details.onTabChange, scope: Deluge.Details}
}
});
});*/

View File

@ -0,0 +1,96 @@
/*
Script: Deluge.Formatters.js
A collection of functions for string formatting values.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
Deluge.Formatters = {
date: function(timestamp) {
function zeroPad(num, count) {
var numZeropad = num + '';
while (numZeropad.length < count) {
numZeropad = '0' + numZeropad;
}
return numZeropad;
}
timestamp = timestamp * 1000;
var date = new Date(timestamp);
return String.format('{0}/{1}/{2}', zeroPad(date.getDate(), 2), zeroPad(date.getMonth() + 1, 2), date.getFullYear());
},
size: function(bytes) {
bytes = bytes / 1024.0;
if (bytes < 1024) { return bytes.toFixed(1) + ' KiB'; }
else { bytes = bytes / 1024; }
if (bytes < 1024) { return bytes.toFixed(1) + ' MiB'; }
else { bytes = bytes / 1024; }
return bytes.toFixed(1) + ' GiB'
},
speed: function(bits) {
return fsize(bits) + '/s'
},
timeRemaining: function(time) {
if (time == 0) { return '∞' }
if (time < 60) { return time + 's'; }
else { time = time / 60; }
if (time < 60) {
var minutes = Math.floor(time)
var seconds = Math.round(60 * (time - minutes))
if (seconds > 0) {
return minutes + 'm ' + seconds + 's';
} else {
return minutes + 'm'; }
}
else { time = time / 60; }
if (time < 24) {
var hours = Math.floor(time)
var minutes = Math.round(60 * (time - hours))
if (minutes > 0) {
return hours + 'h ' + minutes + 'm';
} else {
return hours + 'h';
}
}
else { time = time / 24; }
var days = Math.floor(time)
var hours = Math.round(24 * (time - days))
if (hours > 0) {
return days + 'd ' + hours + 'h';
} else {
return days + 'd';
}
},
plain: function(value) {
return value;
}
}
var fsize = Deluge.Formatters.size;
var fspeed = Deluge.Formatters.speed;
var ftime = Deluge.Formatters.timeRemaining;
var fdate = Deluge.Formatters.date;
var fplain = Deluge.Formatters.plain;

View File

@ -0,0 +1,33 @@
Deluge.Keys = {
Grid: [
'queue', 'name', 'total_size', 'state', 'progress', 'num_seeds',
'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
'is_auto_managed', 'time_added', 'tracker_host'
],
Status: [
'total_done', 'total_payload_download', 'total_uploaded',
'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
'seed_rank'
],
Files: [
'files', 'file_progress', 'file_priorities'
],
Peers: [
'peers', 'seeds'
],
Details: [
'name', 'save_path', 'total_size', 'num_files', 'tracker_status',
'tracker', 'comment'
],
Options: [
'max_download_speed', 'max_upload_speed', 'max_connections',
'max_upload_slots','is_auto_managed', 'stop_at_ratio', 'stop_ratio',
'remove_at_ratio', 'private', 'prioritize_first_last'
]
};
Ext.each(Deluge.Keys.Grid, function(key) {
Deluge.Keys.Status.push(key);
});

View File

@ -22,29 +22,28 @@ Copyright:
*/
(function(){
var LoginWindow = function(config) {
Ext.apply(this, {
layout: 'fit',
width: 300,
height: 120,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closeAction: 'hide',
closable: false,
modal: true,
plain: true,
resizable: false,
title: _('Login'),
iconCls: 'x-deluge-login-window-icon'
});
Ext.apply(this, config);
LoginWindow.superclass.constructor.call(this);
};
Ext.extend(LoginWindow, Ext.Window, {
Ext.deluge.LoginWindow = Ext.extend(Ext.Window, {
constructor: function(config) {
config = Ext.apply({
layout: 'fit',
width: 300,
height: 120,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'center',
closeAction: 'hide',
closable: false,
modal: true,
plain: true,
resizable: false,
title: _('Login'),
iconCls: 'x-deluge-login-window-icon'
}, config);
Ext.deluge.LoginWindow.superclass.constructor.call(this, config);
},
initComponent: function() {
LoginWindow.superclass.initComponent.call();
Deluge.Events.on('logout', this.onLogout);
Ext.deluge.LoginWindow.superclass.initComponent.call(this);
Deluge.Events.on('logout', this.onLogout, this);
this.on('show', this.onShow, this);
this.addButton({
@ -72,7 +71,7 @@ Copyright:
}
}
}]
});
})
},
onKey: function(field, e) {
@ -82,12 +81,11 @@ Copyright:
onLogin: function() {
var passwordField = this.loginForm.items.get('password');
Deluge.Client.web.login(passwordField.getValue(), {
onSuccess: function(result) {
success: function(result) {
if (result == true) {
Deluge.Events.fire('login');
this.hide();
Deluge.Connections.loginShow();
passwordField.setRawValue('');
Deluge.Events.fire('login')
} else {
Ext.MessageBox.show({
title: _('Login Failed'),
@ -101,7 +99,8 @@ Copyright:
iconCls: 'x-deluge-icon-warning'
});
}
}.bindWithEvent(this)
},
scope: this
});
},
@ -115,5 +114,5 @@ Copyright:
}
});
Deluge.Login = new LoginWindow();
Deluge.Login = new Ext.deluge.LoginWindow();
})();

View File

@ -0,0 +1,95 @@
Deluge.Preferences.addPage(_('Bandwidth'), {
border: false,
xtype: 'form',
layout: 'form',
labelWidth: 10,
items: [{
xtype: 'fieldset',
border: false,
title: _('Global Bandwidth Usage'),
autoHeight: true,
labelWidth: 200,
style: 'margin-bottom: 0px; padding-bottom: 0px;',
defaultType: 'uxspinner',
items: [{
name: 'max_connections',
fieldLabel: _('Maximum Connections'),
width: 60,
value: -1
}, {
name: 'max_upload_slots',
fieldLabel: _('Maximum Upload Slots'),
width: 60,
value: -1
}, {
name: 'max_download_speed',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_upload_speed',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_half_open_connections',
fieldLabel: _('Maximum Half-Open Connections'),
width: 60,
value: -1
}, {
name: 'max_connections_per_second',
fieldLabel: _('Maximum Connection Attempts per Second'),
width: 60,
value: -1
}]
}, {
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
style: 'padding-top: 0px; margin-top: 0px; margin-bottom: 0px;',
items: [{
xtype: 'checkbox',
name: 'ignore_local',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Ignore limits on local network'),
value: -1
}, {
xtype: 'checkbox',
name: 'limit_ip_overhead',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Rate limit IP overhead'),
value: -1
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Per Torrent Bandwidth Usage'),
autoHeight: true,
labelWidth: 200,
defaultType: 'uxspinner',
items: [{
name: 'max_connections_per_torrent',
fieldLabel: _('Maximum Connections'),
width: 60,
value: -1
}, {
name: 'max_upload_slots_per_torrent',
fieldLabel: _('Maximum Upload Slots'),
width: 60,
value: -1
}, {
name: 'max_download_speed_per_torrent',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_upload_speed_per_torrent',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 60,
value: -1
}]
}]
});

View File

@ -0,0 +1,43 @@
Deluge.Preferences.addPage(_('Daemon'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Port'),
autoHeight: true,
defaultType: 'uxspinner',
items: [{
fieldLabel: _('Daemon port'),
id: 'daemon_port'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Connections'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Allow Remote Connections'),
id: 'allow_remote'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Other'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
fieldLabel: '',
labelSeparator: '',
height: 40,
boxLabel: _('Periodically check the website for new releases'),
id: 'new_releases'
}]
}]
});

View File

@ -0,0 +1,58 @@
Deluge.Preferences.addPage(_('Downloads'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Folders'),
labelWidth: 140,
defaultType: 'textfield',
autoHeight: true,
items: [{
name: 'download_location',
fieldLabel: _('Download to'),
width: 125
}, {
name: 'move_completed',
fieldLabel: _('Move completed to'),
width: 125
}, {
name: 'copy_torrent_files',
fieldLabel: _('Copy of .torrent files to'),
width: 125
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Allocation'),
autoHeight: true,
labelWidth: 1,
defaultType: 'radio',
items: [{
name: 'compact_allocation',
labelSeparator: '',
boxLabel: _('Compact')
}, {
name: 'compact_allocation',
labelSeparator: '',
boxLabel: _('Full')
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Options'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
name: 'prioritize_first_last',
labelSeparator: '',
boxLabel: _('Prioritize first and last pieces of torrent')
}, {
name: 'add_paused',
labelSeparator: '',
boxLabel: _('Add torrents in Paused state')
}]
}]
});

View File

@ -0,0 +1,47 @@
Deluge.Preferences.addPage(_('Interface'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Window'),
autoHeight: true,
labelWidth: 1,
items: [{
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show session speed in titlebar'),
id: 'show_session_speed'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Sidebar'),
autoHeight: true,
labelWidth: 1,
items: [{
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Hide filters with zero torrents'),
id: 'hide_sidebar_zero'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Password'),
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'New Password',
inputType: 'password',
id: 'new_password'
}, {
inputType: 'password',
fieldLabel: 'Confirm Password',
id: 'confirm_password'
}]
}]
});

View File

@ -0,0 +1,7 @@
/*Deluge.Preferences.addPage(_('Network'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,7 @@
/*Deluge.Preferences.addPage(_('Notification'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,7 @@
/*Deluge.Preferences.addPage(_('Other'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,7 @@
/*Deluge.Preferences.addPage(_('Plugins'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,8 @@
/*
Deluge.Preferences.addPage(_('Proxy'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,8 @@
/*
Deluge.Preferences.addPage(_('Queue'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
*/

View File

@ -0,0 +1,122 @@
/*
Script: deluge-preferences.js
Contains the preferences window.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
Ext.deluge.PreferencesWindow = Ext.extend(Ext.Window, {
constructor: function(config) {
config = Ext.apply({
layout: 'border',
width: 485,
height: 500,
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
iconCls: 'x-deluge-preferences',
plain: true,
resizable: true,
title: _('Preferences'),
buttons: [{
text: _('Close'),
handler: this.onCloseButtonClick,
scope: this
},{
text: _('Apply')
},{
text: _('Ok')
}],
currentPage: false,
items: [{
xtype: 'grid',
region: 'west',
title: _('Categories'),
store: new Ext.data.SimpleStore({
fields: [{name: 'name', mapping: 0}]
}),
columns: [{id: 'name', renderer: fplain, dataIndex: 'name'}],
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {'rowselect': {fn: this.onPageSelect, scope: this}}
}),
hideHeaders: true,
autoExpandColumn: 'name',
deferredRender: false,
autoScroll: true,
margins: '5 0 5 5',
cmargins: '5 0 5 5',
width: 120,
collapsible: true
}, {
region: 'center',
title: ' ',
layout: 'fit',
height: 400,
margins: '5 5 5 5',
cmargins: '5 5 5 5'
}]
}, config);
Ext.deluge.PreferencesWindow.superclass.constructor.call(this, config);
},
initComponent: function() {
Ext.deluge.PreferencesWindow.superclass.initComponent.call(this);
this.categoriesGrid = this.items.get(0);
this.configPanel = this.items.get(1);
this.pages = {};
this.on('show', this.onShow, this);
},
onCloseButtonClick: function() {
this.hide();
},
addPage: function(name, page) {
var store = this.categoriesGrid.getStore();
store.loadData([[name]], true);
page['bodyStyle'] = 'margin: 5px';
this.pages[name] = this.configPanel.add(page);
this.pages[name].hide();
},
onPageSelect: function(selModel, rowIndex, r) {
if (this.currentPage) {
this.currentPage.hide();
}
var name = r.get('name');
this.pages[name].show();
this.configPanel.setTitle(name);
this.currentPage = this.pages[name];
this.configPanel.doLayout();
},
onShow: function() {
if (!this.categoriesGrid.getSelectionModel().hasSelection()) {
this.categoriesGrid.getSelectionModel().selectFirstRow();
}
}
});
Deluge.Preferences = new Ext.deluge.PreferencesWindow();
})();

View File

@ -0,0 +1,202 @@
/*
Script: deluge-bars.js
Contains all objects and functions related to the statusbar, toolbar and
sidebar.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
// These are just so gen_gettext.js will pick up the strings
// _('State')
// _('Tracker Host')
(function() {
// Renderer for the items in the filter grids.
function filterRenderer(value, p, r) {
var lname = value.toLowerCase().replace('.', '_');
var image = '';
if (r.store.id == 'tracker_host') {
if (value != 'Error') {
image = String.format('url(/tracker/{0})', value);
} else {
lname = null;
}
}
if (image) {
return String.format('<div class="x-deluge-filter" style="background-image: {2};">{0} ({1})</div>', value, r.data['count'], image);
} else if (lname) {
return String.format('<div class="x-deluge-filter x-deluge-{2}">{0} ({1})</div>', value, r.data['count'], lname);
} else {
return String.format('<div class="x-deluge-filter">{0} ({1})</div>', value, r.data['count']);
}
}
Ext.deluge.Sidebar = Ext.extend(Ext.Panel, {
// private
panels: {},
// private
selected: null,
constructor: function(config) {
config = Ext.apply({
id: 'sidebar',
region: 'west',
cls: 'deluge-sidebar',
title: _('Filters'),
layout: 'accordion',
split: true,
width: 200,
minSize: 175,
collapsible: true,
margins: '5 0 0 5',
cmargins: '5 0 0 5'
}, config);
Ext.deluge.Sidebar.superclass.constructor.call(this, config);
},
// private
initComponent: function() {
Ext.deluge.Sidebar.superclass.initComponent.call(this);
Deluge.Events.on("disconnect", this.onDisconnect, this);
},
createFilter: function(filter, states) {
var store = new Ext.data.SimpleStore({
id: filter,
fields: [
{name: 'filter'},
{name: 'count'}
]
});
var title = filter.replace('_', ' ');
var parts = title.split(' ');
title = '';
Ext.each(parts, function(part) {
firstLetter = part.substring(0, 1);
firstLetter = firstLetter.toUpperCase();
part = firstLetter + part.substring(1);
title += part + ' ';
});
var panel = new Ext.grid.GridPanel({
id: filter + '-panel',
store: store,
title: _(title),
columns: [
{id: 'filter', sortable: false, renderer: filterRenderer, dataIndex: 'filter'}
],
stripeRows: false,
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
'rowselect': {fn: this.onFilterSelect, scope: this}
}
}),
hideHeaders: true,
autoExpandColumn: 'filter',
deferredRender: false,
autoScroll: true
});
store.loadData(states);
this.add(panel);
this.doLayout();
this.panels[filter] = panel;
if (!this.selected) {
panel.getSelectionModel().selectFirstRow();
this.selected = {
row: 0,
filter: states[0][0],
panel: panel
}
}
},
getFilters: function() {
var filters = {}
if (!this.selected) {
return filters;
}
if (!this.selected.filter || !this.selected.panel) {
return filters;
}
var filterType = this.selected.panel.store.id;
if (filterType == "state" && this.selected.filter == "All") {
return filters;
}
filters[filterType] = this.selected.filter;
return filters;
},
// private
onDisconnect: function() {
Ext.each(Ext.getKeys(this.panels), function(filter) {
this.remove(filter + '-panel');
}, this);
this.panels.empty();
this.selected = null;
},
onFilterSelect: function(selModel, rowIndex, record) {
if (!this.selected) needsUpdate = true;
else if (this.selected.row != rowIndex) needsUpdate = true;
else needsUpdate = false;
this.selected = {
row: rowIndex,
filter: record.get('filter'),
panel: this.panels[record.store.id]
}
if (needsUpdate) Deluge.UI.update();
},
update: function(filters) {
for (var filter in filters) {
var states = filters[filter];
if (Ext.getKeys(this.panels).indexOf(filter) > -1) {
this.updateFilter(filter, states);
} else {
this.createFilter(filter, states);
}
}
// Perform a cleanup of fitlers that aren't enabled any more
Ext.each(Ext.getKeys(this.panels), function(filter) {
if (Ext.getKeys(filters).indexOf(filter) == -1) {
// We need to remove the panel
}
});
},
updateFilter: function(filter, states) {
this.panels[filter].store.loadData(states);
if (this.selected && this.selected.panel == this.panels[filter]) {
this.panels[filter].getSelectionModel().selectRow(this.selected.row);
}
}
});
Deluge.Sidebar = new Ext.deluge.Sidebar();
})();

View File

@ -0,0 +1,147 @@
(function() {
Ext.deluge.Statusbar = Ext.extend(Ext.StatusBar, {
constructor: function(config) {
config = Ext.apply({
id: 'deluge-statusbar',
defaultIconCls: 'x-not-connected',
defaultText: _('Not Connected'),
}, config);
Ext.deluge.Statusbar.superclass.constructor.call(this, config);
},
initComponent: function() {
Ext.deluge.Statusbar.superclass.initComponent.call(this);
Deluge.Events.on('connect', this.onConnect, this);
Deluge.Events.on('disconnect', this.onDisconnect, this);
},
createButtons: function() {
this.add({
id: 'statusbar-connections',
text: '200 (200)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-connections',
menu: Deluge.Menus.Connections
}, '-', {
id: 'statusbar-downspeed',
text: '9.8KiB/s (30 KiB/s)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-downloading',
menu: Deluge.Menus.Download
}, '-', {
id: 'statusbar-upspeed',
text: '9.8KiB/s (30 KiB/s)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-seeding',
menu: Deluge.Menus.Upload
}, '-', {
id: 'statusbar-traffic',
text: '1.53/2,65 KiB/s',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-traffic'
}, '-', {
id: 'statusbar-dht',
text: '161',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-dht'
});
this.created = true;
},
onConnect: function() {
this.setStatus({
iconCls: 'x-connected',
text: ''
});
if (!this.created) this.createButtons();
else {
this.items.each(function(item) {
item.show();
item.enable();
});
}
},
onDisconnect: function() {
this.clearStatus({useDefaults:true});
this.items.each(function(item) {
item.hide();
item.disable();
});
},
update: function(stats) {
function addSpeed(val) {return val + ' KiB/s'}
var updateStat = function(name, config) {
var item = this.items.get('statusbar-' + name);
if (config.limit.value == -1) {
var str = (config.value.formatter) ? config.value.formatter(config.value.value) : config.value.value;
} else {
var value = (config.value.formatter) ? config.value.formatter(config.value.value) : config.value.value;
var limit = (config.limit.formatter) ? config.limit.formatter(config.limit.value) : config.limit.value;
var str = String.format(config.format, value, limit);
}
item.setText(str);
}.bind(this);
updateStat('connections', {
value: {value: stats.num_connections},
limit: {value: stats.max_num_connections},
format: '{0} ({1})'
});
updateStat('downspeed', {
value: {
value: stats.download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_download,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('upspeed', {
value: {
value: stats.upload_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_upload,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('traffic', {
value: {
value: stats.payload_download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.payload_upload_rate,
formatter: Deluge.Formatters.speed
},
format: '{0}/{1}'
});
this.items.get('statusbar-dht').setText(stats.dht_nodes);
function updateMenu(menu, stat) {
var item = menu.items.get(stat)
if (!item) {
item = menu.items.get('other')
}
item.setChecked(true);
}
updateMenu(Deluge.Menus.Connections, stats.max_num_connections);
updateMenu(Deluge.Menus.Download, stats.max_download);
updateMenu(Deluge.Menus.Upload, stats.max_upload);
}
});
Deluge.Statusbar = new Ext.deluge.Statusbar();
})();

View File

@ -0,0 +1,195 @@
/*
Script: Deluge.Toolbar.js
Contains the Deluge toolbar.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
Ext.deluge.Toolbar = Ext.extend(Ext.Toolbar, {
constructor: function(config) {
config = Ext.apply({
items: [
{
id: 'create',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Create'),
icon: '/icons/create.png',
handler: this.onTorrentAction
},{
id: 'add',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Add'),
icon: '/icons/add.png',
handler: this.onTorrentAdd
},{
id: 'remove',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Remove'),
icon: '/icons/remove.png',
handler: this.onTorrentAction
},'|',{
id: 'pause',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Pause'),
icon: '/icons/pause.png',
handler: this.onTorrentAction
},{
id: 'resume',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Resume'),
icon: '/icons/start.png',
handler: this.onTorrentAction
},'|',{
id: 'up',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Up'),
icon: '/icons/up.png',
handler: this.onTorrentAction
},{
id: 'down',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Down'),
icon: '/icons/down.png',
handler: this.onTorrentAction
},'|',{
id: 'preferences',
cls: 'x-btn-text-icon',
text: _('Preferences'),
icon: '/icons/preferences.png',
handler: this.onPreferencesClick,
scope: this
},{
id: 'connectionman',
cls: 'x-btn-text-icon',
text: _('Connection Manager'),
iconCls: 'x-deluge-connections',
handler: this.onConnectionManagerClick,
scope: this
},'->',{
id: 'help',
cls: 'x-btn-text-icon',
disabled: true,
icon: '/icons/help.png',
text: _('Help'),
handler: this.onHelpClick,
scope: this
},{
id: 'logout',
cls: 'x-btn-text-icon',
icon: '/icons/logout.png',
disabled: true,
text: _('Logout'),
handler: this.onLogout,
scope: this
}
]
}, config);
Ext.deluge.Toolbar.superclass.constructor.call(this, config);
},
connectedButtons: [
'add', 'remove', 'pause', 'resume', 'up', 'down'
],
initComponent: function() {
Ext.deluge.Toolbar.superclass.initComponent.call(this);
Deluge.Events.on('connect', this.onConnect, this);
Deluge.Events.on('login', this.onLogin, this);
},
onConnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).enable();
}, this);
},
onDisconnect: function() {
Ext.each(this.connectedButtons, function(buttonId) {
this.items.get(buttonId).disable();
}, this);
},
onLogin: function() {
this.items.get('logout').enable();
},
onLogout: function() {
this.items.get('logout').disable();
Deluge.Events.fire('logout');
Deluge.Login.show();
},
onConnectionManagerClick: function() {
Deluge.ConnectionManager.show();
},
onPreferencesClick: function() {
Deluge.Preferences.show();
},
onTorrentAction: function(item) {
var selection = Deluge.Torrents.getSelections();
var ids = [];
Ext.each(selection, function(record) {
ids.push(record.id);
});
switch (item.id) {
case 'remove':
Deluge.Events.fire('torrentRemoved', ids);
Deluge.Client.core.remove_torrent(ids, null, {
success: function() {
Deluge.UI.update();
}
});
break;
case 'pause':
case 'resume':
Deluge.Client.core[item.id + '_torrent'](ids, {
success: function() {
Deluge.UI.update();
}
});
break;
case 'up':
case 'down':
Deluge.Client.core['queue_' + item.id](ids, {
success: function() {
Deluge.UI.update();
}
});
break;
}
},
onTorrentAdd: function() {
Deluge.Add.Window.show();
}
});
Deluge.Toolbar = new Ext.deluge.Toolbar();
})();

View File

@ -22,7 +22,6 @@ Copyright:
*/
(function() {
/* Renderers for the Torrent Grid */
function queueRenderer(value) {
return (value == -1) ? '' : value + 1;
@ -35,10 +34,11 @@ Copyright:
return fspeed(value);
}
function torrentProgressRenderer(value, p, r) {
var progress = value.toInt();
value = new Number(value);
var progress = value;
var text = r.data['state'] + ' ' + value.toFixed(2) + '%'
var width = this.style.match(/\w+:\s*(\d+)\w+/)[1].toInt() - 8;
return Deluge.progressBar(value.toInt(), width, text);
var width = new Number(this.style.match(/\w+:\s*(\d+)\w+/)[1]) - 8;
return Deluge.progressBar(value, width, text);
}
function seedsRenderer(value, p, r) {
if (r.data['total_seeds'] > -1) {
@ -55,15 +55,25 @@ Copyright:
}
}
function availRenderer(value, p, r) {
value.toFixed(3);
return new Number(value).toFixed(3);
}
function trackerRenderer(value, p, r) {
return String.format('<div style="background: url(/tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>', value);
}
Ext.namespace("Ext.deluge");
/**
* Ext.deluge.TorrentGrid Class
*
* @author Damien Churchill <damoxc@gmail.com>
* @version 1.2
*
* @class Ext.deluge.TorrentGrid
* @extends Ext.grid.GridPanel
* @constructor
* @param {Object} config Configuration options
*/
Ext.deluge.TorrentGrid = function(config) {
Ext.deluge.TorrentGrid.superclass.constructor.call(this, {
config = Ext.apply({
id: 'torrentGrid',
store: new Ext.data.SimpleStore({
fields: [
@ -174,7 +184,8 @@ Copyright:
deferredRender:false,
autoScroll:true,
margins: '5 5 0 0'
});
}, config);
Ext.deluge.TorrentGrid.superclass.constructor.call(this, config);
}
Ext.extend(Ext.deluge.TorrentGrid, Ext.grid.GridPanel, {
@ -191,6 +202,12 @@ Copyright:
});
},
/**
* Returns the record representing the torrent at the specified index.
*
* @param {int} The row index of the torrent you wish to retrieve.
* @param {Ext.data.Record} The record representing the torrent.
*/
getTorrent: function(rowIndex) {
return this.getStore().getAt(rowIndex);
},
@ -203,6 +220,7 @@ Copyright:
return this.getSelectionModel().getSelections();
},
// private
onTorrentRemoved: function(torrentIds) {
var selModel = this.Grid.getSelectionModel();
$each(torrentIds, function(torrentId) {

View File

@ -31,13 +31,13 @@ Deluge.UI = {
iconCls: 'x-deluge-main-panel',
title: 'Deluge',
layout: 'border',
tbar: Deluge.ToolBar.Bar,
tbar: Deluge.Toolbar,
items: [
Deluge.SideBar.Config,
Deluge.Details.Panel,
Deluge.Sidebar,
Deluge.Details,
Deluge.Torrents
],
bbar: Deluge.StatusBar.Bar
bbar: Deluge.Statusbar
});
this.Viewport = new Ext.Viewport({
@ -47,20 +47,23 @@ Deluge.UI = {
Deluge.Login.show();
Deluge.Events.on("connect", this.onConnect.bindWithEvent(this));
Deluge.Events.on("disconnect", this.onDisconnect.bindWithEvent(this));
Deluge.Client = new JSON.RPC('/json');
Deluge.Events.on("connect", this.onConnect, this);
Deluge.Events.on("disconnect", this.onDisconnect, this);
Deluge.Client = new Ext.ux.util.RpcClient({url: '/json'});
this.update = this.update.bind(this);
},
update: function() {
var filters = Deluge.SideBar.getFilters();
var filters = Deluge.Sidebar.getFilters();
Deluge.Client.web.update_ui(Deluge.Keys.Grid, filters, {
onSuccess: this.onUpdate.bindWithEvent(this),
onFailure: this.onUpdateError.bindWithEvent(this)
success: this.onUpdate,
failure: this.onUpdateError,
scope: this
});
Deluge.Details.update();
Deluge.Client.web.connected({
onSuccess: this.onConnectedCheck.bindWithEvent(this)
success: this.onConnectedCheck,
scope: this
});
},
@ -83,10 +86,10 @@ Deluge.UI = {
},
onUpdate: function(data) {
var torrents = new Array();
$each(data['torrents'], function(torrent, id) {
torrents.include([
torrent.queue,
var torrents = [];
for (var torrentId in data['torrents']) {
var torrent = data['torrents'][torrentId];
torrents.push([torrent.queue,
torrent.name,
torrent.total_size,
torrent.state,
@ -102,12 +105,12 @@ Deluge.UI = {
torrent.distributed_copies,
torrent.time_added,
torrent.tracker_host,
id
torrentId
]);
});
}
Deluge.Torrents.getStore().loadData(torrents);
Deluge.StatusBar.update(data['stats']);
Deluge.SideBar.update(data['filters']);
Deluge.Statusbar.update(data['stats']);
Deluge.Sidebar.update(data['filters']);
this.errorCount = 0;
},
@ -121,14 +124,13 @@ Deluge.UI = {
*/
onConnect: function() {
if (!this.running) {
this.running = this.update.periodical(2000, this);
this.running = setInterval(this.update, 2000);
this.update();
}
},
onDisconnect: function() {
this.stop();
this.notify('Disconnected', 'Deluge has disconnected from the daemon');
},
/*
@ -141,13 +143,13 @@ Deluge.UI = {
*/
stop: function() {
if (this.running) {
$clear(this.running);
clearInterval(this.running);
this.running = false;
Deluge.Torrents.Store.loadData([]);
Deluge.Torrents.getStore().loadData([]);
}
}
}
document.addEvent('domready', function(e) {
Ext.onReady(function(e) {
Deluge.UI.initialize();
});

103
deluge/ui/web/js/Deluge.js Normal file
View File

@ -0,0 +1,103 @@
/*
Script: Deluge.js
Contains the keys for get_torrent(s)_status.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
Ext.namespace('Ext.deluge');
var Deluge = {
author: 'Damien Churchill <damoxc@gmail.com>',
version: '1.2-dev'
};
(function() {
/* Add some helper functions to Ext */
Ext.apply(Function.prototype, {
bind: function(scope) {
var self = this;
return function() {
return self.apply(scope, arguments);
}
}
});
Ext.apply(Ext, {
keys: function(obj) {
var keys = [];
for (i in obj) if (obj.hasOwnProperty(i))
{
keys.push(i);
}
return keys;
},
splat: function(obj) {
var type = Ext.type(obj);
return (type) ? ((type != 'array') ? [obj] : obj) : [];
}
});
Ext.getKeys = Ext.keys;
})();
(function() {
var tpl = '<div class="x-progress-wrap x-progress-renderered">' +
'<div class="x-progress-inner">' +
'<div style="width: {2}px" class="x-progress-bar">' +
'<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'<div class="x-progress-text x-progress-text-back">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'</div>';
Deluge.progressBar = function(progress, width, text) {
var progressWidth = ((width / 100.0) * progress).toFixed(0);
var barWidth = progressWidth - 1;
var textWidth = ((progressWidth - 10) > 0 ? progressWidth - 10 : 0);
return String.format(tpl, text, width, barWidth, textWidth);
}
})();
// Hinting for gettext_gen.py
// _('Do Not Download')
// _('Normal Priority')
// _('High Priority')
// _('Highest Priority')
FILE_PRIORITY = {
0: 'Do Not Download',
1: 'Normal Priority',
2: 'High Priority',
5: 'Highest Priority',
'Do Not Download': 0,
'Normal Priority': 1,
'High Priority': 2,
'Highest Priority': 5
}
FILE_PRIORITY_CSS = {
0: 'x-no-download',
1: 'x-normal-download',
2: 'x-high-download',
5: 'x-highest-download'
}

View File

@ -1,501 +0,0 @@
/*
Script: deluge-bars.js
Contains all objects and functions related to the statusbar, toolbar and
sidebar.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
Deluge.ToolBar = {
connected_buttons: [
'add', 'remove', 'pause', 'resume', 'up', 'down'
],
onTorrentAdd: function() {
Deluge.Add.Window.show();
},
onConnect: function() {
$each(this.connected_buttons, function(button_id) {
this.Bar.items.get(button_id).enable();
}, this);
},
onDisconnect: function() {
$each(this.connected_buttons, function(button_id) {
this.Bar.items.get(button_id).disable();
}, this);
},
onLogin: function() {
this.Bar.items.get('logout').enable();
},
onLogout: function() {
this.Bar.items.get('logout').disable();
Deluge.Events.fire('logout');
Deluge.Login.show();
},
onConnectionManagerClick: function(item) {
Deluge.Connections.Window.show();
},
onPreferencesClick: function() {
Deluge.Preferences.show();
},
onTorrentAction: function(item) {
var selection = Deluge.Torrents.getSelections();
var ids = new Array();
$each(selection, function(record) {
ids.include(record.id);
});
switch (item.id) {
case 'remove':
Deluge.Events.fire('torrentRemoved', ids);
Deluge.Client.core.remove_torrent(ids, null, {
onSuccess: function() {
Deluge.UI.update();
}
});
break;
case 'pause':
case 'resume':
Deluge.Client.core[item.id + '_torrent'](ids, {
onSuccess: function() {
Deluge.UI.update();
}
});
break;
case 'up':
case 'down':
Deluge.Client.core['queue_' + item.id](ids, {
onSuccess: function() {
Deluge.UI.update();
}
});
break;
}
},
onToolbarRender: function(toolbar) {
Deluge.Events.on('connect', this.onConnect.bindWithEvent(this));
Deluge.Events.on('login', this.onLogin.bindWithEvent(this));
}
}
Deluge.ToolBar.Bar = new Ext.Toolbar({
items: [
{
id: 'create',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Create'),
icon: '/icons/create.png',
handler: Deluge.ToolBar.onTorrentAction
},{
id: 'add',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Add'),
icon: '/icons/add.png',
handler: Deluge.ToolBar.onTorrentAdd
},{
id: 'remove',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Remove'),
icon: '/icons/remove.png',
handler: Deluge.ToolBar.onTorrentAction
},'|',{
id: 'pause',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Pause'),
icon: '/icons/pause.png',
handler: Deluge.ToolBar.onTorrentAction
},{
id: 'resume',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Resume'),
icon: '/icons/start.png',
handler: Deluge.ToolBar.onTorrentAction
},'|',{
id: 'up',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Up'),
icon: '/icons/up.png',
handler: Deluge.ToolBar.onTorrentAction
},{
id: 'down',
cls: 'x-btn-text-icon',
disabled: true,
text: _('Down'),
icon: '/icons/down.png',
handler: Deluge.ToolBar.onTorrentAction
},'|',{
id: 'preferences',
cls: 'x-btn-text-icon',
text: _('Preferences'),
icon: '/icons/preferences.png',
handler: Deluge.ToolBar.onPreferencesClick,
scope: Deluge.ToolBar
},{
id: 'connectionman',
cls: 'x-btn-text-icon',
text: _('Connection Manager'),
iconCls: 'x-deluge-connections',
handler: Deluge.ToolBar.onConnectionManagerClick,
scope: Deluge.ToolBar
},'->',{
id: 'help',
cls: 'x-btn-text-icon',
disabled: true,
icon: '/icons/help.png',
text: _('Help'),
handler: Deluge.ToolBar.onHelpClick,
scope: Deluge.ToolBar
},{
id: 'logout',
cls: 'x-btn-text-icon',
icon: '/icons/logout.png',
disabled: true,
text: _('Logout'),
handler: Deluge.ToolBar.onLogout,
scope: Deluge.ToolBar
}
],
listeners: {'render': Deluge.ToolBar.onToolbarRender, scope: Deluge.ToolBar}
});
Deluge.StatusBar = {
onRender: function() {
this.bound = {
onConnect: this.onConnect.bindWithEvent(this),
onDisconnect: this.onDisconnect.bindWithEvent(this)
}
Deluge.Events.on('connect', this.bound.onConnect);
Deluge.Events.on('disconnect', this.bound.onDisconnect);
},
createButtons: function() {
this.Bar.add({
id: 'statusbar-connections',
text: '200 (200)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-connections',
menu: Deluge.Menus.Connections
}, '-', {
id: 'statusbar-downspeed',
text: '9.8KiB/s (30 KiB/s)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-downloading',
menu: Deluge.Menus.Download
}, '-', {
id: 'statusbar-upspeed',
text: '9.8KiB/s (30 KiB/s)',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-seeding',
menu: Deluge.Menus.Upload
}, '-', {
id: 'statusbar-traffic',
text: '1.53/2,65 KiB/s',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-traffic'
}, '-', {
id: 'statusbar-dht',
text: '161',
cls: 'x-btn-text-icon',
iconCls: 'x-deluge-dht'
});
this.created = true;
},
onConnect: function() {
this.Bar.setStatus({
iconCls: 'x-connected',
text: ''
});
if (!this.created) this.createButtons();
else {
this.Bar.items.each(function(item) {
item.show();
item.enable();
});
}
},
onDisconnect: function() {
this.Bar.clearStatus({useDefaults:true});
this.Bar.items.each(function(item) {
item.hide();
item.disable();
});
},
update: function(stats) {
function addSpeed(val) {return val + ' KiB/s'}
var updateStat = function(name, config) {
var item = this.Bar.items.get('statusbar-' + name);
if (config.limit.value == -1) {
var str = (config.value.formatter) ? config.value.formatter(config.value.value) : config.value.value;
} else {
var value = (config.value.formatter) ? config.value.formatter(config.value.value) : config.value.value;
var limit = (config.limit.formatter) ? config.limit.formatter(config.limit.value) : config.limit.value;
var str = String.format(config.format, value, limit);
}
item.setText(str);
}.bind(this);
updateStat('connections', {
value: {value: stats.num_connections},
limit: {value: stats.max_num_connections},
format: '{0} ({1})'
});
updateStat('downspeed', {
value: {
value: stats.download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_download,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('upspeed', {
value: {
value: stats.upload_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.max_upload,
formatter: addSpeed
},
format: '{0} ({1})'
});
updateStat('traffic', {
value: {
value: stats.payload_download_rate,
formatter: Deluge.Formatters.speed
},
limit: {
value: stats.payload_upload_rate,
formatter: Deluge.Formatters.speed
},
format: '{0}/{1}'
});
this.Bar.items.get('statusbar-dht').setText(stats.dht_nodes);
function updateMenu(menu, stat) {
var item = menu.items.get(stat)
if (!item) {
item = menu.items.get('other')
}
item.setChecked(true);
}
updateMenu(Deluge.Menus.Connections, stats.max_num_connections);
updateMenu(Deluge.Menus.Download, stats.max_download);
updateMenu(Deluge.Menus.Upload, stats.max_upload);
}
}
Deluge.StatusBar.Bar = new Ext.StatusBar({
id: 'deluge-statusbar',
defaultIconCls: 'x-not-connected',
defaultText: _('Not Connected'),
listeners: {'render': {scope: Deluge.StatusBar, fn: Deluge.StatusBar.onRender}}
});
// These are just so gen_gettext.js pick up the strings
// _('State')
// _('Tracker Host')
Deluge.SideBar = {
panels: new Hash(),
onRender: function(bar) {
this.Bar = bar;
Deluge.Events.on("disconnect", this.onDisconnect.bindWithEvent(this));
this.selected = null;
},
onDisconnect: function() {
this.panels.getKeys().each(function(el) {
this.Bar.remove(el + '-panel');
}, this);
this.panels.empty();
this.selected = null;
},
renderer: function(value, p, r) {
var lname = value.toLowerCase().replace('.', '_');
var image = '';
if (r.store.id == 'tracker_host') {
if (value != 'Error') {
image = String.format('url(/tracker/{0})', value);
} else {
lname = null;
}
}
if (image) {
return String.format('<div class="x-deluge-filter" style="background-image: {2};">{0} ({1})</div>', value, r.data['count'], image);
} else if (lname) {
return String.format('<div class="x-deluge-filter x-deluge-{2}">{0} ({1})</div>', value, r.data['count'], lname);
} else {
return String.format('<div class="x-deluge-filter">{0} ({1})</div>', value, r.data['count']);
}
},
getFilters: function() {
var filters = {}
if (!this.selected) {
return filters;
}
if (!this.selected.filter || !this.selected.panel) {
return filters;
}
var filterType = this.selected.panel.store.id;
if (filterType == "state" && this.selected.filter == "All") {
return filters;
}
filters[filterType] = this.selected.filter;
return filters;
},
update: function(filters) {
filters = new Hash(filters);
filters.each(function(states, filter) {
if (this.panels.has(filter)) {
this.updateFilter(filter, states);
} else {
this.createFilter(filter, states);
}
}, this);
// Perform a cleanup of fitlers that aren't enabled any more
$each(this.panels.getKeys(), function(filter) {
if (!filters.has(filter)) {
// We need to remove the panel
}
});
},
createFilter: function(filter, states) {
var store = new Ext.data.SimpleStore({
id: filter,
fields: [
{name: 'filter'},
{name: 'count'}
]
});
var title = filter.replace('_', ' ');
var parts = title.split(' ');
title = '';
parts.each(function(part) {
firstLetter = part.substring(0, 1);
firstLetter = firstLetter.toUpperCase();
part = firstLetter + part.substring(1);
title += part + ' ';
});
var panel = new Ext.grid.GridPanel({
id: filter + '-panel',
store: store,
title: _(title),
columns: [
{id: 'filter', sortable: false, renderer: this.renderer, dataIndex: 'filter'}
],
stripeRows: false,
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
'rowselect': this.onSelect.bindWithEvent(this)
}
}),
hideHeaders: true,
autoExpandColumn: 'filter',
deferredRender: false,
autoScroll: true
});
store.loadData(states);
this.Bar.add(panel);
this.Bar.doLayout();
this.panels[filter] = panel;
if (!this.selected) {
panel.getSelectionModel().selectFirstRow();
this.selected = {
row: 0,
filter: states[0][0],
panel: panel
}
}
},
onSelect: function(selModel, rowIndex, record) {
if (!this.selected) needsUpdate = true;
else if (this.selected.row != rowIndex) needsUpdate = true;
else needsUpdate = false;
this.selected = {
row: rowIndex,
filter: record.get('filter'),
panel: this.panels[record.store.id]
}
if (needsUpdate) Deluge.UI.update();
},
updateFilter: function(filter, states) {
this.panels[filter].store.loadData(states);
if (this.selected && this.selected.panel == this.panels[filter]) {
this.panels[filter].getSelectionModel().selectRow(this.selected.row);
}
}
};
Deluge.SideBar.Config = {
region: 'west',
id: 'sidebar',
cls: 'deluge-sidebar',
title: _('Filters'),
layout: 'accordion',
split: true,
width: 200,
minSize: 175,
collapsible: true,
margins: '5 0 0 5',
cmargins: '5 5 0 5',
listeners: {'render': {scope: Deluge.SideBar, fn: Deluge.SideBar.onRender}}
}

View File

@ -1,322 +0,0 @@
/*
Script: deluge-connections.js
Contains all objects and functions related to the connection manager.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
Deluge.Connections = {
disconnect: function() {
Deluge.Events.fire('disconnect');
},
loginShow: function() {
Deluge.Events.on('logout', function(e) {
Deluge.Connections.disconnect();
Deluge.Connections.Window.hide();
});
Deluge.Client.web.connected({
onSuccess: function(connected) {
if (connected) {
Deluge.Events.fire('connect');
} else {
Deluge.Connections.Window.show();
}
}
});
},
onAdd: function(button, e) {
Deluge.Connections.Add.show();
},
onAddHost: function() {
var form = Deluge.Connections.Add.items.first();
var host = form.items.get('host').getValue();
var port = form.items.get('port').getValue();
var username = form.items.get('username').getValue();
var password = form.items.get('_password').getValue();
Deluge.Client.web.add_host(host, port, username, password, {
onSuccess: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: "Unable to add host: " + result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
Deluge.Connections.runCheck();
}
Deluge.Connections.Add.hide();
}
});
},
onAddWindowHide: function() {
// Tidy up the form to ensure all the values are default.
var form = Deluge.Connections.Add.items.first();
form.items.get('host').reset();
form.items.get('port').reset();
form.items.get('username').reset();
form.items.get('_password').reset();
},
onClose: function(e) {
$clear(Deluge.Connections.running);
Deluge.Connections.Window.hide();
},
onConnect: function(e) {
var selected = Deluge.Connections.Grid.getSelectionModel().getSelected();
if (!selected) return;
if (selected.get('status') == _('Connected')) {
Deluge.Client.web.disconnect({
onSuccess: function(result) {
Deluge.Connections.runCheck();
Deluge.Events.fire('disconnect');
}
});
} else {
var id = selected.id;
Deluge.Client.web.connect(id, {
onSuccess: function(methods) {
Deluge.Client = new JSON.RPC('/json', {
methods: methods
});
Deluge.Events.fire('connect');
}
});
$clear(Deluge.Connections.running);
Deluge.Connections.Window.hide();
}
},
onGetHosts: function(hosts) {
Deluge.Connections.Store.loadData(hosts);
var selection = Deluge.Connections.Grid.getSelectionModel();
selection.selectRow(Deluge.Connections.selectedRow);
},
onRemove: function(button) {
var connection = Deluge.Connections.Grid.getSelectionModel().getSelected();
Deluge.Client.web.remove_host(connection.id, {
onSuccess: function(result) {
if (!result) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
} else {
Deluge.Connections.Grid.store.remove(connection);
}
}
});
},
onSelect: function(selModel, rowIndex, record) {
Deluge.Connections.selectedRow = rowIndex;
var button = Deluge.Connections.Window.buttons[1];
if (record.get('status') == _('Connected')) {
button.setText(_('Disconnect'));
} else {
button.setText(_('Connect'));
}
},
onShow: function(window) {
Deluge.Connections.running = Deluge.Connections.runCheck.periodical(2000);
Deluge.Connections.runCheck();
},
onStop: function(button, e) {
var connection = Deluge.Connections.Grid.getSelectionModel().getSelected();
Deluge.Client.web.stop_daemon(connection.id, {
onSuccess: function(result) {
if (!result[0]) {
Ext.MessageBox.show({
title: _('Error'),
msg: result[1],
buttons: Ext.MessageBox.OK,
modal: false,
icon: Ext.MessageBox.ERROR,
iconCls: 'x-deluge-icon-error'
});
}
}
});
},
runCheck: function(callback) {
callback = $pick(callback, Deluge.Connections.onGetHosts);
Deluge.Client.web.get_hosts({
onSuccess: callback
});
}
}
Deluge.Connections.Store = new Ext.data.SimpleStore({
fields: [
{name: 'status', mapping: 3},
{name: 'host', mapping: 1},
{name: 'port', mapping: 2},
{name: 'version', mapping: 4}
],
id: 0
});
var renderHost = function(value, p, r) {
return value + ':' + r.data['port']
}
Deluge.Connections.Grid = new Ext.grid.GridPanel({
store: Deluge.Connections.Store,
columns: [
{header: 'Status', width: 65, sortable: true, renderer: Deluge.Formatters.plain, dataIndex: 'status'},
{id:'host', header: 'Host', width: 150, sortable: true, renderer: renderHost, dataIndex: 'host'},
{header: 'Version', width: 75, sortable: true, renderer: Deluge.Formatters.plain, dataIndex: 'version'}
],
stripeRows: true,
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {'rowselect': Deluge.Connections.onSelect}
}),
autoExpandColumn: 'host',
deferredRender:false,
autoScroll:true,
margins: '0 0 0 0',
bbar: new Ext.Toolbar({
items: [
{
id: 'add',
cls: 'x-btn-text-icon',
text: _('Add'),
icon: '/icons/add.png',
handler: Deluge.Connections.onAdd
}, {
id: 'remove',
cls: 'x-btn-text-icon',
text: _('Remove'),
icon: '/icons/remove.png',
handler: Deluge.Connections.onRemove
}, '->', {
id: 'stop',
cls: 'x-btn-text-icon',
text: _('Stop Daemon'),
icon: '/icons/error.png',
handler: Deluge.Connections.onStop
}
]
})
});
Deluge.Connections.Add = new Ext.Window({
layout: 'fit',
width: 300,
height: 195,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Add Connection'),
iconCls: 'x-deluge-add-window-icon',
items: [new Ext.form.FormPanel({
defaultType: 'textfield',
id: 'connectionAddForm',
baseCls: 'x-plain',
labelWidth: 55,
items: [{
fieldLabel: _('Host'),
id: 'host',
name: 'host',
anchor: '100%',
listeners: {}
},{
fieldLabel: _('Port'),
id: 'port',
xtype: 'uxspinner',
ctCls: 'x-form-uxspinner',
name: 'port',
strategy: Ext.ux.form.Spinner.NumberStrategy(),
value: '58846',
anchor: '50%',
listeners: {}
}, {
fieldLabel: _('Username'),
id: 'username',
name: 'username',
anchor: '100%',
listeners: {}
},{
fieldLabel: _('Password'),
anchor: '100%',
id: '_password',
name: '_password',
inputType: 'password'
}]
})],
buttons: [{
text: _('Close'),
handler: function() {
Deluge.Connections.Add.hide();
}
},{
text: _('Add'),
handler: Deluge.Connections.onAddHost
}],
listeners: {
'hide': Deluge.Connections.onAddWindowHide
}
});
Deluge.Connections.Window = new Ext.Window({
layout: 'fit',
width: 300,
height: 220,
bodyStyle: 'padding: 10px 5px;',
buttonAlign: 'right',
closeAction: 'hide',
closable: true,
plain: true,
title: _('Connection Manager'),
iconCls: 'x-deluge-connect-window-icon',
items: [Deluge.Connections.Grid],
buttons: [{
text: _('Close'),
handler: Deluge.Connections.onClose
},{
text: _('Connect'),
handler: Deluge.Connections.onConnect
}],
listeners: {
'hide': Deluge.Connections.onClose,
'show': Deluge.Connections.onShow
}
});

View File

@ -1,398 +0,0 @@
/*
Script: deluge-preferences.js
Contains the preferences window.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
(function() {
PreferencesWindow = function(config) {
Ext.apply(this, config);
this.layout = 'border';
this.width = 485;
this.height = 500;
this.buttonAlign = 'right';
this.closeAction = 'hide';
this.closable = true;
this.iconCls = 'x-deluge-preferences';
this.plain = true;
this.resizable = false;
this.title = _('Preferences');
this.buttons = [{
text: _('Close'),
handler: this.onCloseButtonClick,
scope: this
},{
text: _('Apply')
},{
text: _('Ok')
}];
this.currentPage = false;
this.items = [{
xtype: 'grid',
region: 'west',
title: _('Categories'),
store: new Ext.data.SimpleStore({
fields: [{name: 'name', mapping: 0}]
}),
columns: [{id: 'name', renderer: fplain, dataIndex: 'name'}],
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {'rowselect': {fn: this.onPageSelect, scope: this}}
}),
hideHeaders: true,
autoExpandColumn: 'name',
deferredRender: false,
autoScroll: true,
margins: '5 0 5 5',
cmargins: '5 0 5 5',
width: 120,
collapsible: true
}, {
region: 'center',
title: ' ',
layout: 'fit',
height: 400,
margins: '5 5 5 5',
cmargins: '5 5 5 5'
}];
PreferencesWindow.superclass.constructor.call(this);
};
Ext.extend(PreferencesWindow, Ext.Window, {
initComponent: function() {
PreferencesWindow.superclass.initComponent.call(this);
this.categoriesGrid = this.items.get(0);
this.configPanel = this.items.get(1);
this.pages = {};
this.on('show', this.onShow.bindWithEvent(this));
},
onCloseButtonClick: function() {
this.hide();
},
addPage: function(name, page) {
var store = this.categoriesGrid.getStore();
store.loadData([[name]], true);
page['bodyStyle'] = 'margin: 5px';
this.pages[name] = this.configPanel.add(page);
this.pages[name].hide();
},
onPageSelect: function(selModel, rowIndex, r) {
if (this.currentPage) {
this.currentPage.hide();
}
var name = r.get('name');
this.pages[name].show();
this.configPanel.setTitle(name);
this.currentPage = this.pages[name];
this.configPanel.doLayout();
},
onShow: function() {
if (!this.categoriesGrid.getSelectionModel().hasSelection()) {
this.categoriesGrid.getSelectionModel().selectFirstRow();
}
}
});
Deluge.Preferences = new PreferencesWindow();
Deluge.Preferences.addPage(_('Downloads'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Folders'),
labelWidth: 140,
defaultType: 'textfield',
autoHeight: true,
items: [{
name: 'download_location',
fieldLabel: _('Download to'),
width: 125
}, {
name: 'move_completed',
fieldLabel: _('Move completed to'),
width: 125
}, {
name: 'copy_torrent_files',
fieldLabel: _('Copy of .torrent files to'),
width: 125
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Allocation'),
autoHeight: true,
labelWidth: 1,
defaultType: 'radio',
items: [{
name: 'compact_allocation',
labelSeparator: '',
boxLabel: _('Compact')
}, {
name: 'compact_allocation',
labelSeparator: '',
boxLabel: _('Full')
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Options'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
name: 'prioritize_first_last',
labelSeparator: '',
boxLabel: _('Prioritize first and last pieces of torrent')
}, {
name: 'add_paused',
labelSeparator: '',
boxLabel: _('Add torrents in Paused state')
}]
}]
});
/*Deluge.Preferences.addPage(_('Network'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});*/
Deluge.Preferences.addPage(_('Bandwidth'), {
border: false,
xtype: 'form',
layout: 'form',
labelWidth: 10,
items: [{
xtype: 'fieldset',
border: false,
title: _('Global Bandwidth Usage'),
autoHeight: true,
labelWidth: 200,
style: 'margin-bottom: 0px; padding-bottom: 0px;',
defaultType: 'uxspinner',
items: [{
name: 'max_connections',
fieldLabel: _('Maximum Connections'),
width: 60,
value: -1
}, {
name: 'max_upload_slots',
fieldLabel: _('Maximum Upload Slots'),
width: 60,
value: -1
}, {
name: 'max_download_speed',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_upload_speed',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_half_open_connections',
fieldLabel: _('Maximum Half-Open Connections'),
width: 60,
value: -1
}, {
name: 'max_connections_per_second',
fieldLabel: _('Maximum Connection Attempts per Second'),
width: 60,
value: -1
}]
}, {
xtype: 'fieldset',
border: false,
title: '',
autoHeight: true,
style: 'padding-top: 0px; margin-top: 0px; margin-bottom: 0px;',
items: [{
xtype: 'checkbox',
name: 'ignore_local',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Ignore limits on local network'),
value: -1
}, {
xtype: 'checkbox',
name: 'limit_ip_overhead',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Rate limit IP overhead'),
value: -1
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Per Torrent Bandwidth Usage'),
autoHeight: true,
labelWidth: 200,
defaultType: 'uxspinner',
items: [{
name: 'max_connections_per_torrent',
fieldLabel: _('Maximum Connections'),
width: 60,
value: -1
}, {
name: 'max_upload_slots_per_torrent',
fieldLabel: _('Maximum Upload Slots'),
width: 60,
value: -1
}, {
name: 'max_download_speed_per_torrent',
fieldLabel: _('Maximum Download Speed (KiB/s)'),
width: 60,
value: -1
}, {
name: 'max_upload_speed_per_torrent',
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
width: 60,
value: -1
}]
}]
});
Deluge.Preferences.addPage(_('Interface'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Window'),
autoHeight: true,
labelWidth: 1,
items: [{
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Show session speed in titlebar'),
id: 'show_session_speed'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Sidebar'),
autoHeight: true,
labelWidth: 1,
items: [{
xtype: 'checkbox',
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Hide filters with zero torrents'),
id: 'hide_sidebar_zero'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Password'),
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'New Password',
inputType: 'password',
id: 'new_password'
}, {
inputType: 'password',
fieldLabel: 'Confirm Password',
id: 'confirm_password'
}]
}]
});
/*Deluge.Preferences.addPage(_('Other'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});*/
Deluge.Preferences.addPage(_('Daemon'), {
border: false,
xtype: 'form',
layout: 'form',
items: [{
xtype: 'fieldset',
border: false,
title: _('Port'),
autoHeight: true,
defaultType: 'uxspinner',
items: [{
fieldLabel: _('Daemon port'),
id: 'daemon_port'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Connections'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Allow Remote Connections'),
id: 'allow_remote'
}]
}, {
xtype: 'fieldset',
border: false,
title: _('Other'),
autoHeight: true,
labelWidth: 1,
defaultType: 'checkbox',
items: [{
fieldLabel: '',
labelSeparator: '',
height: 40,
boxLabel: _('Periodically check the website for new releases'),
id: 'new_releases'
}]
}]
});
/*Deluge.Preferences.addPage(_('Queue'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
Deluge.Preferences.addPage(_('Proxy'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
Deluge.Preferences.addPage(_('Notification'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});
Deluge.Preferences.addPage(_('Plugins'), {
border: false,
xtype: 'form',
layout: 'form',
items: []
});*/
})();

File diff suppressed because one or more lines are too long

View File

@ -1,202 +0,0 @@
/*
Script: deluge.js
Contains the events object, formatters and keys for get_torrent(s)_status.
Copyright:
(C) Damien Churchill 2009 <damoxc@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
*/
var Deluge = {
author: 'Damien Churchill <damoxc@gmail.com>',
version: '1.2-dev'
};
(function() {
var tpl = '<div class="x-progress-wrap x-progress-renderered">' +
'<div class="x-progress-inner">' +
'<div style="width: {2}px" class="x-progress-bar">' +
'<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'<div class="x-progress-text x-progress-text-back">' +
'<div style="width: {1}px;">{0}</div>' +
'</div>' +
'</div>' +
'</div>';
Deluge.progressBar = function(progress, width, text) {
var progressWidth = (width / 100.0) * progress;
var barWidth = progressWidth.toInt() - 1;
var textWidth = ((progressWidth.toInt() - 10) > 0 ? progressWidth.toInt() - 10 : 0);
return String.format(tpl, text, width, barWidth, textWidth);
}
})();
Deluge.Events = {
_events: new Hash(),
fire: function() {
arguments = $A(arguments);
var eventName = arguments.shift();
var eventArgs = arguments;
if (!this._events[eventName]) return;
$each(this._events[eventName], function(fn) {
fn.attempt(eventArgs);
});
},
on: function(eventName, fn) {
var e = $pick(this._events[eventName], new Array());
e.include(fn);
this._events[eventName] = e;
},
removeListener: function(eventName, fn) {
if (!this._events[eventName]) return;
this._events[eventName].remove(fn);
}
};
Deluge.Formatters = {
date: function(timestamp) {
function zeroPad(num, count) {
var numZeropad = num + '';
while (numZeropad.length < count) {
numZeropad = '0' + numZeropad;
}
return numZeropad;
}
timestamp = timestamp * 1000;
var date = new Date(timestamp);
return String.format('{0}/{1}/{2}', zeroPad(date.getDate(), 2), zeroPad(date.getMonth() + 1, 2), date.getFullYear());
},
size: function(bytes) {
bytes = bytes / 1024.0;
if (bytes < 1024) { return bytes.toFixed(1) + ' KiB'; }
else { bytes = bytes / 1024; }
if (bytes < 1024) { return bytes.toFixed(1) + ' MiB'; }
else { bytes = bytes / 1024; }
return bytes.toFixed(1) + ' GiB'
},
speed: function(bits) {
return fsize(bits) + '/s'
},
timeRemaining: function(time) {
if (time == 0) { return '∞' }
if (time < 60) { return time + 's'; }
else { time = time / 60; }
if (time < 60) {
var minutes = Math.floor(time)
var seconds = Math.round(60 * (time - minutes))
if (seconds > 0) {
return minutes + 'm ' + seconds + 's';
} else {
return minutes + 'm'; }
}
else { time = time / 60; }
if (time < 24) {
var hours = Math.floor(time)
var minutes = Math.round(60 * (time - hours))
if (minutes > 0) {
return hours + 'h ' + minutes + 'm';
} else {
return hours + 'h';
}
}
else { time = time / 24; }
var days = Math.floor(time)
var hours = Math.round(24 * (time - days))
if (hours > 0) {
return days + 'd ' + hours + 'h';
} else {
return days + 'd';
}
},
plain: function(value) {
return value;
}
}
// _('Do Not Download')
// _('Normal Priority')
// _('High Priority')
// _('Highest Priority')
FILE_PRIORITY = {
0: 'Do Not Download',
1: 'Normal Priority',
2: 'High Priority',
5: 'Highest Priority',
'Do Not Download': 0,
'Normal Priority': 1,
'High Priority': 2,
'Highest Priority': 5
}
FILE_PRIORITY_CSS = {
0: 'x-no-download',
1: 'x-normal-download',
2: 'x-high-download',
5: 'x-highest-download'
}
var fsize = Deluge.Formatters.size;
var fspeed = Deluge.Formatters.speed;
var ftime = Deluge.Formatters.timeRemaining;
var fdate = Deluge.Formatters.date;
var fplain = Deluge.Formatters.plain;
Deluge.Keys = {
Grid: [
'queue', 'name', 'total_size', 'state', 'progress', 'num_seeds',
'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
'is_auto_managed', 'time_added', 'tracker_host'
],
Status: [
'total_done', 'total_payload_download', 'total_uploaded',
'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
'seed_rank'
],
Files: [
'files', 'file_progress', 'file_priorities'
],
Peers: [
'peers', 'seeds'
],
Details: [
'name', 'save_path', 'total_size', 'num_files', 'tracker_status',
'tracker', 'comment'
],
Options: [
'max_download_speed', 'max_upload_speed', 'max_connections',
'max_upload_slots','is_auto_managed', 'stop_at_ratio', 'stop_ratio',
'remove_at_ratio', 'private', 'prioritize_first_last'
]
};
Deluge.Keys.Status.extend(Deluge.Keys.Grid);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,349 +0,0 @@
//MooTools, <http://mootools.net>, My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var MooTools={version:"1.2.1",build:"0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf"};var Native=function(K){K=K||{};var A=K.name;var I=K.legacy;var B=K.protect;
var C=K.implement;var H=K.generics;var F=K.initialize;var G=K.afterImplement||function(){};var D=F||I;H=H!==false;D.constructor=Native;D.$family={name:"native"};
if(I&&F){D.prototype=I.prototype;}D.prototype.constructor=D;if(A){var E=A.toLowerCase();D.prototype.$family={name:E};Native.typize(D,E);}var J=function(N,L,O,M){if(!B||M||!N.prototype[L]){N.prototype[L]=O;
}if(H){Native.genericize(N,L,B);}G.call(N,L,O);return N;};D.alias=function(N,L,O){if(typeof N=="string"){if((N=this.prototype[N])){return J(this,L,N,O);
}}for(var M in N){this.alias(M,N[M],L);}return this;};D.implement=function(M,L,O){if(typeof M=="string"){return J(this,M,L,O);}for(var N in M){J(this,N,M[N],L);
}return this;};if(C){D.implement(C);}return D;};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments);
return B.prototype[C].apply(D.shift(),D);};}};Native.implement=function(D,C){for(var B=0,A=D.length;B<A;B++){D[B].implement(C);}};Native.typize=function(A,B){if(!A.type){A.type=function(C){return($type(C)===B);
};}};(function(){var A={Array:Array,Date:Date,Function:Function,Number:Number,RegExp:RegExp,String:String};for(var G in A){new Native({name:G,initialize:A[G],protect:true});
}var D={"boolean":Boolean,"native":Native,object:Object};for(var C in D){Native.typize(D[C],C);}var F={Array:["concat","indexOf","join","lastIndexOf","pop","push","reverse","shift","slice","sort","splice","toString","unshift","valueOf"],String:["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]};
for(var E in F){for(var B=F[E].length;B--;){Native.genericize(window[E],F[E][B],true);}}})();var Hash=new Native({name:"Hash",initialize:function(A){if($type(A)=="hash"){A=$unlink(A.getClean());
}for(var B in A){this[B]=A[B];}return this;}});Hash.implement({forEach:function(B,C){for(var A in this){if(this.hasOwnProperty(A)){B.call(C,this[A],A,this);
}}},getClean:function(){var B={};for(var A in this){if(this.hasOwnProperty(A)){B[A]=this[A];}}return B;},getLength:function(){var B=0;for(var A in this){if(this.hasOwnProperty(A)){B++;
}}return B;}});Hash.alias("forEach","each");Array.implement({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);}}});Array.alias("forEach","each");
function $A(C){if(C.item){var D=[];for(var B=0,A=C.length;B<A;B++){D[B]=C[B];}return D;}return Array.prototype.slice.call(C);}function $arguments(A){return function(){return arguments[A];
};}function $chk(A){return !!(A||A===0);}function $clear(A){clearTimeout(A);clearInterval(A);return null;}function $defined(A){return(A!=undefined);}function $each(C,B,D){var A=$type(C);
((A=="arguments"||A=="collection"||A=="array")?Array:Hash).each(C,B,D);}function $empty(){}function $extend(C,A){for(var B in (A||{})){C[B]=A[B];}return C;
}function $H(A){return new Hash(A);}function $lambda(A){return(typeof A=="function")?A:function(){return A;};}function $merge(){var E={};for(var D=0,A=arguments.length;
D<A;D++){var B=arguments[D];if($type(B)!="object"){continue;}for(var C in B){var G=B[C],F=E[C];E[C]=(F&&$type(G)=="object"&&$type(F)=="object")?$merge(F,G):$unlink(G);
}}return E;}function $pick(){for(var B=0,A=arguments.length;B<A;B++){if(arguments[B]!=undefined){return arguments[B];}}return null;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);
}function $splat(B){var A=$type(B);return(A)?((A!="array"&&A!="arguments")?[B]:B):[];}var $time=Date.now||function(){return +new Date;};function $try(){for(var B=0,A=arguments.length;
B<A;B++){try{return arguments[B]();}catch(C){}}return null;}function $type(A){if(A==undefined){return false;}if(A.$family){return(A.$family.name=="number"&&!isFinite(A))?false:A.$family.name;
}if(A.nodeName){switch(A.nodeType){case 1:return"element";case 3:return(/\S/).test(A.nodeValue)?"textnode":"whitespace";}}else{if(typeof A.length=="number"){if(A.callee){return"arguments";
}else{if(A.item){return"collection";}}}}return typeof A;}function $unlink(C){var B;switch($type(C)){case"object":B={};for(var E in C){B[E]=$unlink(C[E]);
}break;case"hash":B=new Hash(C);break;case"array":B=[];for(var D=0,A=C.length;D<A;D++){B[D]=$unlink(C[D]);}break;default:return C;}return B;}var Browser=$merge({Engine:{name:"unknown",version:0},Platform:{name:(window.orientation!=undefined)?"ipod":(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime),query:!!(document.querySelector)},Plugins:{},Engines:{presto:function(){return(!window.opera)?false:((arguments.callee.caller)?960:((document.getElementsByClassName)?950:925));
},trident:function(){return(!window.ActiveXObject)?false:((window.XMLHttpRequest)?5:4);},webkit:function(){return(navigator.taintEnabled)?false:((Browser.Features.xpath)?((Browser.Features.query)?525:420):419);
},gecko:function(){return(document.getBoxObjectFor==undefined)?false:((document.getElementsByClassName)?19:18);}}},Browser||{});Browser.Platform[Browser.Platform.name]=true;
Browser.detect=function(){for(var B in this.Engines){var A=this.Engines[B]();if(A){this.Engine={name:B,version:A};this.Engine[B]=this.Engine[B+A]=true;
break;}}return{name:B,version:A};};Browser.detect();Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");
});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var A=($try(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(A[0]||0+"."+A[1]||0),build:parseInt(A[2]||0)};
})();function $exec(B){if(!B){return B;}if(window.execScript){window.execScript(B);}else{var A=document.createElement("script");A.setAttribute("type","text/javascript");
A[(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerText":"text"]=B;document.head.appendChild(A);document.head.removeChild(A);}return B;}Native.UID=1;
var $uid=(Browser.Engine.trident)?function(A){return(A.uid||(A.uid=[Native.UID++]))[0];}:function(A){return A.uid||(A.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:(Browser.Engine.trident)?null:window.Window,initialize:function(A){$uid(A);
if(!A.Element){A.Element=$empty;if(Browser.Engine.webkit){A.document.createElement("iframe");}A.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};
}A.document.window=A;return $extend(A,Window.Prototype);},afterImplement:function(B,A){window[B]=Window.Prototype[B]=A;}});Window.Prototype={$family:{name:"window"}};
new Window(window);var Document=new Native({name:"Document",legacy:(Browser.Engine.trident)?null:window.Document,initialize:function(A){$uid(A);A.head=A.getElementsByTagName("head")[0];
A.html=A.getElementsByTagName("html")[0];if(Browser.Engine.trident&&Browser.Engine.version<=4){$try(function(){A.execCommand("BackgroundImageCache",false,true);
});}if(Browser.Engine.trident){A.window.attachEvent("onunload",function(){A.window.detachEvent("onunload",arguments.callee);A.head=A.html=A.window=null;
});}return $extend(A,Document.Prototype);},afterImplement:function(B,A){document[B]=Document.Prototype[B]=A;}});Document.Prototype={$family:{name:"document"}};
new Document(document);Array.implement({every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;}}return true;
},filter:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},clean:function(){return this.filter($defined);
},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;}}return -1;},map:function(D,E){var C=[];
for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);}return C;},some:function(C,D){for(var B=0,A=this.length;B<A;B++){if(C.call(D,this[B],B,this)){return true;
}}return false;},associate:function(C){var D={},B=Math.min(this.length,C.length);for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},link:function(C){var A={};
for(var E=0,B=this.length;E<B;E++){for(var D in C){if(C[D](this[E])){A[D]=this[E];delete C[D];break;}}}return A;},contains:function(A,B){return this.indexOf(A,B)!=-1;
},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;
},include:function(A){if(!this.contains(A)){this.push(A);}return this;},combine:function(C){for(var B=0,A=C.length;B<A;B++){this.include(C[B]);}return this;
},erase:function(B){for(var A=this.length;A--;A){if(this[A]===B){this.splice(A,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var D=[];
for(var B=0,A=this.length;B<A;B++){var C=$type(this[B]);if(!C){continue;}D=D.concat((C=="array"||C=="collection"||C=="arguments")?Array.flatten(this[B]):this[B]);
}return D;},hexToRgb:function(B){if(this.length!=3){return null;}var A=this.map(function(C){if(C.length==1){C+=C;}return C.toInt(16);});return(B)?A:"rgb("+A+")";
},rgbToHex:function(D){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;A++){var C=(this[A]-0).toString(16);
B.push((C.length==1)?"0"+C:C);}return(D)?B:"#"+B.join("");}});Function.implement({extend:function(A){for(var B in A){this[B]=A[B];}return this;},create:function(B){var A=this;
B=B||{};return function(D){var C=B.arguments;C=(C!=undefined)?$splat(C):Array.slice(arguments,(B.event)?1:0);if(B.event){C=[D||window.event].extend(C);
}var E=function(){return A.apply(B.bind||null,C);};if(B.delay){return setTimeout(E,B.delay);}if(B.periodical){return setInterval(E,B.periodical);}if(B.attempt){return $try(E);
}return E();};},run:function(A,B){return this.apply(B,$splat(A));},pass:function(A,B){return this.create({bind:B,arguments:A});},bind:function(B,A){return this.create({bind:B,arguments:A});
},bindWithEvent:function(B,A){return this.create({bind:B,arguments:A,event:true});},attempt:function(A,B){return this.create({bind:B,arguments:A,attempt:true})();
},delay:function(B,C,A){return this.create({bind:C,arguments:A,delay:B})();},periodical:function(C,B,A){return this.create({bind:B,arguments:A,periodical:C})();
}});Number.implement({limit:function(B,A){return Math.min(A,Math.max(B,this));},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;},times:function(B,C){for(var A=0;
A<this;A++){B.call(C,A,this);}},toFloat:function(){return parseFloat(this);},toInt:function(A){return parseInt(this,A||10);}});Number.alias("times","each");
(function(B){var A={};B.each(function(C){if(!Number[C]){A[C]=function(){return Math[C].apply(null,[this].concat($A(arguments)));};}});Number.implement(A);
})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);String.implement({test:function(A,B){return((typeof A=="string")?new RegExp(A,B):A).test(this);
},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A="";
var C=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C);
}}return C;},substitute:function(A,B){return this.replace(B||(/\\?\{([^{}]+)\}/g),function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:"";
});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null;
},hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},combine:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C);
},this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null;
},set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this);
return this;},include:function(B,C){var A=this[B];if(A==undefined){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this));
},this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false;
}}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[];
Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(A){var B=[];
Hash.each(this,function(F,E){if(A){E=A+"["+E+"]";}var D;switch($type(F)){case"object":D=Hash.toQueryString(F,E);break;case"array":var C={};F.each(function(H,G){C[G]=H;
});D=Hash.toQueryString(C,E);break;default:D=E+"="+encodeURIComponent(F);}if(F!=undefined){B.push(D);}});return B.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"});
var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;var K=F.document;A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type;
var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;var M=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111;
if(D>0&&D<13){M="f"+D;}}M=M||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){K=(!K.compatMode||K.compatMode=="CSS1Compat")?K.html:K.body;
var I={x:A.pageX||A.clientX+K.scrollLeft,y:A.pageY||A.clientY+K.scrollTop};var C={x:(A.pageX)?A.pageX-F.pageXOffset:A.clientX,y:(A.pageY)?A.pageY-F.pageYOffset:A.clientY};
if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;}var E=(A.which==3)||(A.button==2);var L=null;if(J.match(/over|out/)){switch(J){case"mouseover":L=A.relatedTarget||A.fromElement;
break;case"mouseout":L=A.relatedTarget||A.toElement;}if(!(function(){while(L&&L.nodeType==3){L=L.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){L=false;
}}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:L,target:G,code:B,key:M,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey});
}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault();
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
}else{this.event.returnValue=false;}return this;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(){for(var E in this){if($type(this[E])!="function"){this[E]=$unlink(this[E]);
}}this.constructor=A;if(Class.prototyping){return this;}var D=(this.initialize)?this.initialize.apply(this,arguments):this;if(this.options&&this.options.initialize){this.options.initialize.call(this);
}return D;};for(var C in Class.Mutators){if(!B[C]){continue;}B=Class.Mutators[C](B,B[C]);delete B[C];}$extend(A,this);A.constructor=Class;A.prototype=B;
return A;}});Class.Mutators={Extends:function(C,A){Class.prototyping=A.prototype;var B=new A;delete B.parent;B=Class.inherit(B,C);delete Class.prototyping;
return B;},Implements:function(A,B){$splat(B).each(function(C){Class.prototying=C;$extend(A,($type(C)=="class")?new C:C);delete Class.prototyping;});return A;
}};Class.extend({inherit:function(B,E){var A=arguments.callee.caller;for(var D in E){var C=E[D];var G=B[D];var F=$type(C);if(G&&F=="function"){if(C!=G){if(A){C.__parent=G;
B[D]=C;}else{Class.override(B,D,C);}}}else{if(F=="object"){B[D]=$merge(G,C);}else{B[D]=C;}}}if(A){B.parent=function(){return arguments.callee.caller.__parent.apply(this,arguments);
};}return B;},override:function(B,A,E){var D=Class.prototyping;if(D&&B[A]!=D[A]){D=null;}var C=function(){var F=this.parent;this.parent=D?D[A]:B[A];var G=E.apply(this,arguments);
this.parent=F;return G;};B[A]=C;}});Class.implement({implement:function(){var A=this.prototype;$each(arguments,function(B){Class.inherit(A,B);});return this;
}});var Chain=new Class({$chain:[],chain:function(){this.$chain.extend(Array.flatten(arguments));return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;
},clearChain:function(){this.$chain.empty();return this;}});var Events=new Class({$events:{},addEvent:function(C,B,A){C=Events.removeOn(C);if(B!=$empty){this.$events[C]=this.$events[C]||[];
this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;},fireEvent:function(C,B,A){C=Events.removeOn(C);
if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();},this);return this;},removeEvent:function(B,A){B=Events.removeOn(B);
if(!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;},removeEvents:function(C){if($type(C)=="object"){for(var D in C){this.removeEvent(D,C[D]);
}return this;}if(C){C=Events.removeOn(C);}for(var D in this.$events){if(C&&C!=D){continue;}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]);
}}return this;}});Events.removeOn=function(A){return A.replace(/^on([A-Z])/,function(B,C){return C.toLowerCase();});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));
if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;}this.addEvent(A,this.options[A]);
delete this.options[A];}return this;}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A);
if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){Element.Prototype[A]=B;if(Array[A]){return ;
}Elements.implement(A,function(){var C=[],G=true;for(var E=0,D=this.length;E<D;E++){var F=this[E][A].apply(this[E],arguments);C.push(F);if(G){G=($type(F)=="element");
}}return(G)?new Elements(C):C;});}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var E=Array.link(arguments,{properties:Object.type,iframe:$defined});
var C=E.properties||{};var B=$(E.iframe)||false;var D=C.onload||$empty;delete C.onload;C.id=C.name=$pick(C.id,C.name,B.id,B.name,"IFrame_"+$time());B=new Element(B||"iframe",C);
var A=function(){var F=$try(function(){return B.contentWindow.location.host;});if(F&&F==window.location.host){var G=new Window(B.contentWindow);new Document(B.contentWindow.document);
$extend(G.Element.prototype,Element.Prototype);}D.call(B.contentWindow,B.contentWindow.document);};(window.frames[C.id])?A():B.addListener("load",A);return B;
}});var Elements=new Native({initialize:function(F,B){B=$extend({ddup:true,cash:true},B);F=F||[];if(B.ddup||B.cash){var G={},E=[];for(var C=0,A=F.length;
C<A;C++){var D=$.element(F[C],!B.cash);if(B.ddup){if(G[D.uid]){continue;}G[D.uid]=true;}E.push(D);}F=E;}return(B.cash)?$extend(F,this):F;}});Elements.implement({filter:function(A,B){if(!A){return this;
}return new Elements(Array.filter(this,(typeof A=="string")?function(C){return C.match(A);}:A,B));}});Document.implement({newElement:function(A,B){if(Browser.Engine.trident&&B){["name","type","checked"].each(function(C){if(!B[C]){return ;
}A+=" "+C+'="'+B[C]+'"';if(C!="checked"){delete B[C];}});A="<"+A+">";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A);
},getDocument:function(){return this;},getWindow:function(){return this.window;}});Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B);
return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);}var F=[];var C=Array.flatten(arguments);
for(var D=0,B=C.length;D<B;D++){var E=C[D];switch($type(E)){case"element":F.push(E);break;case"string":F.extend(this.document.getElements(E,true));}}return new Elements(F);
},getDocument:function(){return this.document;},getWindow:function(){return this;}});$.string=function(C,B,A){C=A.getElementById(C);return(C)?$.element(C,B):null;
};$.element=function(A,D){$uid(A);if(!D&&!A.$family&&!(/^object|embed$/i).test(A.tagName)){var B=Element.Prototype;for(var C in B){A[C]=B[C];}}return A;
};$.object=function(B,C,A){if(B.toElement){return $.element(B.toElement(A),C);}return null;};$.textnode=$.whitespace=$.window=$.document=$arguments(0);
Native.implement([Element,Document],{getElement:function(A,B){return $(this.getElements(A,true)[0]||null,B);},getElements:function(A,D){A=A.split(",");
var C=[];var B=(A.length>1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D});
}});(function(){var H={},F={};var I={input:"checked",option:"selected",textarea:(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerHTML":"value"};
var C=function(L){return(F[L]||(F[L]={}));};var G=function(N,L){if(!N){return ;}var M=N.uid;if(Browser.Engine.trident){if(N.clearAttributes){var P=L&&N.cloneNode(false);
N.clearAttributes();if(P){N.mergeAttributes(P);}}else{if(N.removeEvents){N.removeEvents();}}if((/object/i).test(N.tagName)){for(var O in N){if(typeof N[O]=="function"){N[O]=$empty;
}}Element.dispose(N);}}if(!M){return ;}H[M]=F[M]=null;};var D=function(){Hash.each(H,G);if(Browser.Engine.trident){$A(document.getElementsByTagName("object")).each(G);
}if(window.CollectGarbage){CollectGarbage();}H=F=null;};var J=function(N,L,S,M,P,R){var O=N[S||L];var Q=[];while(O){if(O.nodeType==1&&(!M||Element.match(O,M))){if(!P){return $(O,R);
}Q.push(O);}O=O[L];}return(P)?new Elements(Q,{ddup:false,cash:!R}):null;};var E={html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident||(Browser.Engine.webkit&&Browser.Engine.version<420))?"innerText":"textContent"};
var B=["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"];var K=["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];
Hash.extend(E,B.associate(B));Hash.extend(E,K.associate(K.map(String.toLowerCase)));var A={before:function(M,L){if(L.parentNode){L.parentNode.insertBefore(M,L);
}},after:function(M,L){if(!L.parentNode){return ;}var N=L.nextSibling;(N)?L.parentNode.insertBefore(M,N):L.parentNode.appendChild(M);},bottom:function(M,L){L.appendChild(M);
},top:function(M,L){var N=L.firstChild;(N)?L.insertBefore(M,N):L.appendChild(M);}};A.inside=A.bottom;Hash.each(A,function(L,M){M=M.capitalize();Element.implement("inject"+M,function(N){L(this,$(N,true));
return this;});Element.implement("grab"+M,function(N){L($(N,true),this);return this;});});Element.implement({set:function(O,M){switch($type(O)){case"object":for(var N in O){this.set(N,O[N]);
}break;case"string":var L=Element.Properties.get(O);(L&&L.set)?L.set.apply(this,Array.slice(arguments,1)):this.setProperty(O,M);}return this;},get:function(M){var L=Element.Properties.get(M);
return(L&&L.get)?L.get.apply(this,Array.slice(arguments,1)):this.getProperty(M);},erase:function(M){var L=Element.Properties.get(M);(L&&L.erase)?L.erase.apply(this):this.removeProperty(M);
return this;},setProperty:function(M,N){var L=E[M];if(N==undefined){return this.removeProperty(M);}if(L&&B[M]){N=!!N;}(L)?this[L]=N:this.setAttribute(M,""+N);
return this;},setProperties:function(L){for(var M in L){this.setProperty(M,L[M]);}return this;},getProperty:function(M){var L=E[M];var N=(L)?this[L]:this.getAttribute(M,2);
return(B[M])?!!N:(L)?N:N||null;},getProperties:function(){var L=$A(arguments);return L.map(this.getProperty,this).associate(L);},removeProperty:function(M){var L=E[M];
(L)?this[L]=(L&&B[M])?false:"":this.removeAttribute(M);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;
},hasClass:function(L){return this.className.contains(L," ");},addClass:function(L){if(!this.hasClass(L)){this.className=(this.className+" "+L).clean();
}return this;},removeClass:function(L){this.className=this.className.replace(new RegExp("(^|\\s)"+L+"(?:\\s|$)"),"$1");return this;},toggleClass:function(L){return this.hasClass(L)?this.removeClass(L):this.addClass(L);
},adopt:function(){Array.flatten(arguments).each(function(L){L=$(L,true);if(L){this.appendChild(L);}},this);return this;},appendText:function(M,L){return this.grab(this.getDocument().newTextNode(M),L);
},grab:function(M,L){A[L||"bottom"]($(M,true),this);return this;},inject:function(M,L){A[L||"bottom"](this,$(M,true));return this;},replaces:function(L){L=$(L,true);
L.parentNode.replaceChild(this,L);return this;},wraps:function(M,L){M=$(M,true);return this.replaces(M).grab(M,L);},getPrevious:function(L,M){return J(this,"previousSibling",null,L,false,M);
},getAllPrevious:function(L,M){return J(this,"previousSibling",null,L,true,M);},getNext:function(L,M){return J(this,"nextSibling",null,L,false,M);},getAllNext:function(L,M){return J(this,"nextSibling",null,L,true,M);
},getFirst:function(L,M){return J(this,"nextSibling","firstChild",L,false,M);},getLast:function(L,M){return J(this,"previousSibling","lastChild",L,false,M);
},getParent:function(L,M){return J(this,"parentNode",null,L,false,M);},getParents:function(L,M){return J(this,"parentNode",null,L,true,M);},getChildren:function(L,M){return J(this,"nextSibling","firstChild",L,true,M);
},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;},getElementById:function(O,N){var M=this.ownerDocument.getElementById(O);
if(!M){return null;}for(var L=M.parentNode;L!=this;L=L.parentNode){if(!L){return null;}}return $.element(M,N);},getSelected:function(){return new Elements($A(this.options).filter(function(L){return L.selected;
}));},getComputedStyle:function(M){if(this.currentStyle){return this.currentStyle[M.camelCase()];}var L=this.getDocument().defaultView.getComputedStyle(this,null);
return(L)?L.getPropertyValue([M.hyphenate()]):null;},toQueryString:function(){var L=[];this.getElements("input, select, textarea",true).each(function(M){if(!M.name||M.disabled){return ;
}var N=(M.tagName.toLowerCase()=="select")?Element.getSelected(M).map(function(O){return O.value;}):((M.type=="radio"||M.type=="checkbox")&&!M.checked)?null:M.value;
$splat(N).each(function(O){if(typeof O!="undefined"){L.push(M.name+"="+encodeURIComponent(O));}});});return L.join("&");},clone:function(O,L){O=O!==false;
var R=this.cloneNode(O);var N=function(V,U){if(!L){V.removeAttribute("id");}if(Browser.Engine.trident){V.clearAttributes();V.mergeAttributes(U);V.removeAttribute("uid");
if(V.options){var W=V.options,S=U.options;for(var T=W.length;T--;){W[T].selected=S[T].selected;}}}var X=I[U.tagName.toLowerCase()];if(X&&U[X]){V[X]=U[X];
}};if(O){var P=R.getElementsByTagName("*"),Q=this.getElementsByTagName("*");for(var M=P.length;M--;){N(P[M],Q[M]);}}N(R,this);return $(R);},destroy:function(){Element.empty(this);
Element.dispose(this);G(this,true);return null;},empty:function(){$A(this.childNodes).each(function(L){Element.destroy(L);});return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
},hasChild:function(L){L=$(L,true);if(!L){return false;}if(Browser.Engine.webkit&&Browser.Engine.version<420){return $A(this.getElementsByTagName(L.tagName)).contains(L);
}return(this.contains)?(this!=L&&this.contains(L)):!!(this.compareDocumentPosition(L)&16);},match:function(L){return(!L||(L==this)||(Element.get(this,"tag")==L));
}});Native.implement([Element,Window,Document],{addListener:function(O,N){if(O=="unload"){var L=N,M=this;N=function(){M.removeListener("unload",N);L();
};}else{H[this.uid]=this;}if(this.addEventListener){this.addEventListener(O,N,false);}else{this.attachEvent("on"+O,N);}return this;},removeListener:function(M,L){if(this.removeEventListener){this.removeEventListener(M,L,false);
}else{this.detachEvent("on"+M,L);}return this;},retrieve:function(M,L){var O=C(this.uid),N=O[M];if(L!=undefined&&N==undefined){N=O[M]=L;}return $pick(N);
},store:function(M,L){var N=C(this.uid);N[M]=L;return this;},eliminate:function(L){var M=C(this.uid);delete M[L];return this;}});window.addListener("unload",D);
})();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";
}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};Element.Properties.html=(function(){var C=document.createElement("div");
var A={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};
A.thead=A.tfoot=A.tbody;var B={set:function(){var E=Array.flatten(arguments).join("");var F=Browser.Engine.trident&&A[this.get("tag")];if(F){var G=C;G.innerHTML=F[1]+E+F[2];
for(var D=F[0];D--;){G=G.firstChild;}this.empty().adopt(G.childNodes);}else{this.innerHTML=E;}}};B.erase=B.set;return B;})();if(Browser.Engine.webkit&&Browser.Engine.version<420){Element.Properties.text={get:function(){if(this.innerText){return this.innerText;
}var A=this.ownerDocument.newElement("div",{html:this.innerHTML}).inject(this.ownerDocument.body);var B=A.innerText;A.destroy();return B;}};}Element.Properties.events={set:function(A){this.addEvents(A);
}};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this;
}H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J);
}return true;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F];if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow());
if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(C,B){var A=this.retrieve("events");if(!A||!A[C]){return this;
}var F=A[C].keys.indexOf(B);if(F==-1){return this;}A[C].keys.splice(F,1);var E=A[C].values.splice(F,1)[0];var D=Element.Events.get(C);if(D){if(D.onRemove){D.onRemove.call(this,B);
}C=D.base||C;}return(Element.NativeEvents[C])?this.removeListener(C,E):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;
},removeEvents:function(A){if($type(A)=="object"){for(var C in A){this.removeEvent(C,A[C]);}return this;}var B=this.retrieve("events");if(!B){return this;
}if(!A){for(var C in B){this.removeEvents(C);}this.eliminate("events");}else{if(B[A]){while(B[A].keys[0]){this.removeEvent(A,B[A].keys[0]);}B[A]=null;}}return this;
},fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})();
},this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E);
},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
(function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C));
};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});
})();Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";
}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";
}this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true);
},getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat";
}B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E;
}).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity");
case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue;
}for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/);
if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0;
B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px";
}if((Browser.Engine.presto)&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]);
}return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});
Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles;
var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color";
F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(H,I){if(B(this)){this.getWindow().scrollTo(H,I);
}else{this.scrollLeft=H;this.scrollTop=I;}return this;},getSize:function(){if(B(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight};
},getScrollSize:function(){if(B(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(B(this)){return this.getWindow().getScroll();
}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var I=this,H={x:0,y:0};while(I&&!B(I)){H.x+=I.scrollLeft;H.y+=I.scrollTop;I=I.parentNode;
}return H;},getOffsetParent:function(){var H=this;if(B(H)){return null;}if(!Browser.Engine.trident){return H.offsetParent;}while((H=H.parentNode)&&!B(H)){if(D(H,"position")!="static"){return H;
}}return null;},getOffsets:function(){if(Browser.Engine.trident){var L=this.getBoundingClientRect(),J=this.getDocument().documentElement;return{x:L.left+J.scrollLeft-J.clientLeft,y:L.top+J.scrollTop-J.clientTop};
}var I=this,H={x:0,y:0};if(B(this)){return H;}while(I&&!B(I)){H.x+=I.offsetLeft;H.y+=I.offsetTop;if(Browser.Engine.gecko){if(!F(I)){H.x+=C(I);H.y+=G(I);
}var K=I.parentNode;if(K&&D(K,"overflow")!="visible"){H.x+=C(K);H.y+=G(K);}}else{if(I!=this&&Browser.Engine.webkit){H.x+=C(I);H.y+=G(I);}}I=I.offsetParent;
}if(Browser.Engine.gecko&&!F(this)){H.x-=C(this);H.y-=G(this);}return H;},getPosition:function(K){if(B(this)){return{x:0,y:0};}var L=this.getOffsets(),I=this.getScrolls();
var H={x:L.x-I.x,y:L.y-I.y};var J=(K&&(K=$(K)))?K.getPosition():{x:0,y:0};return{x:H.x-J.x,y:H.y-J.y};},getCoordinates:function(J){if(B(this)){return this.getWindow().getCoordinates();
}var H=this.getPosition(J),I=this.getSize();var K={left:H.x,top:H.y,width:I.x,height:I.y};K.right=K.left+K.width;K.bottom=K.top+K.height;return K;},computePosition:function(H){return{left:H.x-E(this,"margin-left"),top:H.y-E(this,"margin-top")};
},position:function(H){return this.setStyles(this.computePosition(H));}});Native.implement([Document,Window],{getSize:function(){var I=this.getWindow();
if(Browser.Engine.presto||Browser.Engine.webkit){return{x:I.innerWidth,y:I.innerHeight};}var H=A(this);return{x:H.clientWidth,y:H.clientHeight};},getScroll:function(){var I=this.getWindow();
var H=A(this);return{x:I.pageXOffset||H.scrollLeft,y:I.pageYOffset||H.scrollTop};},getScrollSize:function(){var I=A(this);var H=this.getSize();return{x:Math.max(I.scrollWidth,H.x),y:Math.max(I.scrollHeight,H.y)};
},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var H=this.getSize();return{top:0,left:0,bottom:H.y,right:H.x,height:H.y,width:H.x};
}});var D=Element.getComputedStyle;function E(H,I){return D(H,I).toInt()||0;}function F(H){return D(H,"-moz-box-sizing")=="border-box";}function G(H){return E(H,"border-top-width");
}function C(H){return E(H,"border-left-width");}function B(H){return(/^(?:body|html)$/i).test(H.tagName);}function A(H){var I=H.getDocument();return(!I.compatMode||I.compatMode=="CSS1Compat")?I.html:I.body;
}})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(",");
var C,E={};for(var D=0,B=H.length;D<B;D++){var A=H[D],F=Selectors.Utils.search(this,A,E);if(D!=0&&F.item){F=$A(F);}C=(D==0)?F:(C.item)?$A(C).concat(F):C.concat(F);
}return new Elements(C,{ddup:(H.length>1),cash:!G});}});Element.implement({match:function(B){if(!B||(B==this)){return true;}var D=Selectors.Utils.parseTagAndID(B);
var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true;
}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};
Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F];
}var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0;
if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"};
break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"};
break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E];
}var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[5],C=D[6],J=D[7];if(I){H.classes.push(I);
}else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B});
}}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null;
}return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false];
},filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length;
D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D];
if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=(B.getElementById)?B.getElementById(D,true):Element.getElementById(B,D,true);
return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(I,H,N){var B=[];var C=H.trim().replace(Selectors.RegExps.splitter,function(Y,X,W){B.push(X);
return":)"+W;}).split(":)");var J,E,U;for(var T=0,P=C.length;T<P;T++){var S=C[T];if(T==0&&Selectors.RegExps.quick.test(S)){J=I.getElementsByTagName(S);
continue;}var A=B[T-1];var K=Selectors.Utils.parseTagAndID(S);var V=K[0],L=K[1];if(T==0){J=Selectors.Utils.getByTagAndID(I,V,L);}else{var D={},G=[];for(var R=0,Q=J.length;
R<Q;R++){G=Selectors.Getters[A](G,J[R],V,L,D);}J=G;}var F=Selectors.Utils.parseSelector(S);if(F){E=[];for(var O=0,M=J.length;O<M;O++){U=J[O];if(Selectors.Utils.filter(U,F,N)){E.push(U);
}}J=E;}}return J;}};Selectors.Getters={" ":function(H,G,I,A,E){var D=Selectors.Utils.getByTagAndID(G,I,A);for(var C=0,B=D.length;C<B;C++){var F=D[C];if(Selectors.Utils.chk(F,E)){H.push(F);
}}return H;},">":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;E<D;E++){var B=C[E];if(B.parentNode==G&&Selectors.Utils.chk(B,F)){H.push(B);
}}return H;},"+":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(Selectors.Utils.chk(B,D)&&Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}break;}}return C;},"~":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(!Selectors.Utils.chk(B,D)){break;}if(Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}}}return C;}};Selectors.Filters={byTag:function(B,A){return(A=="*"||(B.tagName&&B.tagName.toLowerCase()==A));},byID:function(A,B){return(!B||(A.id&&A.id==B));
},byClass:function(B,A){return(B.className&&B.className.contains(A," "));},byPseudo:function(A,D,C,B){return D.call(A,C,B);},byAttribute:function(C,D,B,E){var A=Element.prototype.getProperty.call(C,D);
if(!A){return(B=="!=");}if(!B||E==undefined){return true;}switch(B){case"=":return(A==E);case"*=":return(A.contains(E));case"^=":return(A.substr(0,E.length)==E);
case"$=":return(A.substr(A.length-E.length)==E);case"!=":return(A!=E);case"~=":return A.contains(E," ");case"|=":return A.contains(E,"-");}return false;
}};Selectors.Pseudo=new Hash({checked:function(){return this.checked;},empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(A){return !Element.match(this,A);
},contains:function(A){return(this.innerText||this.textContent||"").contains(A);},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var A=this;
while((A=A.nextSibling)){if(A.nodeType==1){return false;}}return true;},"only-child":function(){var B=this;while((B=B.previousSibling)){if(B.nodeType==1){return false;
}}var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;}}return true;},"nth-child":function(G,E){G=(G==undefined)?"n":G;var C=Selectors.Utils.parseNthArgument(G);
if(C.special!="n"){return Selectors.Pseudo[C.special].call(this,C.a,E);}var F=0;E.positions=E.positions||{};var D=$uid(this);if(!E.positions[D]){var B=this;
while((B=B.previousSibling)){if(B.nodeType!=1){continue;}F++;var A=E.positions[$uid(B)];if(A!=undefined){F=A+F;break;}}E.positions[D]=F;}return(E.positions[D]%C.a==C.b);
},index:function(A){var B=this,C=0;while((B=B.previousSibling)){if(B.nodeType==1&&++C>A){return false;}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A);
},odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);}});Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this);
}}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;window.fireEvent("domready");document.fireEvent("domready");};if(Browser.Engine.trident){var A=document.createElement("div");
(function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();}))?B():arguments.callee.delay(50);})();
}else{if(Browser.Engine.webkit&&Browser.Engine.version<525){(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50);
})();}else{window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}}})();var JSON=new Hash({$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16);
},encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]";
case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);}});return"{"+A+"}";case"number":case"boolean":return String(B);
case false:return"null";}return null;},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;
}return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B;
this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path;
}if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure";
}this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C);
};Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={};
var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments);
};})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J='<object id="'+B+'"';for(var I in H){J+=" "+I+'="'+H[I]+'"';}J+=">";for(var C in E){if(E[C]){J+='<param name="'+C+'" value="'+E[C]+'" />';
}}J+="</object>";this.object=((A)?A.empty():new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A);
return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments));
}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore"},initialize:function(A){this.subject=this.subject||this;
this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();var B=this.options.wait;if(B===false){this.options.link="cancel";
}},getTransition:function(){return function(A){return -(Math.cos(Math.PI*A)-1)/2;};},step:function(){var A=$time();if(A<this.time+this.options.duration){var B=this.transition((A-this.time)/this.options.duration);
this.set(this.compute(this.from,this.to,B));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(A){return A;},compute:function(C,B,A){return Fx.compute(C,B,A);
},check:function(A){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));
return false;}return false;},start:function(B,A){if(!this.check(arguments.callee,B,A)){return this;}this.from=B;this.to=A;this.time=0;this.transition=this.getTransition();
this.startTimer();this.onStart();return this;},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();
}return this;},onStart:function(){this.fireEvent("start",this.subject);},onComplete:function(){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
}},onCancel:function(){this.fireEvent("cancel",this.subject).clearChain();},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();
return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;
}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);return true;}});Fx.compute=function(C,B,A){return(B-C)*A+C;
};Fx.Durations={"short":250,normal:500,"long":1000};Fx.CSS=new Class({Extends:Fx,prepare:function(D,E,B){B=$splat(B);var C=B[1];if(!$chk(C)){B[1]=B[0];
B[0]=D.getStyle(E);}var A=B.map(this.parse);return{from:A[0],to:A[1]};},parse:function(A){A=$lambda(A)();A=(typeof A=="string")?A.split(" "):$splat(A);
return A.map(function(C){C=String(C);var B=false;Fx.CSS.Parsers.each(function(F,E){if(B){return ;}var D=F.parse(C);if($chk(D)){B={value:D,parser:F};}});
B=B||{value:C,parser:Fx.CSS.Parsers.String};return B;});},compute:function(D,C,B){var A=[];(Math.min(D.length,C.length)).times(function(E){A.push({value:D[E].parser.compute(D[E].value,C[E].value,B),parser:D[E].parser});
});A.$family={name:"fx:css:value"};return A;},serve:function(C,B){if($type(C)!="fx:css:value"){C=this.parse(C);}var A=[];C.each(function(D){A=A.concat(D.parser.serve(D.value,B));
});return A;},render:function(A,D,C,B){A.setStyle(D,this.serve(C,B));},search:function(A){if(Fx.CSS.Cache[A]){return Fx.CSS.Cache[A];}var B={};Array.each(document.styleSheets,function(E,D){var C=E.href;
if(C&&C.contains("://")&&!C.contains(document.domain)){return ;}var F=E.rules||E.cssRules;Array.each(F,function(I,G){if(!I.style){return ;}var H=(I.selectorText)?I.selectorText.replace(/^\w+/,function(J){return J.toLowerCase();
}):null;if(!H||!H.test("^"+A+"$")){return ;}Element.Styles.each(function(K,J){if(!I.style[J]||Element.ShortStyles[J]){return ;}K=String(I.style[J]);B[J]=(K.test(/^rgb/))?K.rgbToHex():K;
});});});return Fx.CSS.Cache[A]=B;}});Fx.CSS.Cache={};Fx.CSS.Parsers=new Hash({Color:{parse:function(A){if(A.match(/^#[0-9a-f]{3,6}$/i)){return A.hexToRgb(true);
}return((A=A.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[A[1],A[2],A[3]]:false;},compute:function(C,B,A){return C.map(function(E,D){return Math.round(Fx.compute(C[D],B[D],A));
});},serve:function(A){return A.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(B,A){return(A)?B+A:B;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});
Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(B,A){if(arguments.length==1){A=B;
B=this.property||this.options.property;}this.render(this.element,B,A,this.options.unit);return this;},start:function(C,E,D){if(!this.check(arguments.callee,C,E,D)){return this;
}var B=Array.flatten(arguments);this.property=this.options.property||B.shift();var A=this.prepare(this.element,this.property,B);return this.parent(A.from,A.to);
}});Element.Properties.tween={set:function(A){var B=this.retrieve("tween");if(B){B.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("tween")){if(A||!this.retrieve("tween:options")){this.set("tween",A);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));
}return this.retrieve("tween");}};Element.implement({tween:function(A,C,B){this.get("tween").start(arguments);return this;},fade:function(C){var E=this.get("tween"),D="opacity",A;
C=$pick(C,"toggle");switch(C){case"in":E.start(D,1);break;case"out":E.start(D,0);break;case"show":E.set(D,1);break;case"hide":E.set(D,0);break;case"toggle":var B=this.retrieve("fade:flag",this.get("opacity")==1);
E.start(D,(B)?0:1);this.store("fade:flag",!B);A=true;break;default:E.start(D,arguments);}if(!A){this.eliminate("fade:flag");}return this;},highlight:function(C,A){if(!A){A=this.retrieve("highlight:original",this.getStyle("background-color"));
A=(A=="transparent")?"#fff":A;}var B=this.get("tween");B.start("background-color",C||"#ffff88",A).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
B.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(A){if(typeof A=="string"){A=this.search(A);
}for(var B in A){this.render(this.element,B,A[B],this.options.unit);}return this;},compute:function(E,D,C){var A={};for(var B in E){A[B]=this.parent(E[B],D[B],C);
}return A;},start:function(B){if(!this.check(arguments.callee,B)){return this;}if(typeof B=="string"){B=this.search(B);}var E={},D={};for(var C in B){var A=this.prepare(this.element,C,B[C]);
E[C]=A.from;D[C]=A.to;}return this.parent(E,D);}});Element.Properties.morph={set:function(A){var B=this.retrieve("morph");if(B){B.cancel();}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("morph")){if(A||!this.retrieve("morph:options")){this.set("morph",A);}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));
}return this.retrieve("morph");}};Element.implement({morph:function(A){this.get("morph").start(A);return this;}});Fx.implement({getTransition:function(){var A=this.options.transition||Fx.Transitions.Sine.easeInOut;
if(typeof A=="string"){var B=A.split(":");A=Fx.Transitions;A=A[B[0]]||A[B[0].capitalize()];if(B[1]){A=A["ease"+B[1].capitalize()+(B[2]?B[2].capitalize():"")];
}}return A;}});Fx.Transition=function(B,A){A=$splat(A);return $extend(B,{easeIn:function(C){return B(C,A);},easeOut:function(C){return 1-B(1-C,A);},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;
}});};Fx.Transitions=new Hash({linear:$arguments(0)});Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);}};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);
},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);
},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;1;B+=A,A/=2){if(D>=(7-4*B)/11){C=A*A-Math.pow((11-6*B-11*D)/4,2);
break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);
});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request();
this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ;
}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};
this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300));
},processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts);
},success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B);
return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(A){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));return false;}return false;
},send:function(I){if(!this.check(arguments.callee,I)){return this;}this.running=true;var G=$type(I);if(G=="string"||G=="element"){I={data:I};}var D=this.options;
I=$extend({data:D.data,url:D.url,method:D.method},I);var E=I.data,B=I.url,A=I.method;switch($type(E)){case"element":E=$(E).toQueryString();break;case"object":case"hash":E=Hash.toQueryString(E);
}if(this.options.format){var H="format="+this.options.format;E=(E)?H+"&"+E:H;}if(this.options.emulation&&["put","delete"].contains(A)){var F="_method="+A;
E=(E)?F+"&"+E:F;A="post";}if(this.options.urlEncoded&&A=="post"){var C=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+C);
}if(E&&A=="get"){B=B+(B.contains("?")?"&":"?")+E;E=null;}this.xhr.open(A.toUpperCase(),B,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);
this.headers.each(function(K,J){try{this.xhr.setRequestHeader(J,K);}catch(L){this.fireEvent("exception",[J,K]);}},this);this.fireEvent("request");this.xhr.send(E);
if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;
this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var A={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined});
return this.send($extend(C,{method:B.toLowerCase()}));};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send");
if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A));
},get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options")));
}return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D="<root>"+C+"</root>",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM");
G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length;
F<E;F++){var H=Element.clone(D.childNodes[F],true,true);if(H){A.grab(H);}}return A;})||A.set("html",C);},success:function(D){var C=this.options,B=this.response;
B.html=D.stripScripts(function(E){B.javascript=E;});var A=this.processHTML(B.html);B.tree=A.childNodes;B.elements=A.getElements("*");if(C.filter){B.tree=B.elements.filter(C.filter);
}if(C.update){$(C.update).empty().set("html",B.html);}if(C.evalScripts){$exec(B.javascript);}this.onSuccess(B.tree,B.elements,B.html,B.javascript);}});
Element.Properties.load={set:function(A){var B=this.retrieve("load");if(B){B.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},A));
},get:function(A){if(A||!this.retrieve("load")){if(A||!this.retrieve("load:options")){this.set("load",A);}this.store("load",new Request.HTML(this.retrieve("load:options")));
}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));return this;
}});Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(A){this.parent(A);this.headers.extend({Accept:"application/json","X-Request":"JSON"});
},success:function(A){this.response.json=JSON.decode(A,this.options.secure);this.onSuccess(this.response.json,A);}});

View File

@ -1,364 +0,0 @@
/*
* Mootools Ext Adapter
* Author: christoph.pojer@gmail.com - http://og5.net/christoph
* Last Update: 6 April 2008
* Version: 0.9a
*
* Requires:
* Core, Browser, Array, Function, Number, String, Hash, Event, Class,
* Class.Extras, Element, Element.Event, Element.Style, Element.Dimensions,
* DomReady, Fx, Fx.CSS, Fx.Morph, Fx.Transitions, Request, Fx.Scroll
*
*/
(function(){
Ext.lib.Dom = {
getViewWidth : function(full) {
return document['get'+(full ? 'Scroll' : '')+'Width']();
},
getViewHeight : function(full) {
return document['get'+(full ? 'Scroll' : '')+'Height']();
},
getDocumentHeight: function() {
return document.getScrollHeight();
},
getDocumentWidth: function() {
return document.getScrollWidth();
},
getViewportHeight: function() {
return document.getHeight();
},
getViewportWidth: function() {
return document.getWidth();
},
isAncestor : function(p, c){
return $(p).hasChild(c);
},
getRegion : function(el){
return Ext.lib.Region.getRegion(el);
},
getY : function(el){
return $(el).getTop();
},
getX : function(el){
return $(el).getLeft();
},
getXY : function(el){
return Hash.getValues($(el).getPosition());
},
setXY : function(el, xy){
var pts = Ext.get(el).translatePoints(xy);
Hash.each(pts, function(v, i){
if(!v) return;
$(el).setStyle(i, v+'px');
});
},
setX : function(el, x){
this.setXY(el, [x, false]);
},
setY : function(el, y){
this.setXY(el, [false, y]);
}
};
function getElement(el){
if($type(el)=='object') return new Document(el);
return $(el);
}
Ext.lib.Event = {
getPageX : function(e){
return new Event(e.browserEvent || e).page.x;
},
getPageY : function(e){
return new Event(e.browserEvent || e).page.y;
},
getXY : function(e){
var p = new Event(e.browserEvent || e).page;
return p ? [p.x, p.y] : [0, 0];
},
getTarget : function(e){
return new Event(e.browserEvent || e).target;
},
resolveTextNode: function(node) {
return node && 3 == node.nodeType ? node.parentNode : node;
},
getRelatedTarget: function(e) {
return new Event(e.browserEvent || e).relatedTarget;
},
on: function(el, e, fn){
el = getElement(el);
if(el) el.addListener(e, fn);
},
un: function(el, e, fn){
el = getElement(el);
if(el) el.removeListener(e, fn);
},
purgeElement: function(el){
el = getElement(el);
if(el) el.removeEvents();
},
preventDefault: function(e){
new Event(e.browserEvent || e).preventDefault();
},
stopPropagation: function(e){
new Event(e.browserEvent || e).stopPropagation();
},
stopEvent: function(e){
new Event(e.browserEvent || e).stop();
},
onAvailable: function(id, fn, scope){
if(Browser.loaded) fn.call(scope || window, $(id));
else document.addEvent('domready', fn);
}
};
Ext.lib.Ajax = function(){
var createSuccess = function(cb){
return cb.success ? function(text, xml){
cb.success.call(cb.scope||window, {
responseText: text,
responseXML : xml,
argument: cb.argument
});
} : Ext.emptyFn;
};
var createFailure = function(cb){
return cb.failure ? function(text, xml){
cb.failure.call(cb.scope||window, {
responseText: text,
responseXML : xml,
argument: cb.argument
});
} : Ext.emptyFn;
};
return {
request: function(method, uri, cb, data, options){
var o = {
url: uri,
method: method.toLowerCase(),
data: data || '',
/*timeout: cb.timeout,*/
onSuccess: createSuccess(cb),
onFailure: createFailure(cb)
};
if(options){
if(options.headers)
o.headers = options.headers;
if(options.xmlData){
o.method = 'post';
o.headers = {'Content-type': 'text/xml'};
o.data = options.xmlData;
}
if(options.jsonData){
o.method = 'post';
o.headers = {'Content-type': 'text/javascript'};
o.data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
}
}
new Request(o).send();
},
formRequest: function(form, uri, cb, data, isUpload, sslUri){
new Request({
url: uri,
method: (Ext.getDom(form).method || 'post').toLowerCase(),
data: $(form).toQueryString()+(data?'&'+data:''),
/*timeout: cb.timeout,*/
onSuccess: createSuccess(cb),
onFailure: createFailure(cb)
}).send();
},
isCallInProgress: function(trans){
//still need a way to access the request object.
return false;
},
abort: function(trans){
//like above
return false;
},
serializeForm: function(form){
return $(form.dom || form).toQueryString();
}
};
}();
Ext.lib.Anim = function(){
var createAnim = function(cb, scope){
return {
stop : function(skipToLast){
this.effect.pause();
},
isAnimated : function(){
return !!this.effect.timer;
},
proxyCallback : function(){
Ext.callback(cb, scope);
}
};
};
var transition = function(t){
if(!Fx.Transitions[t]) t = 'linear';
return Fx.Transitions[t];
};
var obj = {
scroll : function(el, args, duration, easing, cb, scope){
var anim = createAnim(cb, scope);
anim.effect = new Fx.Scroll(el, {
duration: duration * 1000,
transisions: transition(easing),
onComplete: anim.proxyCallback
}).start(args);
return anim;
},
run : function(el, args, duration, easing, cb, scope, type){
if(easing=='easeNone') easing = 'linear';
var anim = createAnim(cb, scope);
var style = {};
for(i in args){
if(i=='points'){
var by, p, e = Ext.fly(el, '_animrun');
e.position();
if(by = args[i].by){
var xy = e.getXY();
p = e.translatePoints([xy[0]+by[0], xy[1]+by[1]]);
}else{
p = e.translatePoints(args[i].to);
}
style.left = p.left;
style.top = p.top;
}else{
style[i] = args[i].from ? [args[i].from, args[i].to] : [args[i].to];
}
}
anim.effect = new Fx.Morph(el, {
duration: duration * 1000,
transition: transition(easing),
onComplete: anim.proxyCallback
}).start(style);
return anim;
}
};
return Hash.extend(obj, {
motion: obj.run,
color: obj.run
});
}();
Ext.lib.Region = function(t, r, b, l) {
this.top = t;
this[1] = t;
this.right = r;
this.bottom = b;
this.left = l;
this[0] = l;
};
Ext.lib.Region.prototype = {
contains : function(region) {
return ( region.left >= this.left &&
region.right <= this.right &&
region.top >= this.top &&
region.bottom <= this.bottom );
},
getArea : function() {
return ( (this.bottom - this.top) * (this.right - this.left) );
},
intersect : function(region) {
var t = Math.max( this.top, region.top );
var r = Math.min( this.right, region.right );
var b = Math.min( this.bottom, region.bottom );
var l = Math.max( this.left, region.left );
if (b >= t && r >= l) {
return new Ext.lib.Region(t, r, b, l);
} else {
return null;
}
},
union : function(region) {
var t = Math.min( this.top, region.top );
var r = Math.max( this.right, region.right );
var b = Math.max( this.bottom, region.bottom );
var l = Math.min( this.left, region.left );
return new Ext.lib.Region(t, r, b, l);
},
constrainTo : function(r) {
this.top = this.top.constrain(r.top, r.bottom);
this.bottom = this.bottom.constrain(r.top, r.bottom);
this.left = this.left.constrain(r.left, r.right);
this.right = this.right.constrain(r.left, r.right);
return this;
},
adjust : function(t, l, b, r){
this.top += t;
this.left += l;
this.right += r;
this.bottom += b;
return this;
}
};
Ext.lib.Region.getRegion = function(el) {
var p = Ext.lib.Dom.getXY(el);
var t = p[1];
var r = p[0] + el.offsetWidth;
var b = p[1] + el.offsetHeight;
var l = p[0];
return new Ext.lib.Region(t, r, b, l);
};
Ext.lib.Point = function(x, y) {
if (Ext.isArray(x)) {
y = x[1];
x = x[0];
}
this.x = this.right = this.left = this[0] = x;
this.y = this.top = this.bottom = this[1] = y;
};
Ext.lib.Point.prototype = new Ext.lib.Region();
})();

File diff suppressed because one or more lines are too long

View File

@ -40,7 +40,7 @@ Example:
Returns:
The proxy that can be used to directly call methods on the server.
*/
JSON.RPC = new Class({
RPC = new Class({
Implements: Options,
options: {