work in progress js_uploader plugin, turn java uploader into plugin - not done yet

This commit is contained in:
Friendika 2011-01-26 00:34:39 -08:00
commit 2fc89deaea
68 changed files with 6768 additions and 0 deletions

View file

@ -0,0 +1,24 @@
<?php
function java_upload_photo_post_init(&$a,&$b) {
if($_POST['partitionCount'])
$a->data['java_upload'] = true;
else
$a->data['java_upload'] = false;
}
function java_upload_photo_post_end(&$a,&$b) {
if(x($a->data,'java_upload') && $a->data['java_upload'])
killme();
}

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="fileuploader.css" rel="stylesheet" type="text/css">
<style>
body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}
</style>
</head>
<body>
<p><a href="http://github.com/valums/file-uploader">Back to project page</a></p>
<p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>
<p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>
<div id="file-uploader-demo1">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
<!-- or put a simple form for upload here -->
</noscript>
</div>
<script src="fileuploader.js" type="text/javascript"></script>
<script>
function createUploader(){
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader-demo1'),
action: 'do-nothing.htm',
debug: true
});
}
// in your app create uploader as soon as the DOM is ready
// don't wait for the window to load
window.onload = createUploader;
</script>
</body>
</html>

View file

@ -0,0 +1 @@
{success:true}

View file

@ -0,0 +1,31 @@
.qq-uploader { position:relative; width: 100%;}
.qq-upload-button {
display:block; /* or inline-block */
width: 105px; padding: 7px 0; text-align:center;
background:#880000; border-bottom:1px solid #ddd;color:#fff;
}
.qq-upload-button-hover {background:#cc0000;}
.qq-upload-button-focus {outline:1px dotted black;}
.qq-upload-drop-area {
position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
background:#FF9797; text-align:center;
}
.qq-upload-drop-area span {
display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
}
.qq-upload-drop-area-active {background:#FF7171;}
.qq-upload-list {margin:15px 35px; padding:0; list-style:disc;}
.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px;}
.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
margin-right: 7px;
}
.qq-upload-file {}
.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
.qq-upload-size,.qq-upload-cancel {font-size:11px;}
.qq-upload-failed-text {display:none;}
.qq-upload-fail .qq-upload-failed-text {display:inline;}

View file

