summaryrefslogtreecommitdiff
path: root/javascript/jquery/plugins
diff options
context:
space:
mode:
authorspider <spider@bitweaver.org>2015-02-18 12:21:07 -0500
committerspider <spider@bitweaver.org>2015-02-18 12:21:07 -0500
commit6c205972f2b8d8fdeacdd0569567a594b8017750 (patch)
tree6e82c6a24fa631c1d98b64f579a02b7ec7ded6be /javascript/jquery/plugins
parent3e766d4c2a8a0db7446272f262c453954f583af0 (diff)
downloadutil-6c205972f2b8d8fdeacdd0569567a594b8017750.tar.gz
util-6c205972f2b8d8fdeacdd0569567a594b8017750.tar.bz2
util-6c205972f2b8d8fdeacdd0569567a594b8017750.zip
move all javascript/libs/* to javascript/*
Diffstat (limited to 'javascript/jquery/plugins')
-rw-r--r--javascript/jquery/plugins/autocomplete/jquery.autocomplete-min.js11
-rw-r--r--javascript/jquery/plugins/autocomplete/jquery.autocomplete.js390
-rw-r--r--javascript/jquery/plugins/autocomplete/shadow.pngbin0 -> 3403 bytes
-rw-r--r--javascript/jquery/plugins/autocomplete/styles.css6
-rw-r--r--javascript/jquery/plugins/cm_pageflip/pageflip.js380
-rw-r--r--javascript/jquery/plugins/colorbox/colorbox.css69
-rw-r--r--javascript/jquery/plugins/colorbox/images/border.pngbin0 -> 112 bytes
-rw-r--r--javascript/jquery/plugins/colorbox/images/controls.pngbin0 -> 2893 bytes
-rw-r--r--javascript/jquery/plugins/colorbox/images/loading.gifbin0 -> 9427 bytes
-rw-r--r--javascript/jquery/plugins/colorbox/images/loading_background.pngbin0 -> 157 bytes
-rw-r--r--javascript/jquery/plugins/colorbox/images/overlay.pngbin0 -> 182 bytes
-rw-r--r--javascript/jquery/plugins/colorbox/jquery.colorbox-min.js7
-rw-r--r--javascript/jquery/plugins/colorbox/jquery.colorbox.js1063
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/css/colorpicker.css167
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/css/layout.css218
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/Thumbs.dbbin0 -> 19968 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/blank.gifbin0 -> 49 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_background.pngbin0 -> 1897 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_hex.pngbin0 -> 532 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_hsb_b.pngbin0 -> 970 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_hsb_h.pngbin0 -> 1012 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_hsb_s.pngbin0 -> 1171 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_indic.gifbin0 -> 86 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_overlay.pngbin0 -> 10355 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_rgb_b.pngbin0 -> 970 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_rgb_g.pngbin0 -> 1069 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_rgb_r.pngbin0 -> 1066 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_select.gifbin0 -> 78 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/colorpicker_submit.pngbin0 -> 984 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_background.pngbin0 -> 1916 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_hex.pngbin0 -> 562 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_hsb_b.pngbin0 -> 1097 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_hsb_h.pngbin0 -> 970 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_hsb_s.pngbin0 -> 1168 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_indic.gifbin0 -> 86 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_rgb_b.pngbin0 -> 1008 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_rgb_g.pngbin0 -> 1069 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_rgb_r.pngbin0 -> 1018 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/custom_submit.pngbin0 -> 3843 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/select.pngbin0 -> 506 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/select2.pngbin0 -> 518 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/images/slider.pngbin0 -> 315 bytes
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/js/colorpicker.js484
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/js/eye.js34
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/js/layout.js67
-rwxr-xr-xjavascript/jquery/plugins/colorpicker/js/utils.js252
-rw-r--r--javascript/jquery/plugins/cropper/cropper.css278
-rw-r--r--javascript/jquery/plugins/cropper/cropper.js1588
-rw-r--r--javascript/jquery/plugins/cropper/cropper.min.css9
-rw-r--r--javascript/jquery/plugins/cropper/cropper.min.js9
-rw-r--r--javascript/jquery/plugins/fancybox/blank.gifbin0 -> 43 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_close.pngbin0 -> 1517 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_closebox.pngbin0 -> 1910 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_left.pngbin0 -> 1623 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_loading.pngbin0 -> 10195 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_nav_left.pngbin0 -> 1446 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_nav_right.pngbin0 -> 1454 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_progress.pngbin0 -> 12412 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_right.pngbin0 -> 1645 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_e.pngbin0 -> 107 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_n.pngbin0 -> 106 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_ne.pngbin0 -> 347 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_nw.pngbin0 -> 324 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_s.pngbin0 -> 111 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_se.pngbin0 -> 352 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_sw.pngbin0 -> 340 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_shadow_w.pngbin0 -> 103 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_title_left.pngbin0 -> 503 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_title_main.pngbin0 -> 96 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_title_over.pngbin0 -> 70 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancy_title_right.pngbin0 -> 506 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancybox-x.pngbin0 -> 203 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancybox-y.pngbin0 -> 176 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancybox.pngbin0 -> 15287 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancybox_loading.gifbin0 -> 4270 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/fancybox_sprite.pngbin0 -> 3633 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/helpers/fancybox_buttons.pngbin0 -> 2396 bytes
-rw-r--r--javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.css85
-rw-r--r--javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.js115
-rw-r--r--javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.css54
-rw-r--r--javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.js157
-rw-r--r--javascript/jquery/plugins/fancybox/jquery.easing-1.3.pack.js72
-rw-r--r--javascript/jquery/plugins/fancybox/jquery.fancybox.css222
-rw-r--r--javascript/jquery/plugins/fancybox/jquery.fancybox.js1456
-rw-r--r--javascript/jquery/plugins/fancybox/jquery.fancybox.pack.js35
-rw-r--r--javascript/jquery/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js14
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.css9
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.js294
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.min.js19
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.pack.js15
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/lib/jquery.bgiframe.js104
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/lib/jquery.delegate.js56
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/lib/jquery.dimensions.js504
-rw-r--r--javascript/jquery/plugins/jquery-tooltip/lib/jquery.js3383
-rw-r--r--javascript/jquery/plugins/migrate/jquery.migrate.js521
-rw-r--r--javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.js180
-rw-r--r--javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.min.js11
97 files changed, 12338 insertions, 0 deletions
diff --git a/javascript/jquery/plugins/autocomplete/jquery.autocomplete-min.js b/javascript/jquery/plugins/autocomplete/jquery.autocomplete-min.js
new file mode 100644
index 0000000..7018fd0
--- /dev/null
+++ b/javascript/jquery/plugins/autocomplete/jquery.autocomplete-min.js
@@ -0,0 +1,11 @@
+/**
+* Ajax Autocomplete for jQuery, version 1.1.3
+* (c) 2010 Tomas Kirda
+*
+* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
+* For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
+*
+* Last Review: 04/19/2010
+*/
+
+(function(d){function l(b,a,c){a="("+c.replace(m,"\\$1")+")";return b.replace(new RegExp(a,"gi"),"<strong>$1</strong>")}function i(b,a){this.el=d(b);this.el.attr("autocomplete","off");this.suggestions=[];this.data=[];this.badQueries=[];this.selectedIndex=-1;this.currentValue=this.el.val();this.intervalId=0;this.cachedResponse=[];this.onChangeInterval=null;this.ignoreValueChange=false;this.serviceUrl=a.serviceUrl;this.isLocal=false;this.options={autoSubmit:false,minChars:1,maxHeight:300,deferRequestBy:0, width:0,highlight:true,params:{},fnFormatResult:l,delimiter:null,zIndex:9999};this.initialize();this.setOptions(a)}var m=new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\)","g");d.fn.autocomplete=function(b){return new i(this.get(0)||d("<input />"),b)};i.prototype={killerFn:null,initialize:function(){var b,a,c;b=this;a=Math.floor(Math.random()*1048576).toString(16);c="Autocomplete_"+a;this.killerFn=function(e){if(d(e.target).parents(".autocomplete").size()===0){b.killSuggestions(); b.disableKillerFn()}};if(!this.options.width)this.options.width=this.el.width();this.mainContainerId="AutocompleteContainter_"+a;d('<div id="'+this.mainContainerId+'" style="position:absolute;z-index:9999;"><div class="autocomplete-w1"><div class="autocomplete" id="'+c+'" style="display:none; width:300px;"></div></div></div>').appendTo("body");this.container=d("#"+c);this.fixPosition();window.opera?this.el.keypress(function(e){b.onKeyPress(e)}):this.el.keydown(function(e){b.onKeyPress(e)});this.el.keyup(function(e){b.onKeyUp(e)}); this.el.blur(function(){b.enableKillerFn()});this.el.focus(function(){b.fixPosition()})},setOptions:function(b){var a=this.options;d.extend(a,b);if(a.lookup){this.isLocal=true;if(d.isArray(a.lookup))a.lookup={suggestions:a.lookup,data:[]}}d("#"+this.mainContainerId).css({zIndex:a.zIndex});this.container.css({maxHeight:a.maxHeight+"px",width:a.width})},clearCache:function(){this.cachedResponse=[];this.badQueries=[]},disable:function(){this.disabled=true},enable:function(){this.disabled=false},fixPosition:function(){var b= this.el.offset();d("#"+this.mainContainerId).css({top:b.top+this.el.innerHeight()+"px",left:b.left+"px"})},enableKillerFn:function(){d(document).bind("click",this.killerFn)},disableKillerFn:function(){d(document).unbind("click",this.killerFn)},killSuggestions:function(){var b=this;this.stopKillSuggestions();this.intervalId=window.setInterval(function(){b.hide();b.stopKillSuggestions()},300)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},onKeyPress:function(b){if(!(this.disabled|| !this.enabled)){switch(b.keyCode){case 27:this.el.val(this.currentValue);this.hide();break;case 9:case 13:if(this.selectedIndex===-1){this.hide();return}this.select(this.selectedIndex);if(b.keyCode===9)return;break;case 38:this.moveUp();break;case 40:this.moveDown();break;default:return}b.stopImmediatePropagation();b.preventDefault()}},onKeyUp:function(b){if(!this.disabled){switch(b.keyCode){case 38:case 40:return}clearInterval(this.onChangeInterval);if(this.currentValue!==this.el.val())if(this.options.deferRequestBy> 0){var a=this;this.onChangeInterval=setInterval(function(){a.onValueChange()},this.options.deferRequestBy)}else this.onValueChange()}},onValueChange:function(){clearInterval(this.onChangeInterval);this.currentValue=this.el.val();var b=this.getQuery(this.currentValue);this.selectedIndex=-1;if(this.ignoreValueChange)this.ignoreValueChange=false;else b===""||b.length<this.options.minChars?this.hide():this.getSuggestions(b)},getQuery:function(b){var a;a=this.options.delimiter;if(!a)return d.trim(b);b= b.split(a);return d.trim(b[b.length-1])},getSuggestionsLocal:function(b){var a,c,e,g,f;c=this.options.lookup;e=c.suggestions.length;a={suggestions:[],data:[]};b=b.toLowerCase();for(f=0;f<e;f++){g=c.suggestions[f];if(g.toLowerCase().indexOf(b)===0){a.suggestions.push(g);a.data.push(c.data[f])}}return a},getSuggestions:function(b){var a,c;if((a=this.isLocal?this.getSuggestionsLocal(b):this.cachedResponse[b])&&d.isArray(a.suggestions)){this.suggestions=a.suggestions;this.data=a.data;this.suggest()}else if(!this.isBadQuery(b)){c= this;c.options.params.query=b;d.get(this.serviceUrl,c.options.params,function(e){c.processResponse(e)},"text")}},isBadQuery:function(b){for(var a=this.badQueries.length;a--;)if(b.indexOf(this.badQueries[a])===0)return true;return false},hide:function(){this.enabled=false;this.selectedIndex=-1;this.container.hide()},suggest:function(){if(this.suggestions.length===0)this.hide();else{var b,a,c,e,g,f,j,k;b=this;a=this.suggestions.length;e=this.options.fnFormatResult;g=this.getQuery(this.currentValue); j=function(h){return function(){b.activate(h)}};k=function(h){return function(){b.select(h)}};this.container.hide().empty();for(f=0;f<a;f++){c=this.suggestions[f];c=d((b.selectedIndex===f?'<div class="selected"':"<div")+' title="'+c+'">'+e(c,this.data[f],g)+"</div>");c.mouseover(j(f));c.click(k(f));this.container.append(c)}this.enabled=true;this.container.show()}},processResponse:function(b){var a;try{a=eval("("+b+")")}catch(c){return}if(!d.isArray(a.data))a.data=[];if(!this.options.noCache){this.cachedResponse[a.query]= a;a.suggestions.length===0&&this.badQueries.push(a.query)}if(a.query===this.getQuery(this.currentValue)){this.suggestions=a.suggestions;this.data=a.data;this.suggest()}},activate:function(b){var a,c;a=this.container.children();this.selectedIndex!==-1&&a.length>this.selectedIndex&&d(a.get(this.selectedIndex)).removeClass();this.selectedIndex=b;if(this.selectedIndex!==-1&&a.length>this.selectedIndex){c=a.get(this.selectedIndex);d(c).addClass("selected")}return c},deactivate:function(b,a){b.className= "";if(this.selectedIndex===a)this.selectedIndex=-1},select:function(b){var a;if(a=this.suggestions[b]){this.el.val(a);if(this.options.autoSubmit){a=this.el.parents("form");a.length>0&&a.get(0).submit()}this.ignoreValueChange=true;this.hide();this.onSelect(b)}},moveUp:function(){if(this.selectedIndex!==-1)if(this.selectedIndex===0){this.container.children().get(0).className="";this.selectedIndex=-1;this.el.val(this.currentValue)}else this.adjustScroll(this.selectedIndex-1)},moveDown:function(){this.selectedIndex!== this.suggestions.length-1&&this.adjustScroll(this.selectedIndex+1)},adjustScroll:function(b){var a,c,e;a=this.activate(b).offsetTop;c=this.container.scrollTop();e=c+this.options.maxHeight-25;if(a<c)this.container.scrollTop(a);else a>e&&this.container.scrollTop(a-this.options.maxHeight+25);this.el.val(this.getValue(this.suggestions[b]))},onSelect:function(b){var a,c;a=this.options.onSelect;c=this.suggestions[b];b=this.data[b];this.el.val(this.getValue(c));d.isFunction(a)&&a(c,b,this.el)},getValue:function(b){var a, c;a=this.options.delimiter;if(!a)return b;c=this.currentValue;a=c.split(a);if(a.length===1)return b;return c.substr(0,c.length-a[a.length-1].length)+b}}})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/autocomplete/jquery.autocomplete.js b/javascript/jquery/plugins/autocomplete/jquery.autocomplete.js
new file mode 100644
index 0000000..6a7ce87
--- /dev/null
+++ b/javascript/jquery/plugins/autocomplete/jquery.autocomplete.js
@@ -0,0 +1,390 @@
+/**
+* Ajax Autocomplete for jQuery, version 1.1.3
+* (c) 2010 Tomas Kirda
+*
+* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
+* For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
+*
+* Last Review: 04/19/2010
+*/
+
+/*jslint onevar: true, evil: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
+/*global window: true, document: true, clearInterval: true, setInterval: true, jQuery: true */
+
+(function($) {
+
+ var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
+
+ function fnFormatResult(value, data, currentValue) {
+ var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
+ return value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
+ }
+
+ function Autocomplete(el, options) {
+ this.el = $(el);
+ this.el.attr('autocomplete', 'off');
+ this.suggestions = [];
+ this.data = [];
+ this.badQueries = [];
+ this.selectedIndex = -1;
+ this.currentValue = this.el.val();
+ this.intervalId = 0;
+ this.cachedResponse = [];
+ this.onChangeInterval = null;
+ this.ignoreValueChange = false;
+ this.serviceUrl = options.serviceUrl;
+ this.isLocal = false;
+ this.options = {
+ autoSubmit: false,
+ minChars: 1,
+ maxHeight: 300,
+ deferRequestBy: 0,
+ width: 0,
+ highlight: true,
+ params: {},
+ fnFormatResult: fnFormatResult,
+ delimiter: null,
+ zIndex: 9999
+ };
+ this.initialize();
+ this.setOptions(options);
+ }
+
+ $.fn.autocomplete = function(options) {
+ return new Autocomplete(this.get(0)||$('<input />'), options);
+ };
+
+
+ Autocomplete.prototype = {
+
+ killerFn: null,
+
+ initialize: function() {
+
+ var me, uid, autocompleteElId;
+ me = this;
+ uid = Math.floor(Math.random()*0x100000).toString(16);
+ autocompleteElId = 'Autocomplete_' + uid;
+
+ this.killerFn = function(e) {
+ if ($(e.target).parents('.autocomplete').size() === 0) {
+ me.killSuggestions();
+ me.disableKillerFn();
+ }
+ };
+
+ if (!this.options.width) { this.options.width = this.el.width(); }
+ this.mainContainerId = 'AutocompleteContainter_' + uid;
+
+ $('<div id="' + this.mainContainerId + '" style="position:absolute;z-index:9999;"><div class="autocomplete-w1"><div class="autocomplete" id="' + autocompleteElId + '" style="display:none; width:300px;"></div></div></div>').appendTo('body');
+
+ this.container = $('#' + autocompleteElId);
+ this.fixPosition();
+ if (window.opera) {
+ this.el.keypress(function(e) { me.onKeyPress(e); });
+ } else {
+ this.el.keydown(function(e) { me.onKeyPress(e); });
+ }
+ this.el.keyup(function(e) { me.onKeyUp(e); });
+ this.el.blur(function() { me.enableKillerFn(); });
+ this.el.focus(function() { me.fixPosition(); });
+ },
+
+ setOptions: function(options){
+ var o = this.options;
+ $.extend(o, options);
+ if(o.lookup){
+ this.isLocal = true;
+ if($.isArray(o.lookup)){ o.lookup = { suggestions:o.lookup, data:[] }; }
+ }
+ $('#'+this.mainContainerId).css({ zIndex:o.zIndex });
+ this.container.css({ maxHeight: o.maxHeight + 'px', width:o.width });
+ },
+
+ clearCache: function(){
+ this.cachedResponse = [];
+ this.badQueries = [];
+ },
+
+ disable: function(){
+ this.disabled = true;
+ },
+
+ enable: function(){
+ this.disabled = false;
+ },
+
+ fixPosition: function() {
+ var offset = this.el.offset();
+ $('#' + this.mainContainerId).css({ top: (offset.top + this.el.innerHeight()) + 'px', left: offset.left + 'px' });
+ },
+
+ enableKillerFn: function() {
+ var me = this;
+ $(document).bind('click', me.killerFn);
+ },
+
+ disableKillerFn: function() {
+ var me = this;
+ $(document).unbind('click', me.killerFn);
+ },
+
+ killSuggestions: function() {
+ var me = this;
+ this.stopKillSuggestions();
+ this.intervalId = window.setInterval(function() { me.hide(); me.stopKillSuggestions(); }, 300);
+ },
+
+ stopKillSuggestions: function() {
+ window.clearInterval(this.intervalId);
+ },
+
+ onKeyPress: function(e) {
+ if (this.disabled || !this.enabled) { return; }
+ // return will exit the function
+ // and event will not be prevented
+ switch (e.keyCode) {
+ case 27: //KEY_ESC:
+ this.el.val(this.currentValue);
+ this.hide();
+ break;
+ case 9: //KEY_TAB:
+ case 13: //KEY_RETURN:
+ if (this.selectedIndex === -1) {
+ this.hide();
+ return;
+ }
+ this.select(this.selectedIndex);
+ if(e.keyCode === 9){ return; }
+ break;
+ case 38: //KEY_UP:
+ this.moveUp();
+ break;
+ case 40: //KEY_DOWN:
+ this.moveDown();
+ break;
+ default:
+ return;
+ }
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ },
+
+ onKeyUp: function(e) {
+ if(this.disabled){ return; }
+ switch (e.keyCode) {
+ case 38: //KEY_UP:
+ case 40: //KEY_DOWN:
+ return;
+ }
+ clearInterval(this.onChangeInterval);
+ if (this.currentValue !== this.el.val()) {
+ if (this.options.deferRequestBy > 0) {
+ // Defer lookup in case when value changes very quickly:
+ var me = this;
+ this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy);
+ } else {
+ this.onValueChange();
+ }
+ }
+ },
+
+ onValueChange: function() {
+ clearInterval(this.onChangeInterval);
+ this.currentValue = this.el.val();
+ var q = this.getQuery(this.currentValue);
+ this.selectedIndex = -1;
+ if (this.ignoreValueChange) {
+ this.ignoreValueChange = false;
+ return;
+ }
+ if (q === '' || q.length < this.options.minChars) {
+ this.hide();
+ } else {
+ this.getSuggestions(q);
+ }
+ },
+
+ getQuery: function(val) {
+ var d, arr;
+ d = this.options.delimiter;
+ if (!d) { return $.trim(val); }
+ arr = val.split(d);
+ return $.trim(arr[arr.length - 1]);
+ },
+
+ getSuggestionsLocal: function(q) {
+ var ret, arr, len, val, i;
+ arr = this.options.lookup;
+ len = arr.suggestions.length;
+ ret = { suggestions:[], data:[] };
+ q = q.toLowerCase();
+ for(i=0; i< len; i++){
+ val = arr.suggestions[i];
+ if(val.toLowerCase().indexOf(q) === 0){
+ ret.suggestions.push(val);
+ ret.data.push(arr.data[i]);
+ }
+ }
+ return ret;
+ },
+
+ getSuggestions: function(q) {
+ var cr, me;
+ cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];
+ if (cr && $.isArray(cr.suggestions)) {
+ this.suggestions = cr.suggestions;
+ this.data = cr.data;
+ this.suggest();
+ } else if (!this.isBadQuery(q)) {
+ me = this;
+ me.options.params.query = q;
+ $.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text');
+ }
+ },
+
+ isBadQuery: function(q) {
+ var i = this.badQueries.length;
+ while (i--) {
+ if (q.indexOf(this.badQueries[i]) === 0) { return true; }
+ }
+ return false;
+ },
+
+ hide: function() {
+ this.enabled = false;
+ this.selectedIndex = -1;
+ this.container.hide();
+ },
+
+ suggest: function() {
+ if (this.suggestions.length === 0) {
+ this.hide();
+ return;
+ }
+
+ var me, len, div, f, v, i, s, mOver, mClick;
+ me = this;
+ len = this.suggestions.length;
+ f = this.options.fnFormatResult;
+ v = this.getQuery(this.currentValue);
+ mOver = function(xi) { return function() { me.activate(xi); }; };
+ mClick = function(xi) { return function() { me.select(xi); }; };
+ this.container.hide().empty();
+ for (i = 0; i < len; i++) {
+ s = this.suggestions[i];
+ div = $((me.selectedIndex === i ? '<div class="selected"' : '<div') + ' title="' + s + '">' + f(s, this.data[i], v) + '</div>');
+ div.mouseover(mOver(i));
+ div.click(mClick(i));
+ this.container.append(div);
+ }
+ this.enabled = true;
+ this.container.show();
+ },
+
+ processResponse: function(text) {
+ var response;
+ try {
+ response = eval('(' + text + ')');
+ } catch (err) { return; }
+ if (!$.isArray(response.data)) { response.data = []; }
+ if(!this.options.noCache){
+ this.cachedResponse[response.query] = response;
+ if (response.suggestions.length === 0) { this.badQueries.push(response.query); }
+ }
+ if (response.query === this.getQuery(this.currentValue)) {
+ this.suggestions = response.suggestions;
+ this.data = response.data;
+ this.suggest();
+ }
+ },
+
+ activate: function(index) {
+ var divs, activeItem;
+ divs = this.container.children();
+ // Clear previous selection:
+ if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
+ $(divs.get(this.selectedIndex)).removeClass();
+ }
+ this.selectedIndex = index;
+ if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
+ activeItem = divs.get(this.selectedIndex);
+ $(activeItem).addClass('selected');
+ }
+ return activeItem;
+ },
+
+ deactivate: function(div, index) {
+ div.className = '';
+ if (this.selectedIndex === index) { this.selectedIndex = -1; }
+ },
+
+ select: function(i) {
+ var selectedValue, f;
+ selectedValue = this.suggestions[i];
+ if (selectedValue) {
+ this.el.val(selectedValue);
+ if (this.options.autoSubmit) {
+ f = this.el.parents('form');
+ if (f.length > 0) { f.get(0).submit(); }
+ }
+ this.ignoreValueChange = true;
+ this.hide();
+ this.onSelect(i);
+ }
+ },
+
+ moveUp: function() {
+ if (this.selectedIndex === -1) { return; }
+ if (this.selectedIndex === 0) {
+ this.container.children().get(0).className = '';
+ this.selectedIndex = -1;
+ this.el.val(this.currentValue);
+ return;
+ }
+ this.adjustScroll(this.selectedIndex - 1);
+ },
+
+ moveDown: function() {
+ if (this.selectedIndex === (this.suggestions.length - 1)) { return; }
+ this.adjustScroll(this.selectedIndex + 1);
+ },
+
+ adjustScroll: function(i) {
+ var activeItem, offsetTop, upperBound, lowerBound;
+ activeItem = this.activate(i);
+ offsetTop = activeItem.offsetTop;
+ upperBound = this.container.scrollTop();
+ lowerBound = upperBound + this.options.maxHeight - 25;
+ if (offsetTop < upperBound) {
+ this.container.scrollTop(offsetTop);
+ } else if (offsetTop > lowerBound) {
+ this.container.scrollTop(offsetTop - this.options.maxHeight + 25);
+ }
+ this.el.val(this.getValue(this.suggestions[i]));
+ },
+
+ onSelect: function(i) {
+ var me, fn, s, d;
+ me = this;
+ fn = me.options.onSelect;
+ s = me.suggestions[i];
+ d = me.data[i];
+ me.el.val(me.getValue(s));
+ if ($.isFunction(fn)) { fn(s, d, me.el); }
+ },
+
+ getValue: function(value){
+ var del, currVal, arr, me;
+ me = this;
+ del = me.options.delimiter;
+ if (!del) { return value; }
+ currVal = me.currentValue;
+ arr = currVal.split(del);
+ if (arr.length === 1) { return value; }
+ return currVal.substr(0, currVal.length - arr[arr.length - 1].length) + value;
+ }
+
+ };
+
+}(jQuery));
diff --git a/javascript/jquery/plugins/autocomplete/shadow.png b/javascript/jquery/plugins/autocomplete/shadow.png
new file mode 100644
index 0000000..a2561df
--- /dev/null
+++ b/javascript/jquery/plugins/autocomplete/shadow.png
Binary files differ
diff --git a/javascript/jquery/plugins/autocomplete/styles.css b/javascript/jquery/plugins/autocomplete/styles.css
new file mode 100644
index 0000000..dd9f97e
--- /dev/null
+++ b/javascript/jquery/plugins/autocomplete/styles.css
@@ -0,0 +1,6 @@
+
+.autocomplete-w1 { background:url(img/shadow.png) no-repeat bottom right; position:absolute; top:0px; left:0px; margin:8px 0 0 6px; /* IE6 fix: */ _background:none; _margin:0; }
+.autocomplete { border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; }
+.autocomplete .selected { background:#F0F0F0; }
+.autocomplete div { padding:2px 5px; white-space:nowrap; }
+.autocomplete strong { font-weight:normal; color:#3399FF; }
diff --git a/javascript/jquery/plugins/cm_pageflip/pageflip.js b/javascript/jquery/plugins/cm_pageflip/pageflip.js
new file mode 100644
index 0000000..5087d87
--- /dev/null
+++ b/javascript/jquery/plugins/cm_pageflip/pageflip.js
@@ -0,0 +1,380 @@
+/*
+Javascript Pageflip v0.2 by Charles Mangin (http://option8.com)
+
+
+Creative Commons License:
+
+Javascript Pageflip v0.2 by Charles Mangin is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
+
+You are free:
+
+to Share — to copy, distribute, display, and perform the work
+to Remix — to make derivative works
+
+Under the following conditions:
+
+Attribution. You must attribute this work to Charles Mangin ( with link: http://option8.com ).
+
+
+Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same,
+similar or a compatible license.
+
+For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is
+with a link to this web page: http://creativecommons.org/licenses/by-sa/3.0/us/
+
+Any of the above conditions can be waived if you get permission from the copyright holder.
+
+Apart from the remix rights granted under this license, nothing in this license impairs or restricts the author's moral rights.
+
+*/
+
+/**
+ * Modifications performed 06.11.10:
+ * - In pageLayout(), pageWidth and pageHeight are now set to the current values of .pageimage class
+ * to enable dynamic resizing of pages
+ * - Sixth page added to allow visibility thorough 2 consecutive pages with transparent elements.
+ * - Initialize function changed to be called manually as opposed to window.onload()
+ * - Add optional parameter to flipForward and flipBack to pass in callback function for when flipping is complete.
+ * - Add variables to store callback functions for flipForward and flipBack
+ * @author Brian Stegmann
+ */
+
+//Variables to hold callback functions for flipForward and FlipBack
+var onFlipForwardFinish;
+var onFlipBackFinish;
+
+/* set up variables */
+
+var imageArray = new Array();
+
+
+// display page l/r. next spread l/r. previous spread l/r.
+var pageN1, page0, page1, page2, page3, page4, page6;
+
+
+// img tags within each page hold the contents
+var pageN1img, page0img, page1img, page2img, page3img, page4img, page6img;;
+
+// originally worked with bg images, but now the bg is shadow
+var pageIndex = 0; // initial starting page
+
+var page1image = new Image(); // Create new Image object
+var page2image = new Image(); // Create new Image object
+
+// next LEFT page
+var page3image = new Image(); // Create new Image object
+var page3OriginX; // page 3 starting position
+var page3x; // page 3 current position
+var page3DeltaX; // frame-to-frame diff in page 3 x value
+// next RIGHT page
+var page4image = new Image(); // Create new Image object
+
+// previous RIGHT page
+var page0image = new Image(); // Create new Image object
+var page0OriginX; // page 0 starting position
+var page0x;
+var page0DeltaX; // frame-to-frame diff in page 3 x value
+// previous LEFT page
+var pageN1image = new Image(); // Create new Image object
+
+//second next RIGHT page
+var page6image = new Image();
+
+// timer
+var currentStep, totalSteps;
+
+
+var pageWidth, page2Width, page3Width, page4Width, page6Width, page1Width, page0Width;
+var pageHeight;
+
+
+var page3TargetX; // page 3 aims for 0px
+var page0TargetX; // page 0 aims for pagewidth px
+
+// the div that holds it all
+var pagesContainer;
+
+// animating on/off
+var flipping;
+
+
+function pageLayout() {
+
+// console.log("doing layout");
+
+
+ page1image.src = imageArray[pageIndex].src; // Set source path
+ page1img = document.getElementById('page1img');
+ page1img.src = page1image.src ;
+
+ if(typeof(imageArray[pageIndex+1]) != "undefined") {
+ page2image.src = imageArray[pageIndex+1].src; // Set source path
+ page2img = document.getElementById('page2img');
+ page2img.src = page2image.src ;
+ }
+
+ if(typeof(imageArray[pageIndex+2]) != "undefined") {
+ page3image.src = imageArray[pageIndex+2].src; // Set source path
+ page3img = document.getElementById('page3img');
+ page3img.src = page3image.src ;
+ }
+ if(typeof(imageArray[pageIndex+3]) != "undefined") {
+ page4image.src = imageArray[pageIndex+3].src; // Set source path
+ page4img = document.getElementById('page4img');
+ page4img.src = page4image.src ;
+ }
+ if(typeof(imageArray[pageIndex+5]) != "undefined") {
+ page6image.src = imageArray[pageIndex+5].src; // Set source path
+ page6img = document.getElementById('page6img');
+ page6img.src = page6image.src ;
+ }
+ if(typeof(imageArray[pageIndex-1]) != "undefined") {
+ page0image.src = imageArray[pageIndex-1].src; // Set source path
+ page0img = document.getElementById('page0img');
+ page0img.src = page0image.src ;
+ }
+ if(typeof(imageArray[pageIndex-2]) != "undefined") {
+ pageN1image.src = imageArray[pageIndex-2].src; // Set source path
+ pageN1img = document.getElementById('pageN1img');
+ pageN1img.src = pageN1image.src ;
+ }
+
+// set the page width all the pages key off. if image1 is an odd size, choose a different one to key
+ //pageWidth = page1image.width;
+ //pageHeight = page1image.height;
+
+ pageWidth = $('.pageimage').width();
+ pageHeight = $('.pageimage').height();
+
+// console.log("page width = " + page1img.width);
+
+
+// set up pages
+ page1 = document.getElementById('page1');
+
+
+ page2 = document.getElementById('page2');
+ page3 = document.getElementById('page3');
+ page4 = document.getElementById('page4');
+
+ page6 = document.getElementById('page6');
+
+ page0 = document.getElementById('page0');
+ pageN1 = document.getElementById('pageN1');
+
+// uniform height/width for the page DIVs
+ page0.style.height = pageN1.style.height = page1.style.height = page2.style.height =
+ page3.style.height = page4.style.height = page6.style.height = (pageHeight+2) + "px";
+
+
+ page0.style.width = pageN1.style.width = page1.style.width = page2.style.width =
+ page3.style.width = page4.style.width = page6.style.width = (pageWidth+2) + "px";
+
+
+ page0Width = pageWidth;
+ page2Width = pageWidth;
+
+// set the next/previous pages up for their animations
+ page2.style.left = page4.style.left = page6.style.left = pageWidth + "px";
+ page0.style.left = 0 + "px";
+ page1.style.left = 0 + "px";
+
+ page3TargetX = 0;
+ page0TargetX = pageWidth;
+
+
+
+// initial position for page 3 - flip forward
+ page3OriginX = pageWidth * 2;
+ page3.style.left = pageWidth * 2 + "px";
+ page3Width = 0;
+ page3.style.width = page3Width + "px";
+
+// initial position for page 0 - flip back
+ page0OriginX = 0;
+ page0.style.left = 0 + "px";
+ page0Width = 0;
+ page0.style.width = page0Width + "px";
+
+
+// set up next page flip
+ currentStep = 1;
+ totalSteps = flipTime/smoothness;
+
+ // start out the page3 canvas at start position
+ page3x = 2 * pageWidth;
+ page0x = 0;
+
+// hide the previous pages
+ page0.style.display = "none";
+ pageN1.style.display = "none";
+
+// clicky cursor
+ if(typeof(imageArray[pageIndex]) != "undefined") {
+ page1.style.cursor="hand";
+ } else {
+ page1.style.cursor="default";
+ }
+
+ if(typeof(imageArray[pageIndex+1]) != "undefined") {
+ page2.style.cursor="hand";
+ } else {
+ page2.style.cursor="default";
+ }
+
+ // ready to go...
+ flipping = false;
+
+}
+
+
+function flipForward() {
+
+// linear
+ //page3DeltaX = (page3TargetX-page3OriginX)/totalSteps; // distance per step
+ //page3x += page3DeltaX;
+
+ page3OldX = page3x;
+
+// ease out
+// page3x = page3OriginX + (Math.sin( (currentStep/totalSteps) * (Math.PI/2) ) * (page3TargetX-page3OriginX) );
+
+// ease in/out
+ page3x = ((1 + Math.cos( (currentStep/totalSteps) * (Math.PI) ))/2) * (page3OriginX - page3TargetX);
+
+ page3DeltaX = page3x - page3OldX;
+
+ // shadow
+ page3ShadowWidth = -4 * page3DeltaX;
+ page3.style.paddingLeft = page3ShadowWidth + "px"
+
+ page3.style.left = page3x - page3ShadowWidth + "px";
+
+ page2Width += page3DeltaX;
+
+ if(page2Width > 0) { // surprise, IE doesn't like negative width
+ page2.style.width = Math.floor(page2Width) + "px";
+ } else {
+ page2Width = 0;
+ page2.style.width = Math.floor(page2Width) + "px";
+ }
+ page3Width -= page3DeltaX/2;
+ page3.style.width = Math.floor(page3Width) + "px";
+
+ if(currentStep == totalSteps){
+ clearInterval(nextPageFlip);
+ pageIndex += 2;
+ pageLayout();
+ if(onFlipForwardFinish != null) {
+ onFlipForwardFinish();
+ }
+ }
+
+ currentStep ++;
+
+}
+
+/**
+ * Function to initiate forward flip.
+ *
+ * @param flipForwardOnComplete function
+ */
+function nextPage( flipForwardOnComplete ) {
+
+ onFlipForwardFinish = flipForwardOnComplete;
+
+ if((typeof(imageArray[pageIndex+2]) != "undefined") && (flipping == false) ){
+ nextPageFlip = setInterval(flipForward,smoothness);
+ flipping = true;
+ }
+}
+
+
+function flipBack() {
+
+ page0.style.display = "block";
+ pageN1.style.display = "block";
+
+
+ page0OldX = page0x;
+
+
+// ease in/out
+ page0x = page0OriginX + ((1 - Math.cos( (currentStep/totalSteps) * (Math.PI) ))/2) * (page0TargetX - page0OriginX);
+
+ page0DeltaX = page0x - page0OldX;
+
+
+ page0.style.left = page0x + "px";
+ page1.style.left = page0x + "px";
+
+ // move contents over to pretend we're cropping from the left
+ page0.style.textIndent = -1 * pageWidth + page0x + "px";
+
+// grow the -1 page to match the movement of page 0
+ pageN1.style.width = page0x + "px";
+
+//shrink page 1 to match movement of page 0
+ page1Width = page1.style.width.replace('px', '');
+
+
+ page1Width -= page0DeltaX;
+ if(page1Width < 0) {
+ page1Width = 0;
+ }
+
+ page1.style.width = page1Width + 'px';
+ page1img.style.width = page1Width + 'px';
+
+ page0Width += page0DeltaX;
+
+ // shadow
+ page0ShadowWidth = 4 * page0DeltaX;
+ page0.style.paddingRight = page0ShadowWidth + "px"
+
+ page0.style.width = Math.floor(page0Width) + page0ShadowWidth + "px";
+
+
+ if(currentStep == totalSteps){
+ clearInterval(nextPageFlip);
+ pageIndex -= 2;
+ page1img.style.width = pageWidth + 'px';
+ pageLayout();
+ if(onFlipBackFinish != null) {
+ onFlipBackFinish();
+ }
+ }
+
+ currentStep ++;
+
+}
+
+/**
+ * Function to initiate back flip.
+ *
+ * @param flipForwardOnComplete function
+ */
+function previousPage( flipBackOnComplete ) {
+
+ onFlipBackFinish = flipBackOnComplete;
+
+ if( (typeof(imageArray[pageIndex-1]) != "undefined") && (flipping == false)){
+ nextPageFlip = setInterval(flipBack,smoothness);
+ flipping = true;
+ }
+}
+
+
+function pageFlipInitialize() {
+
+// console.log("ready");
+
+// build the image array from jquery
+imageArray = $(".pageimage");
+
+//console.log(imageArray[0].src);
+
+ pageLayout();
+
+};
+// window ready
diff --git a/javascript/jquery/plugins/colorbox/colorbox.css b/javascript/jquery/plugins/colorbox/colorbox.css
new file mode 100644
index 0000000..1dedd90
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/colorbox.css
@@ -0,0 +1,69 @@
+/*
+ Colorbox Core Style:
+ The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
+#cboxOverlay{position:fixed; width:100%; height:100%;}
+#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
+#cboxContent{position:relative;}
+#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
+#cboxTitle{margin:0;}
+#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
+#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
+.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
+.cboxIframe{width:100%; height:100%; display:block; border:0;}
+#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
+
+/*
+ User Style:
+ Change the following styles to modify the appearance of Colorbox. They are
+ ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay{background:url(images/overlay.png) repeat 0 0;}
+#colorbox{outline:0;}
+ #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px 0;}
+ #cboxTopRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px 0;}
+ #cboxBottomLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px -29px;}
+ #cboxBottomRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px -29px;}
+ #cboxMiddleLeft{width:21px; background:url(images/controls.png) left top repeat-y;}
+ #cboxMiddleRight{width:21px; background:url(images/controls.png) right top repeat-y;}
+ #cboxTopCenter{height:21px; background:url(images/border.png) 0 0 repeat-x;}
+ #cboxBottomCenter{height:21px; background:url(images/border.png) 0 -29px repeat-x;}
+ #cboxContent{background:#fff; overflow:hidden;}
+ .cboxIframe{background:#fff;}
+ #cboxError{padding:50px; border:1px solid #ccc;}
+ #cboxLoadedContent{margin-bottom:28px;}
+ #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
+ #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
+ #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
+ #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
+
+ /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
+ #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
+
+ /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
+ #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
+
+ #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
+ #cboxPrevious{position:absolute; bottom:0; left:0; background:url(images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxPrevious:hover{background-position:-75px -25px;}
+ #cboxNext{position:absolute; bottom:0; left:27px; background:url(images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxNext:hover{background-position:-50px -25px;}
+ #cboxClose{position:absolute; bottom:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxClose:hover{background-position:-25px -25px;}
+
+/*
+ The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
+ when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9.
+ See: http://jacklmoore.com/notes/ie-transparency-problems/
+*/
+.cboxIE #cboxTopLeft,
+.cboxIE #cboxTopCenter,
+.cboxIE #cboxTopRight,
+.cboxIE #cboxBottomLeft,
+.cboxIE #cboxBottomCenter,
+.cboxIE #cboxBottomRight,
+.cboxIE #cboxMiddleLeft,
+.cboxIE #cboxMiddleRight {
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
+} \ No newline at end of file
diff --git a/javascript/jquery/plugins/colorbox/images/border.png b/javascript/jquery/plugins/colorbox/images/border.png
new file mode 100644
index 0000000..f463a10
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/images/border.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorbox/images/controls.png b/javascript/jquery/plugins/colorbox/images/controls.png
new file mode 100644
index 0000000..dcfd6fb
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/images/controls.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorbox/images/loading.gif b/javascript/jquery/plugins/colorbox/images/loading.gif
new file mode 100644
index 0000000..b4695d8
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/images/loading.gif
Binary files differ
diff --git a/javascript/jquery/plugins/colorbox/images/loading_background.png b/javascript/jquery/plugins/colorbox/images/loading_background.png
new file mode 100644
index 0000000..6ae83e6
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/images/loading_background.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorbox/images/overlay.png b/javascript/jquery/plugins/colorbox/images/overlay.png
new file mode 100644
index 0000000..53ea98f
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/images/overlay.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorbox/jquery.colorbox-min.js b/javascript/jquery/plugins/colorbox/jquery.colorbox-min.js
new file mode 100644
index 0000000..230da8f
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/jquery.colorbox-min.js
@@ -0,0 +1,7 @@
+/*!
+ Colorbox v1.4.27 - 2013-07-16
+ jQuery lightbox and modal window plugin
+ (c) 2013 Jack Moore - http://www.jacklmoore.com/colorbox
+ license: http://www.opensource.org/licenses/mit-license.php
+*/
+(function(t,e,i){function o(i,o,n){var r=e.createElement(i);return o&&(r.id=te+o),n&&(r.style.cssText=n),t(r)}function n(){return i.innerHeight?i.innerHeight:t(i).height()}function r(t){var e=E.length,i=(j+t)%e;return 0>i?e+i:i}function l(t,e){return Math.round((/%/.test(t)?("x"===e?H.width():n())/100:1)*parseInt(t,10))}function h(t,e){return t.photo||t.photoRegex.test(e)}function s(t,e){return t.retinaUrl&&i.devicePixelRatio>1?e.replace(t.photoRegex,t.retinaSuffix):e}function a(t){"contains"in v[0]&&!v[0].contains(t.target)&&(t.stopPropagation(),v.focus())}function d(){var e,i=t.data(A,Z);null==i?(O=t.extend({},Y),console&&console.log&&console.log("Error: cboxElement missing settings object")):O=t.extend({},i);for(e in O)t.isFunction(O[e])&&"on"!==e.slice(0,2)&&(O[e]=O[e].call(A));O.rel=O.rel||A.rel||t(A).data("rel")||"nofollow",O.href=O.href||t(A).attr("href"),O.title=O.title||A.title,"string"==typeof O.href&&(O.href=t.trim(O.href))}function c(i,o){t(e).trigger(i),se.trigger(i),t.isFunction(o)&&o.call(A)}function u(){var t,e,i,o,n,r=te+"Slideshow_",l="click."+te;O.slideshow&&E[1]?(e=function(){clearTimeout(t)},i=function(){(O.loop||E[j+1])&&(t=setTimeout(J.next,O.slideshowSpeed))},o=function(){R.html(O.slideshowStop).unbind(l).one(l,n),se.bind(ne,i).bind(oe,e).bind(re,n),v.removeClass(r+"off").addClass(r+"on")},n=function(){e(),se.unbind(ne,i).unbind(oe,e).unbind(re,n),R.html(O.slideshowStart).unbind(l).one(l,function(){J.next(),o()}),v.removeClass(r+"on").addClass(r+"off")},O.slideshowAuto?o():n()):v.removeClass(r+"off "+r+"on")}function p(i){G||(A=i,d(),E=t(A),j=0,"nofollow"!==O.rel&&(E=t("."+ee).filter(function(){var e,i=t.data(this,Z);return i&&(e=t(this).data("rel")||i.rel||this.rel),e===O.rel}),j=E.index(A),-1===j&&(E=E.add(A),j=E.length-1)),g.css({opacity:parseFloat(O.opacity),cursor:O.overlayClose?"pointer":"auto",visibility:"visible"}).show(),V&&v.add(g).removeClass(V),O.className&&v.add(g).addClass(O.className),V=O.className,O.closeButton?P.html(O.close).appendTo(x):P.appendTo("<div/>"),$||($=q=!0,v.css({visibility:"hidden",display:"block"}),W=o(ae,"LoadedContent","width:0; height:0; overflow:hidden"),x.css({width:"",height:""}).append(W),_=b.height()+k.height()+x.outerHeight(!0)-x.height(),D=T.width()+C.width()+x.outerWidth(!0)-x.width(),N=W.outerHeight(!0),z=W.outerWidth(!0),O.w=l(O.initialWidth,"x"),O.h=l(O.initialHeight,"y"),J.position(),u(),c(ie,O.onOpen),B.add(S).hide(),v.focus(),O.trapFocus&&e.addEventListener&&(e.addEventListener("focus",a,!0),se.one(le,function(){e.removeEventListener("focus",a,!0)})),O.returnFocus&&se.one(le,function(){t(A).focus()})),w())}function f(){!v&&e.body&&(X=!1,H=t(i),v=o(ae).attr({id:Z,"class":t.support.opacity===!1?te+"IE":"",role:"dialog",tabindex:"-1"}).hide(),g=o(ae,"Overlay").hide(),L=t([o(ae,"LoadingOverlay")[0],o(ae,"LoadingGraphic")[0]]),y=o(ae,"Wrapper"),x=o(ae,"Content").append(S=o(ae,"Title"),M=o(ae,"Current"),K=t('<button type="button"/>').attr({id:te+"Previous"}),I=t('<button type="button"/>').attr({id:te+"Next"}),R=o("button","Slideshow"),L),P=t('<button type="button"/>').attr({id:te+"Close"}),y.append(o(ae).append(o(ae,"TopLeft"),b=o(ae,"TopCenter"),o(ae,"TopRight")),o(ae,!1,"clear:left").append(T=o(ae,"MiddleLeft"),x,C=o(ae,"MiddleRight")),o(ae,!1,"clear:left").append(o(ae,"BottomLeft"),k=o(ae,"BottomCenter"),o(ae,"BottomRight"))).find("div div").css({"float":"left"}),F=o(ae,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),B=I.add(K).add(M).add(R),t(e.body).append(g,v.append(y,F)))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),p(this))}return v?(X||(X=!0,I.click(function(){J.next()}),K.click(function(){J.prev()}),P.click(function(){J.close()}),g.click(function(){O.overlayClose&&J.close()}),t(e).bind("keydown."+te,function(t){var e=t.keyCode;$&&O.escKey&&27===e&&(t.preventDefault(),J.close()),$&&O.arrowKey&&E[1]&&!t.altKey&&(37===e?(t.preventDefault(),K.click()):39===e&&(t.preventDefault(),I.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+te,"."+ee,i):t("."+ee).live("click."+te,i)),!0):!1}function w(){var n,r,a,u=J.prep,p=++de;q=!0,U=!1,A=E[j],d(),c(he),c(oe,O.onLoad),O.h=O.height?l(O.height,"y")-N-_:O.innerHeight&&l(O.innerHeight,"y"),O.w=O.width?l(O.width,"x")-z-D:O.innerWidth&&l(O.innerWidth,"x"),O.mw=O.w,O.mh=O.h,O.maxWidth&&(O.mw=l(O.maxWidth,"x")-z-D,O.mw=O.w&&O.w<O.mw?O.w:O.mw),O.maxHeight&&(O.mh=l(O.maxHeight,"y")-N-_,O.mh=O.h&&O.h<O.mh?O.h:O.mh),n=O.href,Q=setTimeout(function(){L.show()},100),O.inline?(a=o(ae).hide().insertBefore(t(n)[0]),se.one(he,function(){a.replaceWith(W.children())}),u(t(n))):O.iframe?u(" "):O.html?u(O.html):h(O,n)?(n=s(O,n),U=e.createElement("img"),t(U).addClass(te+"Photo").bind("error",function(){O.title=!1,u(o(ae,"Error").html(O.imgError))}).one("load",function(){var e;p===de&&(U.alt=t(A).attr("alt")||t(A).attr("data-alt")||"",O.retinaImage&&i.devicePixelRatio>1&&(U.height=U.height/i.devicePixelRatio,U.width=U.width/i.devicePixelRatio),O.scalePhotos&&(r=function(){U.height-=U.height*e,U.width-=U.width*e},O.mw&&U.width>O.mw&&(e=(U.width-O.mw)/U.width,r()),O.mh&&U.height>O.mh&&(e=(U.height-O.mh)/U.height,r())),O.h&&(U.style.marginTop=Math.max(O.mh-U.height,0)/2+"px"),E[1]&&(O.loop||E[j+1])&&(U.style.cursor="pointer",U.onclick=function(){J.next()}),U.style.width=U.width+"px",U.style.height=U.height+"px",setTimeout(function(){u(U)},1))}),setTimeout(function(){U.src=n},1)):n&&F.load(n,O.data,function(e,i){p===de&&u("error"===i?o(ae,"Error").html(O.xhrError):t(this).contents())})}var g,v,y,x,b,T,C,k,E,H,W,F,L,S,M,R,I,K,P,B,O,_,D,N,z,A,j,U,$,q,G,Q,J,V,X,Y={transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:!1,returnFocus:!0,trapFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0},Z="colorbox",te="cbox",ee=te+"Element",ie=te+"_open",oe=te+"_load",ne=te+"_complete",re=te+"_cleanup",le=te+"_closed",he=te+"_purge",se=t("<a/>"),ae="div",de=0,ce={};t.colorbox||(t(f),J=t.fn[Z]=t[Z]=function(e,i){var o=this;if(e=e||{},f(),m()){if(t.isFunction(o))o=t("<a/>"),e.open=!0;else if(!o[0])return o;i&&(e.onComplete=i),o.each(function(){t.data(this,Z,t.extend({},t.data(this,Z)||Y,e))}).addClass(ee),(t.isFunction(e.open)&&e.open.call(o)||e.open)&&p(o[0])}return o},J.position=function(e,i){function o(){b[0].style.width=k[0].style.width=x[0].style.width=parseInt(v[0].style.width,10)-D+"px",x[0].style.height=T[0].style.height=C[0].style.height=parseInt(v[0].style.height,10)-_+"px"}var r,h,s,a=0,d=0,c=v.offset();if(H.unbind("resize."+te),v.css({top:-9e4,left:-9e4}),h=H.scrollTop(),s=H.scrollLeft(),O.fixed?(c.top-=h,c.left-=s,v.css({position:"fixed"})):(a=h,d=s,v.css({position:"absolute"})),d+=O.right!==!1?Math.max(H.width()-O.w-z-D-l(O.right,"x"),0):O.left!==!1?l(O.left,"x"):Math.round(Math.max(H.width()-O.w-z-D,0)/2),a+=O.bottom!==!1?Math.max(n()-O.h-N-_-l(O.bottom,"y"),0):O.top!==!1?l(O.top,"y"):Math.round(Math.max(n()-O.h-N-_,0)/2),v.css({top:c.top,left:c.left,visibility:"visible"}),y[0].style.width=y[0].style.height="9999px",r={width:O.w+z+D,height:O.h+N+_,top:a,left:d},e){var u=0;t.each(r,function(t){return r[t]!==ce[t]?(u=e,void 0):void 0}),e=u}ce=r,e||v.css(r),v.dequeue().animate(r,{duration:e||0,complete:function(){o(),q=!1,y[0].style.width=O.w+z+D+"px",y[0].style.height=O.h+N+_+"px",O.reposition&&setTimeout(function(){H.bind("resize."+te,J.position)},1),i&&i()},step:o})},J.resize=function(t){var e;$&&(t=t||{},t.width&&(O.w=l(t.width,"x")-z-D),t.innerWidth&&(O.w=l(t.innerWidth,"x")),W.css({width:O.w}),t.height&&(O.h=l(t.height,"y")-N-_),t.innerHeight&&(O.h=l(t.innerHeight,"y")),t.innerHeight||t.height||(e=W.scrollTop(),W.css({height:"auto"}),O.h=W.height()),W.css({height:O.h}),e&&W.scrollTop(e),J.position("none"===O.transition?0:O.speed))},J.prep=function(i){function n(){return O.w=O.w||W.width(),O.w=O.mw&&O.mw<O.w?O.mw:O.w,O.w}function l(){return O.h=O.h||W.height(),O.h=O.mh&&O.mh<O.h?O.mh:O.h,O.h}if($){var a,d="none"===O.transition?0:O.speed;W.empty().remove(),W=o(ae,"LoadedContent").append(i),W.hide().appendTo(F.show()).css({width:n(),overflow:O.scrolling?"auto":"hidden"}).css({height:l()}).prependTo(x),F.hide(),t(U).css({"float":"none"}),a=function(){function i(){t.support.opacity===!1&&v[0].style.removeAttribute("filter")}var n,l,a=E.length,u="frameBorder",p="allowTransparency";$&&(l=function(){clearTimeout(Q),L.hide(),c(ne,O.onComplete)},S.html(O.title).add(W).show(),a>1?("string"==typeof O.current&&M.html(O.current.replace("{current}",j+1).replace("{total}",a)).show(),I[O.loop||a-1>j?"show":"hide"]().html(O.next),K[O.loop||j?"show":"hide"]().html(O.previous),O.slideshow&&R.show(),O.preloading&&t.each([r(-1),r(1)],function(){var i,o,n=E[this],r=t.data(n,Z);r&&r.href?(i=r.href,t.isFunction(i)&&(i=i.call(n))):i=t(n).attr("href"),i&&h(r,i)&&(i=s(r,i),o=e.createElement("img"),o.src=i)})):B.hide(),O.iframe?(n=o("iframe")[0],u in n&&(n[u]=0),p in n&&(n[p]="true"),O.scrolling||(n.scrolling="no"),t(n).attr({src:O.href,name:(new Date).getTime(),"class":te+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",l).appendTo(W),se.one(he,function(){n.src="//about:blank"}),O.fastIframe&&t(n).trigger("load")):l(),"fade"===O.transition?v.fadeTo(d,1,i):i())},"fade"===O.transition?v.fadeTo(d,0,function(){J.position(0,a)}):J.position(d,a)}},J.next=function(){!q&&E[1]&&(O.loop||E[j+1])&&(j=r(1),p(E[j]))},J.prev=function(){!q&&E[1]&&(O.loop||j)&&(j=r(-1),p(E[j]))},J.close=function(){$&&!G&&(G=!0,$=!1,c(re,O.onCleanup),H.unbind("."+te),g.fadeTo(O.fadeOut||0,0),v.stop().fadeTo(O.fadeOut||0,0,function(){v.add(g).css({opacity:1,cursor:"auto"}).hide(),c(he),W.empty().remove(),setTimeout(function(){G=!1,c(le,O.onClosed)},1)}))},J.remove=function(){v&&(v.stop(),t.colorbox.close(),v.stop().remove(),g.remove(),G=!1,v=null,t("."+ee).removeData(Z).removeClass(ee),t(e).unbind("click."+te))},J.element=function(){return t(A)},J.settings=Y)})(jQuery,document,window); \ No newline at end of file
diff --git a/javascript/jquery/plugins/colorbox/jquery.colorbox.js b/javascript/jquery/plugins/colorbox/jquery.colorbox.js
new file mode 100644
index 0000000..db00dac
--- /dev/null
+++ b/javascript/jquery/plugins/colorbox/jquery.colorbox.js
@@ -0,0 +1,1063 @@
+/*!
+ Colorbox v1.4.27 - 2013-07-16
+ jQuery lightbox and modal window plugin
+ (c) 2013 Jack Moore - http://www.jacklmoore.com/colorbox
+ license: http://www.opensource.org/licenses/mit-license.php
+*/
+(function ($, document, window) {
+ var
+ // Default settings object.
+ // See http://jacklmoore.com/colorbox for details.
+ defaults = {
+ transition: "elastic",
+ speed: 300,
+ fadeOut: 300,
+ width: false,
+ initialWidth: "600",
+ innerWidth: false,
+ maxWidth: false,
+ height: false,
+ initialHeight: "450",
+ innerHeight: false,
+ maxHeight: false,
+ scalePhotos: true,
+ scrolling: true,
+ inline: false,
+ html: false,
+ iframe: false,
+ fastIframe: true,
+ photo: false,
+ href: false,
+ title: false,
+ rel: false,
+ opacity: 0.9,
+ preloading: true,
+ className: false,
+
+ // alternate image paths for high-res displays
+ retinaImage: false,
+ retinaUrl: false,
+ retinaSuffix: '@2x.$1',
+
+ // internationalization
+ current: "image {current} of {total}",
+ previous: "previous",
+ next: "next",
+ close: "close",
+ xhrError: "This content failed to load.",
+ imgError: "This image failed to load.",
+
+ open: false,
+ returnFocus: true,
+ trapFocus: true,
+ reposition: true,
+ loop: true,
+ slideshow: false,
+ slideshowAuto: true,
+ slideshowSpeed: 2500,
+ slideshowStart: "start slideshow",
+ slideshowStop: "stop slideshow",
+ photoRegex: /\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,
+
+ onOpen: false,
+ onLoad: false,
+ onComplete: false,
+ onCleanup: false,
+ onClosed: false,
+
+ overlayClose: true,
+ escKey: true,
+ arrowKey: true,
+ top: false,
+ bottom: false,
+ left: false,
+ right: false,
+ fixed: false,
+ data: undefined,
+ closeButton: true
+ },
+
+ // Abstracting the HTML and event identifiers for easy rebranding
+ colorbox = 'colorbox',
+ prefix = 'cbox',
+ boxElement = prefix + 'Element',
+
+ // Events
+ event_open = prefix + '_open',
+ event_load = prefix + '_load',
+ event_complete = prefix + '_complete',
+ event_cleanup = prefix + '_cleanup',
+ event_closed = prefix + '_closed',
+ event_purge = prefix + '_purge',
+
+ // Cached jQuery Object Variables
+ $overlay,
+ $box,
+ $wrap,
+ $content,
+ $topBorder,
+ $leftBorder,
+ $rightBorder,
+ $bottomBorder,
+ $related,
+ $window,
+ $loaded,
+ $loadingBay,
+ $loadingOverlay,
+ $title,
+ $current,
+ $slideshow,
+ $next,
+ $prev,
+ $close,
+ $groupControls,
+ $events = $('<a/>'),
+
+ // Variables for cached values or use across multiple functions
+ settings,
+ interfaceHeight,
+ interfaceWidth,
+ loadedHeight,
+ loadedWidth,
+ element,
+ index,
+ photo,
+ open,
+ active,
+ closing,
+ loadingTimer,
+ publicMethod,
+ div = "div",
+ className,
+ requests = 0,
+ previousCSS = {},
+ init;
+
+ // ****************
+ // HELPER FUNCTIONS
+ // ****************
+
+ // Convenience function for creating new jQuery objects
+ function $tag(tag, id, css) {
+ var element = document.createElement(tag);
+
+ if (id) {
+ element.id = prefix + id;
+ }
+
+ if (css) {
+ element.style.cssText = css;
+ }
+
+ return $(element);
+ }
+
+ // Get the window height using innerHeight when available to avoid an issue with iOS
+ // http://bugs.jquery.com/ticket/6724
+ function winheight() {
+ return window.innerHeight ? window.innerHeight : $(window).height();
+ }
+
+ // Determine the next and previous members in a group.
+ function getIndex(increment) {
+ var
+ max = $related.length,
+ newIndex = (index + increment) % max;
+
+ return (newIndex < 0) ? max + newIndex : newIndex;
+ }
+
+ // Convert '%' and 'px' values to integers
+ function setSize(size, dimension) {
+ return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : winheight()) / 100) : 1) * parseInt(size, 10));
+ }
+
+ // Checks an href to see if it is a photo.
+ // There is a force photo option (photo: true) for hrefs that cannot be matched by the regex.
+ function isImage(settings, url) {
+ return settings.photo || settings.photoRegex.test(url);
+ }
+
+ function retinaUrl(settings, url) {
+ return settings.retinaUrl && window.devicePixelRatio > 1 ? url.replace(settings.photoRegex, settings.retinaSuffix) : url;
+ }
+
+ function trapFocus(e) {
+ if ('contains' in $box[0] && !$box[0].contains(e.target)) {
+ e.stopPropagation();
+ $box.focus();
+ }
+ }
+
+ // Assigns function results to their respective properties
+ function makeSettings() {
+ var i,
+ data = $.data(element, colorbox);
+
+ if (data == null) {
+ settings = $.extend({}, defaults);
+ if (console && console.log) {
+ console.log('Error: cboxElement missing settings object');
+ }
+ } else {
+ settings = $.extend({}, data);
+ }
+
+ for (i in settings) {
+ if ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
+ settings[i] = settings[i].call(element);
+ }
+ }
+
+ settings.rel = settings.rel || element.rel || $(element).data('rel') || 'nofollow';
+ settings.href = settings.href || $(element).attr('href');
+ settings.title = settings.title || element.title;
+
+ if (typeof settings.href === "string") {
+ settings.href = $.trim(settings.href);
+ }
+ }
+
+ function trigger(event, callback) {
+ // for external use
+ $(document).trigger(event);
+
+ // for internal use
+ $events.trigger(event);
+
+ if ($.isFunction(callback)) {
+ callback.call(element);
+ }
+ }
+
+ // Slideshow functionality
+ function slideshow() {
+ var
+ timeOut,
+ className = prefix + "Slideshow_",
+ click = "click." + prefix,
+ clear,
+ set,
+ start,
+ stop;
+
+ if (settings.slideshow && $related[1]) {
+ clear = function () {
+ clearTimeout(timeOut);
+ };
+
+ set = function () {
+ if (settings.loop || $related[index + 1]) {
+ timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
+ }
+ };
+
+ start = function () {
+ $slideshow
+ .html(settings.slideshowStop)
+ .unbind(click)
+ .one(click, stop);
+
+ $events
+ .bind(event_complete, set)
+ .bind(event_load, clear)
+ .bind(event_cleanup, stop);
+
+ $box.removeClass(className + "off").addClass(className + "on");
+ };
+
+ stop = function () {
+ clear();
+
+ $events
+ .unbind(event_complete, set)
+ .unbind(event_load, clear)
+ .unbind(event_cleanup, stop);
+
+ $slideshow
+ .html(settings.slideshowStart)
+ .unbind(click)
+ .one(click, function () {
+ publicMethod.next();
+ start();
+ });
+
+ $box.removeClass(className + "on").addClass(className + "off");
+ };
+
+ if (settings.slideshowAuto) {
+ start();
+ } else {
+ stop();
+ }
+ } else {
+ $box.removeClass(className + "off " + className + "on");
+ }
+ }
+
+ function launch(target) {
+ if (!closing) {
+
+ element = target;
+
+ makeSettings();
+
+ $related = $(element);
+
+ index = 0;
+
+ if (settings.rel !== 'nofollow') {
+ $related = $('.' + boxElement).filter(function () {
+ var data = $.data(this, colorbox),
+ relRelated;
+
+ if (data) {
+ relRelated = $(this).data('rel') || data.rel || this.rel;
+ }
+
+ return (relRelated === settings.rel);
+ });
+ index = $related.index(element);
+
+ // Check direct calls to Colorbox.
+ if (index === -1) {
+ $related = $related.add(element);
+ index = $related.length - 1;
+ }
+ }
+
+ $overlay.css({
+ opacity: parseFloat(settings.opacity),
+ cursor: settings.overlayClose ? "pointer" : "auto",
+ visibility: 'visible'
+ }).show();
+
+
+ if (className) {
+ $box.add($overlay).removeClass(className);
+ }
+ if (settings.className) {
+ $box.add($overlay).addClass(settings.className);
+ }
+ className = settings.className;
+
+ if (settings.closeButton) {
+ $close.html(settings.close).appendTo($content);
+ } else {
+ $close.appendTo('<div/>');
+ }
+
+ if (!open) {
+ open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
+
+ // Show colorbox so the sizes can be calculated in older versions of jQuery
+ $box.css({visibility:'hidden', display:'block'});
+
+ $loaded = $tag(div, 'LoadedContent', 'width:0; height:0; overflow:hidden');
+ $content.css({width:'', height:''}).append($loaded);
+
+ // Cache values needed for size calculations
+ interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();
+ interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
+ loadedHeight = $loaded.outerHeight(true);
+ loadedWidth = $loaded.outerWidth(true);
+
+ // Opens inital empty Colorbox prior to content being loaded.
+ settings.w = setSize(settings.initialWidth, 'x');
+ settings.h = setSize(settings.initialHeight, 'y');
+ publicMethod.position();
+
+ slideshow();
+
+ trigger(event_open, settings.onOpen);
+
+ $groupControls.add($title).hide();
+
+ $box.focus();
+
+
+ if (settings.trapFocus) {
+ // Confine focus to the modal
+ // Uses event capturing that is not supported in IE8-
+ if (document.addEventListener) {
+
+ document.addEventListener('focus', trapFocus, true);
+
+ $events.one(event_closed, function () {
+ document.removeEventListener('focus', trapFocus, true);
+ });
+ }
+ }
+
+ // Return focus on closing
+ if (settings.returnFocus) {
+ $events.one(event_closed, function () {
+ $(element).focus();
+ });
+ }
+ }
+
+ load();
+ }
+ }
+
+ // Colorbox's markup needs to be added to the DOM prior to being called
+ // so that the browser will go ahead and load the CSS background images.
+ function appendHTML() {
+ if (!$box && document.body) {
+ init = false;
+ $window = $(window);
+ $box = $tag(div).attr({
+ id: colorbox,
+ 'class': $.support.opacity === false ? prefix + 'IE' : '', // class for optional IE8 & lower targeted CSS.
+ role: 'dialog',
+ tabindex: '-1'
+ }).hide();
+ $overlay = $tag(div, "Overlay").hide();
+ $loadingOverlay = $([$tag(div, "LoadingOverlay")[0],$tag(div, "LoadingGraphic")[0]]);
+ $wrap = $tag(div, "Wrapper");
+ $content = $tag(div, "Content").append(
+ $title = $tag(div, "Title"),
+ $current = $tag(div, "Current"),
+ $prev = $('<button type="button"/>').attr({id:prefix+'Previous'}),
+ $next = $('<button type="button"/>').attr({id:prefix+'Next'}),
+ $slideshow = $tag('button', "Slideshow"),
+ $loadingOverlay
+ );
+
+ $close = $('<button type="button"/>').attr({id:prefix+'Close'});
+
+ $wrap.append( // The 3x3 Grid that makes up Colorbox
+ $tag(div).append(
+ $tag(div, "TopLeft"),
+ $topBorder = $tag(div, "TopCenter"),
+ $tag(div, "TopRight")
+ ),
+ $tag(div, false, 'clear:left').append(
+ $leftBorder = $tag(div, "MiddleLeft"),
+ $content,
+ $rightBorder = $tag(div, "MiddleRight")
+ ),
+ $tag(div, false, 'clear:left').append(
+ $tag(div, "BottomLeft"),
+ $bottomBorder = $tag(div, "BottomCenter"),
+ $tag(div, "BottomRight")
+ )
+ ).find('div div').css({'float': 'left'});
+
+ $loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');
+
+ $groupControls = $next.add($prev).add($current).add($slideshow);
+
+ $(document.body).append($overlay, $box.append($wrap, $loadingBay));
+ }
+ }
+
+ // Add Colorbox's event bindings
+ function addBindings() {
+ function clickHandler(e) {
+ // ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
+ // See: http://jacklmoore.com/notes/click-events/
+ if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey || e.ctrlKey)) {
+ e.preventDefault();
+ launch(this);
+ }
+ }
+
+ if ($box) {
+ if (!init) {
+ init = true;
+
+ // Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
+ $next.click(function () {
+ publicMethod.next();
+ });
+ $prev.click(function () {
+ publicMethod.prev();
+ });
+ $close.click(function () {
+ publicMethod.close();
+ });
+ $overlay.click(function () {
+ if (settings.overlayClose) {
+ publicMethod.close();
+ }
+ });
+
+ // Key Bindings
+ $(document).bind('keydown.' + prefix, function (e) {
+ var key = e.keyCode;
+ if (open && settings.escKey && key === 27) {
+ e.preventDefault();
+ publicMethod.close();
+ }
+ if (open && settings.arrowKey && $related[1] && !e.altKey) {
+ if (key === 37) {
+ e.preventDefault();
+ $prev.click();
+ } else if (key === 39) {
+ e.preventDefault();
+ $next.click();
+ }
+ }
+ });
+
+ if ($.isFunction($.fn.on)) {
+ // For jQuery 1.7+
+ $(document).on('click.'+prefix, '.'+boxElement, clickHandler);
+ } else {
+ // For jQuery 1.3.x -> 1.6.x
+ // This code is never reached in jQuery 1.9, so do not contact me about 'live' being removed.
+ // This is not here for jQuery 1.9, it's here for legacy users.
+ $('.'+boxElement).live('click.'+prefix, clickHandler);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ // Don't do anything if Colorbox already exists.
+ if ($.colorbox) {
+ return;
+ }
+
+ // Append the HTML when the DOM loads
+ $(appendHTML);
+
+
+ // ****************
+ // PUBLIC FUNCTIONS
+ // Usage format: $.colorbox.close();
+ // Usage from within an iframe: parent.jQuery.colorbox.close();
+ // ****************
+
+ publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
+ var $this = this;
+
+ options = options || {};
+
+ appendHTML();
+
+ if (addBindings()) {
+ if ($.isFunction($this)) { // assume a call to $.colorbox
+ $this = $('<a/>');
+ options.open = true;
+ } else if (!$this[0]) { // colorbox being applied to empty collection
+ return $this;
+ }
+
+ if (callback) {
+ options.onComplete = callback;
+ }
+
+ $this.each(function () {
+ $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
+ }).addClass(boxElement);
+
+ if (($.isFunction(options.open) && options.open.call($this)) || options.open) {
+ launch($this[0]);
+ }
+ }
+
+ return $this;
+ };
+
+ publicMethod.position = function (speed, loadedCallback) {
+ var
+ css,
+ top = 0,
+ left = 0,
+ offset = $box.offset(),
+ scrollTop,
+ scrollLeft;
+
+ $window.unbind('resize.' + prefix);
+
+ // remove the modal so that it doesn't influence the document width/height
+ $box.css({top: -9e4, left: -9e4});
+
+ scrollTop = $window.scrollTop();
+ scrollLeft = $window.scrollLeft();
+
+ if (settings.fixed) {
+ offset.top -= scrollTop;
+ offset.left -= scrollLeft;
+ $box.css({position: 'fixed'});
+ } else {
+ top = scrollTop;
+ left = scrollLeft;
+ $box.css({position: 'absolute'});
+ }
+
+ // keeps the top and left positions within the browser's viewport.
+ if (settings.right !== false) {
+ left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);
+ } else if (settings.left !== false) {
+ left += setSize(settings.left, 'x');
+ } else {
+ left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
+ }
+
+ if (settings.bottom !== false) {
+ top += Math.max(winheight() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);
+ } else if (settings.top !== false) {
+ top += setSize(settings.top, 'y');
+ } else {
+ top += Math.round(Math.max(winheight() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
+ }
+
+ $box.css({top: offset.top, left: offset.left, visibility:'visible'});
+
+ // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
+ // but it has to be shrank down around the size of div#colorbox when it's done. If not,
+ // it can invoke an obscure IE bug when using iframes.
+ $wrap[0].style.width = $wrap[0].style.height = "9999px";
+
+ function modalDimensions() {
+ $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = (parseInt($box[0].style.width,10) - interfaceWidth)+'px';
+ $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = (parseInt($box[0].style.height,10) - interfaceHeight)+'px';
+ }
+
+ css = {width: settings.w + loadedWidth + interfaceWidth, height: settings.h + loadedHeight + interfaceHeight, top: top, left: left};
+
+ // setting the speed to 0 if the content hasn't changed size or position
+ if (speed) {
+ var tempSpeed = 0;
+ $.each(css, function(i){
+ if (css[i] !== previousCSS[i]) {
+ tempSpeed = speed;
+ return;
+ }
+ });
+ speed = tempSpeed;
+ }
+
+ previousCSS = css;
+
+ if (!speed) {
+ $box.css(css);
+ }
+
+ $box.dequeue().animate(css, {
+ duration: speed || 0,
+ complete: function () {
+ modalDimensions();
+
+ active = false;
+
+ // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
+ $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
+ $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
+
+ if (settings.reposition) {
+ setTimeout(function () { // small delay before binding onresize due to an IE8 bug.
+ $window.bind('resize.' + prefix, publicMethod.position);
+ }, 1);
+ }
+
+ if (loadedCallback) {
+ loadedCallback();
+ }
+ },
+ step: modalDimensions
+ });
+ };
+
+ publicMethod.resize = function (options) {
+ var scrolltop;
+
+ if (open) {
+ options = options || {};
+
+ if (options.width) {
+ settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
+ }
+
+ if (options.innerWidth) {
+ settings.w = setSize(options.innerWidth, 'x');
+ }
+
+ $loaded.css({width: settings.w});
+
+ if (options.height) {
+ settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
+ }
+
+ if (options.innerHeight) {
+ settings.h = setSize(options.innerHeight, 'y');
+ }
+
+ if (!options.innerHeight && !options.height) {
+ scrolltop = $loaded.scrollTop();
+ $loaded.css({height: "auto"});
+ settings.h = $loaded.height();
+ }
+
+ $loaded.css({height: settings.h});
+
+ if(scrolltop) {
+ $loaded.scrollTop(scrolltop);
+ }
+
+ publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
+ }
+ };
+
+ publicMethod.prep = function (object) {
+ if (!open) {
+ return;
+ }
+
+ var callback, speed = settings.transition === "none" ? 0 : settings.speed;
+
+ $loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
+
+ $loaded = $tag(div, 'LoadedContent').append(object);
+
+ function getWidth() {
+ settings.w = settings.w || $loaded.width();
+ settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
+ return settings.w;
+ }
+ function getHeight() {
+ settings.h = settings.h || $loaded.height();
+ settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
+ return settings.h;
+ }
+
+ $loaded.hide()
+ .appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
+ .css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})
+ .css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
+ .prependTo($content);
+
+ $loadingBay.hide();
+
+ // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
+
+ $(photo).css({'float': 'none'});
+
+ callback = function () {
+ var total = $related.length,
+ iframe,
+ frameBorder = 'frameBorder',
+ allowTransparency = 'allowTransparency',
+ complete;
+
+ if (!open) {
+ return;
+ }
+
+ function removeFilter() { // Needed for IE7 & IE8 in versions of jQuery prior to 1.7.2
+ if ($.support.opacity === false) {
+ $box[0].style.removeAttribute('filter');
+ }
+ }
+
+ complete = function () {
+ clearTimeout(loadingTimer);
+ $loadingOverlay.hide();
+ trigger(event_complete, settings.onComplete);
+ };
+
+
+ $title.html(settings.title).add($loaded).show();
+
+ if (total > 1) { // handle grouping
+ if (typeof settings.current === "string") {
+ $current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();
+ }
+
+ $next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
+ $prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous);
+
+ if (settings.slideshow) {
+ $slideshow.show();
+ }
+
+ // Preloads images within a rel group
+ if (settings.preloading) {
+ $.each([getIndex(-1), getIndex(1)], function(){
+ var src,
+ img,
+ i = $related[this],
+ data = $.data(i, colorbox);
+
+ if (data && data.href) {
+ src = data.href;
+ if ($.isFunction(src)) {
+ src = src.call(i);
+ }
+ } else {
+ src = $(i).attr('href');
+ }
+
+ if (src && isImage(data, src)) {
+ src = retinaUrl(data, src);
+ img = document.createElement('img');
+ img.src = src;
+ }
+ });
+ }
+ } else {
+ $groupControls.hide();
+ }
+
+ if (settings.iframe) {
+ iframe = $tag('iframe')[0];
+
+ if (frameBorder in iframe) {
+ iframe[frameBorder] = 0;
+ }
+
+ if (allowTransparency in iframe) {
+ iframe[allowTransparency] = "true";
+ }
+
+ if (!settings.scrolling) {
+ iframe.scrolling = "no";
+ }
+
+ $(iframe)
+ .attr({
+ src: settings.href,
+ name: (new Date()).getTime(), // give the iframe a unique name to prevent caching
+ 'class': prefix + 'Iframe',
+ allowFullScreen : true, // allow HTML5 video to go fullscreen
+ webkitAllowFullScreen : true,
+ mozallowfullscreen : true
+ })
+ .one('load', complete)
+ .appendTo($loaded);
+
+ $events.one(event_purge, function () {
+ iframe.src = "//about:blank";
+ });
+
+ if (settings.fastIframe) {
+ $(iframe).trigger('load');
+ }
+ } else {
+ complete();
+ }
+
+ if (settings.transition === 'fade') {
+ $box.fadeTo(speed, 1, removeFilter);
+ } else {
+ removeFilter();
+ }
+ };
+
+ if (settings.transition === 'fade') {
+ $box.fadeTo(speed, 0, function () {
+ publicMethod.position(0, callback);
+ });
+ } else {
+ publicMethod.position(speed, callback);
+ }
+ };
+
+ function load () {
+ var href, setResize, prep = publicMethod.prep, $inline, request = ++requests;
+
+ active = true;
+
+ photo = false;
+
+ element = $related[index];
+
+ makeSettings();
+
+ trigger(event_purge);
+
+ trigger(event_load, settings.onLoad);
+
+ settings.h = settings.height ?
+ setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
+ settings.innerHeight && setSize(settings.innerHeight, 'y');
+
+ settings.w = settings.width ?
+ setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
+ settings.innerWidth && setSize(settings.innerWidth, 'x');
+
+ // Sets the minimum dimensions for use in image scaling
+ settings.mw = settings.w;
+ settings.mh = settings.h;
+
+ // Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
+ // If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
+ if (settings.maxWidth) {
+ settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
+ settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
+ }
+ if (settings.maxHeight) {
+ settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
+ settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
+ }
+
+ href = settings.href;
+
+ loadingTimer = setTimeout(function () {
+ $loadingOverlay.show();
+ }, 100);
+
+ if (settings.inline) {
+ // Inserts an empty placeholder where inline content is being pulled from.
+ // An event is bound to put inline content back when Colorbox closes or loads new content.
+ $inline = $tag(div).hide().insertBefore($(href)[0]);
+
+ $events.one(event_purge, function () {
+ $inline.replaceWith($loaded.children());
+ });
+
+ prep($(href));
+ } else if (settings.iframe) {
+ // IFrame element won't be added to the DOM until it is ready to be displayed,
+ // to avoid problems with DOM-ready JS that might be trying to run in that iframe.
+ prep(" ");
+ } else if (settings.html) {
+ prep(settings.html);
+ } else if (isImage(settings, href)) {
+
+ href = retinaUrl(settings, href);
+
+ photo = document.createElement('img');
+
+ $(photo)
+ .addClass(prefix + 'Photo')
+ .bind('error',function () {
+ settings.title = false;
+ prep($tag(div, 'Error').html(settings.imgError));
+ })
+ .one('load', function () {
+ var percent;
+
+ if (request !== requests) {
+ return;
+ }
+
+ photo.alt = $(element).attr('alt') || $(element).attr('data-alt') || '';
+
+ if (settings.retinaImage && window.devicePixelRatio > 1) {
+ photo.height = photo.height / window.devicePixelRatio;
+ photo.width = photo.width / window.devicePixelRatio;
+ }
+
+ if (settings.scalePhotos) {
+ setResize = function () {
+ photo.height -= photo.height * percent;
+ photo.width -= photo.width * percent;
+ };
+ if (settings.mw && photo.width > settings.mw) {
+ percent = (photo.width - settings.mw) / photo.width;
+ setResize();
+ }
+ if (settings.mh && photo.height > settings.mh) {
+ percent = (photo.height - settings.mh) / photo.height;
+ setResize();
+ }
+ }
+
+ if (settings.h) {
+ photo.style.marginTop = Math.max(settings.mh - photo.height, 0) / 2 + 'px';
+ }
+
+ if ($related[1] && (settings.loop || $related[index + 1])) {
+ photo.style.cursor = 'pointer';
+ photo.onclick = function () {
+ publicMethod.next();
+ };
+ }
+
+ photo.style.width = photo.width + 'px';
+ photo.style.height = photo.height + 'px';
+
+ setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.
+ prep(photo);
+ }, 1);
+ });
+
+ setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.
+ photo.src = href;
+ }, 1);
+ } else if (href) {
+ $loadingBay.load(href, settings.data, function (data, status) {
+ if (request === requests) {
+ prep(status === 'error' ? $tag(div, 'Error').html(settings.xhrError) : $(this).contents());
+ }
+ });
+ }
+ }
+
+ // Navigates to the next page/image in a set.
+ publicMethod.next = function () {
+ if (!active && $related[1] && (settings.loop || $related[index + 1])) {
+ index = getIndex(1);
+ launch($related[index]);
+ }
+ };
+
+ publicMethod.prev = function () {
+ if (!active && $related[1] && (settings.loop || index)) {
+ index = getIndex(-1);
+ launch($related[index]);
+ }
+ };
+
+ // Note: to use this within an iframe use the following format: parent.jQuery.colorbox.close();
+ publicMethod.close = function () {
+ if (open && !closing) {
+
+ closing = true;
+
+ open = false;
+
+ trigger(event_cleanup, settings.onCleanup);
+
+ $window.unbind('.' + prefix);
+
+ $overlay.fadeTo(settings.fadeOut || 0, 0);
+
+ $box.stop().fadeTo(settings.fadeOut || 0, 0, function () {
+
+ $box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();
+
+ trigger(event_purge);
+
+ $loaded.empty().remove(); // Using empty first may prevent some IE7 issues.
+
+ setTimeout(function () {
+ closing = false;
+ trigger(event_closed, settings.onClosed);
+ }, 1);
+ });
+ }
+ };
+
+ // Removes changes Colorbox made to the document, but does not remove the plugin.
+ publicMethod.remove = function () {
+ if (!$box) { return; }
+
+ $box.stop();
+ $.colorbox.close();
+ $box.stop().remove();
+ $overlay.remove();
+ closing = false;
+ $box = null;
+ $('.' + boxElement)
+ .removeData(colorbox)
+ .removeClass(boxElement);
+
+ $(document).unbind('click.'+prefix);
+ };
+
+ // A method for fetching the current element Colorbox is referencing.
+ // returns a jQuery object.
+ publicMethod.element = function () {
+ return $(element);
+ };
+
+ publicMethod.settings = defaults;
+
+}(jQuery, document, window));
diff --git a/javascript/jquery/plugins/colorpicker/css/colorpicker.css b/javascript/jquery/plugins/colorpicker/css/colorpicker.css
new file mode 100755
index 0000000..400263d
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/css/colorpicker.css
@@ -0,0 +1,167 @@
+.colorpicker {
+ width: 356px;
+ height: 176px;
+ overflow: hidden;
+ position: absolute;
+ background: url(../images/colorpicker_background.png);
+ font-family: Arial, Helvetica, sans-serif;
+ display: none;
+}
+.colorpicker_color {
+ width: 150px;
+ height: 150px;
+ left: 14px;
+ top: 13px;
+ position: absolute;
+ background: #f00;
+ overflow: hidden;
+ cursor: crosshair;
+}
+.colorpicker_color div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 150px;
+ height: 150px;
+ background: url(../images/colorpicker_overlay.png);
+}
+.colorpicker_color div div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 11px;
+ height: 11px;
+ overflow: hidden;
+ background: url(../images/colorpicker_select.gif);
+ margin: -5px 0 0 -5px;
+}
+.colorpicker_hue {
+ position: absolute;
+ top: 13px;
+ left: 171px;
+ width: 35px;
+ height: 150px;
+ cursor: n-resize;
+}
+.colorpicker_hue div {
+ position: absolute;
+ width: 35px;
+ height: 9px;
+ overflow: hidden;
+ background: url(../images/colorpicker_indic.gif) left top;
+ margin: -4px 0 0 0;
+ left: 0px;
+}
+.colorpicker_new_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 213px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker_current_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 283px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker input[type="text"]:focus,
+.colorpicker input[type="text"] {
+ background-color: transparent;
+ border: 1px solid transparent;
+ position: absolute;
+ font-size: 10px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #898989;
+ top: 0px;
+ right: 11px;
+ text-align: right;
+ margin: 0;
+ padding: 0;
+ height: auto;
+ width: 50px;
+ transition: none;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+.colorpicker_hex {
+ position: absolute;
+ width: 72px;
+ height: 22px;
+ background: url(../images/colorpicker_hex.png) top;
+ left: 212px;
+ top: 142px;
+}
+.colorpicker_hex input[type="text"] {
+ right: 6px;
+}
+.colorpicker_field {
+ height: 22px;
+ width: 62px;
+ background-position: top;
+ position: absolute;
+}
+.colorpicker_field span {
+ position: absolute;
+ width: 12px;
+ height: 22px;
+ overflow: hidden;
+ top: 0;
+ right: 0;
+ cursor: n-resize;
+}
+.colorpicker_rgb_r {
+ background-image: url(../images/colorpicker_rgb_r.png);
+ top: 52px;
+ left: 212px;
+}
+.colorpicker_rgb_g {
+ background-image: url(../images/colorpicker_rgb_g.png);
+ top: 82px;
+ left: 212px;
+}
+.colorpicker_rgb_b {
+ background-image: url(../images/colorpicker_rgb_b.png);
+ top: 112px;
+ left: 212px;
+}
+.colorpicker_hsb_h {
+ background-image: url(../images/colorpicker_hsb_h.png);
+ top: 52px;
+ left: 282px;
+}
+.colorpicker_hsb_s {
+ background-image: url(../images/colorpicker_hsb_s.png);
+ top: 82px;
+ left: 282px;
+}
+.colorpicker_hsb_b {
+ background-image: url(../images/colorpicker_hsb_b.png);
+ top: 112px;
+ left: 282px;
+}
+.colorpicker_submit {
+ position: absolute;
+ width: 22px;
+ height: 22px;
+ background: url(../images/custom_submit.png) top;
+ left: 322px;
+ top: 142px;
+ overflow: hidden;
+}
+.colorpicker_focus {
+ background-position: center;
+}
+.colorpicker_hex.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_submit.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_slider {
+ background-position: bottom;
+}
diff --git a/javascript/jquery/plugins/colorpicker/css/layout.css b/javascript/jquery/plugins/colorpicker/css/layout.css
new file mode 100755
index 0000000..8b3f00f
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/css/layout.css
@@ -0,0 +1,218 @@
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
+ margin:0;
+ padding:0;
+}
+table {
+ border-collapse:collapse;
+ border-spacing:0;
+}
+fieldset,img {
+ border:0;
+}
+address,caption,cite,code,dfn,em,strong,th,var {
+ font-style:normal;
+ font-weight:normal;
+}
+ol,ul {
+ list-style:none;
+}
+caption,th {
+ text-align:left;
+}
+h1,h2,h3,h4,h5,h6 {
+ font-size:100%;
+ font-weight:normal;
+}
+q:before,q:after {
+ content:'';
+}
+abbr,acronym { border:0;
+}
+html, body {
+ background-color: #fff;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ line-height: 18px;
+ color: #52697E;
+}
+body {
+ text-align: center;
+ overflow: auto;
+}
+.wrapper {
+ width: 700px;
+ margin: 0 auto;
+ text-align: left;
+}
+h1 {
+ font-size: 21px;
+ height: 47px;
+ line-height: 47px;
+ text-transform: uppercase;
+}
+.navigationTabs {
+ height: 23px;
+ line-height: 23px;
+ border-bottom: 1px solid #ccc;
+}
+.navigationTabs li {
+ float: left;
+ height: 23px;
+ line-height: 23px;
+ padding-right: 3px;
+}
+.navigationTabs li a{
+ float: left;
+ dispaly: block;
+ height: 23px;
+ line-height: 23px;
+ padding: 0 10px;
+ overflow: hidden;
+ color: #52697E;
+ background-color: #eee;
+ position: relative;
+ text-decoration: none;
+}
+.navigationTabs li a:hover {
+ background-color: #f0f0f0;
+}
+.navigationTabs li a.active {
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-bottom: 0px solid;
+}
+.tabsContent {
+ border: 1px solid #ccc;
+ border-top: 0px solid;
+ width: 698px;
+ overflow: hidden;
+}
+.tab {
+ padding: 16px;
+ display: none;
+}
+.tab h2 {
+ font-weight: bold;
+ font-size: 16px;
+}
+.tab h3 {
+ font-weight: bold;
+ font-size: 14px;
+ margin-top: 20px;
+}
+.tab p {
+ margin-top: 16px;
+ clear: both;
+}
+.tab ul {
+ margin-top: 16px;
+ list-style: disc;
+}
+.tab li {
+ margin: 10px 0 0 35px;
+}
+.tab a {
+ color: #8FB0CF;
+}
+.tab strong {
+ font-weight: bold;
+}
+.tab pre {
+ font-size: 11px;
+ margin-top: 20px;
+ width: 668px;
+ overflow: auto;
+ clear: both;
+}
+.tab table {
+ width: 100%;
+}
+.tab table td {
+ padding: 6px 10px 6px 0;
+ vertical-align: top;
+}
+.tab dt {
+ margin-top: 16px;
+}
+
+#colorSelector {
+ position: relative;
+ width: 36px;
+ height: 36px;
+ background: url(../images/select.png);
+}
+#colorSelector div {
+ position: absolute;
+ top: 3px;
+ left: 3px;
+ width: 30px;
+ height: 30px;
+ background: url(../images/select.png) center;
+}
+#colorSelector2 {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 36px;
+ height: 36px;
+ background: url(../images/select2.png);
+}
+#colorSelector2 div {
+ position: absolute;
+ top: 4px;
+ left: 4px;
+ width: 28px;
+ height: 28px;
+ background: url(../images/select2.png) center;
+}
+#colorpickerHolder2 {
+ top: 32px;
+ left: 0;
+ width: 356px;
+ height: 0;
+ overflow: hidden;
+ position: absolute;
+}
+#colorpickerHolder2 .colorpicker {
+ background-image: url(../images/custom_background.png);
+ position: absolute;
+ bottom: 0;
+ left: 0;
+}
+#colorpickerHolder2 .colorpicker_hue div {
+ background-image: url(../images/custom_indic.gif);
+}
+#colorpickerHolder2 .colorpicker_hex {
+ background-image: url(../images/custom_hex.png);
+}
+#colorpickerHolder2 .colorpicker_rgb_r {
+ background-image: url(../images/custom_rgb_r.png);
+}
+#colorpickerHolder2 .colorpicker_rgb_g {
+ background-image: url(../images/custom_rgb_g.png);
+}
+#colorpickerHolder2 .colorpicker_rgb_b {
+ background-image: url(../images/custom_rgb_b.png);
+}
+#colorpickerHolder2 .colorpicker_hsb_s {
+ background-image: url(../images/custom_hsb_s.png);
+ display: none;
+}
+#colorpickerHolder2 .colorpicker_hsb_h {
+ background-image: url(../images/custom_hsb_h.png);
+ display: none;
+}
+#colorpickerHolder2 .colorpicker_hsb_b {
+ background-image: url(../images/custom_hsb_b.png);
+ display: none;
+}
+#colorpickerHolder2 .colorpicker_submit {
+ background-image: url(../images/custom_submit.png);
+}
+#colorpickerHolder2 .colorpicker input {
+ color: #778398;
+}
+#customWidget {
+ position: relative;
+ height: 36px;
+}
diff --git a/javascript/jquery/plugins/colorpicker/images/Thumbs.db b/javascript/jquery/plugins/colorpicker/images/Thumbs.db
new file mode 100755
index 0000000..d396c36
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/Thumbs.db
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/blank.gif b/javascript/jquery/plugins/colorpicker/images/blank.gif
new file mode 100755
index 0000000..75b945d
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/blank.gif
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_background.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_background.png
new file mode 100755
index 0000000..8401572
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_background.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_hex.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_hex.png
new file mode 100755
index 0000000..4e532d7
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_hex.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_b.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_b.png
new file mode 100755
index 0000000..dfac595
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_b.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_h.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_h.png
new file mode 100755
index 0000000..3977ed9
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_h.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_s.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_s.png
new file mode 100755
index 0000000..a2a6997
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_hsb_s.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_indic.gif b/javascript/jquery/plugins/colorpicker/images/colorpicker_indic.gif
new file mode 100755
index 0000000..f9fa95e
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_indic.gif
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_overlay.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_overlay.png
new file mode 100755
index 0000000..561cdd9
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_overlay.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_b.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_b.png
new file mode 100755
index 0000000..dfac595
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_b.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_g.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_g.png
new file mode 100755
index 0000000..72b3276
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_g.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_r.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_r.png
new file mode 100755
index 0000000..4855fe0
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_rgb_r.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_select.gif b/javascript/jquery/plugins/colorpicker/images/colorpicker_select.gif
new file mode 100755
index 0000000..599f7f1
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_select.gif
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/colorpicker_submit.png b/javascript/jquery/plugins/colorpicker/images/colorpicker_submit.png
new file mode 100755
index 0000000..7f4c082
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/colorpicker_submit.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_background.png b/javascript/jquery/plugins/colorpicker/images/custom_background.png
new file mode 100755
index 0000000..cf55ffd
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_background.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_hex.png b/javascript/jquery/plugins/colorpicker/images/custom_hex.png
new file mode 100755
index 0000000..888f444
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_hex.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_hsb_b.png b/javascript/jquery/plugins/colorpicker/images/custom_hsb_b.png
new file mode 100755
index 0000000..2f99dae
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_hsb_b.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_hsb_h.png b/javascript/jquery/plugins/colorpicker/images/custom_hsb_h.png
new file mode 100755
index 0000000..a217e92
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_hsb_h.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_hsb_s.png b/javascript/jquery/plugins/colorpicker/images/custom_hsb_s.png
new file mode 100755
index 0000000..7826b41
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_hsb_s.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_indic.gif b/javascript/jquery/plugins/colorpicker/images/custom_indic.gif
new file mode 100755
index 0000000..222fb94
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_indic.gif
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_rgb_b.png b/javascript/jquery/plugins/colorpicker/images/custom_rgb_b.png
new file mode 100755
index 0000000..80764e5
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_rgb_b.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_rgb_g.png b/javascript/jquery/plugins/colorpicker/images/custom_rgb_g.png
new file mode 100755
index 0000000..fc9778b
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_rgb_g.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_rgb_r.png b/javascript/jquery/plugins/colorpicker/images/custom_rgb_r.png
new file mode 100755
index 0000000..91b0cd4
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_rgb_r.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/custom_submit.png b/javascript/jquery/plugins/colorpicker/images/custom_submit.png
new file mode 100755
index 0000000..7bd51c0
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/custom_submit.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/select.png b/javascript/jquery/plugins/colorpicker/images/select.png
new file mode 100755
index 0000000..21213bf
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/select.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/select2.png b/javascript/jquery/plugins/colorpicker/images/select2.png
new file mode 100755
index 0000000..2cd2cab
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/select2.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/images/slider.png b/javascript/jquery/plugins/colorpicker/images/slider.png
new file mode 100755
index 0000000..8b03da9
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/images/slider.png
Binary files differ
diff --git a/javascript/jquery/plugins/colorpicker/js/colorpicker.js b/javascript/jquery/plugins/colorpicker/js/colorpicker.js
new file mode 100755
index 0000000..10a2b22
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/js/colorpicker.js
@@ -0,0 +1,484 @@
+/**
+ *
+ * Color picker
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ * Dual licensed under the MIT and GPL licenses
+ *
+ */
+(function ($) {
+ var ColorPicker = function () {
+ var
+ ids = {},
+ inAction,
+ charMin = 65,
+ visible,
+ tpl = '<div class="colorpicker"><div class="colorpicker_color"><div><div></div></div></div><div class="colorpicker_hue"><div></div></div><div class="colorpicker_new_color"></div><div class="colorpicker_current_color"></div><div class="colorpicker_hex"><input type="text" maxlength="6" size="6" /></div><div class="colorpicker_rgb_r colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_g colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_h colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_s colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_submit"></div></div>',
+ defaults = {
+ eventName: 'click',
+ onShow: function () {},
+ onBeforeShow: function(){},
+ onHide: function () {},
+ onChange: function () {},
+ onSubmit: function () {},
+ color: 'ff0000',
+ livePreview: true,
+ flat: false
+ },
+ fillRGBFields = function (hsb, cal) {
+ var rgb = HSBToRGB(hsb);
+ $(cal).data('colorpicker').fields
+ .eq(1).val(rgb.r).end()
+ .eq(2).val(rgb.g).end()
+ .eq(3).val(rgb.b).end();
+ },
+ fillHSBFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(4).val(hsb.h).end()
+ .eq(5).val(hsb.s).end()
+ .eq(6).val(hsb.b).end();
+ },
+ fillHexFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(0).val(HSBToHex(hsb)).end();
+ },
+ setSelector = function (hsb, cal) {
+ $(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100}));
+ $(cal).data('colorpicker').selectorIndic.css({
+ left: parseInt(150 * hsb.s/100, 10),
+ top: parseInt(150 * (100-hsb.b)/100, 10)
+ });
+ },
+ setHue = function (hsb, cal) {
+ $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10));
+ },
+ setCurrentColor = function (hsb, cal) {
+ $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb));
+ },
+ setNewColor = function (hsb, cal) {
+ $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb));
+ },
+ keyDown = function (ev) {
+ var pressedKey = ev.charCode || ev.keyCode || -1;
+ if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) {
+ return false;
+ }
+ var cal = $(this).parent().parent();
+ if (cal.data('colorpicker').livePreview === true) {
+ change.apply(this);
+ }
+ },
+ change = function (ev) {
+ var cal = $(this).parent().parent(), col;
+ if (this.parentNode.className.indexOf('_hex') > 0) {
+ cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value));
+ } else if (this.parentNode.className.indexOf('_hsb') > 0) {
+ cal.data('colorpicker').color = col = fixHSB({
+ h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10),
+ s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10)
+ });
+ } else {
+ cal.data('colorpicker').color = col = RGBToHSB(fixRGB({
+ r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10),
+ g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10)
+ }));
+ }
+ if (ev) {
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ }
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]);
+ },
+ blur = function (ev) {
+ var cal = $(this).parent().parent();
+ cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ },
+ focus = function () {
+ charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65;
+ $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ $(this).parent().addClass('colorpicker_focus');
+ },
+ downIncrement = function (ev) {
+ var field = $(this).parent().find('input').focus();
+ var current = {
+ el: $(this).parent().addClass('colorpicker_slider'),
+ max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255),
+ y: ev.pageY,
+ field: field,
+ val: parseInt(field.val(), 10),
+ preview: $(this).parent().parent().data('colorpicker').livePreview
+ };
+ $(document).bind('mouseup', current, upIncrement);
+ $(document).bind('mousemove', current, moveIncrement);
+ },
+ moveIncrement = function (ev) {
+ ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10))));
+ if (ev.data.preview) {
+ change.apply(ev.data.field.get(0), [true]);
+ }
+ return false;
+ },
+ upIncrement = function (ev) {
+ change.apply(ev.data.field.get(0), [true]);
+ ev.data.el.removeClass('colorpicker_slider').find('input').focus();
+ $(document).unbind('mouseup', upIncrement);
+ $(document).unbind('mousemove', moveIncrement);
+ return false;
+ },
+ downHue = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ y: $(this).offset().top
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upHue);
+ $(document).bind('mousemove', current, moveHue);
+ },
+ moveHue = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(4)
+ .val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upHue = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upHue);
+ $(document).unbind('mousemove', moveHue);
+ return false;
+ },
+ downSelector = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ pos: $(this).offset()
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upSelector);
+ $(document).bind('mousemove', current, moveSelector);
+ },
+ moveSelector = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(6)
+ .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10))
+ .end()
+ .eq(5)
+ .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upSelector = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upSelector);
+ $(document).unbind('mousemove', moveSelector);
+ return false;
+ },
+ enterSubmit = function (ev) {
+ $(this).addClass('colorpicker_focus');
+ },
+ leaveSubmit = function (ev) {
+ $(this).removeClass('colorpicker_focus');
+ },
+ clickSubmit = function (ev) {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').color;
+ cal.data('colorpicker').origColor = col;
+ setCurrentColor(col, cal.get(0));
+ cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el);
+ },
+ show = function (ev) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]);
+ var pos = $(this).offset();
+ var viewPort = getViewport();
+ var top = pos.top + this.offsetHeight;
+ var left = pos.left;
+ if (top + 176 > viewPort.t + viewPort.h) {
+ top -= this.offsetHeight + 176;
+ }
+ if (left + 356 > viewPort.l + viewPort.w) {
+ left -= 356;
+ }
+ cal.css({left: left + 'px', top: top + 'px'});
+ if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) {
+ cal.show();
+ }
+ $(document).bind('mousedown', {cal: cal}, hide);
+ return false;
+ },
+ hide = function (ev) {
+ if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
+ if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
+ ev.data.cal.hide();
+ }
+ $(document).unbind('mousedown', hide);
+ }
+ },
+ isChildOf = function(parentEl, el, container) {
+ if (parentEl == el) {
+ return true;
+ }
+ if (parentEl.contains) {
+ return parentEl.contains(el);
+ }
+ if ( parentEl.compareDocumentPosition ) {
+ return !!(parentEl.compareDocumentPosition(el) & 16);
+ }
+ var prEl = el.parentNode;
+ while(prEl && prEl != container) {
+ if (prEl == parentEl)
+ return true;
+ prEl = prEl.parentNode;
+ }
+ return false;
+ },
+ getViewport = function () {
+ var m = document.compatMode == 'CSS1Compat';
+ return {
+ l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
+ t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
+ w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
+ h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
+ };
+ },
+ fixHSB = function (hsb) {
+ return {
+ h: Math.min(360, Math.max(0, hsb.h)),
+ s: Math.min(100, Math.max(0, hsb.s)),
+ b: Math.min(100, Math.max(0, hsb.b))
+ };
+ },
+ fixRGB = function (rgb) {
+ return {
+ r: Math.min(255, Math.max(0, rgb.r)),
+ g: Math.min(255, Math.max(0, rgb.g)),
+ b: Math.min(255, Math.max(0, rgb.b))
+ };
+ },
+ fixHex = function (hex) {
+ var len = 6 - hex.length;
+ if (len > 0) {
+ var o = [];
+ for (var i=0; i<len; i++) {
+ o.push('0');
+ }
+ o.push(hex);
+ hex = o.join('');
+ }
+ return hex;
+ },
+ HexToRGB = function (hex) {
+ var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
+ return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
+ },
+ HexToHSB = function (hex) {
+ return RGBToHSB(HexToRGB(hex));
+ },
+ RGBToHSB = function (rgb) {
+ var hsb = {
+ h: 0,
+ s: 0,
+ b: 0
+ };
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.b = max;
+ if (max != 0) {
+
+ }
+ hsb.s = max != 0 ? 255 * delta / max : 0;
+ if (hsb.s != 0) {
+ if (rgb.r == max) {
+ hsb.h = (rgb.g - rgb.b) / delta;
+ } else if (rgb.g == max) {
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ } else {
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ }
+ } else {
+ hsb.h = -1;
+ }
+ hsb.h *= 60;
+ if (hsb.h < 0) {
+ hsb.h += 360;
+ }
+ hsb.s *= 100/255;
+ hsb.b *= 100/255;
+ return hsb;
+ },
+ HSBToRGB = function (hsb) {
+ var rgb = {};
+ var h = Math.round(hsb.h);
+ var s = Math.round(hsb.s*255/100);
+ var v = Math.round(hsb.b*255/100);
+ if(s == 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255-s)*v/255;
+ var t3 = (t1-t2)*(h%60)/60;
+ if(h==360) h = 0;
+ if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3}
+ else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3}
+ else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3}
+ else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3}
+ else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3}
+ else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3}
+ else {rgb.r=0; rgb.g=0; rgb.b=0}
+ }
+ return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};
+ },
+ RGBToHex = function (rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function (nr, val) {
+ if (val.length == 1) {
+ hex[nr] = '0' + val;
+ }
+ });
+ return hex.join('');
+ },
+ HSBToHex = function (hsb) {
+ return RGBToHex(HSBToRGB(hsb));
+ },
+ restoreOriginal = function () {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').origColor;
+ cal.data('colorpicker').color = col;
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ };
+ return {
+ init: function (opt) {
+ opt = $.extend({}, defaults, opt||{});
+ if (typeof opt.color == 'string') {
+ opt.color = HexToHSB(opt.color);
+ } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) {
+ opt.color = RGBToHSB(opt.color);
+ } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) {
+ opt.color = fixHSB(opt.color);
+ } else {
+ return this;
+ }
+ return this.each(function () {
+ if (!$(this).data('colorpickerId')) {
+ var options = $.extend({}, opt);
+ options.origColor = opt.color;
+ var id = 'collorpicker_' + parseInt(Math.random() * 1000);
+ $(this).data('colorpickerId', id);
+ var cal = $(tpl).attr('id', id);
+ if (options.flat) {
+ cal.appendTo(this).show();
+ } else {
+ cal.appendTo(document.body);
+ }
+ options.fields = cal
+ .find('input')
+ .bind('keyup', keyDown)
+ .bind('change', change)
+ .bind('blur', blur)
+ .bind('focus', focus);
+ cal
+ .find('span').bind('mousedown', downIncrement).end()
+ .find('>div.colorpicker_current_color').bind('click', restoreOriginal);
+ options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector);
+ options.selectorIndic = options.selector.find('div div');
+ options.el = this;
+ options.hue = cal.find('div.colorpicker_hue div');
+ cal.find('div.colorpicker_hue').bind('mousedown', downHue);
+ options.newColor = cal.find('div.colorpicker_new_color');
+ options.currentColor = cal.find('div.colorpicker_current_color');
+ cal.data('colorpicker', options);
+ cal.find('div.colorpicker_submit')
+ .bind('mouseenter', enterSubmit)
+ .bind('mouseleave', leaveSubmit)
+ .bind('click', clickSubmit);
+ fillRGBFields(options.color, cal.get(0));
+ fillHSBFields(options.color, cal.get(0));
+ fillHexFields(options.color, cal.get(0));
+ setHue(options.color, cal.get(0));
+ setSelector(options.color, cal.get(0));
+ setCurrentColor(options.color, cal.get(0));
+ setNewColor(options.color, cal.get(0));
+ if (options.flat) {
+ cal.css({
+ position: 'relative',
+ display: 'block'
+ });
+ } else {
+ $(this).bind(options.eventName, show);
+ }
+ }
+ });
+ },
+ showPicker: function() {
+ return this.each( function () {
+ if ($(this).data('colorpickerId')) {
+ show.apply(this);
+ }
+ });
+ },
+ hidePicker: function() {
+ return this.each( function () {
+ if ($(this).data('colorpickerId')) {
+ $('#' + $(this).data('colorpickerId')).hide();
+ }
+ });
+ },
+ setColor: function(col) {
+ if (typeof col == 'string') {
+ col = HexToHSB(col);
+ } else if (col.r != undefined && col.g != undefined && col.b != undefined) {
+ col = RGBToHSB(col);
+ } else if (col.h != undefined && col.s != undefined && col.b != undefined) {
+ col = fixHSB(col);
+ } else {
+ return this;
+ }
+ return this.each(function(){
+ if ($(this).data('colorpickerId')) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').color = col;
+ cal.data('colorpicker').origColor = col;
+ fillRGBFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setCurrentColor(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ }
+ });
+ }
+ };
+ }();
+ $.fn.extend({
+ ColorPicker: ColorPicker.init,
+ ColorPickerHide: ColorPicker.hidePicker,
+ ColorPickerShow: ColorPicker.showPicker,
+ ColorPickerSetColor: ColorPicker.setColor
+ });
+})(jQuery) \ No newline at end of file
diff --git a/javascript/jquery/plugins/colorpicker/js/eye.js b/javascript/jquery/plugins/colorpicker/js/eye.js
new file mode 100755
index 0000000..ea70e64
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/js/eye.js
@@ -0,0 +1,34 @@
+/**
+ *
+ * Zoomimage
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ */
+(function($){
+ var EYE = window.EYE = function() {
+ var _registered = {
+ init: []
+ };
+ return {
+ init: function() {
+ $.each(_registered.init, function(nr, fn){
+ fn.call();
+ });
+ },
+ extend: function(prop) {
+ for (var i in prop) {
+ if (prop[i] != undefined) {
+ this[i] = prop[i];
+ }
+ }
+ },
+ register: function(fn, type) {
+ if (!_registered[type]) {
+ _registered[type] = [];
+ }
+ _registered[type].push(fn);
+ }
+ };
+ }();
+ $(EYE.init);
+})(jQuery);
diff --git a/javascript/jquery/plugins/colorpicker/js/layout.js b/javascript/jquery/plugins/colorpicker/js/layout.js
new file mode 100755
index 0000000..e0dfb8f
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/js/layout.js
@@ -0,0 +1,67 @@
+(function($){
+ var initLayout = function() {
+ var hash = window.location.hash.replace('#', '');
+ var currentTab = $('ul.navigationTabs a')
+ .bind('click', showTab)
+ .filter('a[rel=' + hash + ']');
+ if (currentTab.size() == 0) {
+ currentTab = $('ul.navigationTabs a:first');
+ }
+ showTab.apply(currentTab.get(0));
+ $('#colorpickerHolder').ColorPicker({flat: true});
+ $('#colorpickerHolder2').ColorPicker({
+ flat: true,
+ color: '#00ff00',
+ onSubmit: function(hsb, hex, rgb) {
+ $('#colorSelector2 div').css('backgroundColor', '#' + hex);
+ }
+ });
+ $('#colorpickerHolder2>div').css('position', 'absolute');
+ var widt = false;
+ $('#colorSelector2').bind('click', function() {
+ $('#colorpickerHolder2').stop().animate({height: widt ? 0 : 173}, 500);
+ widt = !widt;
+ });
+ $('#colorpickerField1, #colorpickerField2, #colorpickerField3').ColorPicker({
+ onSubmit: function(hsb, hex, rgb, el) {
+ $(el).val(hex);
+ $(el).ColorPickerHide();
+ },
+ onBeforeShow: function () {
+ $(this).ColorPickerSetColor(this.value);
+ }
+ })
+ .bind('keyup', function(){
+ $(this).ColorPickerSetColor(this.value);
+ });
+ $('#colorSelector').ColorPicker({
+ color: '#0000ff',
+ onShow: function (colpkr) {
+ $(colpkr).fadeIn(500);
+ return false;
+ },
+ onHide: function (colpkr) {
+ $(colpkr).fadeOut(500);
+ return false;
+ },
+ onChange: function (hsb, hex, rgb) {
+ $('#colorSelector div').css('backgroundColor', '#' + hex);
+ }
+ });
+ };
+
+ var showTab = function(e) {
+ var tabIndex = $('ul.navigationTabs a')
+ .removeClass('active')
+ .index(this);
+ $(this)
+ .addClass('active')
+ .blur();
+ $('div.tab')
+ .hide()
+ .eq(tabIndex)
+ .show();
+ };
+
+ EYE.register(initLayout, 'init');
+})(jQuery) \ No newline at end of file
diff --git a/javascript/jquery/plugins/colorpicker/js/utils.js b/javascript/jquery/plugins/colorpicker/js/utils.js
new file mode 100755
index 0000000..cc7ce14
--- /dev/null
+++ b/javascript/jquery/plugins/colorpicker/js/utils.js
@@ -0,0 +1,252 @@
+/**
+ *
+ * Utilities
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ */
+(function($) {
+EYE.extend({
+ getPosition : function(e, forceIt)
+ {
+ var x = 0;
+ var y = 0;
+ var es = e.style;
+ var restoreStyles = false;
+ if (forceIt && jQuery.curCSS(e,'display') == 'none') {
+ var oldVisibility = es.visibility;
+ var oldPosition = es.position;
+ restoreStyles = true;
+ es.visibility = 'hidden';
+ es.display = 'block';
+ es.position = 'absolute';
+ }
+ var el = e;
+ if (el.getBoundingClientRect) { // IE
+ var box = el.getBoundingClientRect();
+ x = box.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) - 2;
+ y = box.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop) - 2;
+ } else {
+ x = el.offsetLeft;
+ y = el.offsetTop;
+ el = el.offsetParent;
+ if (e != el) {
+ while (el) {
+ x += el.offsetLeft;
+ y += el.offsetTop;
+ el = el.offsetParent;
+ }
+ }
+ if (jQuery.browser.safari && jQuery.curCSS(e, 'position') == 'absolute' ) {
+ x -= document.body.offsetLeft;
+ y -= document.body.offsetTop;
+ }
+ el = e.parentNode;
+ while (el && el.tagName.toUpperCase() != 'BODY' && el.tagName.toUpperCase() != 'HTML')
+ {
+ if (jQuery.curCSS(el, 'display') != 'inline') {
+ x -= el.scrollLeft;
+ y -= el.scrollTop;
+ }
+ el = el.parentNode;
+ }
+ }
+ if (restoreStyles == true) {
+ es.display = 'none';
+ es.position = oldPosition;
+ es.visibility = oldVisibility;
+ }
+ return {x:x, y:y};
+ },
+ getSize : function(e)
+ {
+ var w = parseInt(jQuery.curCSS(e,'width'), 10);
+ var h = parseInt(jQuery.curCSS(e,'height'), 10);
+ var wb = 0;
+ var hb = 0;
+ if (jQuery.curCSS(e, 'display') != 'none') {
+ wb = e.offsetWidth;
+ hb = e.offsetHeight;
+ } else {
+ var es = e.style;
+ var oldVisibility = es.visibility;
+ var oldPosition = es.position;
+ es.visibility = 'hidden';
+ es.display = 'block';
+ es.position = 'absolute';
+ wb = e.offsetWidth;
+ hb = e.offsetHeight;
+ es.display = 'none';
+ es.position = oldPosition;
+ es.visibility = oldVisibility;
+ }
+ return {w:w, h:h, wb:wb, hb:hb};
+ },
+ getClient : function(e)
+ {
+ var h, w;
+ if (e) {
+ w = e.clientWidth;
+ h = e.clientHeight;
+ } else {
+ var de = document.documentElement;
+ w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
+ h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
+ }
+ return {w:w,h:h};
+ },
+ getScroll : function (e)
+ {
+ var t=0, l=0, w=0, h=0, iw=0, ih=0;
+ if (e && e.nodeName.toLowerCase() != 'body') {
+ t = e.scrollTop;
+ l = e.scrollLeft;
+ w = e.scrollWidth;
+ h = e.scrollHeight;
+ } else {
+ if (document.documentElement) {
+ t = document.documentElement.scrollTop;
+ l = document.documentElement.scrollLeft;
+ w = document.documentElement.scrollWidth;
+ h = document.documentElement.scrollHeight;
+ } else if (document.body) {
+ t = document.body.scrollTop;
+ l = document.body.scrollLeft;
+ w = document.body.scrollWidth;
+ h = document.body.scrollHeight;
+ }
+ if (typeof pageYOffset != 'undefined') {
+ t = pageYOffset;
+ l = pageXOffset;
+ }
+ iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;
+ ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;
+ }
+ return { t: t, l: l, w: w, h: h, iw: iw, ih: ih };
+ },
+ getMargins : function(e, toInteger)
+ {
+ var t = jQuery.curCSS(e,'marginTop') || '';
+ var r = jQuery.curCSS(e,'marginRight') || '';
+ var b = jQuery.curCSS(e,'marginBottom') || '';
+ var l = jQuery.curCSS(e,'marginLeft') || '';
+ if (toInteger)
+ return {
+ t: parseInt(t, 10)||0,
+ r: parseInt(r, 10)||0,
+ b: parseInt(b, 10)||0,
+ l: parseInt(l, 10)
+ };
+ else
+ return {t: t, r: r, b: b, l: l};
+ },
+ getPadding : function(e, toInteger)
+ {
+ var t = jQuery.curCSS(e,'paddingTop') || '';
+ var r = jQuery.curCSS(e,'paddingRight') || '';
+ var b = jQuery.curCSS(e,'paddingBottom') || '';
+ var l = jQuery.curCSS(e,'paddingLeft') || '';
+ if (toInteger)
+ return {
+ t: parseInt(t, 10)||0,
+ r: parseInt(r, 10)||0,
+ b: parseInt(b, 10)||0,
+ l: parseInt(l, 10)
+ };
+ else
+ return {t: t, r: r, b: b, l: l};
+ },
+ getBorder : function(e, toInteger)
+ {
+ var t = jQuery.curCSS(e,'borderTopWidth') || '';
+ var r = jQuery.curCSS(e,'borderRightWidth') || '';
+ var b = jQuery.curCSS(e,'borderBottomWidth') || '';
+ var l = jQuery.curCSS(e,'borderLeftWidth') || '';
+ if (toInteger)
+ return {
+ t: parseInt(t, 10)||0,
+ r: parseInt(r, 10)||0,
+ b: parseInt(b, 10)||0,
+ l: parseInt(l, 10)||0
+ };
+ else
+ return {t: t, r: r, b: b, l: l};
+ },
+ traverseDOM : function(nodeEl, func)
+ {
+ func(nodeEl);
+ nodeEl = nodeEl.firstChild;
+ while(nodeEl){
+ EYE.traverseDOM(nodeEl, func);
+ nodeEl = nodeEl.nextSibling;
+ }
+ },
+ getInnerWidth : function(el, scroll) {
+ var offsetW = el.offsetWidth;
+ return scroll ? Math.max(el.scrollWidth,offsetW) - offsetW + el.clientWidth:el.clientWidth;
+ },
+ getInnerHeight : function(el, scroll) {
+ var offsetH = el.offsetHeight;
+ return scroll ? Math.max(el.scrollHeight,offsetH) - offsetH + el.clientHeight:el.clientHeight;
+ },
+ getExtraWidth : function(el) {
+ if($.boxModel)
+ return (parseInt($.curCSS(el, 'paddingLeft'))||0)
+ + (parseInt($.curCSS(el, 'paddingRight'))||0)
+ + (parseInt($.curCSS(el, 'borderLeftWidth'))||0)
+ + (parseInt($.curCSS(el, 'borderRightWidth'))||0);
+ return 0;
+ },
+ getExtraHeight : function(el) {
+ if($.boxModel)
+ return (parseInt($.curCSS(el, 'paddingTop'))||0)
+ + (parseInt($.curCSS(el, 'paddingBottom'))||0)
+ + (parseInt($.curCSS(el, 'borderTopWidth'))||0)
+ + (parseInt($.curCSS(el, 'borderBottomWidth'))||0);
+ return 0;
+ },
+ isChildOf: function(parentEl, el, container) {
+ if (parentEl == el) {
+ return true;
+ }
+ if (!el || !el.nodeType || el.nodeType != 1) {
+ return false;
+ }
+ if (parentEl.contains && !$.browser.safari) {
+ return parentEl.contains(el);
+ }
+ if ( parentEl.compareDocumentPosition ) {
+ return !!(parentEl.compareDocumentPosition(el) & 16);
+ }
+ var prEl = el.parentNode;
+ while(prEl && prEl != container) {
+ if (prEl == parentEl)
+ return true;
+ prEl = prEl.parentNode;
+ }
+ return false;
+ },
+ centerEl : function(el, axis)
+ {
+ var clientScroll = EYE.getScroll();
+ var size = EYE.getSize(el);
+ if (!axis || axis == 'vertically')
+ $(el).css(
+ {
+ top: clientScroll.t + ((Math.min(clientScroll.h,clientScroll.ih) - size.hb)/2) + 'px'
+ }
+ );
+ if (!axis || axis == 'horizontally')
+ $(el).css(
+ {
+ left: clientScroll.l + ((Math.min(clientScroll.w,clientScroll.iw) - size.wb)/2) + 'px'
+ }
+ );
+ }
+});
+if (!$.easing.easeout) {
+ $.easing.easeout = function(p, n, firstNum, delta, duration) {
+ return -delta * ((n=n/duration-1)*n*n*n - 1) + firstNum;
+ };
+}
+
+})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/cropper/cropper.css b/javascript/jquery/plugins/cropper/cropper.css
new file mode 100644
index 0000000..5630fd5
--- /dev/null
+++ b/javascript/jquery/plugins/cropper/cropper.css
@@ -0,0 +1,278 @@
+/*!
+ * Cropper v0.7.7
+ * https://github.com/fengyuanchen/cropper
+ *
+ * Copyright 2014-2015 Fengyuan Chen
+ * Released under the MIT license
+ */
+
+.cropper-container {
+ position: relative;
+ overflow: hidden;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none;
+}
+
+.cropper-container img {
+ width: 100%;
+ min-width: 0 !important;
+ max-width: none !important;
+ height: 100%;
+ min-height: 0 !important;
+ max-height: none !important;
+}
+
+.cropper-modal,
+.cropper-canvas {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+}
+
+.cropper-canvas {
+ background-color: #fff;
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+
+.cropper-modal {
+ background-color: #000;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+
+.cropper-dragger {
+ position: absolute;
+ top: 10%;
+ left: 10%;
+ width: 80%;
+ height: 80%;
+}
+
+.cropper-viewer {
+ display: block;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ outline-width: 1px;
+ outline-style: solid;
+ outline-color: #69f;
+ outline-color: rgba(51, 102, 255, .75);
+}
+
+.cropper-dashed {
+ position: absolute;
+ display: block;
+ filter: alpha(opacity=50);
+ border: 0 dashed #fff;
+ opacity: .5;
+}
+
+.cropper-dashed.dashed-h {
+ top: 33.3%;
+ left: 0;
+ width: 100%;
+ height: 33.3%;
+ border-top-width: 1px;
+ border-bottom-width: 1px;
+}
+
+.cropper-dashed.dashed-v {
+ top: 0;
+ left: 33.3%;
+ width: 33.3%;
+ height: 100%;
+ border-right-width: 1px;
+ border-left-width: 1px;
+}
+
+.cropper-face,
+.cropper-line,
+.cropper-point {
+ position: absolute;
+ display: block;
+ width: 100%;
+ height: 100%;
+ filter: alpha(opacity=10);
+ opacity: .1;
+}
+
+.cropper-face {
+ top: 0;
+ left: 0;
+ cursor: move;
+ background-color: #fff;
+}
+
+.cropper-line {
+ background-color: #69f;
+}
+
+.cropper-line.line-e {
+ top: 0;
+ right: -3px;
+ width: 5px;
+ cursor: e-resize;
+}
+
+.cropper-line.line-n {
+ top: -3px;
+ left: 0;
+ height: 5px;
+ cursor: n-resize;
+}
+
+.cropper-line.line-w {
+ top: 0;
+ left: -3px;
+ width: 5px;
+ cursor: w-resize;
+}
+
+.cropper-line.line-s {
+ bottom: -3px;
+ left: 0;
+ height: 5px;
+ cursor: s-resize;
+}
+
+.cropper-point {
+ width: 5px;
+ height: 5px;
+ background-color: #69f;
+ filter: alpha(opacity=75);
+ opacity: .75;
+}
+
+.cropper-point.point-e {
+ top: 50%;
+ right: -3px;
+ margin-top: -3px;
+ cursor: e-resize;
+}
+
+.cropper-point.point-n {
+ top: -3px;
+ left: 50%;
+ margin-left: -3px;
+ cursor: n-resize;
+}
+
+.cropper-point.point-w {
+ top: 50%;
+ left: -3px;
+ margin-top: -3px;
+ cursor: w-resize;
+}
+
+.cropper-point.point-s {
+ bottom: -3px;
+ left: 50%;
+ margin-left: -3px;
+ cursor: s-resize;
+}
+
+.cropper-point.point-ne {
+ top: -3px;
+ right: -3px;
+ cursor: ne-resize;
+}
+
+.cropper-point.point-nw {
+ top: -3px;
+ left: -3px;
+ cursor: nw-resize;
+}
+
+.cropper-point.point-sw {
+ bottom: -3px;
+ left: -3px;
+ cursor: sw-resize;
+}
+
+.cropper-point.point-se {
+ right: -3px;
+ bottom: -3px;
+ width: 20px;
+ height: 20px;
+ cursor: se-resize;
+ filter: alpha(opacity=100);
+ opacity: 1;
+}
+
+.cropper-point.point-se:before {
+ position: absolute;
+ right: -50%;
+ bottom: -50%;
+ display: block;
+ width: 200%;
+ height: 200%;
+ content: " ";
+ background-color: #69f;
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+
+@media (min-width: 768px) {
+ .cropper-point.point-se {
+ width: 15px;
+ height: 15px;
+ }
+}
+
+@media (min-width: 992px) {
+ .cropper-point.point-se {
+ width: 10px;
+ height: 10px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .cropper-point.point-se {
+ width: 5px;
+ height: 5px;
+ filter: alpha(opacity=75);
+ opacity: .75;
+ }
+}
+
+/* Helper classes for JavaScript */
+
+.cropper-hidden {
+ display: none !important;
+}
+
+.cropper-invisible {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: -1;
+ width: auto !important;
+ max-width: none !important;
+ height: auto !important;
+ max-height: none !important;
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+
+.cropper-move {
+ cursor: move;
+}
+
+.cropper-crop {
+ cursor: crosshair;
+}
+
+.cropper-disabled .cropper-canvas,
+.cropper-disabled .cropper-face,
+.cropper-disabled .cropper-line,
+.cropper-disabled .cropper-point {
+ cursor: not-allowed;
+}
diff --git a/javascript/jquery/plugins/cropper/cropper.js b/javascript/jquery/plugins/cropper/cropper.js
new file mode 100644
index 0000000..678b309
--- /dev/null
+++ b/javascript/jquery/plugins/cropper/cropper.js
@@ -0,0 +1,1588 @@
+/*!
+ * Cropper v0.7.7
+ * https://github.com/fengyuanchen/cropper
+ *
+ * Copyright 2014-2015 Fengyuan Chen
+ * Released under the MIT license
+ */
+
+(function (factory) {
+ if (typeof define === "function" && define.amd) {
+ // AMD. Register as anonymous module.
+ define(["jquery"], factory);
+ } else if (typeof exports === "object") {
+ // Node / CommonJS
+ factory(require("jquery"));
+ } else {
+ // Browser globals.
+ factory(jQuery);
+ }
+})(function ($) {
+
+ "use strict";
+
+ var $window = $(window),
+ $document = $(document),
+ location = window.location,
+
+ // Constants
+ TRUE = true,
+ FALSE = false,
+ NULL = null,
+ NAN = NaN,
+ INFINITY = Infinity,
+ STRING_UNDEFINED = "undefined",
+ STRING_DIRECTIVE = "directive",
+ CROPPER_NAMESPACE = ".cropper",
+
+ // RegExps
+ REGEXP_DIRECTIVES = /^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/,
+ REGEXP_OPTIONS = /^(x|y|width|height)$/,
+ REGEXP_PROPERTIES = /^(naturalWidth|naturalHeight|width|height|aspectRatio|ratio|rotate)$/,
+
+ // Classes
+ CLASS_MODAL = "cropper-modal",
+ CLASS_HIDDEN = "cropper-hidden",
+ CLASS_INVISIBLE = "cropper-invisible",
+ CLASS_MOVE = "cropper-move",
+ CLASS_CROP = "cropper-crop",
+ CLASS_DISABLED = "cropper-disabled",
+
+ // Events
+ EVENT_MOUSE_DOWN = "mousedown touchstart",
+ EVENT_MOUSE_MOVE = "mousemove touchmove",
+ EVENT_MOUSE_UP = "mouseup mouseleave touchend touchleave touchcancel",
+ EVENT_WHEEL = "wheel mousewheel DOMMouseScroll",
+ EVENT_RESIZE = "resize" + CROPPER_NAMESPACE, // Bind to window with namespace
+ EVENT_DBLCLICK = "dblclick",
+ EVENT_BUILD = "build" + CROPPER_NAMESPACE,
+ EVENT_BUILT = "built" + CROPPER_NAMESPACE,
+ EVENT_DRAG_START = "dragstart" + CROPPER_NAMESPACE,
+ EVENT_DRAG_MOVE = "dragmove" + CROPPER_NAMESPACE,
+ EVENT_DRAG_END = "dragend" + CROPPER_NAMESPACE,
+
+ // Functions
+ isNumber = function (n) {
+ return typeof n === "number";
+ },
+
+ toArray = function (obj, offset) {
+ var args = [];
+
+ if (typeof offset === "number") { // It's necessary for IE8
+ args.push(offset);
+ }
+
+ return args.slice.apply(obj, args);
+ },
+
+ // Custom proxy to avoid jQuery's guid
+ proxy = function (fn, context) {
+ var args = toArray(arguments, 2);
+
+ return function () {
+ return fn.apply(context, args.concat(toArray(arguments)));
+ };
+ },
+
+ addTimestamp = function (url) {
+ var timestamp = "timestamp=" + (new Date()).getTime();
+
+ return (url + (url.indexOf("?") === -1 ? "?" : "&") + timestamp);
+ },
+
+ // Constructor
+ Cropper = function (element, options) {
+ this.element = element;
+ this.$element = $(element);
+ this.defaults = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) ? options : {});
+ this.$original = NULL;
+ this.ready = FALSE;
+ this.built = FALSE;
+ this.cropped = FALSE;
+ this.rotated = FALSE;
+ this.disabled = FALSE;
+ this.replaced = FALSE;
+ this.init();
+ },
+
+ // Others
+ sqrt = Math.sqrt,
+ min = Math.min,
+ max = Math.max,
+ abs = Math.abs,
+ sin = Math.sin,
+ cos = Math.cos,
+ num = parseFloat;
+
+ Cropper.prototype = {
+ constructor: Cropper,
+
+ support: {
+ canvas: $.isFunction($("<canvas>")[0].getContext)
+ },
+
+ init: function () {
+ var defaults = this.defaults;
+
+ $.each(defaults, function (i, n) {
+ switch (i) {
+ case "aspectRatio":
+ defaults[i] = abs(num(n)) || NAN; // 0 -> NaN
+ break;
+
+ case "autoCropArea":
+ defaults[i] = abs(num(n)) || 0.8; // 0 | NaN -> 0.8
+ break;
+
+ case "minWidth":
+ case "minHeight":
+ defaults[i] = abs(num(n)) || 0; // NaN -> 0
+ break;
+
+ case "maxWidth":
+ case "maxHeight":
+ defaults[i] = abs(num(n)) || INFINITY; // 0 | NaN -> Infinity
+ break;
+
+ // No default
+ }
+ });
+
+ // Set default image data
+ this.image = {
+ rotate: 0
+ };
+
+ this.load();
+ },
+
+ load: function () {
+ var _this = this,
+ $this = this.$element,
+ element = this.element,
+ image = this.image,
+ crossOrigin = "",
+ $clone,
+ url;
+
+ if ($this.is("img")) {
+ url = $this.prop("src");
+ } else if ($this.is("canvas") && this.support.canvas) {
+ url = element.toDataURL();
+ }
+
+ if (!url) {
+ return;
+ }
+
+ // Reset image rotate degree
+ if (this.replaced) {
+ image.rotate = 0;
+ }
+
+ if (this.defaults.checkImageOrigin) {
+ if ($this.prop("crossOrigin") || this.isCrossOriginURL(url)) {
+ crossOrigin = " crossOrigin";
+ url = addTimestamp(url); // Bust cache (#119, #148)
+ }
+ }
+
+ this.$clone = ($clone = $("<img" + crossOrigin + ' src="' + url + '">'));
+
+ $clone.one("load", function () {
+ image.naturalWidth = this.naturalWidth || $clone.width();
+ image.naturalHeight = this.naturalHeight || $clone.height();
+ image.aspectRatio = image.naturalWidth / image.naturalHeight;
+
+ _this.url = url;
+ _this.ready = TRUE;
+ _this.build();
+ });
+
+ // Hide and prepend the clone iamge to the document body (Don't append to).
+ $clone.addClass(CLASS_INVISIBLE).prependTo("body");
+ },
+
+ isCrossOriginURL: function (url) {
+ var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);
+
+ if ((parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port))) {
+ return TRUE;
+ }
+
+ return FALSE;
+ },
+
+ build: function () {
+ var $this = this.$element,
+ defaults = this.defaults,
+ buildEvent,
+ $cropper;
+
+ if (!this.ready) {
+ return;
+ }
+
+ if (this.built) {
+ this.unbuild();
+ }
+
+ $this.one(EVENT_BUILD, defaults.build); // Only trigger once
+ buildEvent = $.Event(EVENT_BUILD);
+ $this.trigger(buildEvent);
+
+ if (buildEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ // Create cropper elements
+ this.$cropper = ($cropper = $(Cropper.TEMPLATE));
+
+ // Hide the original image
+ $this.addClass(CLASS_HIDDEN);
+
+ // Show and prepend the clone iamge to the cropper
+ this.$clone.removeClass(CLASS_INVISIBLE).prependTo($cropper);
+
+ // Save original image for rotation
+ if (!this.rotated) {
+ this.$original = this.$clone.clone();
+
+ // Append the image to document to avoid "NS_ERROR_NOT_AVAILABLE" error on Firefox when call the "drawImage" method.
+ this.$original.addClass(CLASS_HIDDEN).prependTo(this.$cropper);
+
+ this.originalImage = $.extend({}, this.image);
+ }
+
+ this.$container = $this.parent();
+ this.$container.append($cropper);
+
+ this.$canvas = $cropper.find(".cropper-canvas");
+ this.$dragger = $cropper.find(".cropper-dragger");
+ this.$viewer = $cropper.find(".cropper-viewer");
+
+ defaults.autoCrop ? (this.cropped = TRUE) : this.$dragger.addClass(CLASS_HIDDEN);
+ defaults.modal && this.$canvas.addClass(CLASS_MODAL);
+ !defaults.dashed && this.$dragger.find(".cropper-dashed").addClass(CLASS_HIDDEN);
+ !defaults.movable && this.$dragger.find(".cropper-face").data(STRING_DIRECTIVE, "move");
+ !defaults.resizable && this.$dragger.find(".cropper-line, .cropper-point").addClass(CLASS_HIDDEN);
+
+ this.addListeners();
+ this.initPreview();
+
+ this.built = TRUE; // Set `true` before update
+ defaults.dragCrop && this.setDragMode("crop"); // Set after built
+ this.update();
+ this.replaced = FALSE; // Reset to `false` after update
+
+ $this.one(EVENT_BUILT, defaults.built); // Only trigger once
+ $this.trigger(EVENT_BUILT);
+ },
+
+ unbuild: function () {
+ if (!this.built) {
+ return;
+ }
+
+ this.built = FALSE;
+ this.removeListeners();
+
+ this.$preview.empty();
+ this.$preview = NULL;
+
+ this.$dragger = NULL;
+ this.$canvas = NULL;
+ this.$container = NULL;
+
+ this.$cropper.remove();
+ this.$cropper = NULL;
+ },
+
+ update: function (data) {
+ this.initContainer();
+ this.initCropper();
+ this.initImage();
+ this.initDragger();
+
+ if (data) {
+ this.setData(data, TRUE);
+ this.setDragMode("crop");
+ } else {
+ this.setData(this.defaults.data);
+ }
+ },
+
+ resize: function () {
+ clearTimeout(this.resizing);
+ this.resizing = setTimeout($.proxy(this.update, this, this.getData()), 200);
+ },
+
+ preview: function () {
+ var image = this.image,
+ dragger = this.dragger,
+ width = image.width,
+ height = image.height,
+ left = dragger.left - image.left,
+ top = dragger.top - image.top;
+
+ this.$viewer.find("img").css({
+ width: width,
+ height: height,
+ marginLeft: -left,
+ marginTop: -top
+ });
+
+ this.$preview.each(function () {
+ var $this = $(this),
+ ratio = $this.width() / dragger.width;
+
+ $this.find("img").css({
+ width: width * ratio,
+ height: height * ratio,
+ marginLeft: -left * ratio,
+ marginTop: -top * ratio
+ });
+ });
+ },
+
+ addListeners: function () {
+ var defaults = this.defaults;
+
+ this.$element.on(EVENT_DRAG_START, defaults.dragstart).on(EVENT_DRAG_MOVE, defaults.dragmove).on(EVENT_DRAG_END, defaults.dragend);
+ this.$cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.dragstart, this)).on(EVENT_DBLCLICK, $.proxy(this.dblclick, this));
+
+ if (defaults.zoomable) {
+ this.$cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this));
+ }
+
+ if (defaults.multiple) {
+ this.$cropper.on(EVENT_MOUSE_MOVE, $.proxy(this.dragmove, this)).on(EVENT_MOUSE_UP, $.proxy(this.dragend, this));
+ } else {
+ $document.on(EVENT_MOUSE_MOVE, (this._dragmove = proxy(this.dragmove, this))).on(EVENT_MOUSE_UP, (this._dragend = proxy(this.dragend, this)));
+ }
+
+ $window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this)));
+ },
+
+ removeListeners: function () {
+ var defaults = this.defaults;
+
+ this.$element.off(EVENT_DRAG_START, defaults.dragstart).off(EVENT_DRAG_MOVE, defaults.dragmove).off(EVENT_DRAG_END, defaults.dragend);
+ this.$cropper.off(EVENT_MOUSE_DOWN, this.dragstart).off(EVENT_DBLCLICK, this.dblclick);
+
+ if (defaults.zoomable) {
+ this.$cropper.off(EVENT_WHEEL, this.wheel);
+ }
+
+ if (defaults.multiple) {
+ this.$cropper.off(EVENT_MOUSE_MOVE, this.dragmove).off(EVENT_MOUSE_UP, this.dragend);
+ } else {
+ $document.off(EVENT_MOUSE_MOVE, this._dragmove).off(EVENT_MOUSE_UP, this._dragend);
+ }
+
+ $window.off(EVENT_RESIZE, this._resize);
+ },
+
+ initPreview: function () {
+ var img = '<img src="' + this.url + '">';
+
+ this.$preview = $(this.defaults.preview);
+ this.$viewer.html(img);
+ this.$preview.html(img).find("img").css("cssText", "min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;");
+ },
+
+ initContainer: function () {
+ var $container = this.$container;
+
+ this.container = {
+ width: max($container.width(), 300),
+ height: max($container.height(), 150)
+ };
+ },
+
+ initCropper: function () {
+ var container = this.container,
+ image = this.image,
+ cropper;
+
+ if (((image.naturalWidth * container.height / image.naturalHeight) - container.width) >= 0) {
+ cropper = {
+ width: container.width,
+ height: container.width / image.aspectRatio,
+ left: 0
+ };
+
+ cropper.top = (container.height - cropper.height) / 2;
+ } else {
+ cropper = {
+ width: container.height * image.aspectRatio,
+ height: container.height,
+ top: 0
+ };
+
+ cropper.left = (container.width - cropper.width) / 2;
+ }
+
+ this.$cropper.css({
+ width: cropper.width,
+ height: cropper.height,
+ left: cropper.left,
+ top: cropper.top
+ });
+
+ this.cropper = cropper;
+ },
+
+ initImage: function () {
+ var image = this.image,
+ cropper = this.cropper,
+ defaultImage = {
+ _width: cropper.width,
+ _height: cropper.height,
+ width: cropper.width,
+ height: cropper.height,
+ left: 0,
+ top: 0,
+ ratio: cropper.width / image.naturalWidth
+ };
+
+ this.defaultImage = $.extend({}, image, defaultImage);
+
+ if (image._width !== cropper.width || image._height !== cropper.height) {
+ $.extend(image, defaultImage);
+ } else {
+ image = $.extend({}, defaultImage, image);
+
+ // Reset image ratio
+ if (this.replaced) {
+ image.ratio = defaultImage.ratio;
+ }
+ }
+
+ this.image = image;
+ this.renderImage();
+ },
+
+ renderImage: function (mode) {
+ var image = this.image;
+
+ if (mode === "zoom") {
+ image.left -= (image.width - image.oldWidth) / 2;
+ image.top -= (image.height - image.oldHeight) / 2;
+ }
+
+ image.left = min(max(image.left, image._width - image.width), 0);
+ image.top = min(max(image.top, image._height - image.height), 0);
+
+ this.$clone.css({
+ width: image.width,
+ height: image.height,
+ marginLeft: image.left,
+ marginTop: image.top
+ });
+
+ if (mode) {
+ this.defaults.done(this.getData());
+ this.preview();
+ }
+ },
+
+ initDragger: function () {
+ var defaults = this.defaults,
+ cropper = this.cropper,
+ // If not set, use the original aspect ratio of the image.
+ aspectRatio = defaults.aspectRatio || this.image.aspectRatio,
+ ratio = this.image.ratio,
+ autoCropDragger,
+ dragger;
+
+ if (((cropper.height * aspectRatio) - cropper.width) >= 0) {
+ dragger = {
+ height: cropper.width / aspectRatio,
+ width: cropper.width,
+ left: 0,
+ top: (cropper.height - (cropper.width / aspectRatio)) / 2,
+ maxWidth: cropper.width,
+ maxHeight: cropper.width / aspectRatio
+ };
+ } else {
+ dragger = {
+ height: cropper.height,
+ width: cropper.height * aspectRatio,
+ left: (cropper.width - (cropper.height * aspectRatio)) / 2,
+ top: 0,
+ maxWidth: cropper.height * aspectRatio,
+ maxHeight: cropper.height
+ };
+ }
+
+ dragger.minWidth = 0;
+ dragger.minHeight = 0;
+
+ if (defaults.aspectRatio) {
+ if (isFinite(defaults.maxWidth)) {
+ dragger.maxWidth = min(dragger.maxWidth, defaults.maxWidth * ratio);
+ dragger.maxHeight = dragger.maxWidth / aspectRatio;
+ } else if (isFinite(defaults.maxHeight)) {
+ dragger.maxHeight = min(dragger.maxHeight, defaults.maxHeight * ratio);
+ dragger.maxWidth = dragger.maxHeight * aspectRatio;
+ }
+
+ if (defaults.minWidth > 0) {
+ dragger.minWidth = max(0, defaults.minWidth * ratio);
+ dragger.minHeight = dragger.minWidth / aspectRatio;
+ } else if (defaults.minHeight > 0) {
+ dragger.minHeight = max(0, defaults.minHeight * ratio);
+ dragger.minWidth = dragger.minHeight * aspectRatio;
+ }
+ } else {
+ dragger.maxWidth = min(dragger.maxWidth, defaults.maxWidth * ratio);
+ dragger.maxHeight = min(dragger.maxHeight, defaults.maxHeight * ratio);
+ dragger.minWidth = max(0, defaults.minWidth * ratio);
+ dragger.minHeight = max(0, defaults.minHeight * ratio);
+ }
+
+ // minWidth can't be greater than maxWidth, and minHeight too.
+ dragger.minWidth = min(dragger.maxWidth, dragger.minWidth);
+ dragger.minHeight = min(dragger.maxHeight, dragger.minHeight);
+
+ // Center the dragger by default
+ autoCropDragger = $.extend({}, dragger);
+ autoCropDragger.height = dragger.height * defaults.autoCropArea;
+ autoCropDragger.width = dragger.width * defaults.autoCropArea;
+ autoCropDragger.left = (cropper.width - autoCropDragger.width) / 2;
+ autoCropDragger.top = (cropper.height - autoCropDragger.height) / 2;
+
+ autoCropDragger.oldLeft = dragger.oldLeft = dragger.left;
+ autoCropDragger.oldTop = dragger.oldTop = dragger.top;
+
+ this.autoCropDragger = autoCropDragger;
+ this.defaultDragger = $.extend({}, dragger);
+ this.dragger = dragger;
+ },
+
+ renderDragger: function () {
+ var dragger = this.dragger,
+ cropper = this.cropper;
+
+ if (dragger.width > dragger.maxWidth) {
+ dragger.width = dragger.maxWidth;
+ dragger.left = dragger.oldLeft;
+ } else if (dragger.width < dragger.minWidth) {
+ dragger.width = dragger.minWidth;
+ dragger.left = dragger.oldLeft;
+ }
+
+ if (dragger.height > dragger.maxHeight) {
+ dragger.height = dragger.maxHeight;
+ dragger.top = dragger.oldTop;
+ } else if (dragger.height < dragger.minHeight) {
+ dragger.height = dragger.minHeight;
+ dragger.top = dragger.oldTop;
+ }
+
+ dragger.left = min(max(dragger.left, 0), cropper.width - dragger.width);
+ dragger.top = min(max(dragger.top, 0), cropper.height - dragger.height);
+ dragger.oldLeft = dragger.left;
+ dragger.oldTop = dragger.top;
+
+ // Re-render the dragger
+ this.dragger = dragger;
+
+ if (!this.disabled) {
+ this.defaults.done(this.getData());
+ }
+
+ this.$dragger.css({
+ width: dragger.width,
+ height: dragger.height,
+ left: dragger.left,
+ top: dragger.top
+ });
+
+ this.preview();
+ },
+
+ reset: function (deep) {
+ if (!this.cropped) {
+ return;
+ }
+
+ if (deep) {
+ this.defaults.data = {};
+ }
+
+ this.image = $.extend({}, this.defaultImage);
+ this.renderImage();
+ this.dragger = $.extend({}, this.defaultDragger);
+ this.setData(this.defaults.data);
+ },
+
+ clear: function () {
+ if (!this.cropped) {
+ return;
+ }
+
+ this.cropped = FALSE;
+
+ this.setData({
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0
+ });
+
+ this.$canvas.removeClass(CLASS_MODAL);
+ this.$dragger.addClass(CLASS_HIDDEN);
+ },
+
+ destroy: function () {
+ var $this = this.$element;
+
+ if (!this.ready) {
+ return;
+ }
+
+ this.unbuild();
+ $this.removeClass(CLASS_HIDDEN).removeData("cropper");
+
+ if (this.rotated) {
+ $this.attr("src", this.$original.attr("src"));
+ }
+ },
+
+ replace: function (url, /*INTERNAL*/ rotated) {
+ var _this = this,
+ $this = this.$element,
+ element = this.element,
+ context;
+
+ if (url && url !== this.url && url !== $this.attr("src")) {
+ if (!rotated) {
+ this.rotated = FALSE;
+ this.replaced = TRUE;
+ }
+
+ if ($this.is("img")) {
+ $this.attr("src", url);
+ this.load();
+ } else if ($this.is("canvas") && this.support.canvas) {
+ context = element.getContext("2d");
+
+ $('<img src="' + url + '">').one("load", function () {
+ element.width = this.width;
+ element.height = this.height;
+ context.clearRect(0, 0, element.width, element.height);
+ context.drawImage(this, 0, 0);
+ _this.load();
+ });
+ }
+ }
+ },
+
+ setData: function (data, /*INTERNAL*/ once) {
+ var cropper = this.cropper,
+ dragger = this.dragger,
+ image = this.image,
+ aspectRatio = this.defaults.aspectRatio;
+
+ if (!this.built || typeof data === STRING_UNDEFINED) {
+ return;
+ }
+
+ if (data === NULL || $.isEmptyObject(data)) {
+ dragger = $.extend({}, this.autoCropDragger);
+ }
+
+ if ($.isPlainObject(data) && !$.isEmptyObject(data)) {
+
+ if (!once) {
+ this.defaults.data = data;
+ }
+
+ data = this.transformData(data);
+
+ if (isNumber(data.x) && data.x <= cropper.width - image.left) {
+ dragger.left = data.x + image.left;
+ }
+
+ if (isNumber(data.y) && data.y <= cropper.height - image.top) {
+ dragger.top = data.y + image.top;
+ }
+
+ if (aspectRatio) {
+ if (isNumber(data.width) && data.width <= dragger.maxWidth && data.width >= dragger.minWidth) {
+ dragger.width = data.width;
+ dragger.height = dragger.width / aspectRatio;
+ } else if (isNumber(data.height) && data.height <= dragger.maxHeight && data.height >= dragger.minHeight) {
+ dragger.height = data.height;
+ dragger.width = dragger.height * aspectRatio;
+ }
+ } else {
+ if (isNumber(data.width) && data.width <= dragger.maxWidth && data.width >= dragger.minWidth) {
+ dragger.width = data.width;
+ }
+
+ if (isNumber(data.height) && data.height <= dragger.maxHeight && data.height >= dragger.minHeight) {
+ dragger.height = data.height;
+ }
+ }
+ }
+
+ this.dragger = dragger;
+ this.renderDragger();
+ },
+
+ getData: function (rounded) {
+ var dragger = this.dragger,
+ image = this.image,
+ data = {};
+
+ if (this.built) {
+ data = {
+ x: dragger.left - image.left,
+ y: dragger.top - image.top,
+ width: dragger.width,
+ height: dragger.height
+ };
+
+ data = this.transformData(data, TRUE, rounded);
+ }
+
+ return data;
+ },
+
+ transformData: function (data, reversed, rounded) {
+ var ratio = this.image.ratio,
+ result = {};
+
+ $.each(data, function (i, n) {
+ n = num(n);
+
+ if (REGEXP_OPTIONS.test(i) && !isNaN(n)) {
+ result[i] = reversed ? (rounded ? Math.round(n / ratio) : n / ratio) : n * ratio;
+ }
+ });
+
+ return result;
+ },
+
+ setAspectRatio: function (aspectRatio) {
+ var freeRatio = aspectRatio === "auto";
+
+ aspectRatio = num(aspectRatio);
+
+ if (freeRatio || (!isNaN(aspectRatio) && aspectRatio > 0)) {
+ this.defaults.aspectRatio = freeRatio ? NAN : aspectRatio;
+
+ if (this.built) {
+ this.initDragger();
+ this.renderDragger();
+ }
+ }
+ },
+
+ getImageData: function () {
+ var data = {};
+
+ if (this.ready) {
+ $.each(this.image, function (name, value) {
+ if (REGEXP_PROPERTIES.test(name)) {
+ data[name] = value;
+ }
+ });
+ }
+
+ return data;
+ },
+
+ getDataURL: function (options, type, quality) {
+ var canvas = $("<canvas>")[0],
+ data = this.getData(),
+ dataURL = "",
+ context;
+
+ if (!$.isPlainObject(options)) {
+ quality = type;
+ type = options;
+ options = {};
+ }
+
+ options = $.extend({
+ width: data.width,
+ height: data.height
+ }, options);
+
+ if (this.cropped && this.support.canvas) {
+ canvas.width = options.width;
+ canvas.height = options.height;
+ context = canvas.getContext("2d");
+
+ if (type === "image/jpeg") {
+ context.fillStyle = "#fff";
+ context.fillRect(0, 0, options.width, options.height);
+ }
+
+ context.drawImage(this.$clone[0], data.x, data.y, data.width, data.height, 0, 0, options.width, options.height);
+ dataURL = canvas.toDataURL(type, quality);
+ }
+
+ return dataURL;
+ },
+
+ setDragMode: function (mode) {
+ var $canvas = this.$canvas,
+ defaults = this.defaults,
+ cropable = FALSE,
+ movable = FALSE;
+
+ if (!this.built || this.disabled) {
+ return;
+ }
+
+ switch (mode) {
+ case "crop":
+ if (defaults.dragCrop) {
+ cropable = TRUE;
+ $canvas.data(STRING_DIRECTIVE, mode);
+ }
+
+ break;
+
+ case "move":
+ movable = TRUE;
+ $canvas.data(STRING_DIRECTIVE, mode);
+
+ break;
+
+ default:
+ $canvas.removeData(STRING_DIRECTIVE);
+ }
+
+ $canvas.toggleClass(CLASS_CROP, cropable).toggleClass(CLASS_MOVE, movable);
+ },
+
+ enable: function () {
+ if (this.built) {
+ this.disabled = FALSE;
+ this.$cropper.removeClass(CLASS_DISABLED);
+ }
+ },
+
+ disable: function () {
+ if (this.built) {
+ this.disabled = TRUE;
+ this.$cropper.addClass(CLASS_DISABLED);
+ }
+ },
+
+ rotate: function (degree) {
+ var image = this.image;
+
+ degree = num(degree) || 0;
+
+ if (!this.built || degree === 0 || this.disabled || !this.defaults.rotatable || !this.support.canvas) {
+ return;
+ }
+
+ this.rotated = TRUE;
+ degree = (image.rotate = (image.rotate + degree) % 360);
+
+ // replace with "true" to prevent to override the original image
+ this.replace(this.getRotatedDataURL(degree), true);
+ },
+
+ getRotatedDataURL: function (degree) {
+ var canvas = $("<canvas>")[0],
+ context = canvas.getContext("2d"),
+ arc = degree * Math.PI / 180,
+ deg = abs(degree) % 180,
+ acuteAngle = deg > 90 ? (180 - deg) : deg,
+ acuteAngleArc = acuteAngle * Math.PI / 180,
+ originalImage = this.originalImage,
+ naturalWidth = originalImage.naturalWidth,
+ naturalHeight = originalImage.naturalHeight,
+ width = abs(naturalWidth * cos(acuteAngleArc) + naturalHeight * sin(acuteAngleArc)),
+ height = abs(naturalWidth * sin(acuteAngleArc) + naturalHeight * cos(acuteAngleArc));
+
+ canvas.width = width;
+ canvas.height = height;
+ context.save();
+ context.translate(width / 2, height / 2);
+ context.rotate(arc);
+ context.drawImage(this.$original[0], -naturalWidth / 2, -naturalHeight / 2, naturalWidth, naturalHeight);
+ context.restore();
+
+ return canvas.toDataURL();
+ },
+
+ zoom: function (delta) {
+ var image = this.image,
+ width,
+ height,
+ range;
+
+ delta = num(delta);
+
+ if (!this.built || !delta || this.disabled || !this.defaults.zoomable) {
+ return;
+ }
+
+ width = image.width * (1 + delta);
+ height = image.height * (1 + delta);
+ range = width / image._width;
+
+ if (range > 10) {
+ return;
+ }
+
+ if (range < 1) {
+ width = image._width;
+ height = image._height;
+ }
+
+ if (range <= 1) {
+ this.setDragMode("crop");
+ } else {
+ this.setDragMode("move");
+ }
+
+ image.oldWidth = image.width;
+ image.oldHeight = image.height;
+
+ image.width = width;
+ image.height = height;
+ image.ratio = image.width / image.naturalWidth;
+
+ this.renderImage("zoom");
+ },
+
+ dblclick: function () {
+ if (this.disabled) {
+ return;
+ }
+
+ if (this.$canvas.hasClass(CLASS_CROP)) {
+ this.setDragMode("move");
+ } else {
+ this.setDragMode("crop");
+ }
+ },
+
+ wheel: function (event) {
+ var e = event.originalEvent,
+ msDeltaY = 117.25, // IE
+ mozDelatY = 5, // Firefox
+ webkitDelatY = 166.66665649414062, // Chrome, Opera
+ zoomDelta = 0.1, // 10%
+ delta;
+
+ if (this.disabled) {
+ return;
+ }
+
+ event.preventDefault();
+
+ if (e.deltaY) {
+ delta = e.deltaY;
+ delta = delta % mozDelatY === 0 ? delta / mozDelatY : delta % msDeltaY === 0 ? delta / msDeltaY : delta / webkitDelatY;
+ } else {
+ delta = e.wheelDelta ? -e.wheelDelta / 120 : (e.detail ? e.detail / 3 : 0);
+ }
+
+ this.zoom(delta * zoomDelta);
+ },
+
+ dragstart: function (event) {
+ var touches = event.originalEvent.touches,
+ e = event,
+ directive,
+ dragStartEvent,
+ touchesLength;
+
+ if (this.disabled) {
+ return;
+ }
+
+ if (touches) {
+ touchesLength = touches.length;
+
+ if (touchesLength > 1) {
+ if (this.defaults.zoomable && touchesLength === 2) {
+ e = touches[1];
+ this.startX2 = e.pageX;
+ this.startY2 = e.pageY;
+ directive = "zoom";
+ } else {
+ return;
+ }
+ }
+
+ e = touches[0];
+ }
+
+ directive = directive || $(e.target).data(STRING_DIRECTIVE);
+
+ if (REGEXP_DIRECTIVES.test(directive)) {
+ event.preventDefault();
+
+ dragStartEvent = $.Event(EVENT_DRAG_START);
+ this.$element.trigger(dragStartEvent);
+
+ if (dragStartEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this.directive = directive;
+ this.cropping = FALSE;
+ this.startX = e.pageX;
+ this.startY = e.pageY;
+
+ if (directive === "crop") {
+ this.cropping = TRUE;
+ this.$canvas.addClass(CLASS_MODAL);
+ }
+ }
+ },
+
+ dragmove: function (event) {
+ var touches = event.originalEvent.touches,
+ e = event,
+ dragMoveEvent,
+ touchesLength;
+
+ if (this.disabled) {
+ return;
+ }
+
+ if (touches) {
+ touchesLength = touches.length;
+
+ if (touchesLength > 1) {
+ if (this.defaults.zoomable && touchesLength === 2) {
+ e = touches[1];
+ this.endX2 = e.pageX;
+ this.endY2 = e.pageY;
+ } else {
+ return;
+ }
+ }
+
+ e = touches[0];
+ }
+
+ if (this.directive) {
+ event.preventDefault();
+
+ dragMoveEvent = $.Event(EVENT_DRAG_MOVE);
+ this.$element.trigger(dragMoveEvent);
+
+ if (dragMoveEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this.endX = e.pageX;
+ this.endY = e.pageY;
+
+ this.dragging();
+ }
+ },
+
+ dragend: function (event) {
+ var dragEndEvent;
+
+ if (this.disabled) {
+ return;
+ }
+
+ if (this.directive) {
+ event.preventDefault();
+
+ dragEndEvent = $.Event(EVENT_DRAG_END);
+ this.$element.trigger(dragEndEvent);
+
+ if (dragEndEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (this.cropping) {
+ this.cropping = FALSE;
+ this.$canvas.toggleClass(CLASS_MODAL, this.cropped && this.defaults.modal);
+ }
+
+ this.directive = "";
+ }
+ },
+
+ dragging: function () {
+ var directive = this.directive,
+ image = this.image,
+ cropper = this.cropper,
+ maxWidth = cropper.width,
+ maxHeight = cropper.height,
+ dragger = this.dragger,
+ width = dragger.width,
+ height = dragger.height,
+ left = dragger.left,
+ top = dragger.top,
+ right = left + width,
+ bottom = top + height,
+ renderable = TRUE,
+ defaults = this.defaults,
+ aspectRatio = defaults.aspectRatio,
+ range = {
+ x: this.endX - this.startX,
+ y: this.endY - this.startY
+ },
+ offset;
+
+ if (aspectRatio) {
+ range.X = range.y * aspectRatio;
+ range.Y = range.x / aspectRatio;
+ }
+
+ switch (directive) {
+ // Move dragger
+ case "all":
+ left += range.x;
+ top += range.y;
+
+ break;
+
+ // Resize dragger
+ case "e":
+ if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= 0 || bottom >= maxHeight))) {
+ renderable = FALSE;
+ break;
+ }
+
+ width += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top -= range.Y / 2;
+ }
+
+ if (width < 0) {
+ directive = "w";
+ width = 0;
+ }
+
+ break;
+
+ case "n":
+ if (range.y <= 0 && (top <= 0 || aspectRatio && (left <= 0 || right >= maxWidth))) {
+ renderable = FALSE;
+ break;
+ }
+
+ height -= range.y;
+ top += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left += range.X / 2;
+ }
+
+ if (height < 0) {
+ directive = "s";
+ height = 0;
+ }
+
+ break;
+
+ case "w":
+ if (range.x <= 0 && (left <= 0 || aspectRatio && (top <= 0 || bottom >= maxHeight))) {
+ renderable = FALSE;
+ break;
+ }
+
+ width -= range.x;
+ left += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top += range.Y / 2;
+ }
+
+ if (width < 0) {
+ directive = "e";
+ width = 0;
+ }
+
+ break;
+
+ case "s":
+ if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= 0 || right >= maxWidth))) {
+ renderable = FALSE;
+ break;
+ }
+
+ height += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left -= range.X / 2;
+ }
+
+ if (height < 0) {
+ directive = "n";
+ height = 0;
+ }
+
+ break;
+
+ case "ne":
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= 0 || right >= maxWidth)) {
+ renderable = FALSE;
+ break;
+ }
+
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ } else {
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y <= 0 && top <= 0) {
+ renderable = FALSE;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > 0) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (height < 0) {
+ directive = "sw";
+ height = 0;
+ width = 0;
+ }
+
+ break;
+
+ case "nw":
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= 0 || left <= 0)) {
+ renderable = FALSE;
+ break;
+ }
+
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ left += range.X;
+ } else {
+ if (range.x <= 0) {
+ if (left > 0) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y <= 0 && top <= 0) {
+ renderable = FALSE;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > 0) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (height < 0) {
+ directive = "se";
+ height = 0;
+ width = 0;
+ }
+
+ break;
+
+ case "sw":
+ if (aspectRatio) {
+ if (range.x <= 0 && (left <= 0 || bottom >= maxHeight)) {
+ renderable = FALSE;
+ break;
+ }
+
+ width -= range.x;
+ left += range.x;
+ height = width / aspectRatio;
+ } else {
+ if (range.x <= 0) {
+ if (left > 0) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = FALSE;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0) {
+ directive = "ne";
+ height = 0;
+ width = 0;
+ }
+
+ break;
+
+ case "se":
+ if (aspectRatio) {
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
+ renderable = FALSE;
+ break;
+ }
+
+ width += range.x;
+ height = width / aspectRatio;
+ } else {
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = FALSE;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0) {
+ directive = "nw";
+ height = 0;
+ width = 0;
+ }
+
+ break;
+
+ // Move image
+ case "move":
+ image.left += range.x;
+ image.top += range.y;
+ this.renderImage("move");
+ renderable = FALSE;
+
+ break;
+
+ // Scale image
+ case "zoom":
+ if (defaults.zoomable) {
+ this.zoom(function (x, y, x1, y1, x2, y2) {
+ return (sqrt(x2 * x2 + y2 * y2) - sqrt(x1 * x1 + y1 * y1)) / sqrt(x * x + y * y);
+ }(
+ image.width,
+ image.height,
+ abs(this.startX - this.startX2),
+ abs(this.startY - this.startY2),
+ abs(this.endX - this.endX2),
+ abs(this.endY - this.endY2)
+ ));
+
+ this.endX2 = this.startX2;
+ this.endY2 = this.startY2;
+ }
+
+ break;
+
+ // Crop image
+ case "crop":
+ if (range.x && range.y) {
+ offset = this.$cropper.offset();
+ left = this.startX - offset.left;
+ top = this.startY - offset.top;
+ width = dragger.minWidth;
+ height = dragger.minHeight;
+
+ if (range.x > 0) {
+ if (range.y > 0) {
+ directive = "se";
+ } else {
+ directive = "ne";
+ top -= height;
+ }
+ } else {
+ if (range.y > 0) {
+ directive = "sw";
+ left -= width;
+ } else {
+ directive = "nw";
+ left -= width;
+ top -= height;
+ }
+ }
+
+ // Show the dragger if is hidden
+ if (!this.cropped) {
+ this.cropped = TRUE;
+ this.$dragger.removeClass(CLASS_HIDDEN);
+ }
+ }
+
+ break;
+
+ // No default
+ }
+
+ if (renderable) {
+ dragger.width = width;
+ dragger.height = height;
+ dragger.left = left;
+ dragger.top = top;
+ this.directive = directive;
+
+ this.renderDragger();
+ }
+
+ // Override
+ this.startX = this.endX;
+ this.startY = this.endY;
+ }
+ };
+
+ // Use the string compressor: Strmin (https://github.com/fengyuanchen/strmin)
+ Cropper.TEMPLATE = (function (source, words) {
+ words = words.split(",");
+ return source.replace(/\d+/g, function (i) {
+ return words[i];
+ });
+ })('<0 6="5-container"><0 6="5-canvas"></0><0 6="5-dragger"><1 6="5-viewer"></1><1 6="5-8 8-h"></1><1 6="5-8 8-v"></1><1 6="5-face" 3-2="all"></1><1 6="5-7 7-e" 3-2="e"></1><1 6="5-7 7-n" 3-2="n"></1><1 6="5-7 7-w" 3-2="w"></1><1 6="5-7 7-s" 3-2="s"></1><1 6="5-4 4-e" 3-2="e"></1><1 6="5-4 4-n" 3-2="n"></1><1 6="5-4 4-w" 3-2="w"></1><1 6="5-4 4-s" 3-2="s"></1><1 6="5-4 4-ne" 3-2="ne"></1><1 6="5-4 4-nw" 3-2="nw"></1><1 6="5-4 4-sw" 3-2="sw"></1><1 6="5-4 4-se" 3-2="se"></1></0></0>', "div,span,directive,data,point,cropper,class,line,dashed");
+
+ /* Template source:
+ <div class="cropper-container">
+ <div class="cropper-canvas"></div>
+ <div class="cropper-dragger">
+ <span class="cropper-viewer"></span>
+ <span class="cropper-dashed dashed-h"></span>
+ <span class="cropper-dashed dashed-v"></span>
+ <span class="cropper-face" data-directive="all"></span>
+ <span class="cropper-line line-e" data-directive="e"></span>
+ <span class="cropper-line line-n" data-directive="n"></span>
+ <span class="cropper-line line-w" data-directive="w"></span>
+ <span class="cropper-line line-s" data-directive="s"></span>
+ <span class="cropper-point point-e" data-directive="e"></span>
+ <span class="cropper-point point-n" data-directive="n"></span>
+ <span class="cropper-point point-w" data-directive="w"></span>
+ <span class="cropper-point point-s" data-directive="s"></span>
+ <span class="cropper-point point-ne" data-directive="ne"></span>
+ <span class="cropper-point point-nw" data-directive="nw"></span>
+ <span class="cropper-point point-sw" data-directive="sw"></span>
+ <span class="cropper-point point-se" data-directive="se"></span>
+ </div>
+ </div>
+ */
+
+ Cropper.DEFAULTS = {
+ // Basic
+ aspectRatio: "auto",
+ autoCropArea: 0.8, // 80%
+ data: {
+ // x: 0,
+ // y: 0,
+ // width: 300,
+ // height: 150
+ },
+ done: $.noop,
+ preview: "",
+
+ // Toggles
+ multiple: FALSE,
+ autoCrop: TRUE,
+ dragCrop: TRUE,
+ dashed: TRUE,
+ modal: TRUE,
+ movable: TRUE,
+ resizable: TRUE,
+ zoomable: TRUE,
+ rotatable: TRUE,
+ checkImageOrigin: TRUE,
+
+ // Dimensions
+ minWidth: 0,
+ minHeight: 0,
+ maxWidth: INFINITY,
+ maxHeight: INFINITY,
+
+ // Events
+ build: NULL,
+ built: NULL,
+ dragstart: NULL,
+ dragmove: NULL,
+ dragend: NULL
+ };
+
+ Cropper.setDefaults = function (options) {
+ $.extend(Cropper.DEFAULTS, options);
+ };
+
+ // Save the other cropper
+ Cropper.other = $.fn.cropper;
+
+ // Register as jQuery plugin
+ $.fn.cropper = function (options) {
+ var args = toArray(arguments, 1),
+ result;
+
+ this.each(function () {
+ var $this = $(this),
+ data = $this.data("cropper"),
+ fn;
+
+ if (!data) {
+ $this.data("cropper", (data = new Cropper(this, options)));
+ }
+
+ if (typeof options === "string" && $.isFunction((fn = data[options]))) {
+ result = fn.apply(data, args);
+ }
+ });
+
+ return (typeof result !== STRING_UNDEFINED ? result : this);
+ };
+
+ $.fn.cropper.Constructor = Cropper;
+ $.fn.cropper.setDefaults = Cropper.setDefaults;
+
+ // No conflict
+ $.fn.cropper.noConflict = function () {
+ $.fn.cropper = Cropper.other;
+ return this;
+ };
+});
diff --git a/javascript/jquery/plugins/cropper/cropper.min.css b/javascript/jquery/plugins/cropper/cropper.min.css
new file mode 100644
index 0000000..176b533
--- /dev/null
+++ b/javascript/jquery/plugins/cropper/cropper.min.css
@@ -0,0 +1,9 @@
+/*!
+ * Cropper v0.7.7
+ * https://github.com/fengyuanchen/cropper
+ *
+ * Copyright 2014-2015 Fengyuan Chen
+ * Released under the MIT license
+ */
+
+.cropper-container{position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{width:100%;height:100%;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important}.cropper-modal,.cropper-canvas{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-canvas{background-color:#fff;opacity:0;filter:alpha(opacity=0)}.cropper-modal{background-color:#000;opacity:.5;filter:alpha(opacity=50)}.cropper-dragger{position:absolute;top:10%;left:10%;width:80%;height:80%}.cropper-viewer{display:block;width:100%;height:100%;overflow:hidden;outline-width:1px;outline-style:solid;outline-color:#69f;outline-color:rgba(51,102,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #fff;opacity:.5;filter:alpha(opacity=50)}.cropper-dashed.dashed-h{top:33.3%;left:0;width:100%;height:33.3%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.3%;width:33.3%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;cursor:move;background-color:#fff}.cropper-line{background-color:#69f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;background-color:#69f;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:" ";background-color:#69f;opacity:0;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-hidden{display:none!important}.cropper-invisible{position:fixed;top:0;left:0;z-index:-1;width:auto!important;max-width:none!important;height:auto!important;max-height:none!important;opacity:0;filter:alpha(opacity=0)}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-canvas,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file
diff --git a/javascript/jquery/plugins/cropper/cropper.min.js b/javascript/jquery/plugins/cropper/cropper.min.js
new file mode 100644
index 0000000..01cabc0
--- /dev/null
+++ b/javascript/jquery/plugins/cropper/cropper.min.js
@@ -0,0 +1,9 @@
+/*!
+ * Cropper v0.7.7
+ * https://github.com/fengyuanchen/cropper
+ *
+ * Copyright 2014-2015 Fengyuan Chen
+ * Released under the MIT license
+ */
+
+!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){"use strict";var b=a(window),c=a(document),d=window.location,e=!0,f=!1,g=null,h=0/0,i=1/0,j="undefined",k="directive",l=".cropper",m=/^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/,n=/^(x|y|width|height)$/,o=/^(naturalWidth|naturalHeight|width|height|aspectRatio|ratio|rotate)$/,p="cropper-modal",q="cropper-hidden",r="cropper-invisible",s="cropper-move",t="cropper-crop",u="cropper-disabled",v="mousedown touchstart",w="mousemove touchmove",x="mouseup mouseleave touchend touchleave touchcancel",y="wheel mousewheel DOMMouseScroll",z="resize"+l,A="dblclick",B="build"+l,C="built"+l,D="dragstart"+l,E="dragmove"+l,F="dragend"+l,G=function(a){return"number"==typeof a},H=function(a,b){var c=[];return"number"==typeof b&&c.push(b),c.slice.apply(a,c)},I=function(a,b){var c=H(arguments,2);return function(){return a.apply(b,c.concat(H(arguments)))}},J=function(a){var b="timestamp="+(new Date).getTime();return a+(-1===a.indexOf("?")?"?":"&")+b},K=function(b,c){this.element=b,this.$element=a(b),this.defaults=a.extend({},K.DEFAULTS,a.isPlainObject(c)?c:{}),this.$original=g,this.ready=f,this.built=f,this.cropped=f,this.rotated=f,this.disabled=f,this.replaced=f,this.init()},L=Math.sqrt,M=Math.min,N=Math.max,O=Math.abs,P=Math.sin,Q=Math.cos,R=parseFloat;K.prototype={constructor:K,support:{canvas:a.isFunction(a("<canvas>")[0].getContext)},init:function(){var b=this.defaults;a.each(b,function(a,c){switch(a){case"aspectRatio":b[a]=O(R(c))||h;break;case"autoCropArea":b[a]=O(R(c))||.8;break;case"minWidth":case"minHeight":b[a]=O(R(c))||0;break;case"maxWidth":case"maxHeight":b[a]=O(R(c))||i}}),this.image={rotate:0},this.load()},load:function(){var b,c,d=this,f=this.$element,g=this.element,h=this.image,i="";f.is("img")?c=f.prop("src"):f.is("canvas")&&this.support.canvas&&(c=g.toDataURL()),c&&(this.replaced&&(h.rotate=0),this.defaults.checkImageOrigin&&(f.prop("crossOrigin")||this.isCrossOriginURL(c))&&(i=" crossOrigin",c=J(c)),this.$clone=b=a("<img"+i+' src="'+c+'">'),b.one("load",function(){h.naturalWidth=this.naturalWidth||b.width(),h.naturalHeight=this.naturalHeight||b.height(),h.aspectRatio=h.naturalWidth/h.naturalHeight,d.url=c,d.ready=e,d.build()}),b.addClass(r).prependTo("body"))},isCrossOriginURL:function(a){var b=a.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return!b||b[1]===d.protocol&&b[2]===d.hostname&&b[3]===d.port?f:e},build:function(){var b,c,d=this.$element,g=this.defaults;this.ready&&(this.built&&this.unbuild(),d.one(B,g.build),b=a.Event(B),d.trigger(b),b.isDefaultPrevented()||(this.$cropper=c=a(K.TEMPLATE),d.addClass(q),this.$clone.removeClass(r).prependTo(c),this.rotated||(this.$original=this.$clone.clone(),this.$original.addClass(q).prependTo(this.$cropper),this.originalImage=a.extend({},this.image)),this.$container=d.parent(),this.$container.append(c),this.$canvas=c.find(".cropper-canvas"),this.$dragger=c.find(".cropper-dragger"),this.$viewer=c.find(".cropper-viewer"),g.autoCrop?this.cropped=e:this.$dragger.addClass(q),g.modal&&this.$canvas.addClass(p),!g.dashed&&this.$dragger.find(".cropper-dashed").addClass(q),!g.movable&&this.$dragger.find(".cropper-face").data(k,"move"),!g.resizable&&this.$dragger.find(".cropper-line, .cropper-point").addClass(q),this.addListeners(),this.initPreview(),this.built=e,g.dragCrop&&this.setDragMode("crop"),this.update(),this.replaced=f,d.one(C,g.built),d.trigger(C)))},unbuild:function(){this.built&&(this.built=f,this.removeListeners(),this.$preview.empty(),this.$preview=g,this.$dragger=g,this.$canvas=g,this.$container=g,this.$cropper.remove(),this.$cropper=g)},update:function(a){this.initContainer(),this.initCropper(),this.initImage(),this.initDragger(),a?(this.setData(a,e),this.setDragMode("crop")):this.setData(this.defaults.data)},resize:function(){clearTimeout(this.resizing),this.resizing=setTimeout(a.proxy(this.update,this,this.getData()),200)},preview:function(){var b=this.image,c=this.dragger,d=b.width,e=b.height,f=c.left-b.left,g=c.top-b.top;this.$viewer.find("img").css({width:d,height:e,marginLeft:-f,marginTop:-g}),this.$preview.each(function(){var b=a(this),h=b.width()/c.width;b.find("img").css({width:d*h,height:e*h,marginLeft:-f*h,marginTop:-g*h})})},addListeners:function(){var d=this.defaults;this.$element.on(D,d.dragstart).on(E,d.dragmove).on(F,d.dragend),this.$cropper.on(v,a.proxy(this.dragstart,this)).on(A,a.proxy(this.dblclick,this)),d.zoomable&&this.$cropper.on(y,a.proxy(this.wheel,this)),d.multiple?this.$cropper.on(w,a.proxy(this.dragmove,this)).on(x,a.proxy(this.dragend,this)):c.on(w,this._dragmove=I(this.dragmove,this)).on(x,this._dragend=I(this.dragend,this)),b.on(z,this._resize=I(this.resize,this))},removeListeners:function(){var a=this.defaults;this.$element.off(D,a.dragstart).off(E,a.dragmove).off(F,a.dragend),this.$cropper.off(v,this.dragstart).off(A,this.dblclick),a.zoomable&&this.$cropper.off(y,this.wheel),a.multiple?this.$cropper.off(w,this.dragmove).off(x,this.dragend):c.off(w,this._dragmove).off(x,this._dragend),b.off(z,this._resize)},initPreview:function(){var b='<img src="'+this.url+'">';this.$preview=a(this.defaults.preview),this.$viewer.html(b),this.$preview.html(b).find("img").css("cssText","min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;")},initContainer:function(){var a=this.$container;this.container={width:N(a.width(),300),height:N(a.height(),150)}},initCropper:function(){var a,b=this.container,c=this.image;c.naturalWidth*b.height/c.naturalHeight-b.width>=0?(a={width:b.width,height:b.width/c.aspectRatio,left:0},a.top=(b.height-a.height)/2):(a={width:b.height*c.aspectRatio,height:b.height,top:0},a.left=(b.width-a.width)/2),this.$cropper.css({width:a.width,height:a.height,left:a.left,top:a.top}),this.cropper=a},initImage:function(){var b=this.image,c=this.cropper,d={_width:c.width,_height:c.height,width:c.width,height:c.height,left:0,top:0,ratio:c.width/b.naturalWidth};this.defaultImage=a.extend({},b,d),b._width!==c.width||b._height!==c.height?a.extend(b,d):(b=a.extend({},d,b),this.replaced&&(b.ratio=d.ratio)),this.image=b,this.renderImage()},renderImage:function(a){var b=this.image;"zoom"===a&&(b.left-=(b.width-b.oldWidth)/2,b.top-=(b.height-b.oldHeight)/2),b.left=M(N(b.left,b._width-b.width),0),b.top=M(N(b.top,b._height-b.height),0),this.$clone.css({width:b.width,height:b.height,marginLeft:b.left,marginTop:b.top}),a&&(this.defaults.done(this.getData()),this.preview())},initDragger:function(){var b,c,d=this.defaults,e=this.cropper,f=d.aspectRatio||this.image.aspectRatio,g=this.image.ratio;c=e.height*f-e.width>=0?{height:e.width/f,width:e.width,left:0,top:(e.height-e.width/f)/2,maxWidth:e.width,maxHeight:e.width/f}:{height:e.height,width:e.height*f,left:(e.width-e.height*f)/2,top:0,maxWidth:e.height*f,maxHeight:e.height},c.minWidth=0,c.minHeight=0,d.aspectRatio?(isFinite(d.maxWidth)?(c.maxWidth=M(c.maxWidth,d.maxWidth*g),c.maxHeight=c.maxWidth/f):isFinite(d.maxHeight)&&(c.maxHeight=M(c.maxHeight,d.maxHeight*g),c.maxWidth=c.maxHeight*f),d.minWidth>0?(c.minWidth=N(0,d.minWidth*g),c.minHeight=c.minWidth/f):d.minHeight>0&&(c.minHeight=N(0,d.minHeight*g),c.minWidth=c.minHeight*f)):(c.maxWidth=M(c.maxWidth,d.maxWidth*g),c.maxHeight=M(c.maxHeight,d.maxHeight*g),c.minWidth=N(0,d.minWidth*g),c.minHeight=N(0,d.minHeight*g)),c.minWidth=M(c.maxWidth,c.minWidth),c.minHeight=M(c.maxHeight,c.minHeight),b=a.extend({},c),b.height=c.height*d.autoCropArea,b.width=c.width*d.autoCropArea,b.left=(e.width-b.width)/2,b.top=(e.height-b.height)/2,b.oldLeft=c.oldLeft=c.left,b.oldTop=c.oldTop=c.top,this.autoCropDragger=b,this.defaultDragger=a.extend({},c),this.dragger=c},renderDragger:function(){var a=this.dragger,b=this.cropper;a.width>a.maxWidth?(a.width=a.maxWidth,a.left=a.oldLeft):a.width<a.minWidth&&(a.width=a.minWidth,a.left=a.oldLeft),a.height>a.maxHeight?(a.height=a.maxHeight,a.top=a.oldTop):a.height<a.minHeight&&(a.height=a.minHeight,a.top=a.oldTop),a.left=M(N(a.left,0),b.width-a.width),a.top=M(N(a.top,0),b.height-a.height),a.oldLeft=a.left,a.oldTop=a.top,this.dragger=a,this.disabled||this.defaults.done(this.getData()),this.$dragger.css({width:a.width,height:a.height,left:a.left,top:a.top}),this.preview()},reset:function(b){this.cropped&&(b&&(this.defaults.data={}),this.image=a.extend({},this.defaultImage),this.renderImage(),this.dragger=a.extend({},this.defaultDragger),this.setData(this.defaults.data))},clear:function(){this.cropped&&(this.cropped=f,this.setData({x:0,y:0,width:0,height:0}),this.$canvas.removeClass(p),this.$dragger.addClass(q))},destroy:function(){var a=this.$element;this.ready&&(this.unbuild(),a.removeClass(q).removeData("cropper"),this.rotated&&a.attr("src",this.$original.attr("src")))},replace:function(b,c){var d,g=this,h=this.$element,i=this.element;b&&b!==this.url&&b!==h.attr("src")&&(c||(this.rotated=f,this.replaced=e),h.is("img")?(h.attr("src",b),this.load()):h.is("canvas")&&this.support.canvas&&(d=i.getContext("2d"),a('<img src="'+b+'">').one("load",function(){i.width=this.width,i.height=this.height,d.clearRect(0,0,i.width,i.height),d.drawImage(this,0,0),g.load()})))},setData:function(b,c){var d=this.cropper,e=this.dragger,f=this.image,h=this.defaults.aspectRatio;this.built&&typeof b!==j&&((b===g||a.isEmptyObject(b))&&(e=a.extend({},this.autoCropDragger)),a.isPlainObject(b)&&!a.isEmptyObject(b)&&(c||(this.defaults.data=b),b=this.transformData(b),G(b.x)&&b.x<=d.width-f.left&&(e.left=b.x+f.left),G(b.y)&&b.y<=d.height-f.top&&(e.top=b.y+f.top),h?G(b.width)&&b.width<=e.maxWidth&&b.width>=e.minWidth?(e.width=b.width,e.height=e.width/h):G(b.height)&&b.height<=e.maxHeight&&b.height>=e.minHeight&&(e.height=b.height,e.width=e.height*h):(G(b.width)&&b.width<=e.maxWidth&&b.width>=e.minWidth&&(e.width=b.width),G(b.height)&&b.height<=e.maxHeight&&b.height>=e.minHeight&&(e.height=b.height))),this.dragger=e,this.renderDragger())},getData:function(a){var b=this.dragger,c=this.image,d={};return this.built&&(d={x:b.left-c.left,y:b.top-c.top,width:b.width,height:b.height},d=this.transformData(d,e,a)),d},transformData:function(b,c,d){var e=this.image.ratio,f={};return a.each(b,function(a,b){b=R(b),n.test(a)&&!isNaN(b)&&(f[a]=c?d?Math.round(b/e):b/e:b*e)}),f},setAspectRatio:function(a){var b="auto"===a;a=R(a),(b||!isNaN(a)&&a>0)&&(this.defaults.aspectRatio=b?h:a,this.built&&(this.initDragger(),this.renderDragger()))},getImageData:function(){var b={};return this.ready&&a.each(this.image,function(a,c){o.test(a)&&(b[a]=c)}),b},getDataURL:function(b,c,d){var e,f=a("<canvas>")[0],g=this.getData(),h="";return a.isPlainObject(b)||(d=c,c=b,b={}),b=a.extend({width:g.width,height:g.height},b),this.cropped&&this.support.canvas&&(f.width=b.width,f.height=b.height,e=f.getContext("2d"),"image/jpeg"===c&&(e.fillStyle="#fff",e.fillRect(0,0,b.width,b.height)),e.drawImage(this.$clone[0],g.x,g.y,g.width,g.height,0,0,b.width,b.height),h=f.toDataURL(c,d)),h},setDragMode:function(a){var b=this.$canvas,c=this.defaults,d=f,g=f;if(this.built&&!this.disabled){switch(a){case"crop":c.dragCrop&&(d=e,b.data(k,a));break;case"move":g=e,b.data(k,a);break;default:b.removeData(k)}b.toggleClass(t,d).toggleClass(s,g)}},enable:function(){this.built&&(this.disabled=f,this.$cropper.removeClass(u))},disable:function(){this.built&&(this.disabled=e,this.$cropper.addClass(u))},rotate:function(a){var b=this.image;a=R(a)||0,this.built&&0!==a&&!this.disabled&&this.defaults.rotatable&&this.support.canvas&&(this.rotated=e,a=b.rotate=(b.rotate+a)%360,this.replace(this.getRotatedDataURL(a),!0))},getRotatedDataURL:function(b){var c=a("<canvas>")[0],d=c.getContext("2d"),e=b*Math.PI/180,f=O(b)%180,g=f>90?180-f:f,h=g*Math.PI/180,i=this.originalImage,j=i.naturalWidth,k=i.naturalHeight,l=O(j*Q(h)+k*P(h)),m=O(j*P(h)+k*Q(h));return c.width=l,c.height=m,d.save(),d.translate(l/2,m/2),d.rotate(e),d.drawImage(this.$original[0],-j/2,-k/2,j,k),d.restore(),c.toDataURL()},zoom:function(a){var b,c,d,e=this.image;a=R(a),this.built&&a&&!this.disabled&&this.defaults.zoomable&&(b=e.width*(1+a),c=e.height*(1+a),d=b/e._width,d>10||(1>d&&(b=e._width,c=e._height),this.setDragMode(1>=d?"crop":"move"),e.oldWidth=e.width,e.oldHeight=e.height,e.width=b,e.height=c,e.ratio=e.width/e.naturalWidth,this.renderImage("zoom")))},dblclick:function(){this.disabled||this.setDragMode(this.$canvas.hasClass(t)?"move":"crop")},wheel:function(a){var b,c=a.originalEvent,d=117.25,e=5,f=166.66665649414062,g=.1;this.disabled||(a.preventDefault(),c.deltaY?(b=c.deltaY,b=b%e===0?b/e:b%d===0?b/d:b/f):b=c.wheelDelta?-c.wheelDelta/120:c.detail?c.detail/3:0,this.zoom(b*g))},dragstart:function(b){var c,d,g,h=b.originalEvent.touches,i=b;if(!this.disabled){if(h){if(g=h.length,g>1){if(!this.defaults.zoomable||2!==g)return;i=h[1],this.startX2=i.pageX,this.startY2=i.pageY,c="zoom"}i=h[0]}if(c=c||a(i.target).data(k),m.test(c)){if(b.preventDefault(),d=a.Event(D),this.$element.trigger(d),d.isDefaultPrevented())return;this.directive=c,this.cropping=f,this.startX=i.pageX,this.startY=i.pageY,"crop"===c&&(this.cropping=e,this.$canvas.addClass(p))}}},dragmove:function(b){var c,d,e=b.originalEvent.touches,f=b;if(!this.disabled){if(e){if(d=e.length,d>1){if(!this.defaults.zoomable||2!==d)return;f=e[1],this.endX2=f.pageX,this.endY2=f.pageY}f=e[0]}if(this.directive){if(b.preventDefault(),c=a.Event(E),this.$element.trigger(c),c.isDefaultPrevented())return;this.endX=f.pageX,this.endY=f.pageY,this.dragging()}}},dragend:function(b){var c;if(!this.disabled&&this.directive){if(b.preventDefault(),c=a.Event(F),this.$element.trigger(c),c.isDefaultPrevented())return;this.cropping&&(this.cropping=f,this.$canvas.toggleClass(p,this.cropped&&this.defaults.modal)),this.directive=""}},dragging:function(){var a,b=this.directive,c=this.image,d=this.cropper,g=d.width,h=d.height,i=this.dragger,j=i.width,k=i.height,l=i.left,m=i.top,n=l+j,o=m+k,p=e,r=this.defaults,s=r.aspectRatio,t={x:this.endX-this.startX,y:this.endY-this.startY};switch(s&&(t.X=t.y*s,t.Y=t.x/s),b){case"all":l+=t.x,m+=t.y;break;case"e":if(t.x>=0&&(n>=g||s&&(0>=m||o>=h))){p=f;break}j+=t.x,s&&(k=j/s,m-=t.Y/2),0>j&&(b="w",j=0);break;case"n":if(t.y<=0&&(0>=m||s&&(0>=l||n>=g))){p=f;break}k-=t.y,m+=t.y,s&&(j=k*s,l+=t.X/2),0>k&&(b="s",k=0);break;case"w":if(t.x<=0&&(0>=l||s&&(0>=m||o>=h))){p=f;break}j-=t.x,l+=t.x,s&&(k=j/s,m+=t.Y/2),0>j&&(b="e",j=0);break;case"s":if(t.y>=0&&(o>=h||s&&(0>=l||n>=g))){p=f;break}k+=t.y,s&&(j=k*s,l-=t.X/2),0>k&&(b="n",k=0);break;case"ne":if(s){if(t.y<=0&&(0>=m||n>=g)){p=f;break}k-=t.y,m+=t.y,j=k*s}else t.x>=0?g>n?j+=t.x:t.y<=0&&0>=m&&(p=f):j+=t.x,t.y<=0?m>0&&(k-=t.y,m+=t.y):(k-=t.y,m+=t.y);0>k&&(b="sw",k=0,j=0);break;case"nw":if(s){if(t.y<=0&&(0>=m||0>=l)){p=f;break}k-=t.y,m+=t.y,j=k*s,l+=t.X}else t.x<=0?l>0?(j-=t.x,l+=t.x):t.y<=0&&0>=m&&(p=f):(j-=t.x,l+=t.x),t.y<=0?m>0&&(k-=t.y,m+=t.y):(k-=t.y,m+=t.y);0>k&&(b="se",k=0,j=0);break;case"sw":if(s){if(t.x<=0&&(0>=l||o>=h)){p=f;break}j-=t.x,l+=t.x,k=j/s}else t.x<=0?l>0?(j-=t.x,l+=t.x):t.y>=0&&o>=h&&(p=f):(j-=t.x,l+=t.x),t.y>=0?h>o&&(k+=t.y):k+=t.y;0>j&&(b="ne",k=0,j=0);break;case"se":if(s){if(t.x>=0&&(n>=g||o>=h)){p=f;break}j+=t.x,k=j/s}else t.x>=0?g>n?j+=t.x:t.y>=0&&o>=h&&(p=f):j+=t.x,t.y>=0?h>o&&(k+=t.y):k+=t.y;0>j&&(b="nw",k=0,j=0);break;case"move":c.left+=t.x,c.top+=t.y,this.renderImage("move"),p=f;break;case"zoom":r.zoomable&&(this.zoom(function(a,b,c,d,e,f){return(L(e*e+f*f)-L(c*c+d*d))/L(a*a+b*b)}(c.width,c.height,O(this.startX-this.startX2),O(this.startY-this.startY2),O(this.endX-this.endX2),O(this.endY-this.endY2))),this.endX2=this.startX2,this.endY2=this.startY2);break;case"crop":t.x&&t.y&&(a=this.$cropper.offset(),l=this.startX-a.left,m=this.startY-a.top,j=i.minWidth,k=i.minHeight,t.x>0?t.y>0?b="se":(b="ne",m-=k):t.y>0?(b="sw",l-=j):(b="nw",l-=j,m-=k),this.cropped||(this.cropped=e,this.$dragger.removeClass(q)))}p&&(i.width=j,i.height=k,i.left=l,i.top=m,this.directive=b,this.renderDragger()),this.startX=this.endX,this.startY=this.endY}},K.TEMPLATE=function(a,b){return b=b.split(","),a.replace(/\d+/g,function(a){return b[a]})}('<0 6="5-container"><0 6="5-canvas"></0><0 6="5-dragger"><1 6="5-viewer"></1><1 6="5-8 8-h"></1><1 6="5-8 8-v"></1><1 6="5-face" 3-2="all"></1><1 6="5-7 7-e" 3-2="e"></1><1 6="5-7 7-n" 3-2="n"></1><1 6="5-7 7-w" 3-2="w"></1><1 6="5-7 7-s" 3-2="s"></1><1 6="5-4 4-e" 3-2="e"></1><1 6="5-4 4-n" 3-2="n"></1><1 6="5-4 4-w" 3-2="w"></1><1 6="5-4 4-s" 3-2="s"></1><1 6="5-4 4-ne" 3-2="ne"></1><1 6="5-4 4-nw" 3-2="nw"></1><1 6="5-4 4-sw" 3-2="sw"></1><1 6="5-4 4-se" 3-2="se"></1></0></0>',"div,span,directive,data,point,cropper,class,line,dashed"),K.DEFAULTS={aspectRatio:"auto",autoCropArea:.8,data:{},done:a.noop,preview:"",multiple:f,autoCrop:e,dragCrop:e,dashed:e,modal:e,movable:e,resizable:e,zoomable:e,rotatable:e,checkImageOrigin:e,minWidth:0,minHeight:0,maxWidth:i,maxHeight:i,build:g,built:g,dragstart:g,dragmove:g,dragend:g},K.setDefaults=function(b){a.extend(K.DEFAULTS,b)},K.other=a.fn.cropper,a.fn.cropper=function(b){var c,d=H(arguments,1);return this.each(function(){var e,f=a(this),g=f.data("cropper");g||f.data("cropper",g=new K(this,b)),"string"==typeof b&&a.isFunction(e=g[b])&&(c=e.apply(g,d))}),typeof c!==j?c:this},a.fn.cropper.Constructor=K,a.fn.cropper.setDefaults=K.setDefaults,a.fn.cropper.noConflict=function(){return a.fn.cropper=K.other,this}}); \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/blank.gif b/javascript/jquery/plugins/fancybox/blank.gif
new file mode 100644
index 0000000..35d42e8
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/blank.gif
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_close.png b/javascript/jquery/plugins/fancybox/fancy_close.png
new file mode 100644
index 0000000..0703530
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_close.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_closebox.png b/javascript/jquery/plugins/fancybox/fancy_closebox.png
new file mode 100644
index 0000000..4de4396
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_closebox.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_left.png b/javascript/jquery/plugins/fancybox/fancy_left.png
new file mode 100644
index 0000000..61494e6
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_left.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_loading.png b/javascript/jquery/plugins/fancybox/fancy_loading.png
new file mode 100644
index 0000000..2503017
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_loading.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_nav_left.png b/javascript/jquery/plugins/fancybox/fancy_nav_left.png
new file mode 100644
index 0000000..ebaa6a4
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_nav_left.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_nav_right.png b/javascript/jquery/plugins/fancybox/fancy_nav_right.png
new file mode 100644
index 0000000..873294e
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_nav_right.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_progress.png b/javascript/jquery/plugins/fancybox/fancy_progress.png
new file mode 100644
index 0000000..06b7c89
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_progress.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_right.png b/javascript/jquery/plugins/fancybox/fancy_right.png
new file mode 100644
index 0000000..0a56042
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_right.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_e.png b/javascript/jquery/plugins/fancybox/fancy_shadow_e.png
new file mode 100644
index 0000000..2eda089
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_e.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_n.png b/javascript/jquery/plugins/fancybox/fancy_shadow_n.png
new file mode 100644
index 0000000..69aa10e
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_n.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_ne.png b/javascript/jquery/plugins/fancybox/fancy_shadow_ne.png
new file mode 100644
index 0000000..79f6980
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_ne.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_nw.png b/javascript/jquery/plugins/fancybox/fancy_shadow_nw.png
new file mode 100644
index 0000000..7182cd9
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_nw.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_s.png b/javascript/jquery/plugins/fancybox/fancy_shadow_s.png
new file mode 100644
index 0000000..d8858bf
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_s.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_se.png b/javascript/jquery/plugins/fancybox/fancy_shadow_se.png
new file mode 100644
index 0000000..541e3ff
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_se.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_sw.png b/javascript/jquery/plugins/fancybox/fancy_shadow_sw.png
new file mode 100644
index 0000000..b451689
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_sw.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_shadow_w.png b/javascript/jquery/plugins/fancybox/fancy_shadow_w.png
new file mode 100644
index 0000000..8a4e4a8
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_shadow_w.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_title_left.png b/javascript/jquery/plugins/fancybox/fancy_title_left.png
new file mode 100644
index 0000000..6049223
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_title_left.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_title_main.png b/javascript/jquery/plugins/fancybox/fancy_title_main.png
new file mode 100644
index 0000000..8044271
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_title_main.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_title_over.png b/javascript/jquery/plugins/fancybox/fancy_title_over.png
new file mode 100644
index 0000000..d9f458f
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_title_over.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancy_title_right.png b/javascript/jquery/plugins/fancybox/fancy_title_right.png
new file mode 100644
index 0000000..e36d9db
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancy_title_right.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancybox-x.png b/javascript/jquery/plugins/fancybox/fancybox-x.png
new file mode 100644
index 0000000..c2130f8
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancybox-x.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancybox-y.png b/javascript/jquery/plugins/fancybox/fancybox-y.png
new file mode 100644
index 0000000..7ef399b
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancybox-y.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancybox.png b/javascript/jquery/plugins/fancybox/fancybox.png
new file mode 100644
index 0000000..65e14f6
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancybox.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancybox_loading.gif b/javascript/jquery/plugins/fancybox/fancybox_loading.gif
new file mode 100644
index 0000000..742131f
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancybox_loading.gif
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/fancybox_sprite.png b/javascript/jquery/plugins/fancybox/fancybox_sprite.png
new file mode 100644
index 0000000..753021b
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/fancybox_sprite.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/helpers/fancybox_buttons.png b/javascript/jquery/plugins/fancybox/helpers/fancybox_buttons.png
new file mode 100644
index 0000000..e0e1ea8
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/helpers/fancybox_buttons.png
Binary files differ
diff --git a/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.css b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.css
new file mode 100644
index 0000000..1e83200
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.css
@@ -0,0 +1,85 @@
+#fancybox-buttons {
+ position: fixed;
+ left: 0;
+ width: 100%;
+ z-index: 1005;
+}
+
+#fancybox-buttons.top {
+ top: 10px;
+}
+
+#fancybox-buttons.bottom {
+ bottom: 10px;
+}
+
+#fancybox-buttons ul {
+ display: block;
+ width: 170px;
+ height: 30px;
+ margin: 0 auto;
+ padding: 0;
+ list-style: none;
+ background: #111;
+ -webkit-box-shadow: 0 1px 3px #000,0 0 0 1px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.05);
+ -moz-box-shadow: 0 1px 3px #000,0 0 0 1px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.05);
+ background: #111 -webkit-gradient(linear,0% 0%,0% 100%,from(rgba(255,255,255,.2)),color-stop(.5,rgba(255,255,255,.15)),color-stop(.5,rgba(255,255,255,.1)),to(rgba(255,255,255,.15)));
+ background: #111 -moz-linear-gradient(top,rgba(255,255,255,.2) 0%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.1) 50%,rgba(255,255,255,.15) 100%);
+ border-radius: 3px;
+}
+
+#fancybox-buttons ul li {
+ float: left;
+ margin: 0;
+ padding: 0;
+}
+
+#fancybox-buttons a {
+ display: block;
+ width: 30px;
+ height: 30px;
+ text-indent: -9999px;
+ background-image: url('fancybox_buttons.png');
+ background-repeat: no-repeat;
+ outline: none;
+}
+
+#fancybox-buttons a.btnPrev {
+ width: 32px;
+ background-position: 6px 0;
+}
+
+#fancybox-buttons a.btnNext {
+ background-position: -33px 0;
+ border-right: 1px solid #3e3e3e;
+}
+
+#fancybox-buttons a.btnPlay {
+ background-position: 0 -30px;
+}
+
+#fancybox-buttons a.btnPlayOn {
+ background-position: -30px -30px;
+}
+
+#fancybox-buttons a.btnToggle {
+ background-position: 3px -60px;
+ border-left: 1px solid #111;
+ border-right: 1px solid #3e3e3e;
+ width: 35px
+}
+
+#fancybox-buttons a.btnToggleOn {
+ background-position: -27px -60px;
+}
+
+#fancybox-buttons a.btnClose {
+ border-left: 1px solid #111;
+ width: 38px;
+ background-position: -57px 0px;
+}
+
+#fancybox-buttons a.btnDisabled {
+ opacity : 0.5;
+ cursor: default;
+} \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.js b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.js
new file mode 100644
index 0000000..e116e38
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-buttons.js
@@ -0,0 +1,115 @@
+ /*!
+ * Buttons helper for fancyBox
+ * version: 1.0.2
+ * @requires fancyBox v2.0 or later
+ *
+ * Usage:
+ * $(".fancybox").fancybox({
+ * buttons: {
+ * position : 'top'
+ * }
+ * });
+ *
+ * Options:
+ * tpl - HTML template
+ * position - 'top' or 'bottom'
+ *
+ */
+(function ($) {
+ //Shortcut for fancyBox object
+ var F = $.fancybox;
+
+ //Add helper object
+ F.helpers.buttons = {
+ tpl: '<div id="fancybox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a class="btnPlay" title="Start slideshow" href="javascript:;"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:jQuery.fancybox.close();"></a></li></ul></div>',
+ list: null,
+ buttons: {},
+
+ update: function () {
+ var toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn');
+
+ //Size toggle button
+ if (F.current.canShrink) {
+ toggle.addClass('btnToggleOn');
+
+ } else if (!F.current.canExpand) {
+ toggle.addClass('btnDisabled');
+ }
+ },
+
+ beforeLoad: function (opts) {
+ //Remove self if gallery do not have at least two items
+ if (F.group.length < 2) {
+ F.coming.helpers.buttons = false;
+ F.coming.closeBtn = true;
+
+ return;
+ }
+
+ //Increase top margin to give space for buttons
+ F.coming.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30;
+ },
+
+ onPlayStart: function () {
+ if (this.list) {
+ this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn');
+ }
+ },
+
+ onPlayEnd: function () {
+ if (this.list) {
+ this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn');
+ }
+ },
+
+ afterShow: function (opts) {
+ var buttons;
+
+ if (!this.list) {
+ this.list = $(opts.tpl || this.tpl).addClass(opts.position || 'top').appendTo('body');
+
+ this.buttons = {
+ prev : this.list.find('.btnPrev').click( F.prev ),
+ next : this.list.find('.btnNext').click( F.next ),
+ play : this.list.find('.btnPlay').click( F.play ),
+ toggle : this.list.find('.btnToggle').click( F.toggle )
+ }
+ }
+
+ buttons = this.buttons;
+
+ //Prev
+ if (F.current.index > 0 || F.current.loop) {
+ buttons.prev.removeClass('btnDisabled');
+ } else {
+ buttons.prev.addClass('btnDisabled');
+ }
+
+ //Next / Play
+ if (F.current.loop || F.current.index < F.group.length - 1) {
+ buttons.next.removeClass('btnDisabled');
+ buttons.play.removeClass('btnDisabled');
+
+ } else {
+ buttons.next.addClass('btnDisabled');
+ buttons.play.addClass('btnDisabled');
+ }
+
+ this.update();
+ },
+
+ onUpdate: function () {
+ this.update();
+ },
+
+ beforeClose: function () {
+ if (this.list) {
+ this.list.remove();
+ }
+
+ this.list = null;
+ this.buttons = {};
+ }
+ };
+
+}(jQuery)); \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.css b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.css
new file mode 100644
index 0000000..aadfb73
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.css
@@ -0,0 +1,54 @@
+#fancybox-thumbs {
+ position: fixed;
+ left: 0px;
+ width: 100%;
+ overflow: hidden;
+ z-index: 1005;
+}
+
+#fancybox-thumbs.bottom {
+ bottom: 2px;
+}
+
+#fancybox-thumbs.top {
+ top: 2px;
+}
+
+#fancybox-thumbs ul {
+ position: relative;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#fancybox-thumbs ul li {
+ float: left;
+ padding: 1px;
+ opacity: 0.5;
+}
+
+#fancybox-thumbs ul li.active {
+ opacity: 0.75;
+ padding: 0;
+ border: 1px solid #fff;
+}
+
+#fancybox-thumbs ul li:hover {
+ opacity: 1;
+}
+
+#fancybox-thumbs ul li a {
+ display: block;
+ position: relative;
+ overflow: hidden;
+ border: 1px solid #222;
+ background: #111;
+ outline: none;
+}
+
+#fancybox-thumbs ul li img {
+ display: block;
+ position: relative;
+ border: 0;
+ padding: 0;
+} \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.js b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.js
new file mode 100644
index 0000000..04a97db
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/helpers/jquery.fancybox-thumbs.js
@@ -0,0 +1,157 @@
+ /*!
+ * Thumbnail helper for fancyBox
+ * version: 1.0.3
+ * @requires fancyBox v2.0 or later
+ *
+ * Usage:
+ * $(".fancybox").fancybox({
+ * thumbs: {
+ * width : 50,
+ * height : 50
+ * }
+ * });
+ *
+ * Options:
+ * width - thumbnail width
+ * height - thumbnail height
+ * source - function to obtain the URL of the thumbnail image
+ * position - 'top' or 'bottom'
+ *
+ */
+(function ($) {
+ //Shortcut for fancyBox object
+ var F = $.fancybox;
+
+ //Add helper object
+ F.helpers.thumbs = {
+ wrap: null,
+ list: null,
+ width: 0,
+
+ //Default function to obtain the URL of the thumbnail image
+ source: function (el) {
+ var img;
+
+ if ($.type(el) === 'string') {
+ return el;
+ }
+
+ img = $(el).find('img');
+
+ return img.length ? img.attr('src') : el.href;
+ },
+
+ init: function (opts) {
+ var that = this,
+ list,
+ thumbWidth = opts.width || 50,
+ thumbHeight = opts.height || 50,
+ thumbSource = opts.source || this.source;
+
+ //Build list structure
+ list = '';
+
+ for (var n = 0; n < F.group.length; n++) {
+ list += '<li><a style="width:' + thumbWidth + 'px;height:' + thumbHeight + 'px;" href="javascript:jQuery.fancybox.jumpto(' + n + ');"></a></li>';
+ }
+
+ this.wrap = $('<div id="fancybox-thumbs"></div>').addClass(opts.position || 'bottom').appendTo('body');
+ this.list = $('<ul>' + list + '</ul>').appendTo(this.wrap);
+
+ //Load each thumbnail
+ $.each(F.group, function (i) {
+ $("<img />").load(function () {
+ var width = this.width,
+ height = this.height,
+ widthRatio, heightRatio, parent;
+
+ if (!that.list || !width || !height) {
+ return;
+ }
+
+ //Calculate thumbnail width/height and center it
+ widthRatio = width / thumbWidth;
+ heightRatio = height / thumbHeight;
+ parent = that.list.children().eq(i).find('a');
+
+ if (widthRatio >= 1 && heightRatio >= 1) {
+ if (widthRatio > heightRatio) {
+ width = Math.floor(width / heightRatio);
+ height = thumbHeight;
+
+ } else {
+ width = thumbWidth;
+ height = Math.floor(height / widthRatio);
+ }
+ }
+
+ $(this).css({
+ width: width,
+ height: height,
+ top: Math.floor(thumbHeight / 2 - height / 2),
+ left: Math.floor(thumbWidth / 2 - width / 2)
+ });
+
+ parent.width(thumbWidth).height(thumbHeight);
+
+ $(this).hide().appendTo(parent).fadeIn(300);
+
+ }).attr('src', thumbSource( F.group[ i ] ));
+ });
+
+ //Set initial width
+ this.width = this.list.children().eq(0).outerWidth();
+
+ this.list.width(this.width * (F.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (F.current.index * this.width + this.width * 0.5)));
+ },
+
+ //Center list
+ update: function (opts) {
+ if (this.list) {
+ this.list.stop(true).animate({
+ 'left': Math.floor($(window).width() * 0.5 - (F.current.index * this.width + this.width * 0.5))
+ }, 150);
+ }
+ },
+
+ beforeLoad: function (opts) {
+ //Remove self if gallery do not have at least two items
+ if (F.group.length < 2) {
+ F.coming.helpers.thumbs = false;
+
+ return;
+ }
+
+ //Increase bottom margin to give space for thumbs
+ F.coming.margin[ opts.position === 'top' ? 0 : 2 ] = opts.height + 30;
+ },
+
+ afterShow: function (opts) {
+ //Check if exists and create or update list
+ if (this.list) {
+ this.update(opts);
+
+ } else {
+ this.init(opts);
+ }
+
+ //Set active element
+ this.list.children().removeClass('active').eq(F.current.index).addClass('active');
+ },
+
+ onUpdate: function () {
+ this.update();
+ },
+
+ beforeClose: function () {
+ if (this.wrap) {
+ this.wrap.remove();
+ }
+
+ this.wrap = null;
+ this.list = null;
+ this.width = 0;
+ }
+ }
+
+}(jQuery)); \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/jquery.easing-1.3.pack.js b/javascript/jquery/plugins/fancybox/jquery.easing-1.3.pack.js
new file mode 100644
index 0000000..9028179
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/jquery.easing-1.3.pack.js
@@ -0,0 +1,72 @@
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright © 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('h.i[\'1a\']=h.i[\'z\'];h.O(h.i,{y:\'D\',z:9(x,t,b,c,d){6 h.i[h.i.y](x,t,b,c,d)},17:9(x,t,b,c,d){6 c*(t/=d)*t+b},D:9(x,t,b,c,d){6-c*(t/=d)*(t-2)+b},13:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t+b;6-c/2*((--t)*(t-2)-1)+b},X:9(x,t,b,c,d){6 c*(t/=d)*t*t+b},U:9(x,t,b,c,d){6 c*((t=t/d-1)*t*t+1)+b},R:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t+b;6 c/2*((t-=2)*t*t+2)+b},N:9(x,t,b,c,d){6 c*(t/=d)*t*t*t+b},M:9(x,t,b,c,d){6-c*((t=t/d-1)*t*t*t-1)+b},L:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t*t+b;6-c/2*((t-=2)*t*t*t-2)+b},K:9(x,t,b,c,d){6 c*(t/=d)*t*t*t*t+b},J:9(x,t,b,c,d){6 c*((t=t/d-1)*t*t*t*t+1)+b},I:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t*t*t+b;6 c/2*((t-=2)*t*t*t*t+2)+b},G:9(x,t,b,c,d){6-c*8.C(t/d*(8.g/2))+c+b},15:9(x,t,b,c,d){6 c*8.n(t/d*(8.g/2))+b},12:9(x,t,b,c,d){6-c/2*(8.C(8.g*t/d)-1)+b},Z:9(x,t,b,c,d){6(t==0)?b:c*8.j(2,10*(t/d-1))+b},Y:9(x,t,b,c,d){6(t==d)?b+c:c*(-8.j(2,-10*t/d)+1)+b},W:9(x,t,b,c,d){e(t==0)6 b;e(t==d)6 b+c;e((t/=d/2)<1)6 c/2*8.j(2,10*(t-1))+b;6 c/2*(-8.j(2,-10*--t)+2)+b},V:9(x,t,b,c,d){6-c*(8.o(1-(t/=d)*t)-1)+b},S:9(x,t,b,c,d){6 c*8.o(1-(t=t/d-1)*t)+b},Q:9(x,t,b,c,d){e((t/=d/2)<1)6-c/2*(8.o(1-t*t)-1)+b;6 c/2*(8.o(1-(t-=2)*t)+1)+b},P:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d)==1)6 b+c;e(!p)p=d*.3;e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);6-(a*8.j(2,10*(t-=1))*8.n((t*d-s)*(2*8.g)/p))+b},H:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d)==1)6 b+c;e(!p)p=d*.3;e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);6 a*8.j(2,-10*t)*8.n((t*d-s)*(2*8.g)/p)+c+b},T:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d/2)==2)6 b+c;e(!p)p=d*(.3*1.5);e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);e(t<1)6-.5*(a*8.j(2,10*(t-=1))*8.n((t*d-s)*(2*8.g)/p))+b;6 a*8.j(2,-10*(t-=1))*8.n((t*d-s)*(2*8.g)/p)*.5+c+b},F:9(x,t,b,c,d,s){e(s==u)s=1.l;6 c*(t/=d)*t*((s+1)*t-s)+b},E:9(x,t,b,c,d,s){e(s==u)s=1.l;6 c*((t=t/d-1)*t*((s+1)*t+s)+1)+b},16:9(x,t,b,c,d,s){e(s==u)s=1.l;e((t/=d/2)<1)6 c/2*(t*t*(((s*=(1.B))+1)*t-s))+b;6 c/2*((t-=2)*t*(((s*=(1.B))+1)*t+s)+2)+b},A:9(x,t,b,c,d){6 c-h.i.v(x,d-t,0,c,d)+b},v:9(x,t,b,c,d){e((t/=d)<(1/2.k)){6 c*(7.q*t*t)+b}m e(t<(2/2.k)){6 c*(7.q*(t-=(1.5/2.k))*t+.k)+b}m e(t<(2.5/2.k)){6 c*(7.q*(t-=(2.14/2.k))*t+.11)+b}m{6 c*(7.q*(t-=(2.18/2.k))*t+.19)+b}},1b:9(x,t,b,c,d){e(t<d/2)6 h.i.A(x,t*2,0,c,d)*.5+b;6 h.i.v(x,t*2-d,0,c,d)*.5+c*.5+b}});',62,74,'||||||return||Math|function|||||if|var|PI|jQuery|easing|pow|75|70158|else|sin|sqrt||5625|asin|||undefined|easeOutBounce|abs||def|swing|easeInBounce|525|cos|easeOutQuad|easeOutBack|easeInBack|easeInSine|easeOutElastic|easeInOutQuint|easeOutQuint|easeInQuint|easeInOutQuart|easeOutQuart|easeInQuart|extend|easeInElastic|easeInOutCirc|easeInOutCubic|easeOutCirc|easeInOutElastic|easeOutCubic|easeInCirc|easeInOutExpo|easeInCubic|easeOutExpo|easeInExpo||9375|easeInOutSine|easeInOutQuad|25|easeOutSine|easeInOutBack|easeInQuad|625|984375|jswing|easeInOutBounce'.split('|'),0,{}))
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
diff --git a/javascript/jquery/plugins/fancybox/jquery.fancybox.css b/javascript/jquery/plugins/fancybox/jquery.fancybox.css
new file mode 100644
index 0000000..fa9ab43
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/jquery.fancybox.css
@@ -0,0 +1,222 @@
+/*! fancyBox v2.0.5 fancyapps.com | fancyapps.com/fancybox/#license */
+.fancybox-tmp iframe, .fancybox-tmp object {
+ vertical-align: top;
+ padding: 0;
+ margin: 0;
+}
+
+.fancybox-wrap {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1002;
+}
+
+.fancybox-outer {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ background: #f9f9f9;
+ color: #444;
+ text-shadow: none;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.fancybox-opened {
+ z-index: 1003;
+}
+
+.fancybox-opened .fancybox-outer {
+ -webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+ -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+}
+
+.fancybox-inner {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+ position: relative;
+ outline: none;
+ overflow: hidden;
+}
+
+.fancybox-error {
+ color: #444;
+ font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
+ margin: 0;
+ padding: 10px;
+}
+
+.fancybox-image, .fancybox-iframe {
+ display: block;
+ width: 100%;
+ height: 100%;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ vertical-align: top;
+}
+
+.fancybox-image {
+ max-width: 100%;
+ max-height: 100%;
+}
+
+#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
+ background-image: url('fancybox_sprite.png');
+}
+
+#fancybox-loading {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ margin-top: -22px;
+ margin-left: -22px;
+ background-position: 0 -108px;
+ opacity: 0.8;
+ cursor: pointer;
+ z-index: 1010;
+}
+
+#fancybox-loading div {
+ width: 44px;
+ height: 44px;
+ background: url('fancybox_loading.gif') center center no-repeat;
+}
+
+.fancybox-close {
+ position: absolute;
+ top: -18px;
+ right: -18px;
+ width: 36px;
+ height: 36px;
+ cursor: pointer;
+ z-index: 1004;
+}
+
+.fancybox-nav {
+ position: absolute;
+ top: 0;
+ width: 40%;
+ height: 100%;
+ cursor: pointer;
+ background: transparent url('blank.gif'); /* helps IE */
+ z-index: 1003;
+}
+
+.fancybox-prev {
+ left: 0;
+}
+
+.fancybox-next {
+ right: 0;
+}
+
+.fancybox-nav span {
+ position: absolute;
+ top: 50%;
+ width: 36px;
+ height: 36px;
+ margin-top: -18px;
+ cursor: pointer;
+ z-index: 1003;
+ visibility: hidden;
+}
+
+.fancybox-prev span {
+ left: 20px;
+ background-position: 0 -36px;
+}
+
+.fancybox-next span {
+ right: 20px;
+ background-position: 0 -72px;
+}
+
+.fancybox-nav:hover span {
+ visibility: visible;
+}
+
+.fancybox-tmp {
+ position: absolute;
+ top: -9999px;
+ left: -9999px;
+ padding: 0;
+ overflow: visible;
+ visibility: hidden;
+}
+
+/* Overlay helper */
+
+#fancybox-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ display: none;
+ z-index: 1001;
+ background: #000;
+}
+
+/* Title helper */
+
+.fancybox-title {
+ visibility: hidden;
+ font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
+ position: relative;
+ text-shadow: none;
+ z-index: 1005;
+}
+
+.fancybox-opened .fancybox-title {
+ visibility: visible;
+}
+
+.fancybox-title-float-wrap {
+ position: absolute;
+ bottom: 0;
+ right: 50%;
+ margin-bottom: -35px;
+ z-index: 1003;
+ text-align: center;
+}
+
+.fancybox-title-float-wrap .child {
+ display: inline-block;
+ margin-right: -100%;
+ padding: 2px 20px;
+ background: transparent; /* Fallback for web browsers that doesn't support RGBa */
+ background: rgba(0, 0, 0, 0.8);
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+ text-shadow: 0 1px 2px #222;
+ color: #FFF;
+ font-weight: bold;
+ line-height: 24px;
+ white-space: nowrap;
+}
+
+.fancybox-title-outside-wrap {
+ position: relative;
+ margin-top: 10px;
+ color: #fff;
+}
+
+.fancybox-title-inside-wrap {
+ margin-top: 10px;
+}
+
+.fancybox-title-over-wrap {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ color: #fff;
+ padding: 10px;
+ background: #000;
+ background: rgba(0, 0, 0, .8);
+} \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/jquery.fancybox.js b/javascript/jquery/plugins/fancybox/jquery.fancybox.js
new file mode 100644
index 0000000..435f8a0
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/jquery.fancybox.js
@@ -0,0 +1,1456 @@
+ /*!
+ * fancyBox - jQuery Plugin
+ * version: 2.0.5 (02/03/2012)
+ * @requires jQuery v1.6 or later
+ *
+ * Examples at http://fancyapps.com/fancybox/
+ * License: www.fancyapps.com/fancybox/#license
+ *
+ * Copyright 2012 Janis Skarnelis - janis@fancyapps.com
+ *
+ */
+(function (window, document, undefined) {
+ "use strict";
+
+ var $ = window.jQuery,
+ W = $(window),
+ D = $(document),
+ F = $.fancybox = function () {
+ F.open.apply( this, arguments );
+ },
+ didResize = false,
+ resizeTimer = null,
+ isMobile = document.createTouch !== undefined,
+ isString = function(str) {
+ return $.type(str) === "string";
+ };
+
+ $.extend(F, {
+ // The current version of fancyBox
+ version: '2.0.5',
+
+ defaults: {
+ padding: 15,
+ margin: 20,
+
+ width: 800,
+ height: 600,
+ minWidth: 100,
+ minHeight: 100,
+ maxWidth: 9999,
+ maxHeight: 9999,
+
+ autoSize: true,
+ autoResize: !isMobile,
+ autoCenter : !isMobile,
+ fitToView: true,
+ aspectRatio: false,
+ topRatio: 0.5,
+
+ fixed: !($.browser.msie && $.browser.version <= 6) && !isMobile,
+ scrolling: 'auto', // 'auto', 'yes' or 'no'
+ wrapCSS: 'fancybox-default',
+
+ arrows: true,
+ closeBtn: true,
+ closeClick: false,
+ nextClick : false,
+ mouseWheel: true,
+ autoPlay: false,
+ playSpeed: 3000,
+ preload : 3,
+
+ modal: false,
+ loop: true,
+ ajax: { dataType: 'html', headers: { 'X-fancyBox': true } },
+ keys: {
+ next: [13, 32, 34, 39, 40], // enter, space, page down, right arrow, down arrow
+ prev: [8, 33, 37, 38], // backspace, page up, left arrow, up arrow
+ close: [27] // escape key
+ },
+
+ // Override some properties
+ index: 0,
+ type: null,
+ href: null,
+ content: null,
+ title: null,
+
+ // HTML templates
+ tpl: {
+ wrap: '<div class="fancybox-wrap"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div>',
+ image: '<img class="fancybox-image" src="{href}" alt="" />',
+ iframe: '<iframe class="fancybox-iframe" name="fancybox-frame{rnd}" frameborder="0" hspace="0"' + ($.browser.msie ? ' allowtransparency="true"' : '') + '></iframe>',
+ swf: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{href}" /><embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="100%" height="100%" wmode="transparent"></embed></object>',
+ error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
+ closeBtn: '<div title="Close" class="fancybox-item fancybox-close"></div>',
+ next: '<a title="Next" class="fancybox-nav fancybox-next"><span></span></a>',
+ prev: '<a title="Previous" class="fancybox-nav fancybox-prev"><span></span></a>'
+ },
+
+ // Properties for each animation type
+ // Opening fancyBox
+ openEffect: 'fade', // 'elastic', 'fade' or 'none'
+ openSpeed: 250,
+ openEasing: 'swing',
+ openOpacity: true,
+ openMethod: 'zoomIn',
+
+ // Closing fancyBox
+ closeEffect: 'fade', // 'elastic', 'fade' or 'none'
+ closeSpeed: 250,
+ closeEasing: 'swing',
+ closeOpacity: true,
+ closeMethod: 'zoomOut',
+
+ // Changing next gallery item
+ nextEffect: 'elastic', // 'elastic', 'fade' or 'none'
+ nextSpeed: 300,
+ nextEasing: 'swing',
+ nextMethod: 'changeIn',
+
+ // Changing previous gallery item
+ prevEffect: 'elastic', // 'elastic', 'fade' or 'none'
+ prevSpeed: 300,
+ prevEasing: 'swing',
+ prevMethod: 'changeOut',
+
+ // Enabled helpers
+ helpers: {
+ overlay: {
+ speedIn: 0,
+ speedOut: 300,
+ opacity: 0.8,
+ css: {
+ cursor: 'pointer'
+ },
+ closeClick: true
+ },
+ title: {
+ type: 'float' // 'float', 'inside', 'outside' or 'over'
+ }
+ },
+
+ // Callbacks
+ onCancel: $.noop, // If canceling
+ beforeLoad: $.noop, // Before loading
+ afterLoad: $.noop, // After loading
+ beforeShow: $.noop, // Before changing in current item
+ afterShow: $.noop, // After opening
+ beforeClose: $.noop, // Before closing
+ afterClose: $.noop // After closing
+ },
+
+ //Current state
+ group: {}, // Selected group
+ opts: {}, // Group options
+ coming: null, // Element being loaded
+ current: null, // Currently loaded element
+ isOpen: false, // Is currently open
+ isOpened: false, // Have been fully opened at least once
+ wrap: null,
+ outer: null,
+ inner: null,
+
+ player: {
+ timer: null,
+ isActive: false
+ },
+
+ // Loaders
+ ajaxLoad: null,
+ imgPreload: null,
+
+ // Some collections
+ transitions: {},
+ helpers: {},
+
+ /*
+ * Static methods
+ */
+
+ open: function (group, opts) {
+ //Kill existing instances
+ F.close(true);
+
+ //Normalize group
+ if (group && !$.isArray(group)) {
+ group = group instanceof $ ? $(group).get() : [group];
+ }
+
+ F.isActive = true;
+
+ //Extend the defaults
+ F.opts = $.extend(true, {}, F.defaults, opts);
+
+ //All options are merged recursive except keys
+ if ($.isPlainObject(opts) && opts.keys !== undefined) {
+ F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
+ }
+
+ F.group = group;
+
+ F._start(F.opts.index || 0);
+ },
+
+ cancel: function () {
+ if (F.coming && false === F.trigger('onCancel')) {
+ return;
+ }
+
+ F.coming = null;
+
+ F.hideLoading();
+
+ if (F.ajaxLoad) {
+ F.ajaxLoad.abort();
+ }
+
+ F.ajaxLoad = null;
+
+ if (F.imgPreload) {
+ F.imgPreload.onload = F.imgPreload.onabort = F.imgPreload.onerror = null;
+ }
+ },
+
+ close: function (a) {
+ F.cancel();
+
+ if (!F.current || false === F.trigger('beforeClose')) {
+ return;
+ }
+
+ F.unbindEvents();
+
+ //If forced or is still opening then remove immediately
+ if (!F.isOpen || (a && a[0] === true)) {
+ $(".fancybox-wrap").stop().trigger('onReset').remove();
+
+ F._afterZoomOut();
+
+ } else {
+ F.isOpen = F.isOpened = false;
+
+ $(".fancybox-item, .fancybox-nav").remove();
+
+ F.wrap.stop(true).removeClass('fancybox-opened');
+ F.inner.css('overflow', 'hidden');
+
+ F.transitions[F.current.closeMethod]();
+ }
+ },
+
+ // Start/stop slideshow
+ play: function (a) {
+ var clear = function () {
+ clearTimeout(F.player.timer);
+ },
+ set = function () {
+ clear();
+
+ if (F.current && F.player.isActive) {
+ F.player.timer = setTimeout(F.next, F.current.playSpeed);
+ }
+ },
+ stop = function () {
+ clear();
+
+ $('body').unbind('.player');
+
+ F.player.isActive = false;
+
+ F.trigger('onPlayEnd');
+ },
+ start = function () {
+ if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
+ F.player.isActive = true;
+
+ $('body').bind({
+ 'afterShow.player onUpdate.player': set,
+ 'onCancel.player beforeClose.player': stop,
+ 'beforeLoad.player': clear
+ });
+
+ set();
+
+ F.trigger('onPlayStart');
+ }
+ };
+
+ if (F.player.isActive || (a && a[0] === false)) {
+ stop();
+ } else {
+ start();
+ }
+ },
+
+ next: function () {
+ if (F.current) {
+ F.jumpto(F.current.index + 1);
+ }
+ },
+
+ prev: function () {
+ if (F.current) {
+ F.jumpto(F.current.index - 1);
+ }
+ },
+
+ jumpto: function (index) {
+ if (!F.current) {
+ return;
+ }
+
+ index = parseInt(index, 10);
+
+ if (F.group.length > 1 && F.current.loop) {
+ if (index >= F.group.length) {
+ index = 0;
+
+ } else if (index < 0) {
+ index = F.group.length - 1;
+ }
+ }
+
+ if (F.group[index] !== undefined) {
+ F.cancel();
+
+ F._start(index);
+ }
+ },
+
+ reposition: function (a, b) {
+ if (F.isOpen) {
+ if (b && b.type === 'scroll') {
+ F.wrap.stop().animate(F._getPosition(a), 200);
+ } else {
+ F.wrap.css(F._getPosition(a));
+ }
+ }
+ },
+
+ update: function (e) {
+ if (F.isOpen) {
+ // It's a very bad idea to attach handlers to the window scroll event, run this code after a delay
+ if (!didResize) {
+ resizeTimer = setTimeout(function () {
+ var current = F.current;
+
+ if (didResize) {
+ didResize = false;
+
+ if (current) {
+ if (!e || (e && (e.type === 'orientationchange' || (current.autoResize && e.type === 'resize')))) {
+ if (current.autoSize) {
+ F.inner.height('auto');
+ current.height = F.inner.height();
+ }
+
+ F._setDimension();
+
+ if (current.canGrow) {
+ F.inner.height('auto');
+ }
+ }
+
+ if (current.autoCenter) {
+ F.reposition(null, e);
+ }
+
+ F.trigger('onUpdate');
+ }
+ }
+ }, 100);
+ }
+
+ didResize = true;
+ }
+ },
+
+ toggle: function () {
+ if (F.isOpen) {
+ F.current.fitToView = !F.current.fitToView;
+
+ F.update();
+ }
+ },
+
+ hideLoading: function () {
+ D.unbind('keypress.fb');
+
+ $("#fancybox-loading").remove();
+ },
+
+ showLoading: function () {
+ F.hideLoading();
+
+ //If user will press the escape-button, the request will be canceled
+ D.bind('keypress.fb', function(e) {
+ if (e.keyCode == 27) {
+ e.preventDefault();
+ F.cancel();
+ }
+ });
+
+ $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
+ },
+
+ getViewport: function () {
+ return {
+ x: W.scrollLeft(),
+ y: W.scrollTop(),
+ w: W.width(),
+ h: W.height()
+ };
+ },
+
+ // Unbind the keyboard / clicking actions
+ unbindEvents: function () {
+ if (F.wrap) {
+ F.wrap.unbind('.fb');
+ }
+
+ D.unbind('.fb');
+ W.unbind('.fb');
+ },
+
+ bindEvents: function () {
+ var current = F.current,
+ keys = current.keys;
+
+ if (!current) {
+ return;
+ }
+
+ W.bind('resize.fb, orientationchange.fb', F.update);
+
+ if (!current.fixed && current.autoCenter) {
+ W.bind("scroll.fb", F.update);
+ }
+
+ if (keys) {
+ D.bind('keydown.fb', function (e) {
+ var code;
+
+ // Ignore key combinations and key events within form elements
+ if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && $.inArray(e.target.tagName.toLowerCase(), ['input', 'textarea', 'select', 'button']) < 0) {
+ code = e.keyCode;
+
+ if ($.inArray(code, keys.close) > -1) {
+ F.close();
+ e.preventDefault();
+
+ } else if ($.inArray(code, keys.next) > -1) {
+ F.next();
+ e.preventDefault();
+
+ } else if ($.inArray(code, keys.prev) > -1) {
+ F.prev();
+ e.preventDefault();
+ }
+ }
+ });
+ }
+
+ if ($.fn.mousewheel && current.mouseWheel && F.group.length > 1) {
+ F.wrap.bind('mousewheel.fb', function (e, delta) {
+ var target = e.target || null;
+
+ if (delta !== 0 && (!target || target.clientHeight === 0 || (target.scrollHeight === target.clientHeight && target.scrollWidth === target.clientWidth))) {
+ e.preventDefault();
+
+ F[delta > 0 ? 'prev' : 'next']();
+ }
+ });
+ }
+ },
+
+ trigger: function (event) {
+ var ret, obj = F[ $.inArray(event, ['onCancel', 'beforeLoad', 'afterLoad']) > -1 ? 'coming' : 'current' ];
+
+ if (!obj) {
+ return;
+ }
+
+ if ($.isFunction( obj[event] )) {
+ ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
+ }
+
+ if (ret === false) {
+ return false;
+ }
+
+ if (obj.helpers) {
+ $.each(obj.helpers, function (helper, opts) {
+ if (opts && $.isPlainObject(F.helpers[helper]) && $.isFunction(F.helpers[helper][event])) {
+ F.helpers[helper][event](opts, obj);
+ }
+ });
+ }
+
+ $.event.trigger(event + '.fb');
+ },
+
+ isImage: function (str) {
+ return str && str.toString().match(/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i);
+ },
+
+ isSWF: function (str) {
+ return str && str.toString().match(/\.(swf)(.*)?$/i);
+ },
+
+ _start: function (index) {
+ var coming = {},
+ element = F.group[index] || null,
+ isDom,
+ href,
+ type,
+ rez,
+ hrefParts;
+
+ if (element && (element.nodeType || element instanceof $)) {
+ isDom = true;
+
+ if ($.metadata) {
+ coming = $(element).metadata();
+ }
+ }
+
+ coming = $.extend(true, {}, F.opts, {index : index, element : element}, ($.isPlainObject(element) ? element : coming));
+
+ // Re-check overridable options
+ $.each(['href', 'title', 'content', 'type'], function(i,v) {
+ coming[v] = F.opts[ v ] || (isDom && $(element).attr( v )) || coming[ v ] || null;
+ });
+
+ // Convert margin property to array - top, right, bottom, left
+ if (typeof coming.margin === 'number') {
+ coming.margin = [coming.margin, coming.margin, coming.margin, coming.margin];
+ }
+
+ // 'modal' propery is just a shortcut
+ if (coming.modal) {
+ $.extend(true, coming, {
+ closeBtn : false,
+ closeClick: false,
+ nextClick : false,
+ arrows : false,
+ mouseWheel : false,
+ keys : null,
+ helpers: {
+ overlay : {
+ css: {
+ cursor : 'auto'
+ },
+ closeClick : false
+ }
+ }
+ });
+ }
+
+ //Give a chance for callback or helpers to update coming item (type, title, etc)
+ F.coming = coming;
+
+ if (false === F.trigger('beforeLoad')) {
+ F.coming = null;
+ return;
+ }
+
+ type = coming.type;
+ href = coming.href || element;
+
+ ///Check if content type is set, if not, try to get
+ if (!type) {
+ if (isDom) {
+ rez = $(element).data('fancybox-type');
+
+ if (!rez && element.className) {
+ rez = element.className.match(/fancybox\.(\w+)/);
+ type = rez ? rez[1] : null;
+ }
+ }
+
+ if (!type && isString(href)) {
+ if (F.isImage(href)) {
+ type = 'image';
+
+ } else if (F.isSWF(href)) {
+ type = 'swf';
+
+ } else if (href.match(/^#/)) {
+ type = 'inline';
+ }
+ }
+
+ // ...if not - display element itself
+ if (!type) {
+ type = isDom ? 'inline' : 'html';
+ }
+
+ coming.type = type;
+ }
+
+ // Check before try to load; 'inline' and 'html' types need content, others - href
+ if (type === 'inline' || type === 'html') {
+ if (!coming.content) {
+ if (type === 'inline') {
+ coming.content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
+
+ } else {
+ coming.content = element;
+ }
+ }
+
+ if (!coming.content || !coming.content.length) {
+ type = null;
+ }
+
+ } else if (!href) {
+ type = null;
+ }
+
+ /*
+ Add reference to the group, so it`s possible to access from callbacks, example:
+
+ afterLoad : function() {
+ this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
+ }
+
+ */
+
+ hrefParts = href.split(/\s+/, 2);
+
+ coming.group = F.group;
+ coming.isDom = isDom;
+ coming.href = hrefParts.shift();
+ coming.selector = hrefParts.shift();
+
+ if (type === 'image') {
+ F._loadImage();
+
+ } else if (type === 'ajax') {
+ F._loadAjax();
+
+ } else if (type) {
+ F._afterLoad();
+
+ } else {
+ F._error( 'type' );
+ }
+ },
+
+ _error: function ( type ) {
+ F.hideLoading();
+
+ $.extend(F.coming, {
+ type : 'html',
+ autoSize : true,
+ minHeight : 0,
+ hasError : type,
+ content : F.coming.tpl.error
+ });
+
+ F._afterLoad();
+ },
+
+ _loadImage: function () {
+ // Reset preload image so it is later possible to check "complete" property
+ F.imgPreload = new Image();
+
+ F.imgPreload.onload = function () {
+ this.onload = this.onerror = null;
+
+ F.coming.width = this.width;
+ F.coming.height = this.height;
+
+ F._afterLoad();
+ };
+
+ F.imgPreload.onerror = function () {
+ this.onload = this.onerror = null;
+
+ F._error( 'image' );
+ };
+
+ F.imgPreload.src = F.coming.href;
+
+ if (!F.imgPreload.width) {
+ F.showLoading();
+ }
+ },
+
+ _loadAjax: function () {
+ F.showLoading();
+
+ F.ajaxLoad = $.ajax($.extend({}, F.coming.ajax, {
+ url: F.coming.href,
+ error: function (jqXHR, textStatus) {
+ if (F.coming && textStatus !== 'abort') {
+ F._error( 'ajax', jqXHR );
+
+ } else {
+ F.hideLoading();
+ }
+ },
+ success: function (data, textStatus) {
+ if (textStatus === 'success') {
+ F.coming.content = data;
+
+ F._afterLoad();
+ }
+ }
+ }));
+ },
+
+ _preloadImages: function() {
+ var group = F.group,
+ current = F.current,
+ len = group.length,
+ item,
+ href,
+ i,
+ cnt = Math.min(current.preload, len - 1);
+
+ if (!current.preload || group.length < 2) {
+ return;
+ }
+
+ for (i = 1; i <= cnt; i += 1) {
+ item = group[ (current.index + i ) % len ];
+ href = $( item ).attr('href') || item;
+
+ if (item.type === 'image' || F.isImage(href)) {
+ new Image().src = href;
+ }
+ }
+ },
+
+ _afterLoad: function () {
+ F.hideLoading();
+
+ if (!F.coming || false === F.trigger('afterLoad', F.current)) {
+ F.coming = false;
+
+ return;
+ }
+
+ if (F.isOpened) {
+ $(".fancybox-item").remove();
+
+ F.wrap.stop(true).removeClass('fancybox-opened');
+ F.inner.css('overflow', 'hidden');
+
+ F.transitions[F.current.prevMethod]();
+
+ } else {
+ $(".fancybox-wrap").stop().trigger('onReset').remove();
+
+ F.trigger('afterClose');
+ }
+
+ F.unbindEvents();
+
+ F.isOpen = false;
+ F.current = F.coming;
+
+ //Build the neccessary markup
+ F.wrap = $(F.current.tpl.wrap).addClass('fancybox-' + (isMobile ? 'mobile' : 'desktop') + ' fancybox-tmp ' + F.current.wrapCSS).appendTo('body');
+ F.outer = $('.fancybox-outer', F.wrap).css('padding', F.current.padding + 'px');
+ F.inner = $('.fancybox-inner', F.wrap);
+
+ F._setContent();
+ },
+
+ _setContent: function () {
+ var current = F.current, content = current.content, type = current.type, loadingBay;
+
+ switch (type) {
+ case 'inline':
+ case 'ajax':
+ case 'html':
+ if (current.selector) {
+ content = $("<div>").html(content).find(current.selector);
+
+ } else if (content instanceof $) {
+ content = content.show().detach();
+
+ if (content.parent().hasClass('fancybox-inner')) {
+ content.parents('.fancybox-wrap').trigger('onReset').remove();
+ }
+
+ $(F.wrap).bind('onReset', function () {
+ content.appendTo('body').hide();
+ });
+ }
+
+ if (current.autoSize) {
+ loadingBay = $('<div class="fancybox-tmp ' + F.current.wrapCSS + '"></div>').appendTo('body').append(content);
+ current.width = loadingBay.width();
+ current.height = loadingBay.height();
+
+ // Re-check to fix 1px bug in some browsers
+ loadingBay.width( F.current.width );
+
+ if (loadingBay.height() > current.height) {
+ loadingBay.width(current.width + 1);
+
+ current.width = loadingBay.width();
+ current.height = loadingBay.height();
+ }
+
+ content = loadingBay.contents().detach();
+
+ loadingBay.remove();
+ }
+
+ break;
+
+ case 'image':
+ content = current.tpl.image.replace('{href}', current.href);
+
+ current.aspectRatio = true;
+ break;
+
+ case 'swf':
+ content = current.tpl.swf.replace(/\{width\}/g, current.width).replace(/\{height\}/g, current.height).replace(/\{href\}/g, current.href);
+ break;
+ }
+
+ if (type === 'iframe') {
+ content = $(current.tpl.iframe.replace('{rnd}', new Date().getTime()) ).attr('scrolling', current.scrolling);
+
+ current.scrolling = 'auto';
+
+ // Set auto height for iframes
+ if (current.autoSize) {
+ content.width( current.width );
+
+ F.showLoading();
+
+ content.data('ready', false).appendTo(F.inner).bind({
+ onCancel : function() {
+ $(this).unbind();
+
+ F._afterZoomOut();
+ },
+ load : function() {
+ var iframe = $(this), height;
+
+ try {
+ if (this.contentWindow.document.location) {
+ height = iframe.contents().find('body').height() + 12;
+
+ iframe.height( height );
+ }
+
+ } catch (e) {
+ current.autoSize = false;
+ }
+
+ if (iframe.data('ready') === false) {
+ F.hideLoading();
+
+ if (height) {
+ F.current.height = height;
+ }
+
+ F._beforeShow();
+
+ iframe.data('ready', true);
+
+ } else if (height) {
+ F.update();
+ }
+ }
+
+ }).attr('src', current.href);
+
+ return;
+ }
+
+ content.attr('src', current.href);
+
+ } else if (type === 'image' || type === 'swf') {
+ current.autoSize = false;
+ current.scrolling = 'visible';
+ }
+
+ F.inner.append(content);
+
+ F._beforeShow();
+ },
+
+ _beforeShow : function() {
+ F.coming = null;
+
+ //Give a chance for helpers or callbacks to update elements
+ F.trigger('beforeShow');
+
+ //Set initial dimensions and hide
+ F._setDimension();
+
+ F.wrap.hide().removeClass('fancybox-tmp');
+
+ F.bindEvents();
+ F._preloadImages();
+
+ F.transitions[ F.isOpened ? F.current.nextMethod : F.current.openMethod ]();
+ },
+
+ _setDimension: function () {
+ var wrap = F.wrap,
+ outer = F.outer,
+ inner = F.inner,
+ current = F.current,
+ viewport = F.getViewport(),
+ margin = current.margin,
+ padding2 = current.padding * 2,
+ width = current.width,
+ height = current.height,
+ maxWidth = current.maxWidth,
+ maxHeight = current.maxHeight,
+ minWidth = current.minWidth,
+ minHeight = current.minHeight,
+ ratio,
+ height_,
+ space;
+
+ viewport.w -= (margin[1] + margin[3]);
+ viewport.h -= (margin[0] + margin[2]);
+
+ if (width.toString().indexOf('%') > -1) {
+ width = (((viewport.w - padding2) * parseFloat(width)) / 100);
+ }
+
+ if (height.toString().indexOf('%') > -1) {
+ height = (((viewport.h - padding2) * parseFloat(height)) / 100);
+ }
+
+ ratio = width / height;
+
+ width += padding2;
+ height += padding2;
+
+ if (current.fitToView) {
+ maxWidth = Math.min(viewport.w, maxWidth);
+ maxHeight = Math.min(viewport.h, maxHeight);
+ }
+
+ if (current.aspectRatio) {
+ if (width > maxWidth) {
+ width = maxWidth;
+ height = ((width - padding2) / ratio) + padding2;
+ }
+
+ if (height > maxHeight) {
+ height = maxHeight;
+ width = ((height - padding2) * ratio) + padding2;
+ }
+
+ if (width < minWidth) {
+ width = minWidth;
+ height = ((width - padding2) / ratio) + padding2;
+ }
+
+ if (height < minHeight) {
+ height = minHeight;
+ width = ((height - padding2) * ratio) + padding2;
+ }
+
+ } else {
+ width = Math.max(minWidth, Math.min(width, maxWidth));
+ height = Math.max(minHeight, Math.min(height, maxHeight));
+ }
+
+ width = Math.round(width);
+ height = Math.round(height);
+
+ //Reset dimensions
+ $(wrap.add(outer).add(inner)).width('auto').height('auto');
+
+ inner.width(width - padding2).height(height - padding2);
+ wrap.width(width);
+
+ height_ = wrap.height(); // Real wrap height
+
+ //Fit wrapper inside
+ if (width > maxWidth || height_ > maxHeight) {
+ while ((width > maxWidth || height_ > maxHeight) && width > minWidth && height_ > minHeight) {
+ height = height - 10;
+
+ if (current.aspectRatio) {
+ width = Math.round(((height - padding2) * ratio) + padding2);
+
+ if (width < minWidth) {
+ width = minWidth;
+ height = ((width - padding2) / ratio) + padding2;
+ }
+
+ } else {
+ width = width - 10;
+ }
+
+ inner.width(width - padding2).height(height - padding2);
+ wrap.width(width);
+
+ height_ = wrap.height();
+ }
+ }
+
+ current.dim = {
+ width: width,
+ height: height_
+ };
+
+ current.canGrow = current.autoSize && height > minHeight && height < maxHeight;
+ current.canShrink = false;
+ current.canExpand = false;
+
+ if ((width - padding2) < current.width || (height - padding2) < current.height) {
+ current.canExpand = true;
+
+ } else if ((width > viewport.w || height_ > viewport.h) && width > minWidth && height > minHeight) {
+ current.canShrink = true;
+ }
+
+ space = height_ - padding2;
+
+ F.innerSpace = space - inner.height();
+ F.outerSpace = space - outer.height();
+ },
+
+ _getPosition: function (a) {
+ var current = F.current,
+ viewport = F.getViewport(),
+ margin = current.margin,
+ width = F.wrap.width() + margin[1] + margin[3],
+ height = F.wrap.height() + margin[0] + margin[2],
+ rez = {
+ position: 'absolute',
+ top: margin[0] + viewport.y,
+ left: margin[3] + viewport.x
+ };
+
+ if (current.autoCenter && current.fixed && (!a || a[0] === false) && height <= viewport.h && width <= viewport.w) {
+ rez = {
+ position: 'fixed',
+ top: margin[0],
+ left: margin[3]
+ };
+ }
+
+ rez.top = Math.ceil(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))) + 'px';
+ rez.left = Math.ceil(Math.max(rez.left, rez.left + ((viewport.w - width) * 0.5))) + 'px';
+
+ return rez;
+ },
+
+ _afterZoomIn: function () {
+ var current = F.current, scrolling = current ? current.scrolling : 'no';
+
+ if (!current) {
+ return;
+ }
+
+ F.isOpen = F.isOpened = true;
+
+ F.wrap.addClass('fancybox-opened').css('overflow', 'visible');
+
+ F.update();
+
+ F.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
+
+ //Assign a click event
+ if (current.closeClick || current.nextClick) {
+ //This is not the perfect solution but arrows have to be next to content so their height will match
+ // and I do not want another wrapper around content
+ F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
+ if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
+ F[ current.closeClick ? 'close' : 'next' ]();
+ }
+ });
+ }
+
+ //Create a close button
+ if (current.closeBtn) {
+ $(current.tpl.closeBtn).appendTo(F.outer).bind('click.fb', F.close);
+ }
+
+ //Create navigation arrows
+ if (current.arrows && F.group.length > 1) {
+ if (current.loop || current.index > 0) {
+ $(current.tpl.prev).appendTo(F.inner).bind('click.fb', F.prev);
+ }
+
+ if (current.loop || current.index < F.group.length - 1) {
+ $(current.tpl.next).appendTo(F.inner).bind('click.fb', F.next);
+ }
+ }
+
+ F.trigger('afterShow');
+
+ if (F.opts.autoPlay && !F.player.isActive) {
+ F.opts.autoPlay = false;
+
+ F.play();
+ }
+ },
+
+ _afterZoomOut: function () {
+ F.trigger('afterClose');
+
+ F.wrap.trigger('onReset').remove();
+
+ $.extend(F, {
+ group: {},
+ opts: {},
+ current: null,
+ isActive: false,
+ isOpened: false,
+ isOpen: false,
+ wrap: null,
+ outer: null,
+ inner: null
+ });
+ }
+ });
+
+ /*
+ * Default transitions
+ */
+
+ F.transitions = {
+ getOrigPosition: function () {
+ var current = F.current,
+ element = current.element,
+ padding = current.padding,
+ orig = $(current.orig),
+ pos = {},
+ width = 50,
+ height = 50,
+ viewport;
+
+ if (!orig.length && current.isDom && $(element).is(':visible')) {
+ orig = $(element).find('img:first');
+
+ if (!orig.length) {
+ orig = $(element);
+ }
+ }
+
+ if (orig.length) {
+ pos = orig.offset();
+
+ if (orig.is('img')) {
+ width = orig.outerWidth();
+ height = orig.outerHeight();
+ }
+
+ } else {
+ viewport = F.getViewport();
+
+ pos.top = viewport.y + (viewport.h - height) * 0.5;
+ pos.left = viewport.x + (viewport.w - width) * 0.5;
+ }
+
+ pos = {
+ top: Math.ceil(pos.top - padding) + 'px',
+ left: Math.ceil(pos.left - padding) + 'px',
+ width: Math.ceil(width + padding * 2) + 'px',
+ height: Math.ceil(height + padding * 2) + 'px'
+ };
+
+ return pos;
+ },
+
+ step: function (now, fx) {
+ var ratio, innerValue, outerValue;
+
+ if (fx.prop === 'width' || fx.prop === 'height') {
+ innerValue = outerValue = Math.ceil(now - (F.current.padding * 2));
+
+ if (fx.prop === 'height') {
+ ratio = (now - fx.start) / (fx.end - fx.start);
+
+ if (fx.start > fx.end) {
+ ratio = 1 - ratio;
+ }
+
+ innerValue -= F.innerSpace * ratio;
+ outerValue -= F.outerSpace * ratio;
+ }
+
+ F.inner[fx.prop](innerValue);
+ F.outer[fx.prop](outerValue);
+ }
+ },
+
+ zoomIn: function () {
+ var wrap = F.wrap,
+ current = F.current,
+ startPos,
+ endPos,
+ dim = current.dim;
+
+ if (current.openEffect === 'elastic') {
+ endPos = $.extend({}, dim, F._getPosition(true));
+
+ //Remove "position" property
+ delete endPos.position;
+
+ startPos = this.getOrigPosition();
+
+ if (current.openOpacity) {
+ startPos.opacity = 0;
+ endPos.opacity = 1;
+ }
+
+ F.outer.add(F.inner).width('auto').height('auto');
+
+ wrap.css(startPos).show();
+
+ wrap.animate(endPos, {
+ duration: current.openSpeed,
+ easing: current.openEasing,
+ step: this.step,
+ complete: F._afterZoomIn
+ });
+
+ } else {
+ wrap.css($.extend({}, dim, F._getPosition()));
+
+ if (current.openEffect === 'fade') {
+ wrap.fadeIn(current.openSpeed, F._afterZoomIn);
+
+ } else {
+ wrap.show();
+ F._afterZoomIn();
+ }
+ }
+ },
+
+ zoomOut: function () {
+ var wrap = F.wrap,
+ current = F.current,
+ endPos;
+
+ if (current.closeEffect === 'elastic') {
+ if (wrap.css('position') === 'fixed') {
+ wrap.css(F._getPosition(true));
+ }
+
+ endPos = this.getOrigPosition();
+
+ if (current.closeOpacity) {
+ endPos.opacity = 0;
+ }
+
+ wrap.animate(endPos, {
+ duration: current.closeSpeed,
+ easing: current.closeEasing,
+ step: this.step,
+ complete: F._afterZoomOut
+ });
+
+ } else {
+ wrap.fadeOut(current.closeEffect === 'fade' ? current.closeSpeed : 0, F._afterZoomOut);
+ }
+ },
+
+ changeIn: function () {
+ var wrap = F.wrap,
+ current = F.current,
+ startPos;
+
+ if (current.nextEffect === 'elastic') {
+ startPos = F._getPosition(true);
+ startPos.opacity = 0;
+ startPos.top = (parseInt(startPos.top, 10) - 200) + 'px';
+
+ wrap.css(startPos).show().animate({
+ opacity: 1,
+ top: '+=200px'
+ }, {
+ duration: current.nextSpeed,
+ easing: current.nextEasing,
+ complete: F._afterZoomIn
+ });
+
+ } else {
+ wrap.css(F._getPosition());
+
+ if (current.nextEffect === 'fade') {
+ wrap.hide().fadeIn(current.nextSpeed, F._afterZoomIn);
+
+ } else {
+ wrap.show();
+ F._afterZoomIn();
+ }
+ }
+ },
+
+ changeOut: function () {
+ var wrap = F.wrap,
+ current = F.current,
+ cleanUp = function () {
+ $(this).trigger('onReset').remove();
+ };
+
+ wrap.removeClass('fancybox-opened');
+
+ if (current.prevEffect === 'elastic') {
+ wrap.animate({
+ 'opacity': 0,
+ top: '+=200px'
+ }, {
+ duration: current.prevSpeed,
+ easing: current.prevEasing,
+ complete: cleanUp
+ });
+
+ } else {
+ wrap.fadeOut(current.prevEffect === 'fade' ? current.prevSpeed : 0, cleanUp);
+ }
+ }
+ };
+
+ /*
+ * Overlay helper
+ */
+
+ F.helpers.overlay = {
+ overlay: null,
+
+ update: function () {
+ var width, scrollWidth, offsetWidth;
+
+ //Reset width/height so it will not mess
+ this.overlay.width(0).height(0);
+
+ if ($.browser.msie) {
+ scrollWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
+ offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
+
+ width = scrollWidth < offsetWidth ? W.width() : scrollWidth;
+
+ } else {
+ width = D.width();
+ }
+
+ this.overlay.width(width).height(D.height());
+ },
+
+ beforeShow: function (opts) {
+ if (this.overlay) {
+ return;
+ }
+
+ opts = $.extend(true, {
+ speedIn : 'fast',
+ closeClick : true,
+ opacity : 1,
+ css : {
+ background: 'black'
+ }
+ }, opts);
+
+ this.overlay = $('<div id="fancybox-overlay"></div>').css(opts.css).appendTo('body');
+
+ this.update();
+
+ if (opts.closeClick) {
+ this.overlay.bind('click.fb', F.close);
+ }
+
+ W.bind("resize.fb", $.proxy(this.update, this));
+
+ this.overlay.fadeTo(opts.speedIn, opts.opacity);
+ },
+
+ onUpdate: function () {
+ //Update as content may change document dimensions
+ this.update();
+ },
+
+ afterClose: function (opts) {
+ if (this.overlay) {
+ this.overlay.fadeOut(opts.speedOut || 0, function () {
+ $(this).remove();
+ });
+ }
+
+ this.overlay = null;
+ }
+ };
+
+ /*
+ * Title helper
+ */
+
+ F.helpers.title = {
+ beforeShow: function (opts) {
+ var title, text = F.current.title;
+
+ if (text) {
+ title = $('<div class="fancybox-title fancybox-title-' + opts.type + '-wrap">' + text + '</div>').appendTo('body');
+
+ if (opts.type === 'float') {
+ //This helps for some browsers
+ title.width(title.width());
+
+ title.wrapInner('<span class="child"></span>');
+
+ //Increase bottom margin so this title will also fit into viewport
+ F.current.margin[2] += Math.abs(parseInt(title.css('margin-bottom'), 10));
+ }
+
+ title.appendTo(opts.type === 'over' ? F.inner : (opts.type === 'outside' ? F.wrap : F.outer));
+ }
+ }
+ };
+
+ // jQuery plugin initialization
+ $.fn.fancybox = function (options) {
+ var that = $(this),
+ selector = this.selector || '',
+ index,
+ run = function(e) {
+ var what = this, idx = index, relType, relVal;
+
+ if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
+ e.preventDefault();
+
+ relType = options.groupAttr || 'data-fancybox-group';
+ relVal = $(what).attr(relType);
+
+ if (!relVal) {
+ relType = 'rel';
+ relVal = what[ relType ];
+ }
+
+ if (relVal && relVal !== '' && relVal !== 'nofollow') {
+ what = selector.length ? $(selector) : that;
+ what = what.filter('[' + relType + '="' + relVal + '"]');
+ idx = what.index(this);
+ }
+
+ options.index = idx;
+
+ F.open(what, options);
+ }
+ };
+
+ options = options || {};
+ index = options.index || 0;
+
+ if (selector) {
+ D.undelegate(selector, 'click.fb-start').delegate(selector, 'click.fb-start', run);
+
+ } else {
+ that.unbind('click.fb-start').bind('click.fb-start', run);
+ }
+
+ return this;
+ };
+
+}(window, document)); \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/jquery.fancybox.pack.js b/javascript/jquery/plugins/fancybox/jquery.fancybox.pack.js
new file mode 100644
index 0000000..4b73736
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/jquery.fancybox.pack.js
@@ -0,0 +1,35 @@
+/*! fancyBox v2.0.5 fancyapps.com | fancyapps.com/fancybox/#license */
+(function(t,n,s){var d=t.jQuery,l=d(t),m=d(n),a=d.fancybox=function(){a.open.apply(this,arguments)},q=!1,r=n.createTouch!==s;d.extend(a,{version:"2.0.5",defaults:{padding:15,margin:20,width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,autoSize:!0,autoResize:!r,autoCenter:!r,fitToView:!0,aspectRatio:!1,topRatio:0.5,fixed:!(d.browser.msie&&6>=d.browser.version)&&!r,scrolling:"auto",wrapCSS:"fancybox-default",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,
+playSpeed:3E3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-fancyBox":!0}},keys:{next:[13,32,34,39,40],prev:[8,33,37,38],close:[27]},tpl:{wrap:'<div class="fancybox-wrap"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div>',image:'<img class="fancybox-image" src="{href}" alt="" />',iframe:'<iframe class="fancybox-iframe" name="fancybox-frame{rnd}" frameborder="0" hspace="0"'+(d.browser.msie?' allowtransparency="true"':"")+"></iframe>",swf:'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{href}" /><embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="100%" height="100%" wmode="transparent"></embed></object>',
+error:'<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<div title="Close" class="fancybox-item fancybox-close"></div>',next:'<a title="Next" class="fancybox-nav fancybox-next"><span></span></a>',prev:'<a title="Previous" class="fancybox-nav fancybox-prev"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",
+nextEffect:"elastic",nextSpeed:300,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:300,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:{speedIn:0,speedOut:300,opacity:0.8,css:{cursor:"pointer"},closeClick:!0},title:{type:"float"}}},group:{},opts:{},coming:null,current:null,isOpen:!1,isOpened:!1,wrap:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(b,c){a.close(!0);b&&!d.isArray(b)&&(b=
+b instanceof d?d(b).get():[b]);a.isActive=!0;a.opts=d.extend(!0,{},a.defaults,c);d.isPlainObject(c)&&c.keys!==s&&(a.opts.keys=c.keys?d.extend({},a.defaults.keys,c.keys):!1);a.group=b;a._start(a.opts.index||0)},cancel:function(){a.coming&&!1===a.trigger("onCancel")||(a.coming=null,a.hideLoading(),a.ajaxLoad&&a.ajaxLoad.abort(),a.ajaxLoad=null,a.imgPreload&&(a.imgPreload.onload=a.imgPreload.onabort=a.imgPreload.onerror=null))},close:function(b){a.cancel();a.current&&!1!==a.trigger("beforeClose")&&(a.unbindEvents(),
+!a.isOpen||b&&!0===b[0]?(d(".fancybox-wrap").stop().trigger("onReset").remove(),a._afterZoomOut()):(a.isOpen=a.isOpened=!1,d(".fancybox-item, .fancybox-nav").remove(),a.wrap.stop(!0).removeClass("fancybox-opened"),a.inner.css("overflow","hidden"),a.transitions[a.current.closeMethod]()))},play:function(b){var c=function(){clearTimeout(a.player.timer)},f=function(){c();a.current&&a.player.isActive&&(a.player.timer=setTimeout(a.next,a.current.playSpeed))},e=function(){c();d("body").unbind(".player");
+a.player.isActive=!1;a.trigger("onPlayEnd")};if(a.player.isActive||b&&!1===b[0])e();else if(a.current&&(a.current.loop||a.current.index<a.group.length-1))a.player.isActive=!0,d("body").bind({"afterShow.player onUpdate.player":f,"onCancel.player beforeClose.player":e,"beforeLoad.player":c}),f(),a.trigger("onPlayStart")},next:function(){a.current&&a.jumpto(a.current.index+1)},prev:function(){a.current&&a.jumpto(a.current.index-1)},jumpto:function(b){a.current&&(b=parseInt(b,10),1<a.group.length&&a.current.loop&&
+(b>=a.group.length?b=0:0>b&&(b=a.group.length-1)),a.group[b]!==s&&(a.cancel(),a._start(b)))},reposition:function(b,c){a.isOpen&&(c&&"scroll"===c.type?a.wrap.stop().animate(a._getPosition(b),200):a.wrap.css(a._getPosition(b)))},update:function(b){a.isOpen&&(q||setTimeout(function(){var c=a.current;if(q&&(q=!1,c)){if(!b||b&&("orientationchange"===b.type||c.autoResize&&"resize"===b.type))c.autoSize&&(a.inner.height("auto"),c.height=a.inner.height()),a._setDimension(),c.canGrow&&a.inner.height("auto");
+c.autoCenter&&a.reposition(null,b);a.trigger("onUpdate")}},100),q=!0)},toggle:function(){a.isOpen&&(a.current.fitToView=!a.current.fitToView,a.update())},hideLoading:function(){m.unbind("keypress.fb");d("#fancybox-loading").remove()},showLoading:function(){a.hideLoading();m.bind("keypress.fb",function(b){27==b.keyCode&&(b.preventDefault(),a.cancel())});d('<div id="fancybox-loading"><div></div></div>').click(a.cancel).appendTo("body")},getViewport:function(){return{x:l.scrollLeft(),y:l.scrollTop(),
+w:l.width(),h:l.height()}},unbindEvents:function(){a.wrap&&a.wrap.unbind(".fb");m.unbind(".fb");l.unbind(".fb")},bindEvents:function(){var b=a.current,c=b.keys;b&&(l.bind("resize.fb, orientationchange.fb",a.update),!b.fixed&&b.autoCenter&&l.bind("scroll.fb",a.update),c&&m.bind("keydown.fb",function(b){var e;!b.ctrlKey&&!b.altKey&&!b.shiftKey&&!b.metaKey&&0>d.inArray(b.target.tagName.toLowerCase(),["input","textarea","select","button"])&&(e=b.keyCode,-1<d.inArray(e,c.close)?(a.close(),b.preventDefault()):
+-1<d.inArray(e,c.next)?(a.next(),b.preventDefault()):-1<d.inArray(e,c.prev)&&(a.prev(),b.preventDefault()))}),d.fn.mousewheel&&b.mouseWheel&&1<a.group.length&&a.wrap.bind("mousewheel.fb",function(b,c){var d=b.target||null;if(0!==c&&(!d||0===d.clientHeight||d.scrollHeight===d.clientHeight&&d.scrollWidth===d.clientWidth))b.preventDefault(),a[0<c?"prev":"next"]()}))},trigger:function(b){var c,f=a[-1<d.inArray(b,["onCancel","beforeLoad","afterLoad"])?"coming":"current"];if(f){d.isFunction(f[b])&&(c=f[b].apply(f,
+Array.prototype.slice.call(arguments,1)));if(!1===c)return!1;f.helpers&&d.each(f.helpers,function(c,g){if(g&&d.isPlainObject(a.helpers[c])&&d.isFunction(a.helpers[c][b]))a.helpers[c][b](g,f)});d.event.trigger(b+".fb")}},isImage:function(a){return a&&a.toString().match(/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i)},isSWF:function(a){return a&&a.toString().match(/\.(swf)(.*)?$/i)},_start:function(b){var c={},f=a.group[b]||null,e,g,k;if(f&&(f.nodeType||f instanceof d))e=!0,d.metadata&&(c=d(f).metadata());c=d.extend(!0,
+{},a.opts,{index:b,element:f},d.isPlainObject(f)?f:c);d.each(["href","title","content","type"],function(b,g){c[g]=a.opts[g]||e&&d(f).attr(g)||c[g]||null});"number"===typeof c.margin&&(c.margin=[c.margin,c.margin,c.margin,c.margin]);c.modal&&d.extend(!0,c,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{css:{cursor:"auto"},closeClick:!1}}});a.coming=c;if(!1===a.trigger("beforeLoad"))a.coming=null;else{b=c.type;g=c.href||f;b||(e&&(k=d(f).data("fancybox-type"),
+!k&&f.className&&(b=(k=f.className.match(/fancybox\.(\w+)/))?k[1]:null)),!b&&"string"===d.type(g)&&(a.isImage(g)?b="image":a.isSWF(g)?b="swf":g.match(/^#/)&&(b="inline")),b||(b=e?"inline":"html"),c.type=b);if("inline"===b||"html"===b){if(c.content||(c.content="inline"===b?d("string"===d.type(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):f),!c.content||!c.content.length)b=null}else g||(b=null);g=g.split(/\s+/,2);c.group=a.group;c.isDom=e;c.href=g.shift();c.selector=g.shift();"image"===b?a._loadImage():"ajax"===
+b?a._loadAjax():b?a._afterLoad():a._error("type")}},_error:function(b){a.hideLoading();d.extend(a.coming,{type:"html",autoSize:!0,minHeight:0,hasError:b,content:a.coming.tpl.error});a._afterLoad()},_loadImage:function(){a.imgPreload=new Image;a.imgPreload.onload=function(){this.onload=this.onerror=null;a.coming.width=this.width;a.coming.height=this.height;a._afterLoad()};a.imgPreload.onerror=function(){this.onload=this.onerror=null;a._error("image")};a.imgPreload.src=a.coming.href;a.imgPreload.width||
+a.showLoading()},_loadAjax:function(){a.showLoading();a.ajaxLoad=d.ajax(d.extend({},a.coming.ajax,{url:a.coming.href,error:function(b,c){a.coming&&"abort"!==c?a._error("ajax",b):a.hideLoading()},success:function(b,c){"success"===c&&(a.coming.content=b,a._afterLoad())}}))},_preloadImages:function(){var b=a.group,c=a.current,f=b.length,e,g,k,h=Math.min(c.preload,f-1);if(c.preload&&!(2>b.length))for(k=1;k<=h;k+=1)if(e=b[(c.index+k)%f],g=d(e).attr("href")||e,"image"===e.type||a.isImage(g))(new Image).src=
+g},_afterLoad:function(){a.hideLoading();!a.coming||!1===a.trigger("afterLoad",a.current)?a.coming=!1:(a.isOpened?(d(".fancybox-item").remove(),a.wrap.stop(!0).removeClass("fancybox-opened"),a.inner.css("overflow","hidden"),a.transitions[a.current.prevMethod]()):(d(".fancybox-wrap").stop().trigger("onReset").remove(),a.trigger("afterClose")),a.unbindEvents(),a.isOpen=!1,a.current=a.coming,a.wrap=d(a.current.tpl.wrap).addClass("fancybox-"+(r?"mobile":"desktop")+" fancybox-tmp "+a.current.wrapCSS).appendTo("body"),
+a.outer=d(".fancybox-outer",a.wrap).css("padding",a.current.padding+"px"),a.inner=d(".fancybox-inner",a.wrap),a._setContent())},_setContent:function(){var b=a.current,c=b.content,f=b.type,e;switch(f){case "inline":case "ajax":case "html":b.selector?c=d("<div>").html(c).find(b.selector):c instanceof d&&(c=c.show().detach(),c.parent().hasClass("fancybox-inner")&&c.parents(".fancybox-wrap").trigger("onReset").remove(),d(a.wrap).bind("onReset",function(){c.appendTo("body").hide()}));b.autoSize&&(e=d('<div class="fancybox-tmp '+
+a.current.wrapCSS+'"></div>').appendTo("body").append(c),b.width=e.width(),b.height=e.height(),e.width(a.current.width),e.height()>b.height&&(e.width(b.width+1),b.width=e.width(),b.height=e.height()),c=e.contents().detach(),e.remove());break;case "image":c=b.tpl.image.replace("{href}",b.href);b.aspectRatio=!0;break;case "swf":c=b.tpl.swf.replace(/\{width\}/g,b.width).replace(/\{height\}/g,b.height).replace(/\{href\}/g,b.href)}if("iframe"===f){c=d(b.tpl.iframe.replace("{rnd}",(new Date).getTime())).attr("scrolling",
+b.scrolling);b.scrolling="auto";if(b.autoSize){c.width(b.width);a.showLoading();c.data("ready",!1).appendTo(a.inner).bind({onCancel:function(){d(this).unbind();a._afterZoomOut()},load:function(){var c=d(this),f;try{this.contentWindow.document.location&&(f=c.contents().find("body").height()+12,c.height(f))}catch(e){b.autoSize=!1}!1===c.data("ready")?(a.hideLoading(),f&&(a.current.height=f),a._beforeShow(),c.data("ready",!0)):f&&a.update()}}).attr("src",b.href);return}c.attr("src",b.href)}else if("image"===
+f||"swf"===f)b.autoSize=!1,b.scrolling="visible";a.inner.append(c);a._beforeShow()},_beforeShow:function(){a.coming=null;a.trigger("beforeShow");a._setDimension();a.wrap.hide().removeClass("fancybox-tmp");a.bindEvents();a._preloadImages();a.transitions[a.isOpened?a.current.nextMethod:a.current.openMethod]()},_setDimension:function(){var b=a.wrap,c=a.outer,f=a.inner,e=a.current,g=a.getViewport(),k=e.margin,h=2*e.padding,i=e.width,j=e.height,l=e.maxWidth,o=e.maxHeight,m=e.minWidth,n=e.minHeight,p;g.w-=
+k[1]+k[3];g.h-=k[0]+k[2];-1<i.toString().indexOf("%")&&(i=(g.w-h)*parseFloat(i)/100);-1<j.toString().indexOf("%")&&(j=(g.h-h)*parseFloat(j)/100);k=i/j;i+=h;j+=h;e.fitToView&&(l=Math.min(g.w,l),o=Math.min(g.h,o));e.aspectRatio?(i>l&&(i=l,j=(i-h)/k+h),j>o&&(j=o,i=(j-h)*k+h),i<m&&(i=m,j=(i-h)/k+h),j<n&&(j=n,i=(j-h)*k+h)):(i=Math.max(m,Math.min(i,l)),j=Math.max(n,Math.min(j,o)));i=Math.round(i);j=Math.round(j);d(b.add(c).add(f)).width("auto").height("auto");f.width(i-h).height(j-h);b.width(i);p=b.height();
+if(i>l||p>o)for(;(i>l||p>o)&&i>m&&p>n;)j-=10,e.aspectRatio?(i=Math.round((j-h)*k+h),i<m&&(i=m,j=(i-h)/k+h)):i-=10,f.width(i-h).height(j-h),b.width(i),p=b.height();e.dim={width:i,height:p};e.canGrow=e.autoSize&&j>n&&j<o;e.canShrink=!1;e.canExpand=!1;if(i-h<e.width||j-h<e.height)e.canExpand=!0;else if((i>g.w||p>g.h)&&i>m&&j>n)e.canShrink=!0;b=p-h;a.innerSpace=b-f.height();a.outerSpace=b-c.height()},_getPosition:function(b){var c=a.current,f=a.getViewport(),d=c.margin,g=a.wrap.width()+d[1]+d[3],k=a.wrap.height()+
+d[0]+d[2],h={position:"absolute",top:d[0]+f.y,left:d[3]+f.x};if(c.autoCenter&&c.fixed&&(!b||!1===b[0])&&k<=f.h&&g<=f.w)h={position:"fixed",top:d[0],left:d[3]};h.top=Math.ceil(Math.max(h.top,h.top+(f.h-k)*c.topRatio))+"px";h.left=Math.ceil(Math.max(h.left,h.left+0.5*(f.w-g)))+"px";return h},_afterZoomIn:function(){var b=a.current,c=b?b.scrolling:"no";b&&(a.isOpen=a.isOpened=!0,a.wrap.addClass("fancybox-opened").css("overflow","visible"),a.update(),a.inner.css("overflow","yes"===c?"scroll":"no"===c?
+"hidden":c),(b.closeClick||b.nextClick)&&a.inner.css("cursor","pointer").bind("click.fb",function(c){if(!d(c.target).is("a")&&!d(c.target).parent().is("a"))a[b.closeClick?"close":"next"]()}),b.closeBtn&&d(b.tpl.closeBtn).appendTo(a.outer).bind("click.fb",a.close),b.arrows&&1<a.group.length&&((b.loop||0<b.index)&&d(b.tpl.prev).appendTo(a.inner).bind("click.fb",a.prev),(b.loop||b.index<a.group.length-1)&&d(b.tpl.next).appendTo(a.inner).bind("click.fb",a.next)),a.trigger("afterShow"),a.opts.autoPlay&&
+!a.player.isActive&&(a.opts.autoPlay=!1,a.play()))},_afterZoomOut:function(){a.trigger("afterClose");a.wrap.trigger("onReset").remove();d.extend(a,{group:{},opts:{},current:null,isActive:!1,isOpened:!1,isOpen:!1,wrap:null,outer:null,inner:null})}});a.transitions={getOrigPosition:function(){var b=a.current,c=b.element,f=b.padding,e=d(b.orig),g={},k=50,h=50;!e.length&&b.isDom&&d(c).is(":visible")&&(e=d(c).find("img:first"),e.length||(e=d(c)));e.length?(g=e.offset(),e.is("img")&&(k=e.outerWidth(),h=
+e.outerHeight())):(b=a.getViewport(),g.top=b.y+0.5*(b.h-h),g.left=b.x+0.5*(b.w-k));return g={top:Math.ceil(g.top-f)+"px",left:Math.ceil(g.left-f)+"px",width:Math.ceil(k+2*f)+"px",height:Math.ceil(h+2*f)+"px"}},step:function(b,c){var d,e,g;if("width"===c.prop||"height"===c.prop)e=g=Math.ceil(b-2*a.current.padding),"height"===c.prop&&(d=(b-c.start)/(c.end-c.start),c.start>c.end&&(d=1-d),e-=a.innerSpace*d,g-=a.outerSpace*d),a.inner[c.prop](e),a.outer[c.prop](g)},zoomIn:function(){var b=a.wrap,c=a.current,
+f,e;f=c.dim;"elastic"===c.openEffect?(e=d.extend({},f,a._getPosition(!0)),delete e.position,f=this.getOrigPosition(),c.openOpacity&&(f.opacity=0,e.opacity=1),a.outer.add(a.inner).width("auto").height("auto"),b.css(f).show(),b.animate(e,{duration:c.openSpeed,easing:c.openEasing,step:this.step,complete:a._afterZoomIn})):(b.css(d.extend({},f,a._getPosition())),"fade"===c.openEffect?b.fadeIn(c.openSpeed,a._afterZoomIn):(b.show(),a._afterZoomIn()))},zoomOut:function(){var b=a.wrap,c=a.current,d;"elastic"===
+c.closeEffect?("fixed"===b.css("position")&&b.css(a._getPosition(!0)),d=this.getOrigPosition(),c.closeOpacity&&(d.opacity=0),b.animate(d,{duration:c.closeSpeed,easing:c.closeEasing,step:this.step,complete:a._afterZoomOut})):b.fadeOut("fade"===c.closeEffect?c.closeSpeed:0,a._afterZoomOut)},changeIn:function(){var b=a.wrap,c=a.current,d;"elastic"===c.nextEffect?(d=a._getPosition(!0),d.opacity=0,d.top=parseInt(d.top,10)-200+"px",b.css(d).show().animate({opacity:1,top:"+=200px"},{duration:c.nextSpeed,
+easing:c.nextEasing,complete:a._afterZoomIn})):(b.css(a._getPosition()),"fade"===c.nextEffect?b.hide().fadeIn(c.nextSpeed,a._afterZoomIn):(b.show(),a._afterZoomIn()))},changeOut:function(){var b=a.wrap,c=a.current,f=function(){d(this).trigger("onReset").remove()};b.removeClass("fancybox-opened");"elastic"===c.prevEffect?b.animate({opacity:0,top:"+=200px"},{duration:c.prevSpeed,easing:c.prevEasing,complete:f}):b.fadeOut("fade"===c.prevEffect?c.prevSpeed:0,f)}};a.helpers.overlay={overlay:null,update:function(){var a,
+c;this.overlay.width(0).height(0);d.browser.msie?(a=Math.max(n.documentElement.scrollWidth,n.body.scrollWidth),c=Math.max(n.documentElement.offsetWidth,n.body.offsetWidth),a=a<c?l.width():a):a=m.width();this.overlay.width(a).height(m.height())},beforeShow:function(b){this.overlay||(b=d.extend(!0,{speedIn:"fast",closeClick:!0,opacity:1,css:{background:"black"}},b),this.overlay=d('<div id="fancybox-overlay"></div>').css(b.css).appendTo("body"),this.update(),b.closeClick&&this.overlay.bind("click.fb",
+a.close),l.bind("resize.fb",d.proxy(this.update,this)),this.overlay.fadeTo(b.speedIn,b.opacity))},onUpdate:function(){this.update()},afterClose:function(a){this.overlay&&this.overlay.fadeOut(a.speedOut||0,function(){d(this).remove()});this.overlay=null}};a.helpers.title={beforeShow:function(b){var c;if(c=a.current.title)c=d('<div class="fancybox-title fancybox-title-'+b.type+'-wrap">'+c+"</div>").appendTo("body"),"float"===b.type&&(c.width(c.width()),c.wrapInner('<span class="child"></span>'),a.current.margin[2]+=
+Math.abs(parseInt(c.css("margin-bottom"),10))),c.appendTo("over"===b.type?a.inner:"outside"===b.type?a.wrap:a.outer)}};d.fn.fancybox=function(b){var c=d(this),f=this.selector||"",e,g=function(g){var h=this,i=e,j;!g.ctrlKey&&!g.altKey&&!g.shiftKey&&!g.metaKey&&(g.preventDefault(),g=b.groupAttr||"data-fancybox-group",j=d(h).attr(g),j||(g="rel",j=h[g]),j&&""!==j&&"nofollow"!==j&&(h=f.length?d(f):c,h=h.filter("["+g+'="'+j+'"]'),i=h.index(this)),b.index=i,a.open(h,b))},b=b||{};e=b.index||0;f?m.undelegate(f,
+"click.fb-start").delegate(f,"click.fb-start",g):c.unbind("click.fb-start").bind("click.fb-start",g);return this}})(window,document); \ No newline at end of file
diff --git a/javascript/jquery/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js b/javascript/jquery/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js
new file mode 100644
index 0000000..cb66588
--- /dev/null
+++ b/javascript/jquery/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js
@@ -0,0 +1,14 @@
+/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
+* Licensed under the MIT License (LICENSE.txt).
+*
+* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+* Thanks to: Seamus Leahy for adding deltaX and deltaY
+*
+* Version: 3.0.4
+*
+* Requires: 1.2.2+
+*/
+
+(function(d){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),c=0,h=0,e=0;a=d.event.fix(b);a.type="mousewheel";if(a.wheelDelta)c=a.wheelDelta/120;if(a.detail)c=-a.detail/3;e=c;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){e=0;h=-1*c}if(b.wheelDeltaY!==undefined)e=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,c,h,e);return d.event.handle.apply(this,i)}var f=["DOMMouseScroll","mousewheel"];d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=
+f.length;a;)this.addEventListener(f[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=f.length;a;)this.removeEventListener(f[--a],g,false);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.css b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.css
new file mode 100644
index 0000000..77d0357
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.css
@@ -0,0 +1,9 @@
+#tooltip {
+ position: absolute;
+ z-index: 3000;
+ border: 1px solid #111;
+ background-color: #eee;
+ padding: 5px;
+ opacity: 0.85;
+}
+#tooltip h3, #tooltip div { margin: 0; }
diff --git a/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.js b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.js
new file mode 100644
index 0000000..af2d3df
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.js
@@ -0,0 +1,294 @@
+/*
+ * jQuery Tooltip plugin 1.3
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+ * http://docs.jquery.com/Plugins/Tooltip
+ *
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
+ *
+ * $Id: jquery.tooltip.js,v 1.1 2009/11/09 19:06:02 tylerbello Exp $
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+
+;(function($) {
+
+ // the tooltip element
+ var helper = {},
+ // the current tooltipped element
+ current,
+ // the title of the current element, used for restoring
+ title,
+ // timeout id for delayed tooltips
+ tID,
+ // IE 5.5 or 6
+ IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
+ // flag for mouse tracking
+ track = false;
+
+ $.tooltip = {
+ blocked: false,
+ defaults: {
+ delay: 200,
+ fade: false,
+ showURL: true,
+ extraClass: "",
+ top: 15,
+ left: 15,
+ id: "tooltip"
+ },
+ block: function() {
+ $.tooltip.blocked = !$.tooltip.blocked;
+ }
+ };
+
+ $.fn.extend({
+ tooltip: function(settings) {
+ settings = $.extend({}, $.tooltip.defaults, settings);
+ createHelper(settings);
+ return this.each(function() {
+ $.data(this, "tooltip", settings);
+ this.tOpacity = helper.parent.css("opacity");
+ // copy tooltip into its own expando and remove the title
+ this.tooltipText = this.title;
+ $(this).removeAttr("title");
+ // also remove alt attribute to prevent default tooltip in IE
+ this.alt = "";
+ })
+ .mouseover(save)
+ .mouseout(hide)
+ .click(hide);
+ },
+ fixPNG: IE ? function() {
+ return this.each(function () {
+ var image = $(this).css('backgroundImage');
+ if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
+ image = RegExp.$1;
+ $(this).css({
+ 'backgroundImage': 'none',
+ 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
+ }).each(function () {
+ var position = $(this).css('position');
+ if (position != 'absolute' && position != 'relative')
+ $(this).css('position', 'relative');
+ });
+ }
+ });
+ } : function() { return this; },
+ unfixPNG: IE ? function() {
+ return this.each(function () {
+ $(this).css({'filter': '', backgroundImage: ''});
+ });
+ } : function() { return this; },
+ hideWhenEmpty: function() {
+ return this.each(function() {
+ $(this)[ $(this).html() ? "show" : "hide" ]();
+ });
+ },
+ url: function() {
+ return this.attr('href') || this.attr('src');
+ }
+ });
+
+ function createHelper(settings) {
+ // there can be only one tooltip helper
+ if( helper.parent )
+ return;
+ // create the helper, h3 for title, div for url
+ helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
+ // add to document
+ .appendTo(document.body)
+ // hide it at first
+ .hide();
+
+ // apply bgiframe if available
+ if ( $.fn.bgiframe )
+ helper.parent.bgiframe();
+
+ // save references to title and url elements
+ helper.title = $('h3', helper.parent);
+ helper.body = $('div.body', helper.parent);
+ helper.url = $('div.url', helper.parent);
+ }
+
+ function settings(element) {
+ return $.data(element, "tooltip");
+ }
+
+ // main event handler to start showing tooltips
+ function handle(event) {
+ // show helper, either with timeout or on instant
+ if( settings(this).delay )
+ tID = setTimeout(show, settings(this).delay);
+ else
+ show();
+
+ // if selected, update the helper position when the mouse moves
+ track = !!settings(this).track;
+ $(document.body).bind('mousemove', update);
+
+ // update at least once
+ update(event);
+ }
+
+ // save elements title before the tooltip is displayed
+ function save() {
+ // if this is the current source, or it has no title (occurs with click event), stop
+ if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
+ return;
+
+ // save current
+ current = this;
+ title = this.tooltipText;
+
+ if ( settings(this).bodyHandler ) {
+ helper.title.hide();
+ var bodyContent = settings(this).bodyHandler.call(this);
+ if (bodyContent.nodeType || bodyContent.jquery) {
+ helper.body.empty().append(bodyContent)
+ } else {
+ helper.body.html( bodyContent );
+ }
+ helper.body.show();
+ } else if ( settings(this).showBody ) {
+ var parts = title.split(settings(this).showBody);
+ helper.title.html(parts.shift()).show();
+ helper.body.empty();
+ for(var i = 0, part; (part = parts[i]); i++) {
+ if(i > 0)
+ helper.body.append("<br/>");
+ helper.body.append(part);
+ }
+ helper.body.hideWhenEmpty();
+ } else {
+ helper.title.html(title).show();
+ helper.body.hide();
+ }
+
+ // if element has href or src, add and show it, otherwise hide it
+ if( settings(this).showURL && $(this).url() )
+ helper.url.html( $(this).url().replace('http://', '') ).show();
+ else
+ helper.url.hide();
+
+ // add an optional class for this tip
+ helper.parent.addClass(settings(this).extraClass);
+
+ // fix PNG background for IE
+ if (settings(this).fixPNG )
+ helper.parent.fixPNG();
+
+ handle.apply(this, arguments);
+ }
+
+ // delete timeout and show helper
+ function show() {
+ tID = null;
+ if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
+ if (helper.parent.is(":animated"))
+ helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
+ else
+ helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
+ } else {
+ helper.parent.show();
+ }
+ update();
+ }
+
+ /**
+ * callback for mousemove
+ * updates the helper position
+ * removes itself when no current element
+ */
+ function update(event) {
+ if($.tooltip.blocked)
+ return;
+
+ if (event && event.target.tagName == "OPTION") {
+ return;
+ }
+
+ // stop updating when tracking is disabled and the tooltip is visible
+ if ( !track && helper.parent.is(":visible")) {
+ $(document.body).unbind('mousemove', update)
+ }
+
+ // if no current element is available, remove this listener
+ if( current == null ) {
+ $(document.body).unbind('mousemove', update);
+ return;
+ }
+
+ // remove position helper classes
+ helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
+
+ var left = helper.parent[0].offsetLeft;
+ var top = helper.parent[0].offsetTop;
+ if (event) {
+ // position the helper 15 pixel to bottom right, starting from mouse position
+ left = event.pageX + settings(current).left;
+ top = event.pageY + settings(current).top;
+ var right='auto';
+ if (settings(current).positionLeft) {
+ right = $(window).width() - left;
+ left = 'auto';
+ }
+ helper.parent.css({
+ left: left,
+ right: right,
+ top: top
+ });
+ }
+
+ var v = viewport(),
+ h = helper.parent[0];
+ // check horizontal position
+ if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
+ left -= h.offsetWidth + 20 + settings(current).left;
+ helper.parent.css({left: left + 'px'}).addClass("viewport-right");
+ }
+ // check vertical position
+ if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
+ top -= h.offsetHeight + 20 + settings(current).top;
+ helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
+ }
+ }
+
+ function viewport() {
+ return {
+ x: $(window).scrollLeft(),
+ y: $(window).scrollTop(),
+ cx: $(window).width(),
+ cy: $(window).height()
+ };
+ }
+
+ // hide helper and restore added classes and the title
+ function hide(event) {
+ if($.tooltip.blocked)
+ return;
+ // clear timeout if possible
+ if(tID)
+ clearTimeout(tID);
+ // no more current element
+ current = null;
+
+ var tsettings = settings(this);
+ function complete() {
+ helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
+ }
+ if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
+ if (helper.parent.is(':animated'))
+ helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
+ else
+ helper.parent.stop().fadeOut(tsettings.fade, complete);
+ } else
+ complete();
+
+ if( settings(this).fixPNG )
+ helper.parent.unfixPNG();
+ }
+
+})(jQuery);
diff --git a/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.min.js b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.min.js
new file mode 100644
index 0000000..6b66f01
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery Tooltip plugin 1.3
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+ * http://docs.jquery.com/Plugins/Tooltip
+ *
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
+ *
+ * $Id: jquery.tooltip.min.js,v 1.1 2009/11/09 19:06:02 tylerbello Exp $
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */;(function($){var helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,fade:false,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return this.each(function(){$.data(this,"tooltip",settings);this.tOpacity=helper.parent.css("opacity");this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).mouseover(save).mouseout(hide).click(hide);},fixPNG:IE?function(){return this.each(function(){var image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"}).each(function(){var position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return this;},unfixPNG:IE?function(){return this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return this;},hideWhenEmpty:function(){return this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return this.attr('href')||this.attr('src');}});function createHelper(settings){if(helper.parent)return;helper.parent=$('<div id="'+settings.id+'"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function settings(element){return $.data(element,"tooltip");}function handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
+show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else if(settings(this).showBody){var parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var i=0,part;(part=parts[i]);i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
+helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function show(){tID=null;if((!IE||!$.fn.bgiframe)&&settings(current).fade){if(helper.parent.is(":animated"))helper.parent.stop().show().fadeTo(settings(current).fade,current.tOpacity);else
+helper.parent.is(':visible')?helper.parent.fadeTo(settings(current).fade,current.tOpacity):helper.parent.fadeIn(settings(current).fade);}else{helper.parent.show();}update();}function update(event){if($.tooltip.blocked)return;if(event&&event.target.tagName=="OPTION"){return;}if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var left=helper.parent[0].offsetLeft;var top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;var right='auto';if(settings(current).positionLeft){right=$(window).width()-left;left='auto';}helper.parent.css({left:left,right:right,top:top});}var v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;var tsettings=settings(this);function complete(){helper.parent.removeClass(tsettings.extraClass).hide().css("opacity","");}if((!IE||!$.fn.bgiframe)&&tsettings.fade){if(helper.parent.is(':animated'))helper.parent.stop().fadeTo(tsettings.fade,0,complete);else
+helper.parent.stop().fadeOut(tsettings.fade,complete);}else
+complete();if(settings(this).fixPNG)helper.parent.unfixPNG();}})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.pack.js b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.pack.js
new file mode 100644
index 0000000..76dd88d
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/jquery.tooltip.pack.js
@@ -0,0 +1,15 @@
+/*
+ * jQuery Tooltip plugin 1.3
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+ * http://docs.jquery.com/Plugins/Tooltip
+ *
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
+ *
+ * $Id: jquery.tooltip.pack.js,v 1.1 2009/11/09 19:06:02 tylerbello Exp $
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(8($){j e={},9,m,B,A=$.2u.2g&&/29\\s(5\\.5|6\\.)/.1M(1H.2t),M=12;$.k={w:12,1h:{Z:25,r:12,1d:19,X:"",G:15,E:15,16:"k"},2s:8(){$.k.w=!$.k.w}};$.N.1v({k:8(a){a=$.1v({},$.k.1h,a);1q(a);g 2.F(8(){$.1j(2,"k",a);2.11=e.3.n("1g");2.13=2.m;$(2).24("m");2.22=""}).21(1e).1U(q).1S(q)},H:A?8(){g 2.F(8(){j b=$(2).n(\'Y\');4(b.1J(/^o\\(["\']?(.*\\.1I)["\']?\\)$/i)){b=1F.$1;$(2).n({\'Y\':\'1D\',\'1B\':"2r:2q.2m.2l(2j=19, 2i=2h, 1p=\'"+b+"\')"}).F(8(){j a=$(2).n(\'1o\');4(a!=\'2f\'&&a!=\'1u\')$(2).n(\'1o\',\'1u\')})}})}:8(){g 2},1l:A?8(){g 2.F(8(){$(2).n({\'1B\':\'\',Y:\'\'})})}:8(){g 2},1x:8(){g 2.F(8(){$(2)[$(2).D()?"l":"q"]()})},o:8(){g 2.1k(\'28\')||2.1k(\'1p\')}});8 1q(a){4(e.3)g;e.3=$(\'<t 16="\'+a.16+\'"><10></10><t 1i="f"></t><t 1i="o"></t></t>\').27(K.f).q();4($.N.L)e.3.L();e.m=$(\'10\',e.3);e.f=$(\'t.f\',e.3);e.o=$(\'t.o\',e.3)}8 7(a){g $.1j(a,"k")}8 1f(a){4(7(2).Z)B=26(l,7(2).Z);p l();M=!!7(2).M;$(K.f).23(\'W\',u);u(a)}8 1e(){4($.k.w||2==9||(!2.13&&!7(2).U))g;9=2;m=2.13;4(7(2).U){e.m.q();j a=7(2).U.1Z(2);4(a.1Y||a.1V){e.f.1c().T(a)}p{e.f.D(a)}e.f.l()}p 4(7(2).18){j b=m.1T(7(2).18);e.m.D(b.1R()).l();e.f.1c();1Q(j i=0,R;(R=b[i]);i++){4(i>0)e.f.T("<1P/>");e.f.T(R)}e.f.1x()}p{e.m.D(m).l();e.f.q()}4(7(2).1d&&$(2).o())e.o.D($(2).o().1O(\'1N://\',\'\')).l();p e.o.q();e.3.P(7(2).X);4(7(2).H)e.3.H();1f.1L(2,1K)}8 l(){B=S;4((!A||!$.N.L)&&7(9).r){4(e.3.I(":17"))e.3.Q().l().O(7(9).r,9.11);p e.3.I(\':1a\')?e.3.O(7(9).r,9.11):e.3.1G(7(9).r)}p{e.3.l()}u()}8 u(c){4($.k.w)g;4(c&&c.1W.1X=="1E"){g}4(!M&&e.3.I(":1a")){$(K.f).1b(\'W\',u)}4(9==S){$(K.f).1b(\'W\',u);g}e.3.V("z-14").V("z-1A");j b=e.3[0].1z;j a=e.3[0].1y;4(c){b=c.2o+7(9).E;a=c.2n+7(9).G;j d=\'1w\';4(7(9).2k){d=$(C).1r()-b;b=\'1w\'}e.3.n({E:b,14:d,G:a})}j v=z(),h=e.3[0];4(v.x+v.1s<h.1z+h.1n){b-=h.1n+20+7(9).E;e.3.n({E:b+\'1C\'}).P("z-14")}4(v.y+v.1t<h.1y+h.1m){a-=h.1m+20+7(9).G;e.3.n({G:a+\'1C\'}).P("z-1A")}}8 z(){g{x:$(C).2e(),y:$(C).2d(),1s:$(C).1r(),1t:$(C).2p()}}8 q(a){4($.k.w)g;4(B)2c(B);9=S;j b=7(2);8 J(){e.3.V(b.X).q().n("1g","")}4((!A||!$.N.L)&&b.r){4(e.3.I(\':17\'))e.3.Q().O(b.r,0,J);p e.3.Q().2b(b.r,J)}p J();4(7(2).H)e.3.1l()}})(2a);',62,155,'||this|parent|if|||settings|function|current||||||body|return|||var|tooltip|show|title|css|url|else|hide|fade||div|update||blocked|||viewport|IE|tID|window|html|left|each|top|fixPNG|is|complete|document|bgiframe|track|fn|fadeTo|addClass|stop|part|null|append|bodyHandler|removeClass|mousemove|extraClass|backgroundImage|delay|h3|tOpacity|false|tooltipText|right||id|animated|showBody|true|visible|unbind|empty|showURL|save|handle|opacity|defaults|class|data|attr|unfixPNG|offsetHeight|offsetWidth|position|src|createHelper|width|cx|cy|relative|extend|auto|hideWhenEmpty|offsetTop|offsetLeft|bottom|filter|px|none|OPTION|RegExp|fadeIn|navigator|png|match|arguments|apply|test|http|replace|br|for|shift|click|split|mouseout|jquery|target|tagName|nodeType|call||mouseover|alt|bind|removeAttr|200|setTimeout|appendTo|href|MSIE|jQuery|fadeOut|clearTimeout|scrollTop|scrollLeft|absolute|msie|crop|sizingMethod|enabled|positionLeft|AlphaImageLoader|Microsoft|pageY|pageX|height|DXImageTransform|progid|block|userAgent|browser'.split('|'),0,{})) \ No newline at end of file
diff --git a/javascript/jquery/plugins/jquery-tooltip/lib/jquery.bgiframe.js b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.bgiframe.js
new file mode 100644
index 0000000..5d270f3
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.bgiframe.js
@@ -0,0 +1,104 @@
+/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate: 2007-06-20 03:23:36 +0200 (Mi, 20 Jun 2007) $
+ * $Rev: 2110 $
+ *
+ * Version 2.1
+ */
+
+(function($){
+
+/**
+ * The bgiframe is chainable and applies the iframe hack to get
+ * around zIndex issues in IE6. It will only apply itself in IE
+ * and adds a class to the iframe called 'bgiframe'. The iframe
+ * is appeneded as the first child of the matched element(s)
+ * with a tabIndex and zIndex of -1.
+ *
+ * By default the plugin will take borders, sized with pixel units,
+ * into account. If a different unit is used for the border's width,
+ * then you will need to use the top and left settings as explained below.
+ *
+ * NOTICE: This plugin has been reported to cause perfromance problems
+ * when used on elements that change properties (like width, height and
+ * opacity) a lot in IE6. Most of these problems have been caused by
+ * the expressions used to calculate the elements width, height and
+ * borders. Some have reported it is due to the opacity filter. All
+ * these settings can be changed if needed as explained below.
+ *
+ * @example $('div').bgiframe();
+ * @before <div><p>Paragraph</p></div>
+ * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>
+ *
+ * @param Map settings Optional settings to configure the iframe.
+ * @option String|Number top The iframe must be offset to the top
+ * by the width of the top border. This should be a negative
+ * number representing the border-top-width. If a number is
+ * is used here, pixels will be assumed. Otherwise, be sure
+ * to specify a unit. An expression could also be used.
+ * By default the value is "auto" which will use an expression
+ * to get the border-top-width if it is in pixels.
+ * @option String|Number left The iframe must be offset to the left
+ * by the width of the left border. This should be a negative
+ * number representing the border-left-width. If a number is
+ * is used here, pixels will be assumed. Otherwise, be sure
+ * to specify a unit. An expression could also be used.
+ * By default the value is "auto" which will use an expression
+ * to get the border-left-width if it is in pixels.
+ * @option String|Number width This is the width of the iframe. If
+ * a number is used here, pixels will be assume. Otherwise, be sure
+ * to specify a unit. An experssion could also be used.
+ * By default the value is "auto" which will use an experssion
+ * to get the offsetWidth.
+ * @option String|Number height This is the height of the iframe. If
+ * a number is used here, pixels will be assume. Otherwise, be sure
+ * to specify a unit. An experssion could also be used.
+ * By default the value is "auto" which will use an experssion
+ * to get the offsetHeight.
+ * @option Boolean opacity This is a boolean representing whether or not
+ * to use opacity. If set to true, the opacity of 0 is applied. If
+ * set to false, the opacity filter is not applied. Default: true.
+ * @option String src This setting is provided so that one could change
+ * the src of the iframe to whatever they need.
+ * Default: "javascript:false;"
+ *
+ * @name bgiframe
+ * @type jQuery
+ * @cat Plugins/bgiframe
+ * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
+ */
+$.fn.bgIframe = $.fn.bgiframe = function(s) {
+ // This is only for IE6
+ if ( $.browser.msie && parseInt($.browser.version) <= 6 ) {
+ s = $.extend({
+ top : 'auto', // auto == .currentStyle.borderTopWidth
+ left : 'auto', // auto == .currentStyle.borderLeftWidth
+ width : 'auto', // auto == offsetWidth
+ height : 'auto', // auto == offsetHeight
+ opacity : true,
+ src : 'javascript:false;'
+ }, s || {});
+ var prop = function(n){return n&&n.constructor==Number?n+'px':n;},
+ html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
+ 'style="display:block;position:absolute;z-index:-1;'+
+ (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
+ 'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
+ 'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
+ 'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
+ 'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
+ '"/>';
+ return this.each(function() {
+ if ( $('> iframe.bgiframe', this).length == 0 )
+ this.insertBefore( document.createElement(html), this.firstChild );
+ });
+ }
+ return this;
+};
+
+// Add browser.version if it doesn't exist
+if (!$.browser.version)
+ $.browser.version = navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1];
+
+})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/jquery-tooltip/lib/jquery.delegate.js b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.delegate.js
new file mode 100644
index 0000000..09f197d
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.delegate.js
@@ -0,0 +1,56 @@
+/*
+ * jQuery delegate plug-in v1.0
+ *
+ * Copyright (c) 2007 Jörn Zaefferer
+ *
+ * $Id: jquery.delegate.js,v 1.1 2009/11/09 19:06:02 tylerbello Exp $
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+
+// provides cross-browser focusin and focusout events
+// IE has native support, in other browsers, use event caputuring (neither bubbles)
+
+// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
+// handler is only called when $(event.target).is(delegate), in the scope of the jQuery-object for event.target
+
+// provides triggerEvent(type: String, target: Element) to trigger delegated events
+;(function($) {
+ $.each({
+ focus: 'focusin',
+ blur: 'focusout'
+ }, function( original, fix ){
+ $.event.special[fix] = {
+ setup:function() {
+ if ( $.browser.msie ) return false;
+ this.addEventListener( original, $.event.special[fix].handler, true );
+ },
+ teardown:function() {
+ if ( $.browser.msie ) return false;
+ this.removeEventListener( original,
+ $.event.special[fix].handler, true );
+ },
+ handler: function(e) {
+ arguments[0] = $.event.fix(e);
+ arguments[0].type = fix;
+ return $.event.handle.apply(this, arguments);
+ }
+ };
+ });
+
+ $.extend($.fn, {
+ delegate: function(type, delegate, handler) {
+ return this.bind(type, function(event) {
+ var target = $(event.target);
+ if (target.is(delegate)) {
+ return handler.apply(target, arguments);
+ }
+ });
+ },
+ triggerEvent: function(type, target) {
+ return this.triggerHandler(type, [jQuery.event.fix({ type: type, target: target })]);
+ }
+ })
+})(jQuery);
diff --git a/javascript/jquery/plugins/jquery-tooltip/lib/jquery.dimensions.js b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.dimensions.js
new file mode 100644
index 0000000..2934714
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.dimensions.js
@@ -0,0 +1,504 @@
+/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate: 2007-06-22 04:38:37 +0200 (Fr, 22 Jun 2007) $
+ * $Rev: 2141 $
+ *
+ * Version: 1.0b2
+ */
+
+(function($){
+
+// store a copy of the core height and width methods
+var height = $.fn.height,
+ width = $.fn.width;
+
+$.fn.extend({
+ /**
+ * If used on document, returns the document's height (innerHeight)
+ * If used on window, returns the viewport's (window) height
+ * See core docs on height() to see what happens when used on an element.
+ *
+ * @example $("#testdiv").height()
+ * @result 200
+ *
+ * @example $(document).height()
+ * @result 800
+ *
+ * @example $(window).height()
+ * @result 400
+ *
+ * @name height
+ * @type Object
+ * @cat Plugins/Dimensions
+ */
+ height: function() {
+ if ( this[0] == window )
+ return self.innerHeight ||
+ $.boxModel && document.documentElement.clientHeight ||
+ document.body.clientHeight;
+
+ if ( this[0] == document )
+ return Math.max( document.body.scrollHeight, document.body.offsetHeight );
+
+ return height.apply(this, arguments);
+ },
+
+ /**
+ * If used on document, returns the document's width (innerWidth)
+ * If used on window, returns the viewport's (window) width
+ * See core docs on height() to see what happens when used on an element.
+ *
+ * @example $("#testdiv").width()
+ * @result 200
+ *
+ * @example $(document).width()
+ * @result 800
+ *
+ * @example $(window).width()
+ * @result 400
+ *
+ * @name width
+ * @type Object
+ * @cat Plugins/Dimensions
+ */
+ width: function() {
+ if ( this[0] == window )
+ return self.innerWidth ||
+ $.boxModel && document.documentElement.clientWidth ||
+ document.body.clientWidth;
+
+ if ( this[0] == document )
+ return Math.max( document.body.scrollWidth, document.body.offsetWidth );
+
+ return width.apply(this, arguments);
+ },
+
+ /**
+ * Returns the inner height value (without border) for the first matched element.
+ * If used on document, returns the document's height (innerHeight)
+ * If used on window, returns the viewport's (window) height
+ *
+ * @example $("#testdiv").innerHeight()
+ * @result 800
+ *
+ * @name innerHeight
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ innerHeight: function() {
+ return this[0] == window || this[0] == document ?
+ this.height() :
+ this.is(':visible') ?
+ this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
+ this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
+ },
+
+ /**
+ * Returns the inner width value (without border) for the first matched element.
+ * If used on document, returns the document's Width (innerWidth)
+ * If used on window, returns the viewport's (window) width
+ *
+ * @example $("#testdiv").innerWidth()
+ * @result 1000
+ *
+ * @name innerWidth
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ innerWidth: function() {
+ return this[0] == window || this[0] == document ?
+ this.width() :
+ this.is(':visible') ?
+ this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
+ this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
+ },
+
+ /**
+ * Returns the outer height value (including border) for the first matched element.
+ * Cannot be used on document or window.
+ *
+ * @example $("#testdiv").outerHeight()
+ * @result 1000
+ *
+ * @name outerHeight
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ outerHeight: function() {
+ return this[0] == window || this[0] == document ?
+ this.height() :
+ this.is(':visible') ?
+ this[0].offsetHeight :
+ this.height() + num(this,'borderTopWidth') + num(this, 'borderBottomWidth') + num(this, 'paddingTop') + num(this, 'paddingBottom');
+ },
+
+ /**
+ * Returns the outer width value (including border) for the first matched element.
+ * Cannot be used on document or window.
+ *
+ * @example $("#testdiv").outerHeight()
+ * @result 1000
+ *
+ * @name outerHeight
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ outerWidth: function() {
+ return this[0] == window || this[0] == document ?
+ this.width() :
+ this.is(':visible') ?
+ this[0].offsetWidth :
+ this.width() + num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') + num(this, 'paddingLeft') + num(this, 'paddingRight');
+ },
+
+ /**
+ * Returns how many pixels the user has scrolled to the right (scrollLeft).
+ * Works on containers with overflow: auto and window/document.
+ *
+ * @example $("#testdiv").scrollLeft()
+ * @result 100
+ *
+ * @name scrollLeft
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ /**
+ * Sets the scrollLeft property and continues the chain.
+ * Works on containers with overflow: auto and window/document.
+ *
+ * @example $("#testdiv").scrollLeft(10).scrollLeft()
+ * @result 10
+ *
+ * @name scrollLeft
+ * @param Number value A positive number representing the desired scrollLeft.
+ * @type jQuery
+ * @cat Plugins/Dimensions
+ */
+ scrollLeft: function(val) {
+ if ( val != undefined )
+ // set the scroll left
+ return this.each(function() {
+ if (this == window || this == document)
+ window.scrollTo( val, $(window).scrollTop() );
+ else
+ this.scrollLeft = val;
+ });
+
+ // return the scroll left offest in pixels
+ if ( this[0] == window || this[0] == document )
+ return self.pageXOffset ||
+ $.boxModel && document.documentElement.scrollLeft ||
+ document.body.scrollLeft;
+
+ return this[0].scrollLeft;
+ },
+
+ /**
+ * Returns how many pixels the user has scrolled to the bottom (scrollTop).
+ * Works on containers with overflow: auto and window/document.
+ *
+ * @example $("#testdiv").scrollTop()
+ * @result 100
+ *
+ * @name scrollTop
+ * @type Number
+ * @cat Plugins/Dimensions
+ */
+ /**
+ * Sets the scrollTop property and continues the chain.
+ * Works on containers with overflow: auto and window/document.
+ *
+ * @example $("#testdiv").scrollTop(10).scrollTop()
+ * @result 10
+ *
+ * @name scrollTop
+ * @param Number value A positive number representing the desired scrollTop.
+ * @type jQuery
+ * @cat Plugins/Dimensions
+ */
+ scrollTop: function(val) {
+ if ( val != undefined )
+ // set the scroll top
+ return this.each(function() {
+ if (this == window || this == document)
+ window.scrollTo( $(window).scrollLeft(), val );
+ else
+ this.scrollTop = val;
+ });
+
+ // return the scroll top offset in pixels
+ if ( this[0] == window || this[0] == document )
+ return self.pageYOffset ||
+ $.boxModel && document.documentElement.scrollTop ||
+ document.body.scrollTop;
+
+ return this[0].scrollTop;
+ },
+
+ /**
+ * Returns the top and left positioned offset in pixels.
+ * The positioned offset is the offset between a positioned
+ * parent and the element itself.
+ *
+ * @example $("#testdiv").position()
+ * @result { top: 100, left: 100 }
+ *
+ * @name position
+ * @param Map options Optional settings to configure the way the offset is calculated.
+ * @option Boolean margin Should the margin of the element be included in the calculations? False by default.
+ * @option Boolean border Should the border of the element be included in the calculations? False by default.
+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
+ * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
+ * chain will not be broken and the result will be assigned to this object.
+ * @type Object
+ * @cat Plugins/Dimensions
+ */
+ position: function(options, returnObject) {
+ var elem = this[0], parent = elem.parentNode, op = elem.offsetParent,
+ options = $.extend({ margin: false, border: false, padding: false, scroll: false }, options || {}),
+ x = elem.offsetLeft,
+ y = elem.offsetTop,
+ sl = elem.scrollLeft,
+ st = elem.scrollTop;
+
+ // Mozilla and IE do not add the border
+ if ($.browser.mozilla || $.browser.msie) {
+ // add borders to offset
+ x += num(elem, 'borderLeftWidth');
+ y += num(elem, 'borderTopWidth');
+ }
+
+ if ($.browser.mozilla) {
+ do {
+ // Mozilla does not add the border for a parent that has overflow set to anything but visible
+ if ($.browser.mozilla && parent != elem && $.css(parent, 'overflow') != 'visible') {
+ x += num(parent, 'borderLeftWidth');
+ y += num(parent, 'borderTopWidth');
+ }
+
+ if (parent == op) break; // break if we are already at the offestParent
+ } while ((parent = parent.parentNode) && (parent.tagName.toLowerCase() != 'body' || parent.tagName.toLowerCase() != 'html'));
+ }
+
+ var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
+
+ if (returnObject) { $.extend(returnObject, returnValue); return this; }
+ else { return returnValue; }
+ },
+
+ /**
+ * Returns the location of the element in pixels from the top left corner of the viewport.
+ *
+ * For accurate readings make sure to use pixel values for margins, borders and padding.
+ *
+ * Known issues:
+ * - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
+ * Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
+ *
+ * @example $("#testdiv").offset()
+ * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
+ *
+ * @example $("#testdiv").offset({ scroll: false })
+ * @result { top: 90, left: 90 }
+ *
+ * @example var offset = {}
+ * $("#testdiv").offset({ scroll: false }, offset)
+ * @result offset = { top: 90, left: 90 }
+ *
+ * @name offset
+ * @param Map options Optional settings to configure the way the offset is calculated.
+ * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
+ * @option Boolean border Should the border of the element be included in the calculations? False by default.
+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
+ * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
+ * When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
+ * to the returned object, scrollTop and scrollLeft.
+ * @options Boolean lite Will use offsetLite instead of offset when set to true. False by default.
+ * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
+ * chain will not be broken and the result will be assigned to this object.
+ * @type Object
+ * @cat Plugins/Dimensions
+ */
+ offset: function(options, returnObject) {
+ var x = 0, y = 0, sl = 0, st = 0,
+ elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
+ mo = $.browser.mozilla, ie = $.browser.msie, sf = $.browser.safari, oa = $.browser.opera,
+ absparent = false, relparent = false,
+ options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false }, options || {});
+
+ // Use offsetLite if lite option is true
+ if (options.lite) return this.offsetLite(options, returnObject);
+
+ if (elem.tagName.toLowerCase() == 'body') {
+ // Safari is the only one to get offsetLeft and offsetTop properties of the body "correct"
+ // Except they all mess up when the body is positioned absolute or relative
+ x = elem.offsetLeft;
+ y = elem.offsetTop;
+ // Mozilla ignores margin and subtracts border from body element
+ if (mo) {
+ x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
+ y += num(elem, 'marginTop') + (num(elem, 'borderTopWidth') *2);
+ } else
+ // Opera ignores margin
+ if (oa) {
+ x += num(elem, 'marginLeft');
+ y += num(elem, 'marginTop');
+ } else
+ // IE does not add the border in Standards Mode
+ if (ie && jQuery.boxModel) {
+ x += num(elem, 'borderLeftWidth');
+ y += num(elem, 'borderTopWidth');
+ }
+ } else {
+ do {
+ parPos = $.css(parent, 'position');
+
+ x += parent.offsetLeft;
+ y += parent.offsetTop;
+
+ // Mozilla and IE do not add the border
+ if (mo || ie) {
+ // add borders to offset
+ x += num(parent, 'borderLeftWidth');
+ y += num(parent, 'borderTopWidth');
+
+ // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
+ if (mo && parPos == 'absolute') absparent = true;
+ // IE does not include the border on the body if an element is position static and without an absolute or relative parent
+ if (ie && parPos == 'relative') relparent = true;
+ }
+
+ op = parent.offsetParent;
+ if (options.scroll || mo) {
+ do {
+ if (options.scroll) {
+ // get scroll offsets
+ sl += parent.scrollLeft;
+ st += parent.scrollTop;
+ }
+
+ // Mozilla does not add the border for a parent that has overflow set to anything but visible
+ if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
+ x += num(parent, 'borderLeftWidth');
+ y += num(parent, 'borderTopWidth');
+ }
+
+ parent = parent.parentNode;
+ } while (parent != op);
+ }
+ parent = op;
+
+ if (parent.tagName.toLowerCase() == 'body' || parent.tagName.toLowerCase() == 'html') {
+ // Safari and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
+ if ((sf || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
+ x += num(parent, 'marginLeft');
+ y += num(parent, 'marginTop');
+ }
+ // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
+ // IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
+ if ( (mo && !absparent && elemPos != 'fixed') ||
+ (ie && elemPos == 'static' && !relparent) ) {
+ x += num(parent, 'borderLeftWidth');
+ y += num(parent, 'borderTopWidth');
+ }
+ break; // Exit the loop
+ }
+ } while (parent);
+ }
+
+ var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
+
+ if (returnObject) { $.extend(returnObject, returnValue); return this; }
+ else { return returnValue; }
+ },
+
+ /**
+ * Returns the location of the element in pixels from the top left corner of the viewport.
+ * This method is much faster than offset but not as accurate. This method can be invoked
+ * by setting the lite option to true in the offset method.
+ *
+ * @name offsetLite
+ * @param Map options Optional settings to configure the way the offset is calculated.
+ * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
+ * @option Boolean border Should the border of the element be included in the calculations? False by default.
+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
+ * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
+ * When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
+ * to the returned object, scrollTop and scrollLeft.
+ * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
+ * chain will not be broken and the result will be assigned to this object.
+ * @type Object
+ * @cat Plugins/Dimensions
+ */
+ offsetLite: function(options, returnObject) {
+ var x = 0, y = 0, sl = 0, st = 0, parent = this[0], op,
+ options = $.extend({ margin: true, border: false, padding: false, scroll: true }, options || {});
+
+ do {
+ x += parent.offsetLeft;
+ y += parent.offsetTop;
+
+ op = parent.offsetParent;
+ if (options.scroll) {
+ // get scroll offsets
+ do {
+ sl += parent.scrollLeft;
+ st += parent.scrollTop;
+ parent = parent.parentNode;
+ } while(parent != op);
+ }
+ parent = op;
+ } while (parent && parent.tagName.toLowerCase() != 'body' && parent.tagName.toLowerCase() != 'html');
+
+ var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);
+
+ if (returnObject) { $.extend(returnObject, returnValue); return this; }
+ else { return returnValue; }
+ }
+});
+
+/**
+ * Handles converting a CSS Style into an Integer.
+ * @private
+ */
+var num = function(el, prop) {
+ return parseInt($.css(el.jquery?el[0]:el,prop))||0;
+};
+
+/**
+ * Handles the return value of the offset and offsetLite methods.
+ * @private
+ */
+var handleOffsetReturn = function(elem, options, x, y, sl, st) {
+ if ( !options.margin ) {
+ x -= num(elem, 'marginLeft');
+ y -= num(elem, 'marginTop');
+ }
+
+ // Safari and Opera do not add the border for the element
+ if ( options.border && ($.browser.safari || $.browser.opera) ) {
+ x += num(elem, 'borderLeftWidth');
+ y += num(elem, 'borderTopWidth');
+ } else if ( !options.border && !($.browser.safari || $.browser.opera) ) {
+ x -= num(elem, 'borderLeftWidth');
+ y -= num(elem, 'borderTopWidth');
+ }
+
+ if ( options.padding ) {
+ x += num(elem, 'paddingLeft');
+ y += num(elem, 'paddingTop');
+ }
+
+ // do not include scroll offset on the element
+ if ( options.scroll ) {
+ sl -= elem.scrollLeft;
+ st -= elem.scrollTop;
+ }
+
+ return options.scroll ? { top: y - st, left: x - sl, scrollTop: st, scrollLeft: sl }
+ : { top: y, left: x };
+};
+
+})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/jquery-tooltip/lib/jquery.js b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.js
new file mode 100644
index 0000000..a727a8f
--- /dev/null
+++ b/javascript/jquery/plugins/jquery-tooltip/lib/jquery.js
@@ -0,0 +1,3383 @@
+(function(){
+/*
+ * jQuery 1.2.2 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2009/11/09 19:06:02 $
+ * $Rev: 4454 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( window.jQuery )
+ var _jQuery = window.jQuery;
+
+var jQuery = window.jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.prototype.init( selector, context );
+};
+
+// Map over the $ in case of overwrite
+if ( window.$ )
+ var _$ = window.$;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+// Is it a simple selector
+var isSimple = /^.[^:#\[\.]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ return this;
+
+ // Handle HTML strings
+ } else if ( typeof selector == "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Make sure an element was located
+ if ( elem )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ else {
+ this[0] = elem;
+ this.length = 1;
+ return this;
+ }
+
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ // The current version of jQuery being used
+ jquery: "1.2.2",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // The number of elements contained in the matched element set
+ length: 0,
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ var ret = -1;
+
+ // Locate the position of the desired element
+ this.each(function(i){
+ if ( this == elem )
+ ret = i;
+ });
+
+ return ret;
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( name.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text != "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery( html, this[0].ownerDocument )
+ .clone()
+ .insertBefore( this[0] )
+ .map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, false, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, true, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ find: function( selector ) {
+ var elems = jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ });
+
+ return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+ jQuery.unique( elems ) :
+ elems );
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var clone = this.cloneNode(true),
+ container = document.createElement("div"),
+ container2 = document.createElement("div");
+ container.appendChild(clone);
+ container2.innerHTML = container.innerHTML;
+ return container2.firstChild;
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true )
+ this.find("*").andSelf().each(function(i){
+ if (this.nodeType == 3)
+ return;
+ var events = jQuery.data( this, "events" );
+
+ for ( var type in events )
+ for ( var handler in events[ type ] )
+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, this ) );
+ },
+
+ not: function( selector ) {
+ if ( selector.constructor == String )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return !selector ? this : this.pushStack( jQuery.merge(
+ this.get(),
+ selector.constructor == String ?
+ jQuery( selector ).get() :
+ selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
+ selector : [selector] ) );
+ },
+
+ is: function( selector ) {
+ return selector ?
+ jQuery.multiFilter( selector, this ).length > 0 :
+ false;
+ },
+
+ hasClass: function( selector ) {
+ return this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value == undefined ) {
+
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+
+ // Everything else, we just grab the value
+ } else
+ return (this[0].value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = value.constructor == Array ?
+ value :
+ [ value ];
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value == undefined ?
+ (this.length ?
+ this[0].innerHTML :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function( args, table, reverse, callback ) {
+ var clone = this.length > 1, elems;
+
+ return this.each(function(){
+ if ( !elems ) {
+ elems = jQuery.clean( args, this.ownerDocument );
+
+ if ( reverse )
+ elems.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
+
+ var scripts = jQuery( [] );
+
+ jQuery.each(elems, function(){
+ var elem = clone ?
+ jQuery( this ).clone( true )[0] :
+ this;
+
+ // execute all scripts after the elements have been injected
+ if ( jQuery.nodeName( elem, "script" ) ) {
+ scripts = scripts.add( elem );
+ } else {
+ // Remove any inner scripts for later evaluation
+ if ( elem.nodeType == 1 )
+ scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+ // Inject the elements into the document
+ callback.call( obj, elem );
+ }
+ });
+
+ scripts.each( evalScript );
+ });
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.prototype.init.prototype = jQuery.prototype;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target != "object" && typeof target != "function" )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == 1 ) {
+ target = this;
+ i = 0;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ // Prevent never-ending loop
+ if ( target === options[ name ] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
+ target[ name ] = jQuery.extend( target[ name ], options[ name ] );
+
+ // Don't bring in undefined values
+ else if ( options[ name ] != undefined )
+ target[ name ] = options[ name ];
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning this function.
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.browser.msie )
+ script.text = data;
+ else
+ script.appendChild( document.createTextNode( data ) );
+
+ head.appendChild( script );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ if ( args ) {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length; i < length; i++ )
+ if ( callback.apply( object[ i ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length, value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames != undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use is(".class")
+ has: function( elem, className ) {
+ return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+ var padding = 0, border = 0;
+ jQuery.each( which, function() {
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ val -= Math.round(padding + border);
+ }
+
+ if ( jQuery(elem).is(":visible") )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, val);
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret;
+
+ // A helper method for determining if an element's values are broken
+ function color( elem ) {
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle( elem, null );
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ ret = jQuery.attr( elem.style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037
+ if ( jQuery.browser.opera && name == "display" ) {
+ var save = elem.style.display;
+ elem.style.display = "block";
+ elem.style.display = save;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && elem.style && elem.style[ name ] )
+ ret = elem.style[ name ];
+
+ else if ( document.defaultView && document.defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
+
+ if ( getComputedStyle && !color( elem ) )
+ ret = getComputedStyle.getPropertyValue( name );
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ var swap = [], stack = [];
+
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( var i = 0; i < stack.length; i++ )
+ if ( color( stack[ i ] ) ) {
+ swap[ i ] = stack[ i ].style.display;
+ stack[ i ].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = name == "display" && swap[ stack.length - 1 ] != null ?
+ "none" :
+ ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
+
+ // Finally, revert the display styles back
+ for ( var i = 0; i < swap.length; i++ )
+ if ( swap[ i ] != null )
+ stack[ i ].style.display = swap[ i ];
+ }
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+
+ // Revert the changed values
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context ) {
+ var ret = [];
+ context = context || document;
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if (typeof context.createElement == 'undefined')
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ jQuery.each(elems, function(i, elem){
+ if ( !elem )
+ return;
+
+ if ( elem.constructor == Number )
+ elem = elem.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof elem == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
+ return;
+
+ if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
+ ret.push( elem );
+
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var fix = jQuery.isXMLDoc( elem ) ?
+ {} :
+ jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[ name ] ) {
+ if ( value != undefined )
+ elem[ fix[ name ] ] = value;
+
+ return elem[ fix[ name ] ];
+
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( value != undefined )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ }
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof array != "array" )
+ for ( var i = 0, length = array.length; i < length; i++ )
+ ret.push( array[ i ] );
+ else
+ ret = array.slice( 0 );
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ if ( array[ i ] == elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[ i ]; i++ )
+ if ( second[ i ].nodeType != 8 )
+ first.push( second[ i ] );
+
+ } else
+ for ( var i = 0; second[ i ]; i++ )
+ first.push( second[ i ] );
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof callback == "string" )
+ callback = eval("false||function(a,i){return " + callback + "}");
+
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value !== null && value != undefined ) {
+ if ( value.constructor != Array )
+ value = [ value ];
+
+ ret = ret.concat( value );
+ }
+ }
+
+ return ret;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+var styleFloat = jQuery.browser.msie ?
+ "styleFloat" :
+ "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength",
+ selectedIndex: "selectedIndex",
+ defaultValue: "defaultValue",
+ tagName: "tagName",
+ nodeName: "nodeName"
+ }
+});
+
+jQuery.each({
+ parent: "elem.parentNode",
+ parents: "jQuery.dir(elem,'parentNode')",
+ next: "jQuery.nth(elem,2,'nextSibling')",
+ prev: "jQuery.nth(elem,2,'previousSibling')",
+ nextAll: "jQuery.dir(elem,'nextSibling')",
+ prevAll: "jQuery.dir(elem,'previousSibling')",
+ siblings: "jQuery.sibling(elem.parentNode.firstChild,elem)",
+ children: "jQuery.sibling(elem.firstChild)",
+ contents: "jQuery.nodeName(elem,'iframe')?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes)"
+}, function(name, fn){
+ fn = eval("false||function(elem){return " + fn + "}");
+
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function() {
+ var args = arguments;
+
+ return this.each(function(){
+ for ( var i = 0, length = args.length; i < length; i++ )
+ jQuery( args[ i ] )[ original ]( this );
+ });
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames ) {
+ jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add(this).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery( ">*", this ).remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+jQuery.each([ "Height", "Width" ], function(i, name){
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Opera reports document.body.client[Width/Height] properly in both quirks and standards
+ jQuery.browser.opera && document.body[ "client" + name ] ||
+
+ // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
+ jQuery.browser.safari && window[ "inner" + name ] ||
+
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
+ Math.max(document.body["offset" + name], document.documentElement["offset" + name])
+ ) :
+
+ // Get or set width or height on the element
+ size == undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, size.constructor == String ? size : size + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
+ "#": "a.getAttribute('id')==m[2]",
+ ":": {
+ // Position Checks
+ lt: "i<m[3]-0",
+ gt: "i>m[3]-0",
+ nth: "m[3]-0==i",
+ eq: "m[3]-0==i",
+ first: "i==0",
+ last: "i==r.length-1",
+ even: "i%2==0",
+ odd: "i%2",
+
+ // Child Checks
+ "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
+ "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
+ "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+
+ // Parent Checks
+ parent: "a.firstChild",
+ empty: "!a.firstChild",
+
+ // Text Check
+ contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",
+
+ // Visibility
+ visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
+ hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+
+ // Form attributes
+ enabled: "!a.disabled",
+ disabled: "a.disabled",
+ checked: "a.checked",
+ selected: "a.selected||jQuery.attr(a,'selected')",
+
+ // Form elements
+ text: "'text'==a.type",
+ radio: "'radio'==a.type",
+ checkbox: "'checkbox'==a.type",
+ file: "'file'==a.type",
+ password: "'password'==a.type",
+ submit: "'submit'==a.type",
+ image: "'image'==a.type",
+ reset: "'reset'==a.type",
+ button: '"button"==a.type||jQuery.nodeName(a,"button")',
+ input: "/input|select|textarea|button/i.test(a.nodeName)",
+
+ // :has()
+ has: "jQuery.find(m[3],a).length",
+
+ // :header
+ header: "/h\\d/i.test(a.nodeName)",
+
+ // :animated
+ animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // check to make sure context is a DOM element or a document
+ if ( context && context.nodeType != 1 && context.nodeType != 9)
+ return [ ];
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last, nodeName;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var merge = {};
+ nodeName = m[2].toUpperCase();
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ // optimize if only one selector found (most common case)
+ r = isSimple.test( m[3] ) ?
+ jQuery.filter(m[3], r, true).r :
+ jQuery( r ).not( m[3] );
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+ // calculate the numbers (first)n+(last) including if they are negative
+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+ // loop through all the elements left in the jQuery object
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 0 ) {
+ if ( node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var f = jQuery.expr[m[1]];
+ if ( typeof f != "string" )
+ f = jQuery.expr[m[1]][m[2]];
+
+ // Build a custom macro to enclose it
+ f = eval("false||function(a,i){return " + f + "}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, f, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && elem.setInterval != undefined )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
+
+ return val;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types == undefined )
+ for ( var type in events )
+ this.remove( elem, type );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, elem, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ event = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( event )
+ data.unshift( this.fix({ type: type, target: elem }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
+ val = jQuery.data(elem, "handle").apply( elem, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( event )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && jQuery.isFunction( extra ) ) {
+ // call the extra function and tack the current return value on the end for possible inspection
+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );
+ // if anything is returned, give it precedence and have it overwrite the previous value
+ if (ret !== undefined)
+ val = ret;
+ }
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = handler;
+ args[0].data = handler.data;
+
+ // Filter the functions by class
+ if ( !parts[1] || handler.type == parts[1] ) {
+ var ret = handler.apply( this, args );
+
+ if ( val !== false )
+ val = ret;
+
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ special: {
+ ready: {
+ setup: function() {
+ // Make sure the ready event is setup
+ bindReady();
+ return;
+ },
+
+ teardown: function() { return; }
+ },
+
+ mouseenter: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseenter
+ arguments[0].type = "mouseenter";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ },
+
+ mouseleave: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseleave
+ arguments[0].type = "mouseleave";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ }
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ return undefined;
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var args = arguments;
+
+ return this.click(function(event) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[this.lastToggle].apply( this, arguments ) || false;
+ });
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
+ if ( document.addEventListener && !jQuery.browser.opera)
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used and is not in a frame
+ // Continually check to see if the document is ready
+ if ( jQuery.browser.msie && window == top ) (function(){
+ if (jQuery.isReady) return;
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+
+ if ( jQuery.browser.opera )
+ document.addEventListener( "DOMContentLoaded", function () {
+ if (jQuery.isReady) return;
+ for (var i = 0; i < document.styleSheets.length; i++)
+ if (document.styleSheets[i].disabled) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ }, false);
+
+ if ( jQuery.browser.safari ) {
+ var numStyles;
+ (function(){
+ if (jQuery.isReady) return;
+ if ( document.readyState != "loaded" && document.readyState != "complete" ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ if ( numStyles === undefined )
+ numStyles = jQuery("style, link[rel=stylesheet]").length;
+ if ( document.styleSheets.length != numStyles ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event, elem) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
+ // Return true if we actually just moused on to a sub-element
+ return parent == elem;
+};
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery(window).bind("unload", function() {
+ jQuery("*").add(document).unbind();
+});
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null,
+ username: null,
+ password: null,
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=\?(&|$)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" ) {
+ var ts = (new Date()).getTime();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && ( s.dataType == "script" || s.dataType =="json" ) && s.type.toLowerCase() == "get" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async, s.username, s.password);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock || "";
+ if ( jQuery.css(this,"display") == "none" ) {
+ var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+ this.style.display = elem.css("display");
+ // handle an edge condition where css is - div { display:none; } or similar
+ if (this.style.display == "none")
+ this.style.display = "block";
+ elem.remove();
+ }
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+ if ( this.nodeType != 1)
+ return false;
+
+ var opt = jQuery.extend({}, optall);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return undefined;
+
+ type = type || "fx";
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+ timerId: null,
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timerId == null ) {
+ jQuery.timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( jQuery.timerId );
+ jQuery.timerId = null;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = (new Date()).getTime();
+
+ if ( gotoEnd || t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var parent = elem.parentNode,
+ offsetChild = elem,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522,
+ fixed = jQuery.css(elem, "position") == "fixed";
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ var box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ // This border/offset is typically represented by the clientLeft and clientTop properties
+ // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
+ // Therefore this method will be off by 2px in IE while in quirksmode
+ add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table or table cells
+ if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
+ border( offsetParent );
+
+ // Add the document scroll offsets if position is fixed on any offsetParent
+ if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
+ fixed = true;
+
+ // Set offsetChild to previous offsetParent unless it is the body element
+ offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
+ // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
+ if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) ||
+ (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+
+ // Add the document scroll offsets if position is fixed
+ if ( fixed )
+ add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ function border(elem) {
+ add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+
+ return results;
+};
+})();
diff --git a/javascript/jquery/plugins/migrate/jquery.migrate.js b/javascript/jquery/plugins/migrate/jquery.migrate.js
new file mode 100644
index 0000000..25b6c81
--- /dev/null
+++ b/javascript/jquery/plugins/migrate/jquery.migrate.js
@@ -0,0 +1,521 @@
+/*!
+ * jQuery Migrate - v1.2.1 - 2013-05-08
+ * https://github.com/jquery/jquery-migrate
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
+ */
+(function( jQuery, window, undefined ) {
+// See http://bugs.jquery.com/ticket/13335
+// "use strict";
+
+
+var warnedAbout = {};
+
+// List of warnings already given; public read only
+jQuery.migrateWarnings = [];
+
+// Set to true to prevent console output; migrateWarnings still maintained
+// jQuery.migrateMute = false;
+
+// Show a message on the console so devs know we're active
+if ( !jQuery.migrateMute && window.console && window.console.log ) {
+ window.console.log("JQMIGRATE: Logging is active");
+}
+
+// Set to false to disable traces that appear with warnings
+if ( jQuery.migrateTrace === undefined ) {
+ jQuery.migrateTrace = true;
+}
+
+// Forget any warnings we've already given; public
+jQuery.migrateReset = function() {
+ warnedAbout = {};
+ jQuery.migrateWarnings.length = 0;
+};
+
+function migrateWarn( msg) {
+ var console = window.console;
+ if ( !warnedAbout[ msg ] ) {
+ warnedAbout[ msg ] = true;
+ jQuery.migrateWarnings.push( msg );
+ if ( console && console.warn && !jQuery.migrateMute ) {
+ console.warn( "JQMIGRATE: " + msg );
+ if ( jQuery.migrateTrace && console.trace ) {
+ console.trace();
+ }
+ }
+ }
+}
+
+function migrateWarnProp( obj, prop, value, msg ) {
+ if ( Object.defineProperty ) {
+ // On ES5 browsers (non-oldIE), warn if the code tries to get prop;
+ // allow property to be overwritten in case some other plugin wants it
+ try {
+ Object.defineProperty( obj, prop, {
+ configurable: true,
+ enumerable: true,
+ get: function() {
+ migrateWarn( msg );
+ return value;
+ },
+ set: function( newValue ) {
+ migrateWarn( msg );
+ value = newValue;
+ }
+ });
+ return;
+ } catch( err ) {
+ // IE8 is a dope about Object.defineProperty, can't warn there
+ }
+ }
+
+ // Non-ES5 (or broken) browser; just set the property
+ jQuery._definePropertyBroken = true;
+ obj[ prop ] = value;
+}
+
+if ( document.compatMode === "BackCompat" ) {
+ // jQuery has never supported or tested Quirks Mode
+ migrateWarn( "jQuery is not compatible with Quirks Mode" );
+}
+
+
+var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
+ oldAttr = jQuery.attr,
+ valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
+ function() { return null; },
+ valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
+ function() { return undefined; },
+ rnoType = /^(?:input|button)$/i,
+ rnoAttrNodeType = /^[238]$/,
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+ ruseDefault = /^(?:checked|selected)$/i;
+
+// jQuery.attrFn
+migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
+
+jQuery.attr = function( elem, name, value, pass ) {
+ var lowerName = name.toLowerCase(),
+ nType = elem && elem.nodeType;
+
+ if ( pass ) {
+ // Since pass is used internally, we only warn for new jQuery
+ // versions where there isn't a pass arg in the formal params
+ if ( oldAttr.length < 4 ) {
+ migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
+ }
+ if ( elem && !rnoAttrNodeType.test( nType ) &&
+ (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
+ return jQuery( elem )[ name ]( value );
+ }
+ }
+
+ // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
+ // for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
+ if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
+ migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
+ }
+
+ // Restore boolHook for boolean property/attribute synchronization
+ if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
+ jQuery.attrHooks[ lowerName ] = {
+ get: function( elem, name ) {
+ // Align boolean attributes with corresponding properties
+ // Fall back to attribute presence where some booleans are not supported
+ var attrNode,
+ property = jQuery.prop( elem, name );
+ return property === true || typeof property !== "boolean" &&
+ ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
+
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ var propName;
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ // value is true since we know at this point it's type boolean and not false
+ // Set boolean attributes to the same name and set the DOM property
+ propName = jQuery.propFix[ name ] || name;
+ if ( propName in elem ) {
+ // Only set the IDL specifically if it already exists on the element
+ elem[ propName ] = true;
+ }
+
+ elem.setAttribute( name, name.toLowerCase() );
+ }
+ return name;
+ }
+ };
+
+ // Warn only for attributes that can remain distinct from their properties post-1.9
+ if ( ruseDefault.test( lowerName ) ) {
+ migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
+ }
+ }
+
+ return oldAttr.call( jQuery, elem, name, value );
+};
+
+// attrHooks: value
+jQuery.attrHooks.value = {
+ get: function( elem, name ) {
+ var nodeName = ( elem.nodeName || "" ).toLowerCase();
+ if ( nodeName === "button" ) {
+ return valueAttrGet.apply( this, arguments );
+ }
+ if ( nodeName !== "input" && nodeName !== "option" ) {
+ migrateWarn("jQuery.fn.attr('value') no longer gets properties");
+ }
+ return name in elem ?
+ elem.value :
+ null;
+ },
+ set: function( elem, value ) {
+ var nodeName = ( elem.nodeName || "" ).toLowerCase();
+ if ( nodeName === "button" ) {
+ return valueAttrSet.apply( this, arguments );
+ }
+ if ( nodeName !== "input" && nodeName !== "option" ) {
+ migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+};
+
+
+var matched, browser,
+ oldInit = jQuery.fn.init,
+ oldParseJSON = jQuery.parseJSON,
+ // Note: XSS check is done below after string is trimmed
+ rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
+
+// $(html) "looks like html" rule change
+jQuery.fn.init = function( selector, context, rootjQuery ) {
+ var match;
+
+ if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
+ (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
+ // This is an HTML string according to the "old" rules; is it still?
+ if ( selector.charAt( 0 ) !== "<" ) {
+ migrateWarn("$(html) HTML strings must start with '<' character");
+ }
+ if ( match[ 3 ] ) {
+ migrateWarn("$(html) HTML text after last tag is ignored");
+ }
+ // Consistently reject any HTML-like string starting with a hash (#9521)
+ // Note that this may break jQuery 1.6.x code that otherwise would work.
+ if ( match[ 0 ].charAt( 0 ) === "#" ) {
+ migrateWarn("HTML string cannot start with a '#' character");
+ jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
+ }
+ // Now process using loose rules; let pre-1.8 play too
+ if ( context && context.context ) {
+ // jQuery object as context; parseHTML expects a DOM object
+ context = context.context;
+ }
+ if ( jQuery.parseHTML ) {
+ return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),
+ context, rootjQuery );
+ }
+ }
+ return oldInit.apply( this, arguments );
+};
+jQuery.fn.init.prototype = jQuery.fn;
+
+// Let $.parseJSON(falsy_value) return null
+jQuery.parseJSON = function( json ) {
+ if ( !json && json !== null ) {
+ migrateWarn("jQuery.parseJSON requires a valid JSON string");
+ return null;
+ }
+ return oldParseJSON.apply( this, arguments );
+};
+
+jQuery.uaMatch = function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+ /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+ [];
+
+ return {
+ browser: match[ 1 ] || "",
+ version: match[ 2 ] || "0"
+ };
+};
+
+// Don't clobber any existing jQuery.browser in case it's different
+if ( !jQuery.browser ) {
+ matched = jQuery.uaMatch( navigator.userAgent );
+ browser = {};
+
+ if ( matched.browser ) {
+ browser[ matched.browser ] = true;
+ browser.version = matched.version;
+ }
+
+ // Chrome is Webkit, but Webkit is also Safari.
+ if ( browser.chrome ) {
+ browser.webkit = true;
+ } else if ( browser.webkit ) {
+ browser.safari = true;
+ }
+
+ jQuery.browser = browser;
+}
+
+// Warn if the code tries to get jQuery.browser
+migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
+
+jQuery.sub = function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+ jQuery.extend( true, jQuerySub, this );
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ migrateWarn( "jQuery.sub() is deprecated" );
+ return jQuerySub;
+};
+
+
+// Ensure that $.ajax gets the new parseJSON defined in core.js
+jQuery.ajaxSetup({
+ converters: {
+ "text json": jQuery.parseJSON
+ }
+});
+
+
+var oldFnData = jQuery.fn.data;
+
+jQuery.fn.data = function( name ) {
+ var ret, evt,
+ elem = this[0];
+
+ // Handles 1.7 which has this behavior and 1.8 which doesn't
+ if ( elem && name === "events" && arguments.length === 1 ) {
+ ret = jQuery.data( elem, name );
+ evt = jQuery._data( elem, name );
+ if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
+ migrateWarn("Use of jQuery.fn.data('events') is deprecated");
+ return evt;
+ }
+ }
+ return oldFnData.apply( this, arguments );
+};
+
+
+var rscriptType = /\/(java|ecma)script/i,
+ oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
+
+jQuery.fn.andSelf = function() {
+ migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
+ return oldSelf.apply( this, arguments );
+};
+
+// Since jQuery.clean is used internally on older versions, we only shim if it's missing
+if ( !jQuery.clean ) {
+ jQuery.clean = function( elems, context, fragment, scripts ) {
+ // Set context per 1.8 logic
+ context = context || document;
+ context = !context.nodeType && context[0] || context;
+ context = context.ownerDocument || context;
+
+ migrateWarn("jQuery.clean() is deprecated");
+
+ var i, elem, handleScript, jsTags,
+ ret = [];
+
+ jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
+
+ // Complex logic lifted directly from jQuery 1.8
+ if ( fragment ) {
+ // Special handling of each script element
+ handleScript = function( elem ) {
+ // Check if we consider it executable
+ if ( !elem.type || rscriptType.test( elem.type ) ) {
+ // Detach the script and store it in the scripts array (if provided) or the fragment
+ // Return truthy to indicate that it has been handled
+ return scripts ?
+ scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
+ fragment.appendChild( elem );
+ }
+ };
+
+ for ( i = 0; (elem = ret[i]) != null; i++ ) {
+ // Check if we're done after handling an executable script
+ if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
+ // Append to fragment and handle embedded scripts
+ fragment.appendChild( elem );
+ if ( typeof elem.getElementsByTagName !== "undefined" ) {
+ // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
+ jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
+
+ // Splice the scripts into ret after their former ancestor and advance our index beyond them
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+ i += jsTags.length;
+ }
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var eventAdd = jQuery.event.add,
+ eventRemove = jQuery.event.remove,
+ eventTrigger = jQuery.event.trigger,
+ oldToggle = jQuery.fn.toggle,
+ oldLive = jQuery.fn.live,
+ oldDie = jQuery.fn.die,
+ ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
+ rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
+ rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
+ hoverHack = function( events ) {
+ if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
+ return events;
+ }
+ if ( rhoverHack.test( events ) ) {
+ migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
+ }
+ return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
+ };
+
+// Event props removed in 1.9, put them back if needed; no practical way to warn them
+if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
+ jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
+}
+
+// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
+if ( jQuery.event.dispatch ) {
+ migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
+}
+
+// Support for 'hover' pseudo-event and ajax event warnings
+jQuery.event.add = function( elem, types, handler, data, selector ){
+ if ( elem !== document && rajaxEvent.test( types ) ) {
+ migrateWarn( "AJAX events should be attached to document: " + types );
+ }
+ eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
+};
+jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
+ eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
+};
+
+jQuery.fn.error = function() {
+ var args = Array.prototype.slice.call( arguments, 0);
+ migrateWarn("jQuery.fn.error() is deprecated");
+ args.splice( 0, 0, "error" );
+ if ( arguments.length ) {
+ return this.bind.apply( this, args );
+ }
+ // error event should not bubble to window, although it does pre-1.7
+ this.triggerHandler.apply( this, args );
+ return this;
+};
+
+jQuery.fn.toggle = function( fn, fn2 ) {
+
+ // Don't mess with animation or css toggles
+ if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
+ return oldToggle.apply( this, arguments );
+ }
+ migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
+
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ guid = fn.guid || jQuery.guid++,
+ i = 0,
+ toggler = function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ };
+
+ // link all the functions, so any of them can unbind this click handler
+ toggler.guid = guid;
+ while ( i < args.length ) {
+ args[ i++ ].guid = guid;
+ }
+
+ return this.click( toggler );
+};
+
+jQuery.fn.live = function( types, data, fn ) {
+ migrateWarn("jQuery.fn.live() is deprecated");
+ if ( oldLive ) {
+ return oldLive.apply( this, arguments );
+ }
+ jQuery( this.context ).on( types, this.selector, data, fn );
+ return this;
+};
+
+jQuery.fn.die = function( types, fn ) {
+ migrateWarn("jQuery.fn.die() is deprecated");
+ if ( oldDie ) {
+ return oldDie.apply( this, arguments );
+ }
+ jQuery( this.context ).off( types, this.selector || "**", fn );
+ return this;
+};
+
+// Turn global events into document-triggered events
+jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
+ if ( !elem && !rajaxEvent.test( event ) ) {
+ migrateWarn( "Global events are undocumented and deprecated" );
+ }
+ return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
+};
+jQuery.each( ajaxEvents.split("|"),
+ function( _, name ) {
+ jQuery.event.special[ name ] = {
+ setup: function() {
+ var elem = this;
+
+ // The document needs no shimming; must be !== for oldIE
+ if ( elem !== document ) {
+ jQuery.event.add( document, name + "." + jQuery.guid, function() {
+ jQuery.event.trigger( name, null, elem, true );
+ });
+ jQuery._data( this, name, jQuery.guid++ );
+ }
+ return false;
+ },
+ teardown: function() {
+ if ( this !== document ) {
+ jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
+ }
+ return false;
+ }
+ };
+ }
+);
+
+
+})( jQuery, window );
diff --git a/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.js b/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.js
new file mode 100644
index 0000000..16ce41d
--- /dev/null
+++ b/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.js
@@ -0,0 +1,180 @@
+/*!
+ * jQuery UI Touch Punch 0.2.3
+ *
+ * Copyright 2011–2014, Dave Furfero
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ * jquery.ui.mouse.js
+ */
+(function ($) {
+
+ // Detect touch support
+ $.support.touch = 'ontouchend' in document;
+
+ // Ignore browsers without touch support
+ if (!$.support.touch) {
+ return;
+ }
+
+ var mouseProto = $.ui.mouse.prototype,
+ _mouseInit = mouseProto._mouseInit,
+ _mouseDestroy = mouseProto._mouseDestroy,
+ touchHandled;
+
+ /**
+ * Simulate a mouse event based on a corresponding touch event
+ * @param {Object} event A touch event
+ * @param {String} simulatedType The corresponding mouse event
+ */
+ function simulateMouseEvent (event, simulatedType) {
+
+ // Ignore multi-touch events
+ if (event.originalEvent.touches.length > 1) {
+ return;
+ }
+
+ event.preventDefault();
+
+ var touch = event.originalEvent.changedTouches[0],
+ simulatedEvent = document.createEvent('MouseEvents');
+
+ // Initialize the simulated mouse event using the touch event's coordinates
+ simulatedEvent.initMouseEvent(
+ simulatedType, // type
+ true, // bubbles
+ true, // cancelable
+ window, // view
+ 1, // detail
+ touch.screenX, // screenX
+ touch.screenY, // screenY
+ touch.clientX, // clientX
+ touch.clientY, // clientY
+ false, // ctrlKey
+ false, // altKey
+ false, // shiftKey
+ false, // metaKey
+ 0, // button
+ null // relatedTarget
+ );
+
+ // Dispatch the simulated event to the target element
+ event.target.dispatchEvent(simulatedEvent);
+ }
+
+ /**
+ * Handle the jQuery UI widget's touchstart events
+ * @param {Object} event The widget element's touchstart event
+ */
+ mouseProto._touchStart = function (event) {
+
+ var self = this;
+
+ // Ignore the event if another widget is already being handled
+ if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
+ return;
+ }
+
+ // Set the flag to prevent other widgets from inheriting the touch event
+ touchHandled = true;
+
+ // Track movement to determine if interaction was a click
+ self._touchMoved = false;
+
+ // Simulate the mouseover event
+ simulateMouseEvent(event, 'mouseover');
+
+ // Simulate the mousemove event
+ simulateMouseEvent(event, 'mousemove');
+
+ // Simulate the mousedown event
+ simulateMouseEvent(event, 'mousedown');
+ };
+
+ /**
+ * Handle the jQuery UI widget's touchmove events
+ * @param {Object} event The document's touchmove event
+ */
+ mouseProto._touchMove = function (event) {
+
+ // Ignore event if not handled
+ if (!touchHandled) {
+ return;
+ }
+
+ // Interaction was not a click
+ this._touchMoved = true;
+
+ // Simulate the mousemove event
+ simulateMouseEvent(event, 'mousemove');
+ };
+
+ /**
+ * Handle the jQuery UI widget's touchend events
+ * @param {Object} event The document's touchend event
+ */
+ mouseProto._touchEnd = function (event) {
+
+ // Ignore event if not handled
+ if (!touchHandled) {
+ return;
+ }
+
+ // Simulate the mouseup event
+ simulateMouseEvent(event, 'mouseup');
+
+ // Simulate the mouseout event
+ simulateMouseEvent(event, 'mouseout');
+
+ // If the touch interaction did not move, it should trigger a click
+ if (!this._touchMoved) {
+
+ // Simulate the click event
+ simulateMouseEvent(event, 'click');
+ }
+
+ // Unset the flag to allow other widgets to inherit the touch event
+ touchHandled = false;
+ };
+
+ /**
+ * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
+ * This method extends the widget with bound touch event handlers that
+ * translate touch events to mouse events and pass them to the widget's
+ * original mouse event handling methods.
+ */
+ mouseProto._mouseInit = function () {
+
+ var self = this;
+
+ // Delegate the touch handlers to the widget's element
+ self.element.bind({
+ touchstart: $.proxy(self, '_touchStart'),
+ touchmove: $.proxy(self, '_touchMove'),
+ touchend: $.proxy(self, '_touchEnd')
+ });
+
+ // Call the original $.ui.mouse init method
+ _mouseInit.call(self);
+ };
+
+ /**
+ * Remove the touch event handlers
+ */
+ mouseProto._mouseDestroy = function () {
+
+ var self = this;
+
+ // Delegate the touch handlers to the widget's element
+ self.element.unbind({
+ touchstart: $.proxy(self, '_touchStart'),
+ touchmove: $.proxy(self, '_touchMove'),
+ touchend: $.proxy(self, '_touchEnd')
+ });
+
+ // Call the original $.ui.mouse destroy method
+ _mouseDestroy.call(self);
+ };
+
+})(jQuery); \ No newline at end of file
diff --git a/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.min.js b/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.min.js
new file mode 100644
index 0000000..31272ce
--- /dev/null
+++ b/javascript/jquery/plugins/touch-punch/jquery.ui.touch-punch.min.js
@@ -0,0 +1,11 @@
+/*!
+ * jQuery UI Touch Punch 0.2.3
+ *
+ * Copyright 2011–2014, Dave Furfero
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ * jquery.ui.mouse.js
+ */
+!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); \ No newline at end of file