@ -0,0 +1,1247 @@
/**
* http://github.com/valums/file-uploader
*
* Multiple file upload component with progress-bar, drag-and-drop.
* © 2010 Andrew Valums ( andrew(at)valums.com )
*
* Licensed under GNU GPL 2 or later, see license.txt.
*/
//
// Helper functions
//
var qq = qq || {};
/**
* Adds all missing properties from second obj to first obj
*/
qq.extend = function(first, second){
for (var prop in second){
first[prop] = second[prop];
}
};
/**
* Searches for a given element in the array, returns -1 if it is not present.
* @param {Number} [from] The index at which to begin the search
*/
qq.indexOf = function(arr, elt, from){
if (arr.indexOf) return arr.indexOf(elt, from);
from = from || 0;
var len = arr.length;
if (from < 0) from += len;
for (; from < len; from++){
if (from in arr && arr[from] === elt){
return from;
}
}
return -1;
};
qq.getUniqueId = (function(){
var id = 0;
return function(){ return id++; };
})();
//
// Events
qq.attach = function(element, type, fn){
if (element.addEventListener){
element.addEventListener(type, fn, false);
} else if (element.attachEvent){
element.attachEvent('on' + type, fn);
}
};
qq.detach = function(element, type, fn){
if (element.removeEventListener){
element.removeEventListener(type, fn, false);
} else if (element.attachEvent){
element.detachEvent('on' + type, fn);
}
};
qq.preventDefault = function(e){
if (e.preventDefault){
e.preventDefault();
} else{
e.returnValue = false;
}
};
//
// Node manipulations
/**
* Insert node a before node b.
*/
qq.insertBefore = function(a, b){
b.parentNode.insertBefore(a, b);
};
qq.remove = function(element){
element.parentNode.removeChild(element);
};
qq.contains = function(parent, descendant){
// compareposition returns false in this case
if (parent == descendant) return true;
if (parent.contains){
return parent.contains(descendant);
} else {
return !!(descendant.compareDocumentPosition(parent) & 8);
}
};
/**
* Creates and returns element from html string
* Uses innerHTML to create an element
*/
qq.toElement = (function(){
var div = document.createElement('div');
return function(html){
div.innerHTML = html;
var element = div.firstChild;
div.removeChild(element);
return element;
};
})();
//
// Node properties and attributes
/**
* Sets styles for an element.
* Fixes opacity in IE6-8.
*/
qq.css = function(element, styles){
if (styles.opacity != null){
if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
}
}
qq.extend(element.style, styles);
};
qq.hasClass = function(element, name){
var re = new RegExp('(^| )' + name + '( |$)');
return re.test(element.className);
};
qq.addClass = function(element, name){
if (!qq.hasClass(element, name)){
element.className += ' ' + name;
}
};
qq.removeClass = function(element, name){
var re = new RegExp('(^| )' + name + '( |$)');
element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
};
qq.setText = function(element, text){
element.innerText = text;
element.textContent = text;
};
//
// Selecting elements
qq.children = function(element){
var children = [],
child = element.firstChild;
while (child){
if (child.nodeType == 1){
children.push(child);
}
child = child.nextSibling;
}
return children;
};
qq.getByClass = function(element, className){
if (element.querySelectorAll){
return element.querySelectorAll('.' + className);
}
var result = [];
var candidates = element.getElementsByTagName("*");
var len = candidates.length;
for (var i = 0; i < len; i++){
if (qq.hasClass(candidates[i], className)){
result.push(candidates[i]);
}
}
return result;
};
/**
* obj2url() takes a json-object as argument and generates
* a querystring. pretty much like jQuery.param()
*
* how to use:
*
* `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
*
* will result in:
*
* `http://any.url/upload?otherParam=value&a=b&c=d`
*
* @param Object JSON-Object
* @param String current querystring-part
* @return String encoded querystring
*/
qq.obj2url = function(obj, temp, prefixDone){
var uristrings = [],
prefix = '&',
add = function(nextObj, i){
var nextTemp = temp
? (/\[\]$/.test(temp)) // prevent double-encoding
? temp
: temp+'['+i+']'
: i;
if ((nextTemp != 'undefined') && (i != 'undefined')) {
uristrings.push(
(typeof nextObj === 'object')
? qq.obj2url(nextObj, nextTemp, true)
: (Object.prototype.toString.call(nextObj) === '[object Function]')
? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
: encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)
);
}
};
if (!prefixDone && temp) {
prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
uristrings.push(temp);
uristrings.push(qq.obj2url(obj));
} else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
// we wont use a for-in-loop on an array (performance)
for (var i = 0, len = obj.length; i < len; ++i){
add(obj[i], i);
}
} else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
// for anything else but a scalar, we will use for-in-loop
for (var i in obj){
add(obj[i], i);
}
} else {
uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
}
return uristrings.join(prefix)
.replace(/^&/, '')
.replace(/%20/g, '+');
};
//
//
// Uploader Classes
//
//
var qq = qq || {};
/**
* Creates upload button, validates upload, but doesn't create file list or dd.
*/
qq.FileUploaderBasic = function(o){
this._options = {
// set to true to see the server response
debug: false,
action: '/server/upload',
params: {},
button: null,
multiple: true,
maxConnections: 3,
// validation
allowedExtensions: [],
sizeLimit: 0,
minSizeLimit: 0,
// events
// return false to cancel submit
onSubmit: function(id, fileName){},
onProgress: function(id, fileName, loaded, total){},
onComplete: function(id, fileName, responseJSON){},
onCancel: function(id, fileName){},
// messages
messages: {
typeError: "{file} has invalid extension. Only {extensions} are allowed.",
sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
emptyError: "{file} is empty, please select files again without it.",
onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
},
showMessage: function(message){
alert(message);
}
};
qq.extend(this._options, o);
// number of files being uploaded
this._filesInProgress = 0;
this._handler = this._createUploadHandler();
if (this._options.button){
this._button = this._createUploadButton(this._options.button);
}
this._preventLeaveInProgress();
};
qq.FileUploaderBasic.prototype = {
setParams: function(params){
this._options.params = params;
},
getInProgress: function(){
return this._filesInProgress;
},
_createUploadButton: function(element){
var self = this;
return new qq.UploadButton({
element: element,
multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
onChange: function(input){
self._onInputChange(input);
}
});
},
_createUploadHandler: function(){
var self = this,
handlerClass;
if(qq.UploadHandlerXhr.isSupported()){
handlerClass = 'UploadHandlerXhr';
} else {
handlerClass = 'UploadHandlerForm';
}
var handler = new qq[handlerClass]({
debug: this._options.debug,
action: this._options.action,
maxConnections: this._options.maxConnections,
onProgress: function(id, fileName, loaded, total){
self._onProgress(id, fileName, loaded, total);
self._options.onProgress(id, fileName, loaded, total);
},
onComplete: function(id, fileName, result){
self._onComplete(id, fileName, result);
self._options.onComplete(id, fileName, result);
},
onCancel: function(id, fileName){
self._onCancel(id, fileName);
self._options.onCancel(id, fileName);
}
});
return handler;
},
_preventLeaveInProgress: function(){
var self = this;
qq.attach(window, 'beforeunload', function(e){
if (!self._filesInProgress){return;}
var e = e || window.event;
// for ie, ff
e.returnValue = self._options.messages.onLeave;
// for webkit
return self._options.messages.onLeave;
});
},
_onSubmit: function(id, fileName){
this._filesInProgress++;
},
_onProgress: function(id, fileName, loaded, total){
},
_onComplete: function(id, fileName, result){
this._filesInProgress--;
if (result.error){
this._options.showMessage(result.error);
}
},
_onCancel: function(id, fileName){
this._filesInProgress--;
},
_onInputChange: function(input){
if (this._handler instanceof qq.UploadHandlerXhr){
this._uploadFileList(input.files);
} else {
if (this._validateFile(input)){
this._uploadFile(input);
}
}
this._button.reset();
},
_uploadFileList: function(files){
for (var i=0; i<files.length; i++){
if ( !this._validateFile(files[i])){
return;
}
}
for (var i=0; i<files.length; i++){
this._uploadFile(files[i]);
}
},
_uploadFile: function(fileContainer){
var id = this._handler.add(fileContainer);
var fileName = this._handler.getName(id);
if (this._options.onSubmit(id, fileName) !== false){
this._onSubmit(id, fileName);
this._handler.upload(id, this._options.params);
}
},
_validateFile: function(file){
var name, size;
if (file.value){
// it is a file input
// get input value and remove path to normalize
name = file.value.replace(/.*(\/|\\)/, "");
} else {
// fix missing properties in Safari
name = file.fileName != null ? file.fileName : file.name;
size = file.fileSize != null ? file.fileSize : file.size;
}
if (! this._isAllowedExtension(name)){
this._error('typeError', name);
return false;
} else if (size === 0){
this._error('emptyError', name);
return false;
} else if (size && this._options.sizeLimit && size > this._options.sizeLimit){
this._error('sizeError', name);
return false;
} else if (size && size < this._options.minSizeLimit){
this._error('minSizeError', name);
return false;
}
return true;
},
_error: function(code, fileName){
var message = this._options.messages[code];
function r(name, replacement){ message = message.replace(name, replacement); }
r('{file}', this._formatFileName(fileName));
r('{extensions}', this._options.allowedExtensions.join(', '));
r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
this._options.showMessage(message);
},
_formatFileName: function(name){
if (name.length > 33){
name = name.slice(0, 19) + '...' + name.slice(-13);
}
return name;
},
_isAllowedExtension: function(fileName){
var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
var allowed = this._options.allowedExtensions;
if (!allowed.length){return true;}
for (var i=0; i<allowed.length; i++){
if (allowed[i].toLowerCase() == ext){ return true;}
}
return false;
},
_formatSize: function(bytes){
var i = -1;
do {
bytes = bytes / 1024;
i++;
} while (bytes > 99);
return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
}
};
/**
* Class that creates upload widget with drag-and-drop and file list
* @inherits qq.FileUploaderBasic
*/
qq.FileUploader = function(o){
// call parent constructor
qq.FileUploaderBasic.apply(this, arguments);
// additional options
qq.extend(this._options, {
element: null,
// if set, will be used instead of qq-upload-list in template
listElement: null,
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
'<div class="qq-upload-button">Upload a file</div>' +
'<ul class="qq-upload-list"></ul>' +
'</div>',
// template for one item in file list
fileTemplate: '<li>' +
'<span class="qq-upload-file"></span>' +
'<span class="qq-upload-spinner"></span>' +
'<span class="qq-upload-size"></span>' +
'<a class="qq-upload-cancel" href="#">Cancel</a>' +
'<span class="qq-upload-failed-text">Failed</span>' +
'</li>',
classes: {
// used to get elements from templates
button: 'qq-upload-button',
drop: 'qq-upload-drop-area',
dropActive: 'qq-upload-drop-area-active',
list: 'qq-upload-list',
file: 'qq-upload-file',
spinner: 'qq-upload-spinner',
size: 'qq-upload-size',
cancel: 'qq-upload-cancel',
// added to list item when upload completes
// used in css to hide progress spinner
success: 'qq-upload-success',
fail: 'qq-upload-fail'
}
});
// overwrite options with user supplied
qq.extend(this._options, o);
this._element = this._options.element;
this._element.innerHTML = this._options.template;
this._listElement = this._options.listElement || this._find(this._element, 'list');
this._classes = this._options.classes;
this._button = this._createUploadButton(this._find(this._element, 'button'));
this._bindCancelEvent();
this._setupDragDrop();
};
// inherit from Basic Uploader
qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
qq.extend(qq.FileUploader.prototype, {
/**
* Gets one of the elements listed in this._options.classes
**/
_find: function(parent, type){
var element = qq.getByClass(parent, this._options.classes[type])[0];
if (!element){
throw new Error('element not found ' + type);
}
return element;
},
_setupDragDrop: function(){
var self = this,
dropArea = this._find(this._element, 'drop');
var dz = new qq.UploadDropZone({
element: dropArea,
onEnter: function(e){
qq.addClass(dropArea, self._classes.dropActive);
e.stopPropagation();
},
onLeave: function(e){
e.stopPropagation();
},
onLeaveNotDescendants: function(e){
qq.removeClass(dropArea, self._classes.dropActive);
},
onDrop: function(e){
dropArea.style.display = 'none';
qq.removeClass(dropArea, self._classes.dropActive);
self._uploadFileList(e.dataTransfer.files);
}
});
dropArea.style.display = 'none';
qq.attach(document, 'dragenter', function(e){
if (!dz._isValidFileDrag(e)) return;
dropArea.style.display = 'block';
});
qq.attach(document, 'dragleave', function(e){
if (!dz._isValidFileDrag(e)) return;
var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
// only fire when leaving document out
if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){
dropArea.style.display = 'none';
}
});
},
_onSubmit: function(id, fileName){
qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
this._addToList(id, fileName);
},
_onProgress: function(id, fileName, loaded, total){
qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
var item = this._getItemByFileId(id);
var size = this._find(item, 'size');
size.style.display = 'inline';
var text;
if (loaded != total){
text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
} else {
text = this._formatSize(total);
}
qq.setText(size, text);
},
_onComplete: function(id, fileName, result){
qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
// mark completed
var item = this._getItemByFileId(id);
qq.remove(this._find(item, 'cancel'));
qq.remove(this._find(item, 'spinner'));
if (result.success){
qq.addClass(item, this._classes.success);
} else {
qq.addClass(item, this._classes.fail);
}
},
_addToList: function(id, fileName){
var item = qq.toElement(this._options.fileTemplate);
item.qqFileId = id;
var fileElement = this._find(item, 'file');
qq.setText(fileElement, this._formatFileName(fileName));
this._find(item, 'size').style.display = 'none';
this._listElement.appendChild(item);
},
_getItemByFileId: function(id){
var item = this._listElement.firstChild;
// there can't be txt nodes in dynamically created list
// and we can use nextSibling
while (item){
if (item.qqFileId == id) return item;
item = item.nextSibling;
}
},
/**
* delegate click event for cancel link
**/
_bindCancelEvent: function(){
var self = this,
list = this._listElement;
qq.attach(list, 'click', function(e){
e = e || window.event;
var target = e.target || e.srcElement;
if (qq.hasClass(target, self._classes.cancel)){
qq.preventDefault(e);
var item = target.parentNode;
self._handler.cancel(item.qqFileId);
qq.remove(item);
}
});
}
});
qq.UploadDropZone = function(o){
this._options = {
element: null,
onEnter: function(e){},
onLeave: function(e){},
// is not fired when leaving element by hovering descendants
onLeaveNotDescendants: function(e){},
onDrop: function(e){}
};
qq.extend(this._options, o);
this._element = this._options.element;
this._disableDropOutside();
this._attachEvents();
};
qq.UploadDropZone.prototype = {
_disableDropOutside: function(e){
// run only once for all instances
if (!qq.UploadDropZone.dropOutsideDisabled ){
qq.attach(document, 'dragover', function(e){
if (e.dataTransfer){
e.dataTransfer.dropEffect = 'none';
e.preventDefault();
}
});
qq.UploadDropZone.dropOutsideDisabled = true;
}
},
_attachEvents: function(){
var self = this;
qq.attach(self._element, 'dragover', function(e){
if (!self._isValidFileDrag(e)) return;
var effect = e.dataTransfer.effectAllowed;
if (effect == 'move' || effect == 'linkMove'){
e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
} else {
e.dataTransfer.dropEffect = 'copy'; // for Chrome
}
e.stopPropagation();
e.preventDefault();
});
qq.attach(self._element, 'dragenter', function(e){
if (!self._isValidFileDrag(e)) return;
self._options.onEnter(e);
});
qq.attach(self._element, 'dragleave', function(e){
if (!self._isValidFileDrag(e)) return;
self._options.onLeave(e);
var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
// do not fire when moving a mouse over a descendant
if (qq.contains(this, relatedTarget)) return;
self._options.onLeaveNotDescendants(e);
});
qq.attach(self._element, 'drop', function(e){
if (!self._isValidFileDrag(e)) return;
e.preventDefault();
self._options.onDrop(e);
});
},
_isValidFileDrag: function(e){
var dt = e.dataTransfer,
// do not check dt.types.contains in webkit, because it crashes safari 4
isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;
// dt.effectAllowed is none in Safari 5
// dt.types.contains check is for firefox
return dt && dt.effectAllowed != 'none' &&
(dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
}
};
qq.UploadButton = function(o){
this._options = {
element: null,
// if set to true adds multiple attribute to file input
multiple: false,
// name attribute of file input
name: 'file',
onChange: function(input){},
hoverClass: 'qq-upload-button-hover',
focusClass: 'qq-upload-button-focus'
};
qq.extend(this._options, o);
this._element = this._options.element;
// make button suitable container for input
qq.css(this._element, {
position: 'relative',
overflow: 'hidden',
// Make sure browse button is in the right side
// in Internet Explorer
direction: 'ltr'
});
this._input = this._createInput();
};
qq.UploadButton.prototype = {
/* returns file input element */
getInput: function(){
return this._input;
},
/* cleans/recreates the file input */
reset: function(){
if (this._input.parentNode){
qq.remove(this._input);
}
qq.removeClass(this._element, this._options.focusClass);
this._input = this._createInput();
},
_createInput: function(){
var input = document.createElement("input");
if (this._options.multiple){
input.setAttribute("multiple", "multiple");
}
input.setAttribute("type", "file");
input.setAttribute("name", this._options.name);
qq.css(input, {
position: 'absolute',
// in Opera only 'browse' button
// is clickable and it is located at
// the right side of the input
right: 0,
top: 0,
fontFamily: 'Arial',
// 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
fontSize: '118px',
margin: 0,
padding: 0,
cursor: 'pointer',
opacity: 0
});
this._element.appendChild(input);
var self = this;
qq.attach(input, 'change', function(){
self._options.onChange(input);
});
qq.attach(input, 'mouseover', function(){
qq.addClass(self._element, self._options.hoverClass);
});
qq.attach(input, 'mouseout', function(){
qq.removeClass(self._element, self._options.hoverClass);
});
qq.attach(input, 'focus', function(){
qq.addClass(self._element, self._options.focusClass);
});
qq.attach(input, 'blur', function(){
qq.removeClass(self._element, self._options.focusClass);
});
// IE and Opera, unfortunately have 2 tab stops on file input
// which is unacceptable in our case, disable keyboard access
if (window.attachEvent){
// it is IE or Opera
input.setAttribute('tabIndex', "-1");
}
return input;
}
};
/**
* Class for uploading files, uploading itself is handled by child classes
*/
qq.UploadHandlerAbstract = function(o){
this._options = {
debug: false,
action: '/upload.php',
// maximum number of concurrent uploads
maxConnections: 999,
onProgress: function(id, fileName, loaded, total){},
onComplete: function(id, fileName, response){},
onCancel: function(id, fileName){}
};
qq.extend(this._options, o);
this._queue = [];
// params for files in queue
this._params = [];
};
qq.UploadHandlerAbstract.prototype = {
log: function(str){
if (this._options.debug && window.console) console.log('[uploader] ' + str);
},
/**
* Adds file or file input to the queue
* @returns id
**/
add: function(file){},
/**
* Sends the file identified by id and additional query params to the server
*/
upload: function(id, params){
var len = this._queue.push(id);
var copy = {};
qq.extend(copy, params);
this._params[id] = copy;
// if too many active uploads, wait...
if (len <= this._options.maxConnections){
this._upload(id, this._params[id]);
}
},
/**
* Cancels file upload by id
*/
cancel: function(id){
this._cancel(id);
this._dequeue(id);
},
/**
* Cancells all uploads
*/
cancelAll: function(){
for (var i=0; i<this._queue.length; i++){
this._cancel(this._queue[i]);
}
this._queue = [];
},
/**
* Returns name of the file identified by id
*/
getName: function(id){},
/**
* Returns size of the file identified by id
*/
getSize: function(id){},
/**
* Returns id of files being uploaded or
* waiting for their turn
*/
getQueue: function(){
return this._queue;
},
/**
* Actual upload method
*/
_upload: function(id){},
/**
* Actual cancel method
*/
_cancel: function(id){},
/**
* Removes element from queue, starts upload of next
*/
_dequeue: function(id){
var i = qq.indexOf(this._queue, id);
this._queue.splice(i, 1);
var max = this._options.maxConnections;
if (this._queue.length >= max){
var nextId = this._queue[max-1];
this._upload(nextId, this._params[nextId]);
}
}
};
/**
* Class for uploading files using form and iframe
* @inherits qq.UploadHandlerAbstract
*/
qq.UploadHandlerForm = function(o){
qq.UploadHandlerAbstract.apply(this, arguments);
this._inputs = {};
};
// @inherits qq.UploadHandlerAbstract
qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
qq.extend(qq.UploadHandlerForm.prototype, {
add: function(fileInput){
fileInput.setAttribute('name', 'qqfile');
var id = 'qq-upload-handler-iframe' + qq.getUniqueId();
this._inputs[id] = fileInput;
// remove file input from DOM
if (fileInput.parentNode){
qq.remove(fileInput);
}
return id;
},
getName: function(id){
// get input value and remove path to normalize
return this._inputs[id].value.replace(/.*(\/|\\)/, "");
},
_cancel: function(id){
this._options.onCancel(id, this.getName(id));
delete this._inputs[id];
var iframe = document.getElementById(id);
if (iframe){
// to cancel request set src to something else
// we use src="javascript:false;" because it doesn't
// trigger ie6 prompt on https
iframe.setAttribute('src', 'javascript:false;');
qq.remove(iframe);
}
},
_upload: function(id, params){
var input = this._inputs[id];
if (!input){
throw new Error('file with passed id was not added, or already uploaded or cancelled');
}
var fileName = this.getName(id);
var iframe = this._createIframe(id);
var form = this._createForm(iframe, params);
form.appendChild(input);
var self = this;
this._attachLoadEvent(iframe, function(){
self.log('iframe loaded');
var response = self._getIframeContentJSON(iframe);
self._options.onComplete(id, fileName, response);
self._dequeue(id);
delete self._inputs[id];
// timeout added to fix busy state in FF3.6
setTimeout(function(){
qq.remove(iframe);
}, 1);
});
form.submit();
qq.remove(form);
return id;
},
_attachLoadEvent: function(iframe, callback){
qq.attach(iframe, 'load', function(){
// when we remove iframe from dom
// the request stops, but in IE load
// event fires
if (!iframe.parentNode){
return;
}
// fixing Opera 10.53
if (iframe.contentDocument &&
iframe.contentDocument.body &&
iframe.contentDocument.body.innerHTML == "false"){
// In Opera event is fired second time
// when body.innerHTML changed from false
// to server response approx. after 1 sec
// when we upload file with iframe
return;
}
callback();
});
},
/**
* Returns json object received by iframe from server.
*/
_getIframeContentJSON: function(iframe){
// iframe.contentWindow.document - for IE<7
var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
response;
this.log("converting iframe's innerHTML to JSON");
this.log("innerHTML = " + doc.body.innerHTML);
try {
response = eval("(" + doc.body.innerHTML + ")");
} catch(err){
response = {};
}
return response;
},
/**
* Creates iframe with unique name
*/
_createIframe: function(id){
// We can't use following code as the name attribute
// won't be properly registered in IE6, and new window
// on form submit will open
// var iframe = document.createElement('iframe');
// iframe.setAttribute('name', id);
var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
// src="javascript:false;" removes ie6 prompt on https
iframe.setAttribute('id', id);
iframe.style.display = 'none';
document.body.appendChild(iframe);
return iframe;
},
/**
* Creates form, that will be submitted to iframe
*/
_createForm: function(iframe, params){
// We can't use the following code in IE6
// var form = document.createElement('form');
// form.setAttribute('method', 'post');
// form.setAttribute('enctype', 'multipart/form-data');
// Because in this case file won't be attached to request
var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
var queryString = qq.obj2url(params, this._options.action);
form.setAttribute('action', queryString);
form.setAttribute('target', iframe.name);
form.style.display = 'none';
document.body.appendChild(form);
return form;
}
});
/**
* Class for uploading files using xhr
* @inherits qq.UploadHandlerAbstract
*/
qq.UploadHandlerXhr = function(o){
qq.UploadHandlerAbstract.apply(this, arguments);
this._files = [];
this._xhrs = [];
// current loaded size in bytes for each file
this._loaded = [];
};
// static method
qq.UploadHandlerXhr.isSupported = function(){
var input = document.createElement('input');
input.type = 'file';
return (
'multiple' in input &&
typeof File != "undefined" &&
typeof (new XMLHttpRequest()).upload != "undefined" );
};
// @inherits qq.UploadHandlerAbstract
qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
qq.extend(qq.UploadHandlerXhr.prototype, {
/**
* Adds file to the queue
* Returns id to use with upload, cancel
**/
add: function(file){
if (!(file instanceof File)){
throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
}
return this._files.push(file) - 1;
},
getName: function(id){
var file = this._files[id];
// fix missing name in Safari 4
return file.fileName != null ? file.fileName : file.name;
},
getSize: function(id){
var file = this._files[id];
return file.fileSize != null ? file.fileSize : file.size;
},
/**
* Returns uploaded bytes for file identified by id
*/
getLoaded: function(id){
return this._loaded[id] || 0;
},
/**
* Sends the file identified by id and additional query params to the server
* @param {Object} params name-value string pairs
*/
_upload: function(id, params){
var file = this._files[id],
name = this.getName(id),
size = this.getSize(id);
this._loaded[id] = 0;
var xhr = this._xhrs[id] = new XMLHttpRequest();
var self = this;
xhr.upload.onprogress = function(e){
if (e.lengthComputable){
self._loaded[id] = e.loaded;
self._options.onProgress(id, name, e.loaded, e.total);
}
};
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
self._onComplete(id, xhr);
}
};
// build query string
params = params || {};
params['qqfile'] = name;
var queryString = qq.obj2url(params, this._options.action);
xhr.open("POST", queryString, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(file);
},
_onComplete: function(id, xhr){
// the request was aborted/cancelled
if (!this._files[id]) return;
var name = this.getName(id);
var size = this.getSize(id);
this._options.onProgress(id, name, size, size);
if (xhr.status == 200){
this.log("xhr - server response received");
this.log("responseText = " + xhr.responseText);
var response;
try {
response = eval("(" + xhr.responseText + ")");
} catch(err){
response = {};
}
this._options.onComplete(id, name, response);
} else {
this._options.onComplete(id, name, {});
}
this._files[id] = null;
this._xhrs[id] = null;
this._dequeue(id);
},
_cancel: function(id){
this._options.onCancel(id, this.getName(id));
this._files[id] = null;
if (this._xhrs[id]){
this._xhrs[id].abort();
this._xhrs[id] = null;
}
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 2 of the License, 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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -0,0 +1,24 @@
File uploader component is licensed under GNU GPL 2 or later, see gpl-2.0.txt.
© 2010 Andrew Valums
This distribution also includes:
server/OctetStreamReader.java
Dual Licensed under the MIT and GPL v.2
jQuery JavaScript Library
http://jquery.com/
Copyright 2010, John Resig
Dual licensed under the MIT or GPL Version 2 licenses.
http://jquery.org/license
Sizzle.js - CSS selector engine used by jQuery
http://sizzlejs.com/
Copyright 2010, The Dojo Foundation
Released under the MIT, BSD, and GPL Licenses.
QUnit - A JavaScript Unit Testing Framework
http://docs.jquery.com/QUnit
Copyright (c) 2009 John Resig, Jörn Zaefferer
Dual licensed under the MIT (MIT-LICENSE.txt)
and GPL (GPL-LICENSE.txt) licenses.

View file

@ -0,0 +1,152 @@
[donation_link]: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=3PMY37SL9L888&lc=US&item_name=JavaScript%20file%20uploader&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
This plugin uses XHR for uploading multiple files with progress-bar in FF3.6+, Safari4+,
Chrome and falls back to hidden iframe based upload in other browsers,
providing good user experience everywhere.
### <a href="http://valums.com/files/2010/file-uploader/demo.htm">Demo</a> [Donate][donation_link] ###
### Features ###
* multiple file select, progress-bar in FF, Chrome, Safari
* drag-and-drop file select in FF, Chrome
* uploads are cancellable
* no external dependencies
* doesn't use Flash
* fully working with https
* keyboard support in FF, Chrome, Safari
* tested in IE7,8; Firefox 3,3.6,4; Safari4,5; Chrome; Opera10.60;
### License ###
This plugin is open sourced under <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPL 2</a> or later.
If this license doesn't suit you mail me at andrew (at) valums.com.
Please [donate][donation_link] if you are willing to support the further development of file upload plugin.
### Known Issues ###
Plugin breaks back button functionality in Opera.
### Getting started ###
The fileuploader.js contains two classes that are meant to be used directly.
If you need a complete upload widget (from demo) to quickly drop
into your current design, use qq.FileUploader.
If you want to customize uploader, by using a different looking file list
or change the behaviour or functionality use qq.FileUploaderBasic.
The difference between them is that qq.FileUploader provides a list of files,
drag-and-drop, but qq.FileUploaderBasic only creates button and handles validation.
Basic uploader is easier extendable, and doesn't limit possible customization.
qq.FileUploader extends qq.FileUploaderBasic, so that all the options present
in the basic uploader also exist in the full widget.
### qq.FileUploader - Setting up full upload widget ###
Include fileuploader.js and fileuploader.css into your page.
Create container element.
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
<!-- or put a simple form for upload here -->
</noscript>
</div>
Initialize uploader when the DOM is ready. Change the action option.
For example ../server/php.php for the default folder structure.
In the server folder you will find examples for different platforms.
If you can't find the one you need, check the readme.txt in the same folder.
var uploader = new qq.FileUploader({
// pass the dom node (ex. $(selector)[0] for jQuery users)
element: document.getElementById('file-uploader'),
// path to server-side upload script
action: '/server/upload'
});
### Options of both classes ###
// url of the server-side upload script, should be on the same domain
action: '/server/upload',
// additional data to send, name-value pairs
params: {},
// validation
// ex. ['jpg', 'jpeg', 'png', 'gif'] or []
allowedExtensions: [],
// each file size limit in bytes
// this option isn't supported in all browsers
sizeLimit: 0, // max size
minSizeLimit: 0, // min size
// set to true to output server response to console
debug: false,
// events
// you can return false to abort submit
onSubmit: function(id, fileName){},
onProgress: function(id, fileName, loaded, total){},
onComplete: function(id, fileName, responseJSON){},
onCancel: function(id, fileName){},
messages: {
// error messages, see qq.FileUploaderBasic for content
},
showMessage: function(message){ alert(message); }
Instance methods
* setParams(newParams)
#### Changing alert/messages to something more user friendly ####
If you limited file types and max size, you will probably want to change the default alert and
messages as you see fit, this is possible using showMessage callback and messages option.
#### Sending additional params ####
To add a parameter that will be passed as a query string with each upload use params option.
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/server-side.upload',
// additional data to send, name-value pairs
params: {
param1: 'value1',
param2: 'value2'
}
});
To change params based on the state of your app, use
uploader.setParams({
anotherParam: 'value'
});
It can be nicely used in onSubmit callback.
#### Troubleshooting ####
If you can't get the uploader to work, please try the following steps
before asking for help.
If the upload doesn't complete, saying failed.
* Set the debug option of the FileUploader to true.
* Open the page where you have a FileUploader.
* Open developer console in your browser.
* Try to upload the file. You should see a server serponse.
It should be {success:true} for completed requests. If it's not,
then you have a problem with your server-side script.
#### Contributors ####
Thanks to everybody who contributed, either by sending bug reports or donating. And special thanks to:
John Yeary
Sidney Maestre
Patrick Pfeiffer
Sean Sandy (SeanJA)
Andy Newby
Ivan Valles

View file

@ -0,0 +1,125 @@
/*
* Copyright 2010 Blue Lotus Software, LLC.
* Copyright 2010 John Yeary <jyeary@bluelotussoftware.com>.
* Copyright 2010 Allan O'Driscoll
*
* Dual Licensed MIT and GPL v.2
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*
* The GNU General Public License (GPL) Version 2, June 1991
* 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; version 2 of the License.
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.bluelotussoftware.apache.commons.fileupload.example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
/**
* Reads an <code>application/octet-stream</code> and writes it to a file.
* @author John Yeary <jyeary@bluelotussoftware.com>
* @author Allan O'Driscoll
* @version 1.0
*/
public class OctetStreamReader extends HttpServlet {
private static final long serialVersionUID = 6748857432950840322L;
private static final String DESTINATION_DIR_PATH = "files";
private static String realPath;
/**
* {@inheritDoc}
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH) + "/";
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
PrintWriter writer = null;
InputStream is = null;
FileOutputStream fos = null;
try {
writer = response.getWriter();
} catch (IOException ex) {
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
}
String filename = request.getHeader("X-File-Name");
try {
is = request.getInputStream();
fos = new FileOutputStream(new File(realPath + filename));
IOUtils.copy(is, fos);
response.setStatus(response.SC_OK);
writer.print("{success: true}");
} catch (FileNotFoundException ex) {
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
writer.print("{success: false}");
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
} catch (IOException ex) {
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
writer.print("{success: false}");
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
} finally {
try {
fos.close();
is.close();
} catch (IOException ignored) {
}
}
writer.flush();
writer.close();
}
}

View file

@ -0,0 +1 @@
<!--- AJAX FileUploader for ColdFusion version: 1.1.1 feedback: sid.maestre@designovermatter.com -----------update history---------------- 1.1.1 on 9/30/2010 by Martin Webb <martin[at]cubicstate.com> - Change function for Upload to returnformat equals JSON - local var scoping. 1.1 on 9/9/2010 by Sid Maestre - Split Upload function to handle fallback uploads for browsers that don't support XHR data transfer ---> <cfcomponent hint="I handle AJAX File Uploads from Valum's AJAX file uploader library"> <cffunction name="Upload" access="remote" output="false" returntype="any" returnformat="JSON"> <cfargument name="qqfile" type="string" required="true"> <cfset var local = structNew()> <cfset local.response = structNew()> <cfset local.requestData = GetHttpRequestData()> <!--- check if XHR data exists ---> <cfif len(local.requestData.content) GT 0> <cfset local.response = UploadFileXhr(arguments.qqfile, local.requestData.content)> <cfelse> <!--- no XHR data process as standard form submission ---> <cffile action="upload" fileField="arguments.qqfile" destination="#ExpandPath('.')#" nameConflict="makeunique"> <cfset local.response['success'] = true> <cfset local.response['type'] = 'form'> </cfif> <cfreturn local.response> </cffunction> <cffunction name="UploadFileXhr" access="private" output="false" returntype="struct"> <cfargument name="qqfile" type="string" required="true"> <cfargument name="content" type="any" required="true"> <cfset var local = structNew()> <cfset local.response = structNew()> <!--- write the contents of the http request to a file. The filename is passed with the qqfile variable ---> <cffile action="write" file="#ExpandPath('.')#/#arguments.qqfile#" output="#arguments.content#"> <!--- if you want to return some JSON you can do it here. I'm just passing a success message ---> <cfset local.response['success'] = true> <cfset local.response['type'] = 'xhr'> <cfreturn local.response> </cffunction> </cfcomponent>

View file

@ -0,0 +1 @@
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="fileuploader.css" rel="stylesheet" type="text/css"> <style> body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;} </style> </head> <body > <h1>ColdFusion File Uploader Demo</h1> <p><a href="http://github.com/valums/file-uploader">Back to project page</a></p> <p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p> <p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p> <div id="file-uploader-demo1"> <noscript> <p>Please enable JavaScript to use file uploader.</p> <!-- or put a simple form for upload here --> </noscript> </div> <script src="fileuploader.js" type="text/javascript"></script> <script> function createUploader(){ var uploader = new qq.FileUploader({ element: document.getElementById('file-uploader-demo1'), action: '/valums/server/coldfusion.cfc', params: {method: 'Upload'} }); } // in your app create uploader as soon as the DOM is ready // don't wait for the window to load window.onload = createUploader; </script> </body> </html>

View file

@ -0,0 +1,9 @@
Coldfusion example by Sidney Maestre
http://www.designovermatter.com/post.cfm/ajax-file-uploader-for-coldfusion
1. Unzip Andrew's AJAX Uploader into your web root.
2. Replace the demo.htm with demo.cfm in the "client" folder
3. Place coldfusion.cfc in the "server" folder
4. Browse to the demo.cfm file and try it out. The file should be written to the "server" folder.
Questions? You can contact Sidney Maestreme by mail (sid.maestre(at)designovermatter.com) or Twitter @SidneyAllen

View file

@ -0,0 +1,62 @@
#!/usr/bin/perl
use strict;
use CGI::Carp qw(fatalsToBrowser);
use Digest::MD5;
my $uploaddir = '/folder/to/save/in/ajax_upload/tmp_uploads';
my $maxFileSize = 0.5 * 1024 * 1024; # 1/2mb max file size...
use CGI;
my $IN = new CGI;
my $file = $IN->param('POSTDATA');
my $temp_id = $IN->param('temp_id');
# make a random filename, and we guess the file type later on...
my $name = Digest::MD5::md5_base64( rand );
$name =~ s/\+/_/g;
$name =~ s/\//_/g;
my $type;
if ($file =~ /^GIF/) {
$type = "gif";
} elsif ($file =~ /PNG/) {
$type = "png";
} elsif ($file =~ /JFIF/) {
$type = "jpg";
}
if (!$type) {
print qq|{ "success": false, "error": "Invalid file type..." }|;
print STDERR "file has been NOT been uploaded... \n";
}
print STDERR "Making dir: $uploaddir/$temp_id \n";
mkdir("$uploaddir/$temp_id");
open(WRITEIT, ">$uploaddir/$name.$type") or die "Cant write to $uploaddir/$name.$type. Reason: $!";
print WRITEIT $file;
close(WRITEIT);
my $check_size = -s "$uploaddir/$name.$type";
print STDERR qq|Main filesize: $check_size Max Filesize: $maxFileSize \n\n|;
print $IN->header();
if ($check_size < 1) {
print STDERR "ooops, its empty - gonna get rid of it!\n";
print qq|{ "success": false, "error": "File is empty..." }|;
print STDERR "file has been NOT been uploaded... \n";
} elsif ($check_size > $maxFileSize) {
print STDERR "ooops, its too large - gonna get rid of it!\n";
print qq|{ "success": false, "error": "File is too large..." }|;
print STDERR "file has been NOT been uploaded... \n";
} else {
print qq|{ "success": true }|;
print STDERR "file has been successfully uploaded... thank you.\n";
}

View file

@ -0,0 +1,162 @@
<?php
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 10485760;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
if (!is_writable($uploadDirectory)){
return array('error' => "Server error. Upload directory isn't writable.");
}
if (!$this->file){
return array('error' => 'No files were uploaded.');
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large');
}
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'];
//$filename = md5(uniqid());
$ext = $pathinfo['extension'];
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
return array('success'=>true);
} else {
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
}
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 10 * 1024 * 1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

View file

@ -0,0 +1,18 @@
The server-side code should consist of two parts.
1. For IE6-8, Opera, older versions of other browsers you get the file as
you normally do with regular form-base uploads.
2. For browsers which upload file with progress bar, you will need to get the raw
post data and write it to the file.
## Return values ##
You should return json as a text/html, and escape all
'<' as '&lt;', '>' as '&gt;', and '&' as '&amp;'.
Return
{"success":true} when upload was successful
{"error":"error message to display"} in case of error
Send me a mail to andrew (at) valums.com, if you will have any questions.

View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -0,0 +1,46 @@
<?php
usleep(100000);
$fileName;
$fileSize;
if (isset($_GET['qqfile'])){
$fileName = $_GET['qqfile'];
// xhr request
$headers = apache_request_headers();
$fileSize = (int)$headers['Content-Length'];
} elseif (isset($_FILES['qqfile'])){
$fileName = basename($_FILES['qqfile']['name']);
$fileSize = $_FILES['qqfile']['size'];
} else {
die ('{error: "server-error file not passed"}');
}
if ($fileName == '4text.txt'){
die ('jsgkdfgu4eyij');
}
if ($fileSize == 0){
die ('{error: "server-error file size is zero"}');
}
if ($fileSize < 10){
die ('{error: "server-error file size is smaller than 10 bytes"}');
}
if ($fileSize > 9 * 1024){
die ('{error: "server-error file size is bigger than 9kB"}');
}
if (count($_GET)){
array_merge($_GET, array('fileName'=>$fileName));
$response = array_merge($_GET, array('success'=>true, 'fileName'=>$fileName));
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($response), ENT_NOQUOTES);
} else {
die ('{error: "server-error query params not passed"}');
}

View file

@ -0,0 +1,31 @@
<?php
sleep(4);
$fileName;
if (isset($_GET['qqfile'])){
$fileName = $_GET['qqfile'];
// xhr request
$headers = apache_request_headers();
if ((int)$headers['Content-Length'] == 0){
die ('{error: "content length is zero"}');
}
} elseif (isset($_FILES['qqfile'])){
$fileName = basename($_FILES['qqfile']['name']);
// form request
if ($_FILES['qqfile']['size'] == 0){
die ('{error: "file size is zero"}');
}
} else {
die ('{error: "file not passed"}');
}
if (count($_GET)){
$_GET['success'] = true;
echo json_encode(array_merge($_GET));
} else {
die ('{error: "query params not passed"}');
}

View file

@ -0,0 +1,31 @@
<?php
usleep(300);
$fileName;
if (isset($_GET['qqfile'])){
$fileName = $_GET['qqfile'];
// xhr request
$headers = apache_request_headers();
if ((int)$headers['Content-Length'] == 0){
die ('{error: "content length is zero"}');
}
} elseif (isset($_FILES['qqfile'])){
$fileName = basename($_FILES['qqfile']['name']);
// form request
if ($_FILES['qqfile']['size'] == 0){
die ('{error: "file size is zero"}');
}
} else {
die ('{error: "file not passed"}');
}
if (count($_GET)){
//return query params
echo json_encode(array_merge($_GET, array('fileName'=>$fileName)));
} else {
die ('{error: "query params not passed"}');
}

View file

@ -0,0 +1,2 @@
<?php
sleep(9);

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Drag multiple files into input field. (Win7)</p>
<p>Result: One file is selected multiple times. Expected: Multiple files are selected.</p>
<input type="file" multiple></body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
window.addEventListener('load', function(){
document.addEventListener('dragenter', function(e){
e.preventDefault();
},false);
document.addEventListener('dragover', function(e){
e.preventDefault();
// e.dataTransfer.effectAllowed is none
e.dataTransfer.dropEffect = 'copy';
},false);
},false);
</script>
</html>

View file

@ -0,0 +1 @@
<?php header('Content-type: application/javascript'); ?>

View file

@ -0,0 +1 @@
<?php header('Content-type: application/json'); ?>

View file

@ -0,0 +1,2 @@
<?php header("HTTP/1.0 404 Not Found"); ?>
Not found!

View file

@ -0,0 +1 @@
I'm a page.

View file

@ -0,0 +1,6 @@
<?php
header('Content-type: text/html');
$data = str_repeat("a", 5000);
echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);

View file

@ -0,0 +1,7 @@
<?php
header('Content-type: text/html');
$data = array(
'example' => "&a<computer networks>, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
'sub' => array('arr'=>array(10,20,30), 'boo'=>false)
);
echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);

View file

@ -0,0 +1 @@
<?php header('Content-type: text/javascript'); ?>

View file

@ -0,0 +1,2 @@
<?php header('Content-type: text/plain'); ?>
text<p>P tag</p>

View file

@ -0,0 +1,154 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

View file

@ -0,0 +1,200 @@
/*!
* jQuery UI 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI
*/
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.4",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,
b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,
CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable",
"off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=
parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+
b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==
b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
;/*!
* jQuery UI Widget 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Widget
*/
(function(b,j){var k=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return k.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);
b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):
this.each(function(){var g=b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});
this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}b.each(d,function(f,
h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=
b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
;/*!
* jQuery UI Mouse 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Mouse
*
* Depends:
* jquery.ui.widget.js
*/
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
;/*
* jQuery UI Position 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Position
*/
(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h=
0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+=
g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k,
elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"?
-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position=
"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);
;/*
* jQuery UI Draggable 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Draggables
*
* Depends:
* jquery.ui.core.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
*/
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,
b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&
a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),
10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():
f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+
this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+
Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-
this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=
this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.4"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");
if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;
c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=
1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;
this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=
this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=
d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;
if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!=
"HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-
b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&
o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=
p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&
(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
;/*
* jQuery UI Resizable 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Resizables
*
* Depends:
* jquery.ui.core.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
*/
(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
{version:"1.8.4"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
;/*
* jQuery UI Dialog 1.8.4
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Dialog
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.button.js
* jquery.ui.draggable.js
* jquery.ui.mouse.js
* jquery.ui.position.js
* jquery.ui.resizable.js
*/
(function(c,j){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");
if(typeof this.originalTitle!=="string")this.originalTitle="";var a=this,b=a.options,d=b.title||a.originalTitle||"&#160;",f=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(i){a.moveToTop(false,
i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var e=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);
return false}).appendTo(e);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",f).html(d).prependTo(e);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;e.find("*").add(e).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&
g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");
b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,f=d.options;if(f.modal&&!a||!f.stack&&!f.modal)return d._trigger("focus",b);if(f.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=
f.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);
a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(f){if(f.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),e=g.filter(":first");g=g.filter(":last");if(f.target===g[0]&&!f.shiftKey){e.focus(1);return false}else if(f.target===e[0]&&f.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,
f=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(e,h){e=c('<button type="button"></button>').text(e).click(function(){h.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&e.button()});f.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(e){return{position:e.position,
offset:e.offset}}var b=this,d=b.options,f=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(e,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",e,a(h))},drag:function(e,h){b._trigger("drag",e,a(h))},stop:function(e,h){d.position=[h.position.left-f.scrollLeft(),h.position.top-f.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);
b._trigger("dragStop",e,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}a=a===j?this.options.resizable:a;var d=this,f=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:d._minHeight(),
handles:a,start:function(e,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",e,b(h))},resize:function(e,h){d._trigger("resize",e,b(h))},stop:function(e,h){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();d._trigger("resizeStop",e,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,
a.height)},_position:function(a){var b=[],d=[0,0],f;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,e){if(+b[g]===b[g]){d[g]=b[g];b[g]=e}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a);
f||this.uiDialog.hide()},_setOption:function(a,b){var d=this,f=d.uiDialog,g=f.is(":data(resizable)"),e=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);e=true;break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":f.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case "draggable":b?
d._makeDraggable():f.draggable("destroy");break;case "height":e=true;break;case "maxHeight":g&&f.resizable("option","maxHeight",b);e=true;break;case "maxWidth":g&&f.resizable("option","maxWidth",b);e=true;break;case "minHeight":g&&f.resizable("option","minHeight",b);e=true;break;case "minWidth":g&&f.resizable("option","minWidth",b);e=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&f.resizable("destroy");g&&typeof b==="string"&&f.resizable("option","handles",b);!g&&b!==false&&
d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break;case "width":e=true;break}c.Widget.prototype._setOption.apply(d,arguments);e&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-
b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.4",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,
function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
;

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -0,0 +1,334 @@
/*
* jQuery UI CSS Framework @VERSION
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
.ui-helper-clearfix { display: inline-block; }
/* required comment for clearfix to work in Opera \*/
* html .ui-helper-clearfix { height:1%; }
.ui-helper-clearfix { display:block; }
/* end clearfix */
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*
* jQuery UI CSS Framework @VERSION
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
*/
/* Component containers
----------------------------------*/
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
.ui-widget-content a { color: #333333; }
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
.ui-widget-header a { color: #ffffff; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
.ui-widget :active { outline: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
/* Overlays */
.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
* jQuery UI Resizable @VERSION
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Resizable#theming
*/
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
* jQuery UI Dialog @VERSION
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Dialog#theming
*/
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }

View file

@ -0,0 +1,21 @@
{
"name": "qunit",
"author": {
"name": "John Resig",
"email": "jeresig@gmail.com",
"url": "http://ejohn.org/"
},
"maintainer": {
"name": "Jörn Zaefferer",
"email": "joern.zaefferer@googlemail.com",
"url": "http://bassistance.de/"
},
"url": "http://docs.jquery.com/QUnit",
"license": {
"name": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.php"
},
"description": "An easy-to-use JavaScript Unit Testing framework.",
"keywords": [ "testing", "unit", "jquery" ],
"lib": "qunit"
}

View file

@ -0,0 +1,119 @@
ol#qunit-tests {
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
margin:0;
padding:0;
list-style-position:inside;
font-size: smaller;
}
ol#qunit-tests li{
padding:0.4em 0.5em 0.4em 2.5em;
border-bottom:1px solid #fff;
font-size:small;
list-style-position:inside;
}
ol#qunit-tests li ol{
box-shadow: inset 0px 2px 13px #999;
-moz-box-shadow: inset 0px 2px 13px #999;
-webkit-box-shadow: inset 0px 2px 13px #999;
margin-top:0.5em;
margin-left:0;
padding:0.5em;
background-color:#fff;
border-radius:15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
}
ol#qunit-tests li li{
border-bottom:none;
margin:0.5em;
background-color:#fff;
list-style-position: inside;
padding:0.4em 0.5em 0.4em 0.5em;
}
ol#qunit-tests li li.pass{
border-left:26px solid #C6E746;
background-color:#fff;
color:#5E740B;
}
ol#qunit-tests li li.fail{
border-left:26px solid #EE5757;
background-color:#fff;
color:#710909;
}
ol#qunit-tests li.pass{
background-color:#D2E0E6;
color:#528CE0;
}
ol#qunit-tests li.fail{
background-color:#EE5757;
color:#000;
}
ol#qunit-tests li strong {
cursor:pointer;
}
h1#qunit-header{
background-color:#0d3349;
margin:0;
padding:0.5em 0 0.5em 1em;
color:#fff;
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
border-top-right-radius:15px;
border-top-left-radius:15px;
-moz-border-radius-topright:15px;
-moz-border-radius-topleft:15px;
-webkit-border-top-right-radius:15px;
-webkit-border-top-left-radius:15px;
text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
}
h2#qunit-banner{
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
height:5px;
margin:0;
padding:0;
}
h2#qunit-banner.qunit-pass{
background-color:#C6E746;
}
h2#qunit-banner.qunit-fail, #qunit-testrunner-toolbar {
background-color:#EE5757;
}
#qunit-testrunner-toolbar {
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
padding:0;
/*width:80%;*/
padding:0em 0 0.5em 2em;
font-size: small;
}
h2#qunit-userAgent {
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
background-color:#2b81af;
margin:0;
padding:0;
color:#fff;
font-size: small;
padding:0.5em 0 0.5em 2.5em;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
p#qunit-testresult{
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
margin:0;
font-size: small;
color:#2b81af;
border-bottom-right-radius:15px;
border-bottom-left-radius:15px;
-moz-border-radius-bottomright:15px;
-moz-border-radius-bottomleft:15px;
-webkit-border-bottom-right-radius:15px;
-webkit-border-bottom-left-radius:15px;
background-color:#D2E0E6;
padding:0.5em 0.5em 0.5em 2.5em;
}
strong b.fail{
color:#710909;
}
strong b.pass{
color:#5E740B;
}

View file

@ -0,0 +1,1069 @@
/*
* QUnit - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2009 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*/
(function(window) {
var QUnit = {
// Initialize the configuration options
init: function() {
config = {
stats: { all: 0, bad: 0 },
moduleStats: { all: 0, bad: 0 },
started: +new Date,
updateRate: 1000,
blocking: false,
autorun: false,
assertions: [],
filters: [],
queue: []
};
var tests = id("qunit-tests"),
banner = id("qunit-banner"),
result = id("qunit-testresult");
if ( tests ) {
tests.innerHTML = "";
}
if ( banner ) {
banner.className = "";
}
if ( result ) {
result.parentNode.removeChild( result );
}
},
// call on start of module test to prepend name to all tests
module: function(name, testEnvironment) {
config.currentModule = name;
synchronize(function() {
if ( config.currentModule ) {
QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
}
config.currentModule = name;
config.moduleTestEnvironment = testEnvironment;
config.moduleStats = { all: 0, bad: 0 };
QUnit.moduleStart( name, testEnvironment );
});
},
asyncTest: function(testName, expected, callback) {
if ( arguments.length === 2 ) {
callback = expected;
expected = 0;
}
QUnit.test(testName, expected, callback, true);
},
test: function(testName, expected, callback, async) {
var name = testName, testEnvironment, testEnvironmentArg;
if ( arguments.length === 2 ) {
callback = expected;
expected = null;
}
// is 2nd argument a testEnvironment?
if ( expected && typeof expected === 'object') {
testEnvironmentArg = expected;
expected = null;
}
if ( config.currentModule ) {
name = config.currentModule + " module: " + name;
}
if ( !validTest(name) ) {
return;
}
synchronize(function() {
QUnit.testStart( testName );
testEnvironment = extend({
setup: function() {},
teardown: function() {}
}, config.moduleTestEnvironment);
if (testEnvironmentArg) {
extend(testEnvironment,testEnvironmentArg);
}
// allow utility functions to access the current test environment
QUnit.current_testEnvironment = testEnvironment;
config.assertions = [];
config.expected = expected;
try {
if ( !config.pollution ) {
saveGlobal();
}
testEnvironment.setup.call(testEnvironment);
} catch(e) {
QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
}
if ( async ) {
QUnit.stop();
}
try {
callback.call(testEnvironment);
} catch(e) {
fail("Test " + name + " died, exception and test follows", e, callback);
QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
// else next test will carry the responsibility
saveGlobal();
// Restart the tests if they're blocking
if ( config.blocking ) {
start();
}
}
});
synchronize(function() {
try {
checkPollution();
testEnvironment.teardown.call(testEnvironment);
} catch(e) {
QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
}
try {
QUnit.reset();
} catch(e) {
fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
}
if ( config.expected && config.expected != config.assertions.length ) {
QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
}
var good = 0, bad = 0,
tests = id("qunit-tests");
config.stats.all += config.assertions.length;
config.moduleStats.all += config.assertions.length;
if ( tests ) {
var ol = document.createElement("ol");
ol.style.display = "none";
for ( var i = 0; i < config.assertions.length; i++ ) {
var assertion = config.assertions[i];
var li = document.createElement("li");
li.className = assertion.result ? "pass" : "fail";
li.appendChild(document.createTextNode(assertion.message || "(no message)"));
ol.appendChild( li );
if ( assertion.result ) {
good++;
} else {
bad++;
config.stats.bad++;
config.moduleStats.bad++;
}
}
var b = document.createElement("strong");
b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>";
addEvent(b, "click", function() {
var next = b.nextSibling, display = next.style.display;
next.style.display = display === "none" ? "block" : "none";
});
addEvent(b, "dblclick", function(e) {
var target = e && e.target ? e.target : window.event.srcElement;
if ( target.nodeName.toLowerCase() === "strong" ) {
var text = "", node = target.firstChild;
while ( node.nodeType === 3 ) {
text += node.nodeValue;
node = node.nextSibling;
}
text = text.replace(/(^\s*|\s*$)/g, "");
if ( window.location ) {
window.location.href = window.location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent(text);
}
}
});
var li = document.createElement("li");
li.className = bad ? "fail" : "pass";
li.appendChild( b );
li.appendChild( ol );
tests.appendChild( li );
if ( bad ) {
var toolbar = id("qunit-testrunner-toolbar");
if ( toolbar ) {
toolbar.style.display = "block";
id("qunit-filter-pass").disabled = null;
id("qunit-filter-missing").disabled = null;
}
}
} else {
for ( var i = 0; i < config.assertions.length; i++ ) {
if ( !config.assertions[i].result ) {
bad++;
config.stats.bad++;
config.moduleStats.bad++;
}
}
}
QUnit.testDone( testName, bad, config.assertions.length );
if ( !window.setTimeout && !config.queue.length ) {
done();
}
});
if ( window.setTimeout && !config.doneTimer ) {
config.doneTimer = window.setTimeout(function(){
if ( !config.queue.length ) {
done();
} else {
synchronize( done );
}
}, 13);
}
},
/**
* Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
*/
expect: function(asserts) {
config.expected = asserts;
},
/**
* Asserts true.
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
*/
ok: function(a, msg) {
QUnit.log(a, msg);
config.assertions.push({
result: !!a,
message: msg
});
},
/**
* Checks that the first two arguments are equal, with an optional message.
* Prints out both actual and expected values.
*
* Prefered to ok( actual == expected, message )
*
* @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
*
* @param Object actual
* @param Object expected
* @param String message (optional)
*/
equal: function(actual, expected, message) {
push(expected == actual, actual, expected, message);
},
notEqual: function(actual, expected, message) {
push(expected != actual, actual, expected, message);
},
deepEqual: function(a, b, message) {
push(QUnit.equiv(a, b), a, b, message);
},
notDeepEqual: function(a, b, message) {
push(!QUnit.equiv(a, b), a, b, message);
},
strictEqual: function(actual, expected, message) {
push(expected === actual, actual, expected, message);
},
notStrictEqual: function(actual, expected, message) {
push(expected !== actual, actual, expected, message);
},
start: function() {
// A slight delay, to avoid any current callbacks
if ( window.setTimeout ) {
window.setTimeout(function() {
if ( config.timeout ) {
clearTimeout(config.timeout);
}
config.blocking = false;
process();
}, 13);
} else {
config.blocking = false;
process();
}
},
stop: function(timeout) {
config.blocking = true;
if ( timeout && window.setTimeout ) {
config.timeout = window.setTimeout(function() {
QUnit.ok( false, "Test timed out" );
QUnit.start();
}, timeout);
}
},
/**
* Resets the test setup. Useful for tests that modify the DOM.
*/
reset: function() {
if ( window.jQuery ) {
jQuery("#main").html( config.fixture );
jQuery.event.global = {};
jQuery.ajaxSettings = extend({}, config.ajaxSettings);
}
},
/**
* Trigger an event on an element.
*
* @example triggerEvent( document.body, "click" );
*
* @param DOMElement elem
* @param String type
*/
triggerEvent: function( elem, type, event ) {
if ( document.createEvent ) {
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
elem.dispatchEvent( event );
} else if ( elem.fireEvent ) {
elem.fireEvent("on"+type);
}
},
// Safe object type checking
is: function( type, obj ) {
return Object.prototype.toString.call( obj ) === "[object "+ type +"]";
},
// Logging callbacks
done: function(failures, total) {},
log: function(result, message) {},
testStart: function(name) {},
testDone: function(name, failures, total) {},
moduleStart: function(name, testEnvironment) {},
moduleDone: function(name, failures, total) {}
};
// Backwards compatibility, deprecated
QUnit.equals = QUnit.equal;
QUnit.same = QUnit.deepEqual;
// Maintain internal state
var config = {
// The queue of tests to run
queue: [],
// block until document ready
blocking: true
};
// Load paramaters
(function() {
var location = window.location || { search: "", protocol: "file:" },
GETParams = location.search.slice(1).split('&');
for ( var i = 0; i < GETParams.length; i++ ) {
GETParams[i] = decodeURIComponent( GETParams[i] );
if ( GETParams[i] === "noglobals" ) {
GETParams.splice( i, 1 );
i--;
config.noglobals = true;
} else if ( GETParams[i].search('=') > -1 ) {
GETParams.splice( i, 1 );
i--;
}
}
// restrict modules/tests by get parameters
config.filters = GETParams;
// Figure out if we're running the tests from a server or not
QUnit.isLocal = !!(location.protocol === 'file:');
})();
// Expose the API as global variables, unless an 'exports'
// object exists, in that case we assume we're in CommonJS
if ( typeof exports === "undefined" || typeof require === "undefined" ) {
extend(window, QUnit);
window.QUnit = QUnit;
} else {
extend(exports, QUnit);
exports.QUnit = QUnit;
}
if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true;
}
addEvent(window, "load", function() {
// Initialize the config, saving the execution queue
var oldconfig = extend({}, config);
QUnit.init();
extend(config, oldconfig);
config.blocking = false;
var userAgent = id("qunit-userAgent");
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
var toolbar = id("qunit-testrunner-toolbar");
if ( toolbar ) {
toolbar.style.display = "none";
var filter = document.createElement("input");
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
filter.disabled = true;
addEvent( filter, "click", function() {
var li = document.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ) {
if ( li[i].className.indexOf("pass") > -1 ) {
li[i].style.display = filter.checked ? "none" : "";
}
}
});
toolbar.appendChild( filter );
var label = document.createElement("label");
label.setAttribute("for", "qunit-filter-pass");
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
var missing = document.createElement("input");
missing.type = "checkbox";
missing.id = "qunit-filter-missing";
missing.disabled = true;
addEvent( missing, "click", function() {
var li = document.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ) {
if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
}
}
});
toolbar.appendChild( missing );
label = document.createElement("label");
label.setAttribute("for", "qunit-filter-missing");
label.innerHTML = "Hide missing tests (untested code is broken code)";
toolbar.appendChild( label );
}
var main = id('main');
if ( main ) {
config.fixture = main.innerHTML;
}
if ( window.jQuery ) {
config.ajaxSettings = window.jQuery.ajaxSettings;
}
QUnit.start();
});
function done() {
if ( config.doneTimer && window.clearTimeout ) {
window.clearTimeout( config.doneTimer );
config.doneTimer = null;
}
if ( config.queue.length ) {
config.doneTimer = window.setTimeout(function(){
if ( !config.queue.length ) {
done();
} else {
synchronize( done );
}
}, 13);
return;
}
config.autorun = true;
// Log the last module results
if ( config.currentModule ) {
QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
}
var banner = id("qunit-banner"),
tests = id("qunit-tests"),
html = ['Tests completed in ',
+new Date - config.started, ' milliseconds.<br/>',
'<span class="passed">', config.stats.all - config.stats.bad, '</span> tests of <span class="total">', config.stats.all, '</span> passed, <span class="failed">', config.stats.bad,'</span> failed.'].join('');
if ( banner ) {
banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
}
if ( tests ) {
var result = id("qunit-testresult");
if ( !result ) {
result = document.createElement("p");
result.id = "qunit-testresult";
result.className = "result";
tests.parentNode.insertBefore( result, tests.nextSibling );
}
result.innerHTML = html;
}
QUnit.done( config.stats.bad, config.stats.all );
}
function validTest( name ) {
var i = config.filters.length,
run = false;
if ( !i ) {
return true;
}
while ( i-- ) {
var filter = config.filters[i],
not = filter.charAt(0) == '!';
if ( not ) {
filter = filter.slice(1);
}
if ( name.indexOf(filter) !== -1 ) {
return !not;
}
if ( not ) {
run = true;
}
}
return run;
}
function push(result, actual, expected, message) {
message = message || (result ? "okay" : "failed");
QUnit.ok( result, result ? message + ": " + QUnit.jsDump.parse(expected) : message + ", expected: " + QUnit.jsDump.parse(expected) + " result: " + QUnit.jsDump.parse(actual) );
}
function synchronize( callback ) {
config.queue.push( callback );
if ( config.autorun && !config.blocking ) {
process();
}
}
function process() {
var start = (new Date()).getTime();
while ( config.queue.length && !config.blocking ) {
if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
config.queue.shift()();
} else {
setTimeout( process, 13 );
break;
}
}
}
function saveGlobal() {
config.pollution = [];
if ( config.noglobals ) {
for ( var key in window ) {
config.pollution.push( key );
}
}
}
function checkPollution( name ) {
var old = config.pollution;
saveGlobal();
var newGlobals = diff( old, config.pollution );
if ( newGlobals.length > 0 ) {
ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
config.expected++;
}
var deletedGlobals = diff( config.pollution, old );
if ( deletedGlobals.length > 0 ) {
ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
config.expected++;
}
}
// returns a new Array with the elements that are in a but not in b
function diff( a, b ) {
var result = a.slice();
for ( var i = 0; i < result.length; i++ ) {
for ( var j = 0; j < b.length; j++ ) {
if ( result[i] === b[j] ) {
result.splice(i, 1);
i--;
break;
}
}
}
return result;
}
function fail(message, exception, callback) {
if ( typeof console !== "undefined" && console.error && console.warn ) {
console.error(message);
console.error(exception);
console.warn(callback.toString());
} else if ( window.opera && opera.postError ) {
opera.postError(message, exception, callback.toString);
}
}
function extend(a, b) {
for ( var prop in b ) {
a[prop] = b[prop];
}
return a;
}
function addEvent(elem, type, fn) {
if ( elem.addEventListener ) {
elem.addEventListener( type, fn, false );
} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, fn );
} else {
fn();
}
}
function id(name) {
return !!(typeof document !== "undefined" && document && document.getElementById) &&
document.getElementById( name );
}
// Test for equality any JavaScript type.
// Discussions and reference: http://philrathe.com/articles/equiv
// Test suites: http://philrathe.com/tests/equiv
// Author: Philippe Rathé <prathe@gmail.com>
QUnit.equiv = function () {
var innerEquiv; // the real equiv function
var callers = []; // stack to decide between skip/abort functions
var parents = []; // stack to avoiding loops from circular referencing
// Determine what is o.
function hoozit(o) {
if (QUnit.is("String", o)) {
return "string";
} else if (QUnit.is("Boolean", o)) {
return "boolean";
} else if (QUnit.is("Number", o)) {
if (isNaN(o)) {
return "nan";
} else {
return "number";
}
} else if (typeof o === "undefined") {
return "undefined";
// consider: typeof null === object
} else if (o === null) {
return "null";
// consider: typeof [] === object
} else if (QUnit.is( "Array", o)) {
return "array";
// consider: typeof new Date() === object
} else if (QUnit.is( "Date", o)) {
return "date";
// consider: /./ instanceof Object;
// /./ instanceof RegExp;
// typeof /./ === "function"; // => false in IE and Opera,
// true in FF and Safari
} else if (QUnit.is( "RegExp", o)) {
return "regexp";
} else if (typeof o === "object") {
return "object";
} else if (QUnit.is( "Function", o)) {
return "function";
} else {
return undefined;
}
}
// Call the o related callback with the given arguments.
function bindCallbacks(o, callbacks, args) {
var prop = hoozit(o);
if (prop) {
if (hoozit(callbacks[prop]) === "function") {
return callbacks[prop].apply(callbacks, args);
} else {
return callbacks[prop]; // or undefined
}
}
}
var callbacks = function () {
// for string, boolean, number and null
function useStrictEquality(b, a) {
if (b instanceof a.constructor || a instanceof b.constructor) {
// to catch short annotaion VS 'new' annotation of a declaration
// e.g. var i = 1;
// var j = new Number(1);
return a == b;
} else {
return a === b;
}
}
return {
"string": useStrictEquality,
"boolean": useStrictEquality,
"number": useStrictEquality,
"null": useStrictEquality,
"undefined": useStrictEquality,
"nan": function (b) {
return isNaN(b);
},
"date": function (b, a) {
return hoozit(b) === "date" && a.valueOf() === b.valueOf();
},
"regexp": function (b, a) {
return hoozit(b) === "regexp" &&
a.source === b.source && // the regex itself
a.global === b.global && // and its modifers (gmi) ...
a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline;
},
// - skip when the property is a method of an instance (OOP)
// - abort otherwise,
// initial === would have catch identical references anyway
"function": function () {
var caller = callers[callers.length - 1];
return caller !== Object &&
typeof caller !== "undefined";
},
"array": function (b, a) {
var i, j, loop;
var len;
// b could be an object literal here
if ( ! (hoozit(b) === "array")) {
return false;
}
len = a.length;
if (len !== b.length) { // safe and faster
return false;
}
//track reference to avoid circular references
parents.push(a);
for (i = 0; i < len; i++) {
loop = false;
for(j=0;j<parents.length;j++){
if(parents[j] === a[i]){
loop = true;//dont rewalk array
}
}
if (!loop && ! innerEquiv(a[i], b[i])) {
parents.pop();
return false;
}
}
parents.pop();
return true;
},
"object": function (b, a) {
var i, j, loop;
var eq = true; // unless we can proove it
var aProperties = [], bProperties = []; // collection of strings
// comparing constructors is more strict than using instanceof
if ( a.constructor !== b.constructor) {
return false;
}
// stack constructor before traversing properties
callers.push(a.constructor);
//track reference to avoid circular references
parents.push(a);
for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
loop = false;
for(j=0;j<parents.length;j++){
if(parents[j] === a[i])
loop = true; //don't go down the same path twice
}
aProperties.push(i); // collect a's properties
if (!loop && ! innerEquiv(a[i], b[i])) {
eq = false;
break;
}
}
callers.pop(); // unstack, we are done
parents.pop();
for (i in b) {
bProperties.push(i); // collect b's properties
}
// Ensures identical properties name
return eq && innerEquiv(aProperties.sort(), bProperties.sort());
}
};
}();
innerEquiv = function () { // can take multiple arguments
var args = Array.prototype.slice.apply(arguments);
if (args.length < 2) {
return true; // end transition
}
return (function (a, b) {
if (a === b) {
return true; // catch the most you can
} else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
return false; // don't lose time with error prone cases
} else {
return bindCallbacks(a, callbacks, [b, a]);
}
// apply transition with (1..n) arguments
})(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
};
return innerEquiv;
}();
/**
* jsDump
* Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
* Date: 5/15/2008
* @projectDescription Advanced and extensible data dumping for Javascript.
* @version 1.0.0
* @author Ariel Flesler
* @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
*/
QUnit.jsDump = (function() {
function quote( str ) {
return '"' + str.toString().replace(/"/g, '\\"') + '"';
};
function literal( o ) {
return o + '';
};
function join( pre, arr, post ) {
var s = jsDump.separator(),
base = jsDump.indent(),
inner = jsDump.indent(1);
if ( arr.join )
arr = arr.join( ',' + s + inner );
if ( !arr )
return pre + post;
return [ pre, inner + arr, base + post ].join(s);
};
function array( arr ) {
var i = arr.length, ret = Array(i);
this.up();
while ( i-- )
ret[i] = this.parse( arr[i] );
this.down();
return join( '[', ret, ']' );
};
var reName = /^function (\w+)/;
var jsDump = {
parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance
var parser = this.parsers[ type || this.typeOf(obj) ];
type = typeof parser;
return type == 'function' ? parser.call( this, obj ) :
type == 'string' ? parser :
this.parsers.error;
},
typeOf:function( obj ) {
var type;
if ( obj === null ) {
type = "null";
} else if (typeof obj === "undefined") {
type = "undefined";
} else if (QUnit.is("RegExp", obj)) {
type = "regexp";
} else if (QUnit.is("Date", obj)) {
type = "date";
} else if (QUnit.is("Function", obj)) {
type = "function";
} else if (obj.setInterval && obj.document && !obj.nodeType) {
type = "window";
} else if (obj.nodeType === 9) {
type = "document";
} else if (obj.nodeType) {
type = "node";
} else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) {
type = "array";
} else {
type = typeof obj;
}
return type;
},
separator:function() {
return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
},
indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
if ( !this.multiline )
return '';
var chr = this.indentChar;
if ( this.HTML )
chr = chr.replace(/\t/g,' ').replace(/ /g,'&nbsp;');
return Array( this._depth_ + (extra||0) ).join(chr);
},
up:function( a ) {
this._depth_ += a || 1;
},
down:function( a ) {
this._depth_ -= a || 1;
},
setParser:function( name, parser ) {
this.parsers[name] = parser;
},
// The next 3 are exposed so you can use them
quote:quote,
literal:literal,
join:join,
//
_depth_: 1,
// This is the list of parsers, to modify them, use jsDump.setParser
parsers:{
window: '[Window]',
document: '[Document]',
error:'[ERROR]', //when no parser is found, shouldn't happen
unknown: '[Unknown]',
'null':'null',
undefined:'undefined',
'function':function( fn ) {
var ret = 'function',
name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
if ( name )
ret += ' ' + name;
ret += '(';
ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
return join( ret, this.parse(fn,'functionCode'), '}' );
},
array: array,
nodelist: array,
arguments: array,
object:function( map ) {
var ret = [ ];
this.up();
for ( var key in map )
ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
this.down();
return join( '{', ret, '}' );
},
node:function( node ) {
var open = this.HTML ? '&lt;' : '<',
close = this.HTML ? '&gt;' : '>';
var tag = node.nodeName.toLowerCase(),
ret = open + tag;
for ( var a in this.DOMAttrs ) {
var val = node[this.DOMAttrs[a]];
if ( val )
ret += ' ' + a + '=' + this.parse( val, 'attribute' );
}
return ret + close + open + '/' + tag + close;
},
functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
var l = fn.length;
if ( !l ) return '';
var args = Array(l);
while ( l-- )
args[l] = String.fromCharCode(97+l);//97 is 'a'
return ' ' + args.join(', ') + ' ';
},
key:quote, //object calls it internally, the key part of an item in a map
functionCode:'[code]', //function calls it internally, it's the content of the function
attribute:quote, //node calls it internally, it's an html attribute value
string:quote,
date:quote,
regexp:literal, //regex
number:literal,
'boolean':literal
},
DOMAttrs:{//attributes to dump from nodes, name=>realName
id:'id',
name:'name',
'class':'className'
},
HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
indentChar:' ',//indentation unit
multiline:false //if true, items in a collection, are separated by a \n, else just a space.
};
return jsDump;
})();
})(this);

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>QUnit Test Suite</title>
<link rel="stylesheet" href="../qunit/qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="../qunit/qunit.js"></script>
<script type="text/javascript" src="test.js"></script>
<script type="text/javascript" src="same.js"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
</body>
</html>

View file

@ -0,0 +1,1423 @@
module("equiv");
test("Primitive types and constants", function () {
equals(QUnit.equiv(null, null), true, "null");
equals(QUnit.equiv(null, {}), false, "null");
equals(QUnit.equiv(null, undefined), false, "null");
equals(QUnit.equiv(null, 0), false, "null");
equals(QUnit.equiv(null, false), false, "null");
equals(QUnit.equiv(null, ''), false, "null");
equals(QUnit.equiv(null, []), false, "null");
equals(QUnit.equiv(undefined, undefined), true, "undefined");
equals(QUnit.equiv(undefined, null), false, "undefined");
equals(QUnit.equiv(undefined, 0), false, "undefined");
equals(QUnit.equiv(undefined, false), false, "undefined");
equals(QUnit.equiv(undefined, {}), false, "undefined");
equals(QUnit.equiv(undefined, []), false, "undefined");
equals(QUnit.equiv(undefined, ""), false, "undefined");
// Nan usually doest not equal to Nan using the '==' operator.
// Only isNaN() is able to do it.
equals(QUnit.equiv(0/0, 0/0), true, "NaN"); // NaN VS NaN
equals(QUnit.equiv(1/0, 2/0), true, "Infinity"); // Infinity VS Infinity
equals(QUnit.equiv(-1/0, 2/0), false, "-Infinity, Infinity"); // -Infinity VS Infinity
equals(QUnit.equiv(-1/0, -2/0), true, "-Infinity, -Infinity"); // -Infinity VS -Infinity
equals(QUnit.equiv(0/0, 1/0), false, "NaN, Infinity"); // Nan VS Infinity
equals(QUnit.equiv(1/0, 0/0), false, "NaN, Infinity"); // Nan VS Infinity
equals(QUnit.equiv(0/0, null), false, "NaN");
equals(QUnit.equiv(0/0, undefined), false, "NaN");
equals(QUnit.equiv(0/0, 0), false, "NaN");
equals(QUnit.equiv(0/0, false), false, "NaN");
equals(QUnit.equiv(0/0, function () {}), false, "NaN");
equals(QUnit.equiv(1/0, null), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, undefined), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, 0), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, 1), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, false), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, true), false, "NaN, Infinity");
equals(QUnit.equiv(1/0, function () {}), false, "NaN, Infinity");
equals(QUnit.equiv(0, 0), true, "number");
equals(QUnit.equiv(0, 1), false, "number");
equals(QUnit.equiv(1, 0), false, "number");
equals(QUnit.equiv(1, 1), true, "number");
equals(QUnit.equiv(1.1, 1.1), true, "number");
equals(QUnit.equiv(0.0000005, 0.0000005), true, "number");
equals(QUnit.equiv(0, ''), false, "number");
equals(QUnit.equiv(0, '0'), false, "number");
equals(QUnit.equiv(1, '1'), false, "number");
equals(QUnit.equiv(0, false), false, "number");
equals(QUnit.equiv(1, true), false, "number");
equals(QUnit.equiv(true, true), true, "boolean");
equals(QUnit.equiv(true, false), false, "boolean");
equals(QUnit.equiv(false, true), false, "boolean");
equals(QUnit.equiv(false, 0), false, "boolean");
equals(QUnit.equiv(false, null), false, "boolean");
equals(QUnit.equiv(false, undefined), false, "boolean");
equals(QUnit.equiv(true, 1), false, "boolean");
equals(QUnit.equiv(true, null), false, "boolean");
equals(QUnit.equiv(true, undefined), false, "boolean");
equals(QUnit.equiv('', ''), true, "string");
equals(QUnit.equiv('a', 'a'), true, "string");
equals(QUnit.equiv("foobar", "foobar"), true, "string");
equals(QUnit.equiv("foobar", "foo"), false, "string");
equals(QUnit.equiv('', 0), false, "string");
equals(QUnit.equiv('', false), false, "string");
equals(QUnit.equiv('', null), false, "string");
equals(QUnit.equiv('', undefined), false, "string");
// Short annotation VS new annotation
equals(QUnit.equiv(0, new Number()), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Number(), 0), true, "short annotation VS new annotation");
equals(QUnit.equiv(1, new Number(1)), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Number(1), 1), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Number(0), 1), false, "short annotation VS new annotation");
equals(QUnit.equiv(0, new Number(1)), false, "short annotation VS new annotation");
equals(QUnit.equiv(new String(), ""), true, "short annotation VS new annotation");
equals(QUnit.equiv("", new String()), true, "short annotation VS new annotation");
equals(QUnit.equiv(new String("My String"), "My String"), true, "short annotation VS new annotation");
equals(QUnit.equiv("My String", new String("My String")), true, "short annotation VS new annotation");
equals(QUnit.equiv("Bad String", new String("My String")), false, "short annotation VS new annotation");
equals(QUnit.equiv(new String("Bad String"), "My String"), false, "short annotation VS new annotation");
equals(QUnit.equiv(false, new Boolean()), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Boolean(), false), true, "short annotation VS new annotation");
equals(QUnit.equiv(true, new Boolean(true)), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Boolean(true), true), true, "short annotation VS new annotation");
equals(QUnit.equiv(true, new Boolean(1)), true, "short annotation VS new annotation");
equals(QUnit.equiv(false, new Boolean(false)), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Boolean(false), false), true, "short annotation VS new annotation");
equals(QUnit.equiv(false, new Boolean(0)), true, "short annotation VS new annotation");
equals(QUnit.equiv(true, new Boolean(false)), false, "short annotation VS new annotation");
equals(QUnit.equiv(new Boolean(false), true), false, "short annotation VS new annotation");
equals(QUnit.equiv(new Object(), {}), true, "short annotation VS new annotation");
equals(QUnit.equiv({}, new Object()), true, "short annotation VS new annotation");
equals(QUnit.equiv(new Object(), {a:1}), false, "short annotation VS new annotation");
equals(QUnit.equiv({a:1}, new Object()), false, "short annotation VS new annotation");
equals(QUnit.equiv({a:undefined}, new Object()), false, "short annotation VS new annotation");
equals(QUnit.equiv(new Object(), {a:undefined}), false, "short annotation VS new annotation");
});
test("Objects Basics.", function() {
equals(QUnit.equiv({}, {}), true);
equals(QUnit.equiv({}, null), false);
equals(QUnit.equiv({}, undefined), false);
equals(QUnit.equiv({}, 0), false);
equals(QUnit.equiv({}, false), false);
// This test is a hard one, it is very important
// REASONS:
// 1) They are of the same type "object"
// 2) [] instanceof Object is true
// 3) Their properties are the same (doesn't exists)
equals(QUnit.equiv({}, []), false);
equals(QUnit.equiv({a:1}, {a:1}), true);
equals(QUnit.equiv({a:1}, {a:"1"}), false);
equals(QUnit.equiv({a:[]}, {a:[]}), true);
equals(QUnit.equiv({a:{}}, {a:null}), false);
equals(QUnit.equiv({a:1}, {}), false);
equals(QUnit.equiv({}, {a:1}), false);
// Hard ones
equals(QUnit.equiv({a:undefined}, {}), false);
equals(QUnit.equiv({}, {a:undefined}), false);
equals(QUnit.equiv(
{
a: [{ bar: undefined }]
},
{
a: [{ bat: undefined }]
}
), false);
});
test("Arrays Basics.", function() {
equals(QUnit.equiv([], []), true);
// May be a hard one, can invoke a crash at execution.
// because their types are both "object" but null isn't
// like a true object, it doesn't have any property at all.
equals(QUnit.equiv([], null), false);
equals(QUnit.equiv([], undefined), false);
equals(QUnit.equiv([], false), false);
equals(QUnit.equiv([], 0), false);
equals(QUnit.equiv([], ""), false);
// May be a hard one, but less hard
// than {} with [] (note the order)
equals(QUnit.equiv([], {}), false);
equals(QUnit.equiv([null],[]), false);
equals(QUnit.equiv([undefined],[]), false);
equals(QUnit.equiv([],[null]), false);
equals(QUnit.equiv([],[undefined]), false);
equals(QUnit.equiv([null],[undefined]), false);
equals(QUnit.equiv([[]],[[]]), true);
equals(QUnit.equiv([[],[],[]],[[],[],[]]), true);
equals(QUnit.equiv(
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]),
true);
equals(QUnit.equiv(
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // shorter
false);
equals(QUnit.equiv(
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
[[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // deepest element not an array
false);
// same multidimensional
equals(QUnit.equiv(
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,4,[
1,2,[
1,2,3,4,[
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]],
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,4,[
1,2,[
1,2,3,4,[
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]]),
true, "Multidimensional");
// different multidimensional
equals(QUnit.equiv(
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,4,[
1,2,[
1,2,3,4,[
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]],
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,4,[
1,2,[
'1',2,3,4,[ // string instead of number
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]]),
false, "Multidimensional");
// different multidimensional
equals(QUnit.equiv(
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,4,[
1,2,[
1,2,3,4,[
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]],
[1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,6,7,8,9, [
1,2,3,4,5,[
[6,7,8,9, [
[
1,2,3,4,[
2,3,[ // missing an element (4)
1,2,[
1,2,3,4,[
1,2,3,4,5,6,7,8,9,[
0
],1,2,3,4,5,6,7,8,9
],5,6,7,8,9
],4,5,6,7,8,9
],5,6,7,8,9
],5,6,7
]
]
]
]
]]]),
false, "Multidimensional");
});
test("Functions.", function() {
var f0 = function () {};
var f1 = function () {};
// f2 and f3 have the same code, formatted differently
var f2 = function () {var i = 0;};
var f3 = function () {
var i = 0 // this comment and no semicoma as difference
};
equals(QUnit.equiv(function() {}, function() {}), false, "Anonymous functions"); // exact source code
equals(QUnit.equiv(function() {}, function() {return true;}), false, "Anonymous functions");
equals(QUnit.equiv(f0, f0), true, "Function references"); // same references
equals(QUnit.equiv(f0, f1), false, "Function references"); // exact source code, different references
equals(QUnit.equiv(f2, f3), false, "Function references"); // equivalent source code, different references
equals(QUnit.equiv(f1, f2), false, "Function references"); // different source code, different references
equals(QUnit.equiv(function() {}, true), false);
equals(QUnit.equiv(function() {}, undefined), false);
equals(QUnit.equiv(function() {}, null), false);
equals(QUnit.equiv(function() {}, {}), false);
});
test("Date instances.", function() {
// Date, we don't need to test Date.parse() because it returns a number.
// Only test the Date instances by setting them a fix date.
// The date use is midnight January 1, 1970
var d1 = new Date();
d1.setTime(0); // fix the date
var d2 = new Date();
d2.setTime(0); // fix the date
var d3 = new Date(); // The very now
// Anyway their types differs, just in case the code fails in the order in which it deals with date
equals(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 are different
// test same values date and different instances equality
equals(QUnit.equiv(d1, d2), true);
// test different date and different instances difference
equals(QUnit.equiv(d1, d3), false);
});
test("RegExp.", function() {
// Must test cases that imply those traps:
// var a = /./;
// a instanceof Object; // Oops
// a instanceof RegExp; // Oops
// typeof a === "function"; // Oops, false in IE and Opera, true in FF and Safari ("object")
// Tests same regex with same modifiers in different order
var r = /foo/;
var r5 = /foo/gim;
var r6 = /foo/gmi;
var r7 = /foo/igm;
var r8 = /foo/img;
var r9 = /foo/mig;
var r10 = /foo/mgi;
var ri1 = /foo/i;
var ri2 = /foo/i;
var rm1 = /foo/m;
var rm2 = /foo/m;
var rg1 = /foo/g;
var rg2 = /foo/g;
equals(QUnit.equiv(r5, r6), true, "Modifier order");
equals(QUnit.equiv(r5, r7), true, "Modifier order");
equals(QUnit.equiv(r5, r8), true, "Modifier order");
equals(QUnit.equiv(r5, r9), true, "Modifier order");
equals(QUnit.equiv(r5, r10), true, "Modifier order");
equals(QUnit.equiv(r, r5), false, "Modifier");
equals(QUnit.equiv(ri1, ri2), true, "Modifier");
equals(QUnit.equiv(r, ri1), false, "Modifier");
equals(QUnit.equiv(ri1, rm1), false, "Modifier");
equals(QUnit.equiv(r, rm1), false, "Modifier");
equals(QUnit.equiv(rm1, ri1), false, "Modifier");
equals(QUnit.equiv(rm1, rm2), true, "Modifier");
equals(QUnit.equiv(rg1, rm1), false, "Modifier");
equals(QUnit.equiv(rm1, rg1), false, "Modifier");
equals(QUnit.equiv(rg1, rg2), true, "Modifier");
// Different regex, same modifiers
var r11 = /[a-z]/gi;
var r13 = /[0-9]/gi; // oops! different
equals(QUnit.equiv(r11, r13), false, "Regex pattern");
var r14 = /0/ig;
var r15 = /"0"/ig; // oops! different
equals(QUnit.equiv(r14, r15), false, "Regex pattern");
var r1 = /[\n\r\u2028\u2029]/g;
var r2 = /[\n\r\u2028\u2029]/g;
var r3 = /[\n\r\u2028\u2028]/g; // differs from r1
var r4 = /[\n\r\u2028\u2029]/; // differs from r1
equals(QUnit.equiv(r1, r2), true, "Regex pattern");
equals(QUnit.equiv(r1, r3), false, "Regex pattern");
equals(QUnit.equiv(r1, r4), false, "Regex pattern");
// More complex regex
var regex1 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
var regex2 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
// regex 3 is different: '.' not escaped
var regex3 = "^[-_.a-z0-9]+@([-_a-z0-9]+.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
var r21 = new RegExp(regex1);
var r22 = new RegExp(regex2);
var r23 = new RegExp(regex3); // diff from r21, not same pattern
var r23a = new RegExp(regex3, "gi"); // diff from r23, not same modifier
var r24a = new RegExp(regex3, "ig"); // same as r23a
equals(QUnit.equiv(r21, r22), true, "Complex Regex");
equals(QUnit.equiv(r21, r23), false, "Complex Regex");
equals(QUnit.equiv(r23, r23a), false, "Complex Regex");
equals(QUnit.equiv(r23a, r24a), true, "Complex Regex");
// typeof r1 is "function" in some browsers and "object" in others so we must cover this test
var re = / /;
equals(QUnit.equiv(re, function () {}), false, "Regex internal");
equals(QUnit.equiv(re, {}), false, "Regex internal");
});
test("Complex Objects.", function() {
function fn1() {
return "fn1";
}
function fn2() {
return "fn2";
}
// Try to invert the order of some properties to make sure it is covered.
// It can failed when properties are compared between unsorted arrays.
equals(QUnit.equiv(
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
q: [],
p: 1/0,
o: 99
},
l: undefined,
m: null
}
},
d: 0,
i: true,
h: "false"
}
},
e: undefined,
g: "",
h: "h",
f: {},
i: []
},
{
a: 1,
b: null,
c: [{}],
d: {
b: false,
a: 3.14159,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
t: undefined,
u: 0,
s: [1,2,3],
v: {
w: {
x: {
z: null,
y: "Yahoo!"
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
i: true,
h: "false"
}
},
e: undefined,
g: "",
f: {},
h: "h",
i: []
}
), true);
equals(QUnit.equiv(
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
//r: "r", // different: missing a property
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
},
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
}
), false);
equals(QUnit.equiv(
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
},
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
//t: undefined, // different: missing a property with an undefined value
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
}
), false);
equals(QUnit.equiv(
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
},
{
a: 1,
b: null,
c: [{}],
d: {
a: 3.14159,
b: false,
c: {
d: 0,
e: fn1,
f: [[[]]],
g: {
j: {
k: {
n: {
r: "r",
s: [1,2,3],
t: undefined,
u: 0,
v: {
w: {
x: {
y: "Yahoo!",
z: null
}
}
}
},
o: 99,
p: 1/0,
q: {} // different was []
},
l: undefined,
m: null
}
},
h: "false",
i: true
}
},
e: undefined,
f: {},
g: "",
h: "h",
i: []
}
), false);
var same1 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3]],
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var same2 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3]],
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var diff1 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3,4]], // different: 4 was add to the array
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var diff2 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3]],
newprop: undefined, // different: newprop was added
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var diff3 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3]],
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ α" // different: missing last char
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var diff4 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,undefined,{}, [], [1,2,3]], // different: undefined instead of null
bar: undefined
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
var diff5 = {
a: [
"string", null, 0, "1", 1, {
prop: null,
foo: [1,2,null,{}, [], [1,2,3]],
bat: undefined // different: property name not "bar"
}, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
],
unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
b: "b",
c: fn1
};
equals(QUnit.equiv(same1, same2), true);
equals(QUnit.equiv(same2, same1), true);
equals(QUnit.equiv(same2, diff1), false);
equals(QUnit.equiv(diff1, same2), false);
equals(QUnit.equiv(same1, diff1), false);
equals(QUnit.equiv(same1, diff2), false);
equals(QUnit.equiv(same1, diff3), false);
equals(QUnit.equiv(same1, diff3), false);
equals(QUnit.equiv(same1, diff4), false);
equals(QUnit.equiv(same1, diff5), false);
equals(QUnit.equiv(diff5, diff1), false);
});
test("Complex Arrays.", function() {
function fn() {
}
equals(QUnit.equiv(
[1, 2, 3, true, {}, null, [
{
a: ["", '1', 0]
},
5, 6, 7
], "foo"],
[1, 2, 3, true, {}, null, [
{
a: ["", '1', 0]
},
5, 6, 7
], "foo"]),
true);
equals(QUnit.equiv(
[1, 2, 3, true, {}, null, [
{
a: ["", '1', 0]
},
5, 6, 7
], "foo"],
[1, 2, 3, true, {}, null, [
{
b: ["", '1', 0] // not same property name
},
5, 6, 7
], "foo"]),
false);
var a = [{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn,
f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
], [], [[[], "foo", null, {
n: 1/0,
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]];
equals(QUnit.equiv(a,
[{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn,
f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
], [], [[[], "foo", null, {
n: 1/0,
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]]), true);
equals(QUnit.equiv(a,
[{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn,
f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[2]]]], "3"], {}, 1/0 // different: [[[[[2]]]]] instead of [[[[[3]]]]]
], [], [[[], "foo", null, {
n: 1/0,
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]]), false);
equals(QUnit.equiv(a,
[{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn,
f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
], [], [[[], "foo", null, {
n: -1/0, // different, -Infinity instead of Infinity
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]]), false);
equals(QUnit.equiv(a,
[{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn,
f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
], [], [[[], "foo", { // different: null is missing
n: 1/0,
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]]), false);
equals(QUnit.equiv(a,
[{
b: fn,
c: false,
"do": "reserved word",
"for": {
ar: [3,5,9,"hey!", [], {
ar: [1,[
3,4,6,9, null, [], []
]],
e: fn
// different: missing property f: undefined
}]
},
e: 0.43445
}, 5, "string", 0, fn, false, null, undefined, 0, [
4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
], [], [[[], "foo", null, {
n: 1/0,
z: {
a: [3,4,5,6,"yep!", undefined, undefined],
b: {}
}
}, {}]]]), false);
});
test("Prototypal inheritance", function() {
function Gizmo(id) {
this.id = id;
}
function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
var gizmo = new Gizmo("ok");
var hoozit = new Hoozit("ok");
// Try this test many times after test on instances that hold function
// to make sure that our code does not mess with last object constructor memoization.
equals(QUnit.equiv(function () {}, function () {}), false);
// Hoozit inherit from Gizmo
// hoozit instanceof Hoozit; // true
// hoozit instanceof Gizmo; // true
equals(QUnit.equiv(hoozit, gizmo), true);
Gizmo.prototype.bar = true; // not a function just in case we skip them
// Hoozit inherit from Gizmo
// They are equivalent
equals(QUnit.equiv(hoozit, gizmo), true);
// Make sure this is still true !important
// The reason for this is that I forgot to reset the last
// caller to where it were called from.
equals(QUnit.equiv(function () {}, function () {}), false);
// Make sure this is still true !important
equals(QUnit.equiv(hoozit, gizmo), true);
Hoozit.prototype.foo = true; // not a function just in case we skip them
// Gizmo does not inherit from Hoozit
// gizmo instanceof Gizmo; // true
// gizmo instanceof Hoozit; // false
// They are not equivalent
equals(QUnit.equiv(hoozit, gizmo), false);
// Make sure this is still true !important
equals(QUnit.equiv(function () {}, function () {}), false);
});
test("Instances", function() {
function A() {}
var a1 = new A();
var a2 = new A();
function B() {
this.fn = function () {};
}
var b1 = new B();
var b2 = new B();
equals(QUnit.equiv(a1, a2), true, "Same property, same constructor");
// b1.fn and b2.fn are functions but they are different references
// But we decided to skip function for instances.
equals(QUnit.equiv(b1, b2), true, "Same property, same constructor");
equals(QUnit.equiv(a1, b1), false, "Same properties but different constructor"); // failed
function Car(year) {
var privateVar = 0;
this.year = year;
this.isOld = function() {
return year > 10;
};
}
function Human(year) {
var privateVar = 1;
this.year = year;
this.isOld = function() {
return year > 80;
};
}
var car = new Car(30);
var carSame = new Car(30);
var carDiff = new Car(10);
var human = new Human(30);
var diff = {
year: 30
};
var same = {
year: 30,
isOld: function () {}
};
equals(QUnit.equiv(car, car), true);
equals(QUnit.equiv(car, carDiff), false);
equals(QUnit.equiv(car, carSame), true);
equals(QUnit.equiv(car, human), false);
});
test("Complex Instances Nesting (with function value in literals and/or in nested instances)", function() {
function A(fn) {
this.a = {};
this.fn = fn;
this.b = {a: []};
this.o = {};
this.fn1 = fn;
}
function B(fn) {
this.fn = fn;
this.fn1 = function () {};
this.a = new A(function () {});
}
function fnOutside() {
}
function C(fn) {
function fnInside() {
}
this.x = 10;
this.fn = fn;
this.fn1 = function () {};
this.fn2 = fnInside;
this.fn3 = {
a: true,
b: fnOutside // ok make reference to a function in all instances scope
};
this.o1 = {};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1 = new B(function () {});
this.b2 = new B({
x: {
b2: new B(function() {})
}
});
}
function D(fn) {
function fnInside() {
}
this.x = 10;
this.fn = fn;
this.fn1 = function () {};
this.fn2 = fnInside;
this.fn3 = {
a: true,
b: fnOutside, // ok make reference to a function in all instances scope
// This function won't be ingored.
// It isn't visible for all C insances
// and it is not in a property of an instance. (in an Object instances e.g. the object literal)
c: fnInside
};
this.o1 = {};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1 = new B(function () {});
this.b2 = new B({
x: {
b2: new B(function() {})
}
});
}
function E(fn) {
function fnInside() {
}
this.x = 10;
this.fn = fn;
this.fn1 = function () {};
this.fn2 = fnInside;
this.fn3 = {
a: true,
b: fnOutside // ok make reference to a function in all instances scope
};
this.o1 = {};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1 = new B(function () {});
this.b2 = new B({
x: {
b1: new B({a: function() {}}),
b2: new B(function() {})
}
});
}
var a1 = new A(function () {});
var a2 = new A(function () {});
equals(QUnit.equiv(a1, a2), true);
equals(QUnit.equiv(a1, a2), true); // different instances
var b1 = new B(function () {});
var b2 = new B(function () {});
equals(QUnit.equiv(a1, a2), true);
var c1 = new C(function () {});
var c2 = new C(function () {});
equals(QUnit.equiv(c1, c2), true);
var d1 = new D(function () {});
var d2 = new D(function () {});
equals(QUnit.equiv(d1, d2), false);
var e1 = new E(function () {});
var e2 = new E(function () {});
equals(QUnit.equiv(e1, e2), false);
});
test('object with references to self wont loop', function(){
var circularA = {
abc:null
}, circularB = {
abc:null
};
circularA.abc = circularA;
circularB.abc = circularB;
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
circularA.def = 1;
circularB.def = 1;
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
circularA.def = 1;
circularB.def = 0;
equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object (unambigous test)");
});
test('array with references to self wont loop', function(){
var circularA = [],
circularB = [];
circularA.push(circularA);
circularB.push(circularB);
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
circularA.push( 'abc' );
circularB.push( 'abc' );
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
circularA.push( 'hello' );
circularB.push( 'goodbye' );
equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on array (unambigous test)");
});
test('mixed object/array with references to self wont loop', function(){
var circularA = [{abc:null}],
circularB = [{abc:null}];
circularA[0].abc = circularA;
circularB[0].abc = circularB;
circularA.push(circularA);
circularB.push(circularB);
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
circularA[0].def = 1;
circularB[0].def = 1;
equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
circularA[0].def = 1;
circularB[0].def = 0;
equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object/array (unambigous test)");
});
test("Test that must be done at the end because they extend some primitive's prototype", function() {
// Try that a function looks like our regular expression.
// This tests if we check that a and b are really both instance of RegExp
Function.prototype.global = true;
Function.prototype.multiline = true;
Function.prototype.ignoreCase = false;
Function.prototype.source = "my regex";
var re = /my regex/gm;
equals(QUnit.equiv(re, function () {}), false, "A function that looks that a regex isn't a regex");
// This test will ensures it works in both ways, and ALSO especially that we can make differences
// between RegExp and Function constructor because typeof on a RegExpt instance is "function"
equals(QUnit.equiv(function () {}, re), false, "Same conversely, but ensures that function and regexp are distinct because their constructor are different");
});

View file

@ -0,0 +1,171 @@
test("module without setup/teardown (default)", function() {
expect(1);
ok(true);
});
test("expect in test", 3, function() {
ok(true);
ok(true);
ok(true);
});
test("expect in test", 1, function() {
ok(true);
});
module("setup test", {
setup: function() {
ok(true);
}
});
test("module with setup", function() {
expect(2);
ok(true);
});
var state;
module("setup/teardown test", {
setup: function() {
state = true;
ok(true);
},
teardown: function() {
ok(true);
}
});
test("module with setup/teardown", function() {
expect(3);
ok(true);
});
module("setup/teardown test 2");
test("module without setup/teardown", function() {
expect(1);
ok(true);
});
if (typeof setTimeout !== 'undefined') {
state = 'fail';
module("teardown and stop", {
teardown: function() {
equals(state, "done", "Test teardown.");
}
});
test("teardown must be called after test ended", function() {
expect(1);
stop();
setTimeout(function() {
state = "done";
start();
}, 13);
});
} // end setTimeout tests
if (typeof asyncTest !== 'undefined') {
module("asyncTest");
asyncTest("asyncTest", function() {
expect(2);
ok(true);
setTimeout(function() {
state = "done";
ok(true);
start();
}, 13);
});
asyncTest("asyncTest", 2, function() {
ok(true);
setTimeout(function() {
state = "done";
ok(true);
start();
}, 13);
});
} // end asyncTest tests
module("save scope", {
setup: function() {
this.foo = "bar";
},
teardown: function() {
same(this.foo, "bar");
}
});
test("scope check", function() {
expect(2);
same(this.foo, "bar");
});
module("simple testEnvironment setup", {
foo: "bar",
bugid: "#5311" // example of meta-data
});
test("scope check", function() {
same(this.foo, "bar");
});
test("modify testEnvironment",function() {
this.foo="hamster";
});
test("testEnvironment reset for next test",function() {
same(this.foo, "bar");
});
module("testEnvironment with object", {
options:{
recipe:"soup",
ingredients:["hamster","onions"]
}
});
test("scope check", function() {
same(this.options, {recipe:"soup",ingredients:["hamster","onions"]}) ;
});
test("modify testEnvironment",function() {
// since we do a shallow copy, the testEnvironment can be modified
this.options.ingredients.push("carrots");
});
test("testEnvironment reset for next test",function() {
same(this.options, {recipe:"soup",ingredients:["hamster","onions","carrots"]}, "Is this a bug or a feature? Could do a deep copy") ;
});
module("testEnvironment tests");
function makeurl() {
var testEnv = QUnit.current_testEnvironment;
var url = testEnv.url || 'http://example.com/search';
var q = testEnv.q || 'a search test';
return url + '?q='+encodeURIComponent(q);
}
test("makeurl working",function() {
equals( QUnit.current_testEnvironment, this, 'The current testEnvironment is global');
equals( makeurl(), 'http://example.com/search?q=a%20search%20test', 'makeurl returns a default url if nothing specified in the testEnvironment');
});
module("testEnvironment with makeurl settings",{
url:'http://google.com/',
q:'another_search_test'
});
test("makeurl working with settings from testEnvironment",function() {
equals( makeurl(), 'http://google.com/?q=another_search_test', 'rather than passing arguments, we use test metadata to form the url');
});
test("each test can extend the module testEnvironment", {
q:'hamstersoup'
}, function() {
equals( makeurl(), 'http://google.com/?q=hamstersoup', 'url from module, q from test');
});
module("jsDump");
test("jsDump output", function() {
equals( QUnit.jsDump.parse([1, 2]), "[ 1, 2 ]" );
equals( QUnit.jsDump.parse({top: 5, left: 0}), "{ \"top\": 5, \"left\": 0 }" );
equals( QUnit.jsDump.parse(document.getElementById("qunit-header")), "<h1 id=\"qunit-header\"></h1>" );
equals( QUnit.jsDump.parse(document.getElementsByTagName("h1")), "[ <h1 id=\"qunit-header\"></h1> ]" );
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
satastastast

View file

@ -0,0 +1 @@
satastastast

View file

@ -0,0 +1 @@
satastastast

View file

@ -0,0 +1 @@
s

View file

@ -0,0 +1 @@
satastastast

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="../client/fileuploader.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="demo"></div>
<ul id="separate-list"></ul>
<script src="../client/fileuploader.js" type="text/javascript"></script>
<script>
function createUploader(){
var uploader = new qq.FileUploader({
element: document.getElementById('demo'),
listElement: document.getElementById('separate-list'),
action: '../client/do-nothing.htm'
});
}
window.onload = createUploader;
</script>
</body>
</html>

View file

@ -0,0 +1,106 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<!-- test iwth jquery ui dialog -->
<link href="jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css" rel="stylesheet" type="text/css" media="screen" />
<script src="jquery-ui/jquery-ui-1.8.4.custom.min.js" type="text/javascript"></script>
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
<link href="../client/fileuploader.css" rel="stylesheet" type="text/css">
<script src="../client/fileuploader.js" type="text/javascript" ></script>
<script>
jQuery(function(){
$("#dialog").dialog();
asyncTest("qq.FileUploader", function() {
expect(10);
var submitFileName, submitId;
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: 'action-acceptance.php',
params: {
one: 'value1',
two: 'value2'
},
allowedExtensions: ['txt', 'val', 'webm'],
sizeLimit: 9 * 1024,
minSizeLimit: 10,
onSubmit: function(id, fileName){
if (fileName == '5text.txt'){
submitId = id;
submitFileName = fileName;
} else if (fileName == '6text.txt'){
uploader.setParams({'new':'newvalue'});
same(uploader.getInProgress(), 0, 'getFilesInProgress');
setTimeout(function(){
same(uploader.getInProgress(), 1, 'getFilesInProgress');
}, 1);
} else if (fileName == '8text.txt'){
setTimeout(function(){
same(uploader.getInProgress(), 0, 'all uploads should have finished');
start(); // check test results
}, 1000);
return false;
}
},
onComplete: function(id, fileName, responseJSON){
if (fileName == '4text.txt'){
same(responseJSON, {}, 'should be empty if server returned malformed json');
} else if (fileName == '5text.txt'){
same(submitId, id, "id in both callbacks match");
same(submitFileName, fileName, "filename in both callbacks match");
ok(responseJSON.one === 'value1' && responseJSON.two === 'value2', "server received default params");
same(responseJSON.fileName, fileName, "filename in onComplete correct");
} else if (fileName == '6text.txt'){
ok(responseJSON['new'] === 'newvalue' && responseJSON.one == null, "server received new params");
same(uploader.getInProgress(), 0, 'upload should have finished');
} else if (fileName == '8text.txt'){
ok(false, "upload should be cancelled by returning false in onSubmit");
}
}
});
});
});
</script>
</head>
<body>
<h1 id="qunit-header">File uploader tests</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<p>select files in sample-files dir, following order</p>
<ol>
<li>select 1imagelong...long.gif, invalid ext error should appear</li>
<li>select 2larger.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
<li>select 3empty.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
<li>select 4text.txt, uploaded file should be marked as failed (server returns jsgkdfgu4eyij)</li>
<li>select 5text.txt, callback argument tests</li>
<li>select 6text.txt, setParams, isUploading</li>
<li>select 7small.txt, too small size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
<li>select 8text.txt, returning false in onSubmit cancells upload, file should not be added to list</li>
<li>
In FF,Chrome, select all files using drag-and-drop, only 1 error should appear.
</li>
</ol>
<div id="dialog" title="Basic dialog">
File uploader inside a dialog
<div id="file-uploader"></div>
</div>
</body>
</html>

View file

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
.drop-zone {height:100px; width:256px; background:gray; margin:20px;}
</style>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="../client/fileuploader.js" type="text/javascript" ></script>
<script>
function createDropZone(selector){
var element = $(selector)[0];
new qq.UploadDropZone({
element: element,
onEnter: function(){
console.log('enter')
$(element).css('background', 'green');
},
onLeave: function(){
console.log('leave')
},
onLeaveNotDescendants: function(){
console.log('onLeaveNotDescendants')
$(element).css('background', 'gray');
},
onDrop: function(e){
$(element).css('background', 'gray');
console.log('drop');
console.log(e.dataTransfer.files);
}
});
}
jQuery(function(){
createDropZone('#drop-zone1');
createDropZone('#drop-zone2');
});
</script>
</head>
<body>
<div id="drop-zone1" class="drop-zone"><p>drop-zone1</p></div>
<div id="drop-zone2" class="drop-zone"><p>drop-zone2</p></div>
</body>
</html>

View file

@ -0,0 +1,81 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
<script src="../client/fileuploader.js" type="text/javascript" ></script>
<script>
jQuery(function(){
function getHandler(){
if(qq.UploadHandlerXhr.isSupported()){
return qq.UploadHandlerXhr;
} else {
return qq.UploadHandlerForm;
}
}
asyncTest("upload", function() {
expect(2);
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
var savedId;
var uploadHandler = new (getHandler())({
action: 'action-handler-queue-test.php',
maxConnections: 1,
onComplete: function(id, fileName, response){
if (!response.success){
ok(false, 'server did not receive file')
return;
}
delete response.success;
delete response.qqfile;
same(response, data, 'server received file and data');
}
});
$('#testinput1, #testinput2').change(upload);
function upload(){
setTimeout(start, 9000);
var file = this;
if (uploadHandler instanceof qq.UploadHandlerXhr){
file = this.files[0];
}
var id = uploadHandler.add(file);
uploadHandler.upload(id, data);
}
});
});
</script>
</head>
<body>
<h1 id="qunit-header">File uploader tests</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<p>
Please select a file for each input below,
should be less than 4 sec, between selection.
</p>
<input id="testinput1" type="file">
<input id="testinput2" type="file">
</body>
</html>

View file

@ -0,0 +1,382 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
<script src="../client/fileuploader.js" type="text/javascript" ></script>
<script>
jQuery(function(){
module('qq');
test("contains", function(){
var el1 = document.createElement('div');
var el2 = document.createElement('div');
var el3 = document.createElement('div');
el1.appendChild(el2);
el2.appendChild(el3);
var el4 = document.createElement('div');
ok(qq.contains(el1,el1));
ok(qq.contains(el1,el2));
ok(qq.contains(el1,el3));
ok(!qq.contains(el1,el4));
ok(!qq.contains(el3,el2));
});
test("hasClass, addClass, removeClass", function(){
var element = document.createElement('div');
qq.addClass(element, 'some-class');
ok(!qq.hasClass(element, 'some'), 'dash in class name');
});
test("children", function(){
same(qq.children(document.createElement('div')), [], 'empty');
var element = document.createElement('div');
element.innerHTML = 'asdasd<div>text</div><span>asdas</span>asdasd';
same(qq.children(element).length, 2);
});
test("getByClass", function(){
var element = document.createElement('div');
element.style.display = 'none';
element.innerHTML = '<div class="class"><div class="someclass class"></div></div><span></span><div class="test"></div><div class="class"></div>';
document.body.appendChild(element);
var outside = document.createElement('div');
outside.className = 'outside class';
document.body.appendChild(outside);
same(qq.getByClass(document, 'class').length, 4, 'in document');
same(qq.getByClass(element, 'class').length, 3, 'in test div');
qq.remove(element);
qq.remove(outside);
});
test("obj2url", function(){
var tests = [
{title:'empty', obj:{}, expect:''},
{title:'general json', obj:{a:'b',c:'d',e:'f'}, expect:'a=b&c=d&e=f'},
{title:'general json', obj:{a:1,b:2,c:3,d:4}, expect:'a=1&b=2&c=3&d=4'},
{title:'general json array', obj:{a:[1,2,3,4]}, expect:'a[0]=1&a[1]=2&a[2]=3&a[3]=4'},
{title:'complex json', obj:{a:'b',c:'d',e:['f',{g:'h',i:['j',{k:'l',m:'n'}],
o:undefined,p:true,q:false}]},
expect:'a=b&c=d&'
+'e[0]=f&'
+'e[1][g]=h&'
+'e[1][i][0]=j&'
+'e[1][i][1][k]=l&'
+'e[1][i][1][m]=n&'
+'e[1][o]=undefined&'
+'e[1][p]=true&'
+'e[1][q]=false'},
{title:'function', obj:{a:function(){return 'b';}}, expect:'a=b'},
{title:'function no return', obj:{a:function(){},undefined:'b'}, expect:'a=undefined'},
{title:'null', obj:{a:null}, expect:'a=null'},
{title:'prevent double encoding', obj:{a:[1,2,3],'b[]':[4,5,6],'c[d]':[7,8,9]},
expect:'a[0]=1&a[1]=2&a[2]=3&'
+'b[]=4&b[]=5&b[]=6&'
+'c[d][0]=7&c[d][1]=8&c[d][2]=9'},
{title:'spaces', obj:{a:'All your base are belong to us'},
expect:'a=All+your+base+are+belong+to+us'},
{title:'undefined simple', obj:{undefined:undefined}, expect:''},
{title:'undefined complex', obj:{undefined:undefined,
a:{undefined:undefined},
b:[{undefined:'c'},undefined,{d:'e'}]},
expect:'b[1]=undefined&b[2][d]=e'},
{title:'prefix url no params', obj:{a:'b'},
prefix:'http://any.url',
expect:'http://any.url?a=b'},
{title:'prefix url trailing ?', obj:{a:'b'},
prefix:'http://any.url?',
expect:'http://any.url?a=b'},
{title:'prefix url param', obj:{a:'b'}, prefix:'http://any.url?foo',
expect:'http://any.url?foo&a=b'},
{title:'prefix url param=value', obj:{a:'b'},
prefix:'http://any.url?foo=bar',
expect:'http://any.url?foo=bar&a=b'},
{title:'prefix url multi param', obj:{a:'b'},
prefix:'http://any.url?foo=bar&bla=blub',
expect:'http://any.url?foo=bar&bla=blub&a=b'},
{title:'prefix url array param', obj:{a:'b',c:'d'},
prefix:'http://any.url?foo[0]=bla&foo[1]=blub',
expect:'http://any.url?foo[0]=bla&foo[1]=blub&a=b&c=d'}
];
for (var i = 0, l = tests.length; i<l; i++) {
//console.log('------------------ obj2url-test'+(i+1)+': '+tests[i].title);
//console.log('object: '+tests[i].obj);
//console.log('prefix: '+tests[i].prefix);
var result = '';
if (tests[i].prefix) {
result = qq.obj2url(tests[i].obj, tests[i].prefix);
} else {
result = qq.obj2url(tests[i].obj);
}
//console.log('result: '+result);
same(decodeURIComponent(result), tests[i].expect, tests[i].title);
}
});
var uploadTimeout = 700,
loadTimeout = 300;
if (qq.UploadHandlerXhr.isSupported()){
$('.handlerform').remove();
} else {
//
module('qq.UploadHandlerForm');
//
asyncTest("_getIframeContentJSON", function() {
expect(3);
setTimeout(start, loadTimeout);
var exampleObject = {
"example" : "&amp;a&lt;computer networks&gt;, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
"sub" : {
"arr": [10,20,30],
"boo": false
}
};
var testedFn = qq.UploadHandlerForm.prototype._getIframeContentJSON;
// IE 7,8 doesn't support application-javascript, application-json, text-javascript, text-plain
// as a response type, it also doesn't file load event when iframe loads page with 404 header
createIframe('iframe-content-tests/somepage.php', function(iframe){
same(testedFn(iframe), {}, "Server didn't return valid JSON object");
});
createIframe('iframe-content-tests/text-html.php', function(iframe){
same(testedFn(iframe), exampleObject, "text-html");
});
// test larger response (>4k)
//http://www.coderholic.com/firefox-4k-xml-node-limit/
createIframe('iframe-content-tests/text-html-large.php', function(iframe){
same(testedFn(iframe).length, 5000, ">4k");
});
function createIframe(src, onLoad){
var iframe = document.createElement('iframe');
qq.attach(iframe, 'load', function(){
onLoad(iframe);
setTimeout(function(){
qq.remove(iframe);
}, 1);
});
iframe.src = src;
document.body.appendChild(iframe);
}
});
test("upload, cancel with empty input", function(){
expect(1);
var uploadHandlerForm = new qq.UploadHandlerForm({
action: 'action-slow-response.php',
onComplete: function(id, fileName, response){
ok(false, 'onComplete should not run, the request should be cancelled');
}
});
var input = document.createElement('input');
var id = uploadHandlerForm.add(input);
uploadHandlerForm.cancel(id);
try {
// should fail
uploadHandlerForm.upload(id);
} catch (err){
ok(true, "wasn't uploaded after cancelling")
};
});
asyncTest("upload", function() {
expect(4);
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
var savedId;
var uploadHandler = new qq.UploadHandlerForm({
action: 'action-handler-test.php',
onComplete: function(id, fileName, response){
ok(savedId == id, 'proper id in callback');
same(fileName, uploadHandler.getName(id), 'getName method');
data.fileName = fileName;
same(response, data, 'server received file and correct params, filenames match');
}
});
var input = document.getElementById('testinput1');
qq.attach(input, 'change', function(){
setTimeout(start, uploadTimeout);
savedId = uploadHandler.add(input);
ok(savedId != null, 'id returned by add');
uploadHandler.upload(savedId, data);
});
});
asyncTest("cancel", function() {
var uploadHandlerForm = new qq.UploadHandlerForm({
action: 'action-slow-response.php',
onComplete: function(id, fileName, response){
ok(false, 'onComplete should not run, the request should be cancelled');
}
});
var input = document.getElementById('testinput2');
qq.attach(input, 'change', function(){
var id = uploadHandlerForm.add(input);
uploadHandlerForm.upload(id);
uploadHandlerForm.cancel(id);
start();
});
});
test("check that forms and iframes were removed after use", function(){
same($('form,iframe').length, 0, 'check that forms and iframes were removed after use');
});
asyncTest('going back', function(){
setTimeout(function(){
var goBack = confirm("checking that the history wasn't changed, the page will go back to previous now");
if (goBack){
window.history.back();
start();
ok(false, "the page didn't change (fails in Opera)");
}
}, 1000);
});
}
if (!qq.UploadHandlerXhr.isSupported()){
$('.handlerxhr').remove();
} else {
//
module('qq.UploadHandlerXhr');
//
asyncTest("upload", function() {
expect(9);
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
var onProgressCalled = false;
var expectedId, expectedName;
var uploadHandler = new qq.UploadHandlerXhr({
action: 'action-handler-test.php',
onProgress: function(id, fileName, loaded, total){
if (!onProgressCalled) {
onProgressCalled = true;
same(id, expectedId, 'progress event fired with correct id param');
same(fileName, expectedName, 'progress event fired with correct fileName param')
ok(loaded <= total && total > 0, 'progress event fired with possible loaded and total');
same(total, uploadHandler.getSize(id), 'getSize method');
}
},
onComplete: function(id, fileName, response){
same(id, expectedId, 'progress event fired with correct id param');
same(fileName, expectedName, 'progress event fired with correct fileName param')
data.fileName = fileName;
data.qqfile = fileName;
same(response, data, 'server received passed params, filenames match');
same(fileName, uploadHandler.getName(id), 'getName method');
}
});
var input = document.getElementById('handlerxhr1');
qq.attach(input, 'change', function(){
setTimeout(start, uploadTimeout);
var id = uploadHandler.add(input.files[0]);
ok(id != null, 'id returned by add');
expectedId = id;
expectedName = input.files[0].name || input.files[0].fileName;
if (!expectedName){
ok(false, 'false value as a file name used');
}
uploadHandler.upload(id, data);
qq.remove(input);
});
});
asyncTest("cancel", function() {
var uploadHandler = new qq.UploadHandlerXhr({
action: 'action-slow-response.php',
onComplete: function(id, fileName, response){
ok(false, 'onComplete should not run, the request should be cancelled');
}
});
var input = document.getElementById('handlerxhr2');
if (!input){
// input removed because uploading via XHR is not supported
return;
}
qq.attach(input, 'change', function(){
var id = uploadHandler.add(input.files[0]);
uploadHandler.upload(id);
uploadHandler.cancel(id);
start();
qq.remove(input);
});
});
}
});
</script>
</head>
<body>
<h1 id="qunit-header">File uploader tests</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<p>
Open this page via https connection, and make sure that loading bar is not acting strange after all tests are run.
Back button test fails in Opera.
</p>
<p>Please select a file for each input below (in order)</p>
<p>qq.FileUploader</p>
<div id="fileuploader1"></div>
<p>qq.UploadHandlerForm</p>
<input class="handlerform" id="testinput1" type="file">
<input class="handlerform" id="testinput2" type="file">
<p>qq.UploadHandlerXhr</p>
<input class="handlerxhr" id="handlerxhr1" type="file">
<input class="handlerxhr" id="handlerxhr2" type="file">
</body>
</html>

View file

@ -0,0 +1,218 @@
<?php
function js_upload_install() {
register_hooks('photo_post_init', 'addon/js_upload/js_upload.php', 'js_upload_post_init');
register_hooks('photo_post_file', 'addon/js_upload/js_upload.php', 'js_upload_post_file');
register_hooks('photo_post_end', 'addon/js_upload/js_upload.php', 'js_upload_post_end');
}
function js_upload_uninstall() {
register_hooks('photo_post_init', 'addon/js_upload/js_upload.php', 'js_upload_post_init');
register_hooks('photo_post_file', 'addon/js_upload/js_upload.php', 'js_upload_post_file');
register_hooks('photo_post_end', 'addon/js_upload/js_upload.php', 'js_upload_post_end');
}
function js_upload_post_init(&$a,&$b) {
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array("jpeg","gif","png","jpg");
// max file size in bytes
$sizeLimit = 6 * 1024 * 1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
$a->data['upload_jsonresponse'] = htmlspecialchars(json_encode($result), ENT_NOQUOTES);
if(isset($result['error'])) {
logger('mod/photos.php: photos_post(): error uploading photo: ' . $result['error'] , 'LOGGER_DEBUG');
killme();
}
}
function js_upload_photo_post_file(&$a,&$b) {
$b['src'] = 'uploads/'.$result['filename'];
$b['filename'] = $result['filename'];
$b['filesize'] = filesize($src);
}
function js_upload_photo_post_end(&$a,&$b) {
if(x($a->data,'upload_jsonresponse')) {
echo $a->data['upload_jsonresponse'];
@unlink($src);
killme();
}
}
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 10485760;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
logger('mod/photos.php: qqFileUploader(): upload_max_filesize=' . $uploadSize , 'LOGGER_DEBUG');
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
if (!is_writable($uploadDirectory)){
return array('error' => t('Server error. Upload directory isn't writable.'));
}
if (!$this->file){
return array('error' => t('No files were uploaded.'));
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => t('Uploaded file is empty'));
}
if ($size > $this->sizeLimit) {
return array('error' => t('Uploaded file is too large'));
}
$maximagesize = get_config('system','maximagesize');
if(($maximagesize) && ($size > $maximagesize)) {
return array('error' => t('Image exceeds size limit of ') . $maximagesize );
}
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'];
//$filename = md5(uniqid());
$ext = $pathinfo['extension'];
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => t('File has an invalid extension, it should be one of ') . $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
return array('success'=>true,'filename' => $filename . '.' . $ext);
} else {
return array('error'=> t('Could not save uploaded file.') .
t('The upload was cancelled, or server error encountered'),'filename' => $filename . '.' . $ext);
}
}
}