=0;N--){var L=E.snapElements[N].left,J=L+E.snapElements[N].width,I=E.snapElements[N].top,S=I+E.snapElements[N].height;if(!((L-Q=N&&L<=J)||(K>=N&&K<=J)||(LJ))&&((D>=F&&D<=B)||(C>=F&&C<=B)||(DB));break;default:return false;break}};A.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(E,G){var B=A.ui.ddmanager.droppables[E.options.scope];var F=G?G.type:null;var H=(E.currentItem||E.element).find(":data(droppable)").andSelf();droppablesLoop:for(var D=0;D').css({position:C.css("position"),width:C.outerWidth(),height:C.outerHeight(),top:C.css("top"),left:C.css("left")}));var K=this.element;this.element=this.element.parent();this.element.data("resizable",this);this.element.css({marginLeft:K.css("marginLeft"),marginTop:K.css("marginTop"),marginRight:K.css("marginRight"),marginBottom:K.css("marginBottom")});K.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});if(B.browser.safari&&O.preventDefault){K.css("resize","none")}O.proportionallyResize=K.css({position:"static",zoom:1,display:"block"});this.element.css({margin:K.css("margin")});this._proportionallyResize()}if(!O.handles){O.handles=!B(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}}if(O.handles.constructor==String){O.zIndex=O.zIndex||1000;if(O.handles=="all"){O.handles="n,e,s,w,se,sw,ne,nw"}var P=O.handles.split(",");O.handles={};var H={handle:"position: absolute; display: none; overflow:hidden;",n:"top: 0pt; width:100%;",e:"right: 0pt; height:100%;",s:"bottom: 0pt; width:100%;",w:"left: 0pt; height:100%;",se:"bottom: 0pt; right: 0px;",sw:"bottom: 0pt; left: 0px;",ne:"top: 0pt; right: 0px;",nw:"top: 0pt; left: 0px;"};for(var S=0;S'].join("")).css(L);O.handles[T]=".ui-resizable-"+T;this.element.append(F.css(D?U:{}).css(O.knobHandles?E:{}).addClass(O.knobHandles?"ui-resizable-knob-handle":"").addClass(O.knobHandles))}if(O.knobHandles){this.element.addClass("ui-resizable-knob").css(!B.ui.css("ui-resizable-knob")?{}:{})}}this._renderAxis=function(Z){Z=Z||this.element;for(var W in O.handles){if(O.handles[W].constructor==String){O.handles[W]=B(O.handles[W],this.element).show()}if(O.transparent){O.handles[W].css({opacity:0})}if(this.element.is(".ui-wrapper")&&O._nodeName.match(/textarea|input|select|button/i)){var X=B(O.handles[W],this.element),Y=0;Y=/sw|ne|nw|se|n|s/.test(W)?X.outerHeight():X.outerWidth();var V=["padding",/ne|nw|n/.test(W)?"Top":/se|sw|s/.test(W)?"Bottom":/^e$/.test(W)?"Right":"Left"].join("");if(!O.transparent){Z.css(V,Y)}this._proportionallyResize()}if(!B(O.handles[W]).length){continue}}};this._renderAxis(this.element);O._handles=B(".ui-resizable-handle",N.element);if(O.disableSelection){O._handles.disableSelection()}O._handles.mouseover(function(){if(!O.resizing){if(this.className){var V=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}N.axis=O.axis=V&&V[1]?V[1]:"se"}});if(O.autoHide){O._handles.hide();B(N.element).addClass("ui-resizable-autohide").hover(function(){B(this).removeClass("ui-resizable-autohide");O._handles.show()},function(){if(!O.resizing){B(this).addClass("ui-resizable-autohide");O._handles.hide()}})}this._mouseInit()},destroy:function(){var E=this.element,D=E.children(".ui-resizable").get(0);this._mouseDestroy();var C=function(F){B(F).removeClass("ui-resizable ui-resizable-disabled").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};C(E);if(E.is(".ui-wrapper")&&D){E.parent().append(B(D).css({position:E.css("position"),width:E.outerWidth(),height:E.outerHeight(),top:E.css("top"),left:E.css("left")})).end().remove();C(D)}},_mouseCapture:function(D){if(this.options.disabled){return false}var E=false;for(var C in this.options.handles){if(B(this.options.handles[C])[0]==D.target){E=true}}if(!E){return false}return true},_mouseStart:function(D){var E=this.options,C=this.element.position(),F=this.element,I=B.browser.msie&&B.browser.version<7;E.resizing=true;E.documentScroll={top:B(document).scrollTop(),left:B(document).scrollLeft()};if(F.is(".ui-draggable")||(/absolute/).test(F.css("position"))){var K=B.browser.msie&&!E.containment&&(/absolute/).test(F.css("position"))&&!(/relative/).test(F.parent().css("position"));var L=K?this.documentScroll.top:0,H=K?this.documentScroll.left:0;F.css({position:"absolute",top:(C.top+L),left:(C.left+H)})}if(B.browser.opera&&(/relative/).test(F.css("position"))){F.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var M=A(this.helper.css("left")),G=A(this.helper.css("top"));if(E.containment){M+=B(E.containment).scrollLeft()||0;G+=B(E.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:M,top:G};this.size=E.helper||I?{width:F.outerWidth(),height:F.outerHeight()}:{width:F.width(),height:F.height()};this.originalSize=E.helper||I?{width:F.outerWidth(),height:F.outerHeight()}:{width:F.width(),height:F.height()};this.originalPosition={left:M,top:G};this.sizeDiff={width:F.outerWidth()-F.width(),height:F.outerHeight()-F.height()};this.originalMousePosition={left:D.pageX,top:D.pageY};E.aspectRatio=(typeof E.aspectRatio=="number")?E.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);if(E.preserveCursor){var J=B(".ui-resizable-"+this.axis).css("cursor");B("body").css("cursor",J=="auto"?this.axis+"-resize":J)}this._propagate("start",D);return true},_mouseDrag:function(C){var F=this.helper,E=this.options,K={},N=this,H=this.originalMousePosition,L=this.axis;var O=(C.pageX-H.left)||0,M=(C.pageY-H.top)||0;var G=this._change[L];if(!G){return false}var J=G.apply(this,[C,O,M]),I=B.browser.msie&&B.browser.version<7,D=this.sizeDiff;if(E._aspectRatio||C.shiftKey){J=this._updateRatio(J,C)}J=this._respectSize(J,C);this._propagate("resize",C);F.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!E.helper&&E.proportionallyResize){this._proportionallyResize()}this._updateCache(J);this.element.triggerHandler("resize",[C,this.ui()],this.options["resize"]);return false},_mouseStop:function(F){this.options.resizing=false;var G=this.options,K=this;if(G.helper){var E=G.proportionallyResize,C=E&&(/textarea/i).test(E.get(0).nodeName),D=C&&B.ui.hasScroll(E.get(0),"left")?0:K.sizeDiff.height,I=C?0:K.sizeDiff.width;var L={width:(K.size.width-I),height:(K.size.height-D)},H=(parseInt(K.element.css("left"),10)+(K.position.left-K.originalPosition.left))||null,J=(parseInt(K.element.css("top"),10)+(K.position.top-K.originalPosition.top))||null;if(!G.animate){this.element.css(B.extend(L,{top:J,left:H}))}if(G.helper&&!G.animate){this._proportionallyResize()}}if(G.preserveCursor){B("body").css("cursor","auto")}this._propagate("stop",F);if(G.helper){this.helper.remove()}return false},_updateCache:function(C){var D=this.options;this.offset=this.helper.offset();if(C.left){this.position.left=C.left}if(C.top){this.position.top=C.top}if(C.height){this.size.height=C.height}if(C.width){this.size.width=C.width}},_updateRatio:function(F,E){var G=this.options,H=this.position,D=this.size,C=this.axis;if(F.height){F.width=(D.height*G.aspectRatio)}else{if(F.width){F.height=(D.width/G.aspectRatio)}}if(C=="sw"){F.left=H.left+(D.width-F.width);F.top=null}if(C=="nw"){F.top=H.top+(D.height-F.height);F.left=H.left+(D.width-F.width)}return F},_respectSize:function(J,E){var H=this.helper,G=this.options,O=G._aspectRatio||E.shiftKey,N=this.axis,Q=J.width&&G.maxWidth&&G.maxWidthJ.width,P=J.height&&G.minHeight&&G.minHeight>J.height;if(F){J.width=G.minWidth}if(P){J.height=G.minHeight}if(Q){J.width=G.maxWidth}if(K){J.height=G.maxHeight}var D=this.originalPosition.left+this.originalSize.width,M=this.position.top+this.size.height;var I=/sw|nw|w/.test(N),C=/nw|ne|n/.test(N);if(F&&I){J.left=D-G.minWidth}if(Q&&I){J.left=D-G.maxWidth}if(P&&C){J.top=M-G.minHeight}if(K&&C){J.top=M-G.maxHeight}var L=!J.width&&!J.height;if(L&&!J.left&&J.top){J.top=null}else{if(L&&!J.top&&J.left){J.left=null}}return J},_proportionallyResize:function(){var G=this.options;if(!G.proportionallyResize){return }var E=G.proportionallyResize,D=this.helper||this.element;if(!G.borderDif){var C=[E.css("borderTopWidth"),E.css("borderRightWidth"),E.css("borderBottomWidth"),E.css("borderLeftWidth")],F=[E.css("paddingTop"),E.css("paddingRight"),E.css("paddingBottom"),E.css("paddingLeft")];G.borderDif=B.map(C,function(H,J){var I=parseInt(H,10)||0,K=parseInt(F[J],10)||0;return I+K})}E.css({height:(D.height()-G.borderDif[0]-G.borderDif[2])+"px",width:(D.width()-G.borderDif[1]-G.borderDif[3])+"px"})},_renderProxy:function(){var D=this.element,G=this.options;this.elementOffset=D.offset();if(G.helper){this.helper=this.helper||B('
');var C=B.browser.msie&&B.browser.version<7,E=(C?1:0),F=(C?2:-1);this.helper.addClass(G.helper).css({width:D.outerWidth()+F,height:D.outerHeight()+F,position:"absolute",left:this.elementOffset.left-E+"px",top:this.elementOffset.top-E+"px",zIndex:++G.zIndex});this.helper.appendTo("body");if(G.disableSelection){this.helper.disableSelection()}}else{this.helper=D}},_change:{e:function(E,D,C){return{width:this.originalSize.width+D}},w:function(F,D,C){var H=this.options,E=this.originalSize,G=this.originalPosition;return{left:G.left+D,width:E.width-D}},n:function(F,D,C){var H=this.options,E=this.originalSize,G=this.originalPosition;return{top:G.top+C,height:E.height-C}},s:function(E,D,C){return{height:this.originalSize.height+C}},se:function(E,D,C){return B.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[E,D,C]))},sw:function(E,D,C){return B.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[E,D,C]))},ne:function(E,D,C){return B.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[E,D,C]))},nw:function(E,D,C){return B.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[E,D,C]))}},_propagate:function(D,C){B.ui.plugin.call(this,D,[C,this.ui()]);if(D!="resize"){this.element.triggerHandler(["resize",D].join(""),[C,this.ui()],this.options[D])}},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,options:this.options,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));B.extend(B.ui.resizable,{version:"1.6",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input",containment:false,disableSelection:true,distance:1,delay:0,ghost:false,grid:false,knobHandles:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,preserveCursor:true,preventDefault:true,proportionallyResize:false,transparent:false}});B.ui.plugin.add("resizable","alsoResize",{start:function(D,E){var G=E.options,C=B(this).data("resizable"),F=function(H){B(H).each(function(){B(this).data("resizable-alsoresize",{width:parseInt(B(this).width(),10),height:parseInt(B(this).height(),10),left:parseInt(B(this).css("left"),10),top:parseInt(B(this).css("top"),10)})})};if(typeof (G.alsoResize)=="object"&&!G.alsoResize.parentNode){if(G.alsoResize.length){G.alsoResize=G.alsoResize[0];F(G.alsoResize)}else{B.each(G.alsoResize,function(H,I){F(H)})}}else{F(G.alsoResize)}},resize:function(E,G){var H=G.options,D=B(this).data("resizable"),F=D.originalSize,J=D.originalPosition;var I={height:(D.size.height-F.height)||0,width:(D.size.width-F.width)||0,top:(D.position.top-J.top)||0,left:(D.position.left-J.left)||0},C=function(K,L){B(K).each(function(){var O=B(this).data("resizable-alsoresize"),N={},M=L&&L.length?L:["width","height","top","left"];B.each(M||["width","height","top","left"],function(P,R){var Q=(O[R]||0)+(I[R]||0);if(Q&&Q>=0){N[R]=Q||null}});B(this).css(N)})};if(typeof (H.alsoResize)=="object"&&!H.alsoResize.parentNode){B.each(H.alsoResize,function(K,L){C(K,L)})}else{C(H.alsoResize)}},stop:function(C,D){B(this).removeData("resizable-alsoresize-start")}});B.ui.plugin.add("resizable","animate",{stop:function(G,L){var H=L.options,M=B(this).data("resizable");var F=H.proportionallyResize,C=F&&(/textarea/i).test(F.get(0).nodeName),D=C&&B.ui.hasScroll(F.get(0),"left")?0:M.sizeDiff.height,J=C?0:M.sizeDiff.width;var E={width:(M.size.width-J),height:(M.size.height-D)},I=(parseInt(M.element.css("left"),10)+(M.position.left-M.originalPosition.left))||null,K=(parseInt(M.element.css("top"),10)+(M.position.top-M.originalPosition.top))||null;M.element.animate(B.extend(E,K&&I?{top:K,left:I}:{}),{duration:H.animateDuration,easing:H.animateEasing,step:function(){var N={width:parseInt(M.element.css("width"),10),height:parseInt(M.element.css("height"),10),top:parseInt(M.element.css("top"),10),left:parseInt(M.element.css("left"),10)};if(F){F.css({width:N.width,height:N.height})}M._updateCache(N);M._propagate("animate",G)}})}});B.ui.plugin.add("resizable","containment",{start:function(D,N){var H=N.options,P=B(this).data("resizable"),J=P.element;var E=H.containment,I=(E instanceof B)?E.get(0):(/parent/.test(E))?J.parent().get(0):E;if(!I){return }P.containerElement=B(I);if(/document/.test(E)||E==document){P.containerOffset={left:0,top:0};P.containerPosition={left:0,top:0};P.parentData={element:B(document),left:0,top:0,width:B(document).width(),height:B(document).height()||document.body.parentNode.scrollHeight}}else{var L=B(I),G=[];B(["Top","Right","Left","Bottom"]).each(function(R,Q){G[R]=A(L.css("padding"+Q))});P.containerOffset=L.offset();P.containerPosition=L.position();P.containerSize={height:(L.innerHeight()-G[3]),width:(L.innerWidth()-G[1])};var M=P.containerOffset,C=P.containerSize.height,K=P.containerSize.width,F=(B.ui.hasScroll(I,"left")?I.scrollWidth:K),O=(B.ui.hasScroll(I)?I.scrollHeight:C);P.parentData={element:I,left:M.left,top:M.top,width:F,height:O}}},resize:function(E,N){var G=N.options,Q=B(this).data("resizable"),D=Q.containerSize,M=Q.containerOffset,K=Q.size,L=Q.position,O=G._aspectRatio||E.shiftKey,C={top:0,left:0},F=Q.containerElement;if(F[0]!=document&&(/static/).test(F.css("position"))){C=M}if(L.left<(G.helper?M.left:0)){Q.size.width=Q.size.width+(G.helper?(Q.position.left-M.left):(Q.position.left-C.left));if(O){Q.size.height=Q.size.width/G.aspectRatio}Q.position.left=G.helper?M.left:0}if(L.top<(G.helper?M.top:0)){Q.size.height=Q.size.height+(G.helper?(Q.position.top-M.top):Q.position.top);if(O){Q.size.width=Q.size.height*G.aspectRatio}Q.position.top=G.helper?M.top:0}Q.offset.left=Q.parentData.left+Q.position.left;Q.offset.top=Q.parentData.top+Q.position.top;var J=Math.abs((G.helper?Q.offset.left-C.left:(Q.offset.left-C.left))+Q.sizeDiff.width),P=Math.abs((G.helper?Q.offset.top-C.top:(Q.offset.top-M.top))+Q.sizeDiff.height);var I=Q.containerElement.get(0)==Q.element.parent().get(0),H=/relative|absolute/.test(Q.containerElement.css("position"));if(I&&H){J-=Q.parentData.left}if(J+Q.size.width>=Q.parentData.width){Q.size.width=Q.parentData.width-J;if(O){Q.size.height=Q.size.width/G.aspectRatio}}if(P+Q.size.height>=Q.parentData.height){Q.size.height=Q.parentData.height-P;if(O){Q.size.width=Q.size.height*G.aspectRatio}}},stop:function(D,K){var E=K.options,M=B(this).data("resizable"),I=M.position,J=M.containerOffset,C=M.containerPosition,F=M.containerElement;var G=B(M.helper),N=G.offset(),L=G.outerWidth()-M.sizeDiff.width,H=G.outerHeight()-M.sizeDiff.height;if(E.helper&&!E.animate&&(/relative/).test(F.css("position"))){B(this).css({left:N.left-C.left-J.left,width:L,height:H})}if(E.helper&&!E.animate&&(/static/).test(F.css("position"))){B(this).css({left:N.left-C.left-J.left,width:L,height:H})}}});B.ui.plugin.add("resizable","ghost",{start:function(E,F){var G=F.options,C=B(this).data("resizable"),H=G.proportionallyResize,D=C.size;if(!H){C.ghost=C.element.clone()}else{C.ghost=H.clone()}C.ghost.css({opacity:0.25,display:"block",position:"relative",height:D.height,width:D.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof G.ghost=="string"?G.ghost:"");C.ghost.appendTo(C.helper)},resize:function(D,E){var F=E.options,C=B(this).data("resizable"),G=F.proportionallyResize;if(C.ghost){C.ghost.css({position:"relative",height:C.size.height,width:C.size.width})}},stop:function(D,E){var F=E.options,C=B(this).data("resizable"),G=F.proportionallyResize;if(C.ghost&&C.helper){C.helper.get(0).removeChild(C.ghost.get(0))}}});B.ui.plugin.add("resizable","grid",{resize:function(C,K){var F=K.options,M=B(this).data("resizable"),I=M.size,G=M.originalSize,H=M.originalPosition,L=M.axis,J=F._aspectRatio||C.shiftKey;F.grid=typeof F.grid=="number"?[F.grid,F.grid]:F.grid;var E=Math.round((I.width-G.width)/(F.grid[0]||1))*(F.grid[0]||1),D=Math.round((I.height-G.height)/(F.grid[1]||1))*(F.grid[1]||1);if(/^(se|s|e)$/.test(L)){M.size.width=G.width+E;M.size.height=G.height+D}else{if(/^(ne)$/.test(L)){M.size.width=G.width+E;M.size.height=G.height+D;M.position.top=H.top-D}else{if(/^(sw)$/.test(L)){M.size.width=G.width+E;M.size.height=G.height+D;M.position.left=H.left-E}else{M.size.width=G.width+E;M.size.height=G.height+D;M.position.top=H.top-D;M.position.left=H.left-E}}}}});var A=function(C){return parseInt(C,10)||0}})(jQuery);/*
+ * jQuery UI Selectable 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * ui.core.js
+ */
(function(A){A.widget("ui.selectable",A.extend({},A.ui.mouse,{_init:function(){var B=this;this.element.addClass("ui-selectable");this.dragged=false;var C;this.refresh=function(){C=A(B.options.filter,B.element[0]);C.each(function(){var D=A(this);var E=D.offset();A.data(this,"selectable-item",{element:this,$element:D,left:E.left,top:E.top,right:E.left+D.width(),bottom:E.top+D.height(),startselected:false,selected:D.hasClass("ui-selected"),selecting:D.hasClass("ui-selecting"),unselecting:D.hasClass("ui-unselecting")})})};this.refresh();this.selectees=C.addClass("ui-selectee");this._mouseInit();this.helper=A(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(E){var C=this;this.opos=[E.pageX,E.pageY];if(this.options.disabled){return }var D=this.options;this.selectees=A(D.filter,this.element[0]);this.element.triggerHandler("selectablestart",[E,{"selectable":this.element[0],"options":D}],D.start);A("body").append(this.helper);this.helper.css({"z-index":100,"position":"absolute","left":E.clientX,"top":E.clientY,"width":0,"height":0});if(D.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var F=A.data(this,"selectable-item");F.startselected=true;if(!E.metaKey){F.$element.removeClass("ui-selected");F.selected=false;F.$element.addClass("ui-unselecting");F.unselecting=true;C.element.triggerHandler("selectableunselecting",[E,{selectable:C.element[0],unselecting:F.element,options:D}],D.unselecting)}});var B=false;A(E.target).parents().andSelf().each(function(){if(A.data(this,"selectable-item")){B=true}});return this.options.keyboard?!B:true},_mouseDrag:function(I){var C=this;this.dragged=true;if(this.options.disabled){return }var E=this.options;var D=this.opos[0],H=this.opos[1],B=I.pageX,G=I.pageY;if(D>B){var F=B;B=D;D=F}if(H>G){var F=G;G=H;H=F}this.helper.css({left:D,top:H,width:B-D,height:G-H});this.selectees.each(function(){var J=A.data(this,"selectable-item");if(!J||J.element==C.element[0]){return }var K=false;if(E.tolerance=="touch"){K=(!(J.left>B||J.rightG||J.bottomD&&J.rightH&&J.bottom=0;B--){this.items[B].item.removeData("sortable-item")}},_mouseCapture:function(E,F){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(E);var D=null,C=this,B=A(E.target).parents().each(function(){if(A.data(this,"sortable-item")==C){D=A(this);return false}});if(A.data(E.target,"sortable-item")==C){D=A(E.target)}if(!D){return false}if(this.options.handle&&!F){var G=false;A(this.options.handle,D).find("*").andSelf().each(function(){if(this==E.target){G=true}});if(!G){return false}}this.currentItem=D;this._removeCurrentsFromItems();return true},_mouseStart:function(D,E,B){var F=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(D);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");A.extend(this.offset,{click:{left:D.pageX-this.offset.left,top:D.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});if(F.cursorAt){this._adjustOffsetFromHelper(F.cursorAt)}this.originalPosition=this._generatePosition(D);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(F.containment){this._setContainment()}this._propagate("start",D);if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!B){for(var C=this.containers.length-1;C>=0;C--){this.containers[C]._propagate("activate",D,this)}}if(A.ui.ddmanager){A.ui.ddmanager.current=this}if(A.ui.ddmanager&&!F.dropBehaviour){A.ui.ddmanager.prepareOffsets(this,D)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(D);return true},_mouseDrag:function(E){this.position=this._generatePosition(E);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}A.ui.plugin.call(this,"sort",[E,this._ui()]);this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}for(var C=this.items.length-1;C>=0;C--){var D=this.items[C],B=D.item[0],F=this._intersectsWithPointer(D);if(!F){continue}if(B!=this.currentItem[0]&&this.placeholder[F==1?"next":"prev"]()[0]!=B&&!A.ui.contains(this.placeholder[0],B)&&(this.options.type=="semi-dynamic"?!A.ui.contains(this.element[0],B):true)){this.direction=F==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(D)){this.options.sortIndicator.call(this,E,D)}else{break}this._propagate("change",E);break}}this._contactContainers(E);if(A.ui.ddmanager){A.ui.ddmanager.drag(this,E)}this._trigger("sort",E,this._ui());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(C,D){if(!C){return }if(A.ui.ddmanager&&!this.options.dropBehaviour){A.ui.ddmanager.drop(this,C)}if(this.options.revert){var B=this;var E=B.placeholder.offset();B.reverting=true;A(this.helper).animate({left:E.left-this.offset.parent.left-B.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:E.top-this.offset.parent.top-B.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){B._clear(C)})}else{this._clear(C,D)}return false},cancel:function(){if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var B=this.containers.length-1;B>=0;B--){this.containers[B]._propagate("deactivate",null,this);if(this.containers[B].containerCache.over){this.containers[B]._propagate("out",null,this);this.containers[B].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}A.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){A(this.domPosition.prev).after(this.currentItem)}else{A(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(D){var B=this._getItemsAsjQuery(D&&D.connected);var C=[];D=D||{};A(B).each(function(){var E=(A(D.item||this).attr(D.attribute||"id")||"").match(D.expression||(/(.+)[-=_](.+)/));if(E){C.push((D.key||E[1]+"[]")+"="+(D.key&&D.expression?E[1]:E[2]))}});return C.join("&")},toArray:function(D){var B=this._getItemsAsjQuery(D&&D.connected);var C=[];D=D||{};B.each(function(){C.push(A(D.item||this).attr(D.attribute||"id")||"")});return C},_intersectsWith:function(K){var D=this.positionAbs.left,C=D+this.helperProportions.width,J=this.positionAbs.top,I=J+this.helperProportions.height;var E=K.left,B=E+K.width,L=K.top,H=L+K.height;var M=this.offset.click.top,G=this.offset.click.left;var F=(J+M)>L&&(J+M)E&&(D+G)K[this.floating?"width":"height"])){return F}else{return(E0?"down":"up")},_getDragHorizontalDirection:function(){var B=this.positionAbs.left-this.lastPositionAbs.left;return B!=0&&(B>0?"right":"left")},refresh:function(B){this._refreshItems(B);this.refreshPositions()},_getItemsAsjQuery:function(G){var C=this;var B=[];var E=[];if(this.options.connectWith&&G){for(var F=this.options.connectWith.length-1;F>=0;F--){var I=A(this.options.connectWith[F]);for(var D=I.length-1;D>=0;D--){var H=A.data(I[D],"sortable");if(H&&H!=this&&!H.options.disabled){E.push([A.isFunction(H.options.items)?H.options.items.call(H.element):A(H.options.items,H.element).not(".ui-sortable-helper"),H])}}}}E.push([A.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):A(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var F=E.length-1;F>=0;F--){E[F][0].each(function(){B.push(this)})}return A(B)},_removeCurrentsFromItems:function(){var D=this.currentItem.find(":data(sortable-item)");for(var C=0;C=0;E--){var J=A(this.options.connectWith[E]);for(var D=J.length-1;D>=0;D--){var G=A.data(J[D],"sortable");if(G&&G!=this&&!G.options.disabled){F.push([A.isFunction(G.options.items)?G.options.items.call(G.element[0],B,{item:this.currentItem}):A(G.options.items,G.element),G]);this.containers.push(G)}}}}for(var E=F.length-1;E>=0;E--){var I=F[E][1];var C=F[E][0];for(var D=0,K=C.length;D=0;D--){var E=this.items[D];if(E.instance!=this.currentContainer&&this.currentContainer&&E.item[0]!=this.currentItem[0]){continue}var C=this.options.toleranceElement?A(this.options.toleranceElement,E.item):E.item;if(!B){if(this.options.accurateIntersection){E.width=C.outerWidth();E.height=C.outerHeight()}else{E.width=C[0].offsetWidth;E.height=C[0].offsetHeight}}var F=C.offset();E.left=F.left;E.top=F.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var D=this.containers.length-1;D>=0;D--){var F=this.containers[D].element.offset();this.containers[D].containerCache.left=F.left;this.containers[D].containerCache.top=F.top;this.containers[D].containerCache.width=this.containers[D].element.outerWidth();this.containers[D].containerCache.height=this.containers[D].element.outerHeight()}}},_createPlaceholder:function(D){var B=D||this,E=B.options;if(!E.placeholder||E.placeholder.constructor==String){var C=E.placeholder;E.placeholder={element:function(){var F=A(document.createElement(B.currentItem[0].nodeName)).addClass(C||B.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!C){F.style.visibility="hidden";document.body.appendChild(F);F.innerHTML=B.currentItem[0].innerHTML.replace(/name\=\"[^\"\']+\"/g,"").replace(/jQuery[0-9]+\=\"[^\"\']+\"/g,"");document.body.removeChild(F)}return F},update:function(F,G){if(C&&!E.forcePlaceholderSize){return }if(!G.height()){G.height(B.currentItem.innerHeight()-parseInt(B.currentItem.css("paddingTop")||0,10)-parseInt(B.currentItem.css("paddingBottom")||0,10))}if(!G.width()){G.width(B.currentItem.innerWidth()-parseInt(B.currentItem.css("paddingLeft")||0,10)-parseInt(B.currentItem.css("paddingRight")||0,10))}}}}B.placeholder=A(E.placeholder.element.call(B.element,B.currentItem));B.currentItem.after(B.placeholder);E.placeholder.update(B,B.placeholder)},_contactContainers:function(D){for(var C=this.containers.length-1;C>=0;C--){if(this._intersectsWith(this.containers[C].containerCache)){if(!this.containers[C].containerCache.over){if(this.currentContainer!=this.containers[C]){var H=10000;var G=null;var E=this.positionAbs[this.containers[C].floating?"left":"top"];for(var B=this.items.length-1;B>=0;B--){if(!A.ui.contains(this.containers[C].element[0],this.items[B].item[0])){continue}var F=this.items[B][this.containers[C].floating?"left":"top"];if(Math.abs(F-E)this.containment[2]){B.left=this.containment[2]-this.helperProportions.width}if(B.top+this.helperProportions.height>this.containment[3]){B.top=this.containment[3]-this.helperProportions.height}}if(G.grid){var F=this.originalPosition.top+Math.round((B.top-this.originalPosition.top)/G.grid[1])*G.grid[1];B.top=this.containment?(!(Fthis.containment[3])?F:(!(Fthis.containment[2])?E:(!(E=0;B--){if(A.ui.contains(this.containers[B].element[0],this.currentItem[0])){this.containers[B]._propagate("update",C,this,D);this.containers[B]._propagate("receive",C,this,D)}}}for(var B=this.containers.length-1;B>=0;B--){this.containers[B]._propagate("deactivate",C,this,D);if(this.containers[B].containerCache.over){this.containers[B]._propagate("out",C,this);this.containers[B].containerCache.over=0}}this.dragging=false;if(this.cancelHelperRemoval){this._propagate("beforeStop",C,null,D);this._propagate("stop",C,null,D);return false}this._propagate("beforeStop",C,null,D);this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.options.helper!="original"){this.helper.remove()}this.helper=null;this._propagate("stop",C,null,D);return true},_propagate:function(F,B,C,D){A.ui.plugin.call(this,F,[B,this._ui(C)]);var E=!D?this.element.triggerHandler(F=="sort"?F:"sort"+F,[B,this._ui(C)],this.options[F]):true;if(E===false){this.cancel()}},plugins:{},_ui:function(C){var B=C||this;return{helper:B.helper,placeholder:B.placeholder||A([]),position:B.position,absolutePosition:B.positionAbs,item:B.currentItem,sender:C?C.element:null}}}));A.extend(A.ui.sortable,{getter:"serialize toArray",version:"1.6",defaults:{accurateIntersection:true,appendTo:"parent",cancel:":input",delay:0,distance:1,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,helper:"original",items:"> *",scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,sortIndicator:A.ui.sortable.prototype._rearrange,tolerance:"default",zIndex:1000}});A.ui.plugin.add("sortable","cursor",{start:function(D,E){var C=A("body"),B=A(this).data("sortable");if(C.css("cursor")){B.options._cursor=C.css("cursor")}C.css("cursor",B.options.cursor)},beforeStop:function(C,D){var B=A(this).data("sortable");if(B.options._cursor){A("body").css("cursor",B.options._cursor)}}});A.ui.plugin.add("sortable","opacity",{start:function(D,E){var C=E.helper,B=A(this).data("sortable");if(C.css("opacity")){B.options._opacity=C.css("opacity")}C.css("opacity",B.options.opacity)},beforeStop:function(C,D){var B=A(this).data("sortable");if(B.options._opacity){A(D.helper).css("opacity",B.options._opacity)}}});A.ui.plugin.add("sortable","scroll",{start:function(C,D){var B=A(this).data("sortable"),E=B.options;if(B.scrollParent[0]!=document&&B.scrollParent[0].tagName!="HTML"){B.overflowOffset=B.scrollParent.offset()}},sort:function(D,E){var C=A(this).data("sortable"),F=C.options,B=false;if(C.scrollParent[0]!=document&&C.scrollParent[0].tagName!="HTML"){if((C.overflowOffset.top+C.scrollParent[0].offsetHeight)-D.pageY').insertBefore(H.headers);E(' ').appendTo(H.headers);H.headers.addClass("ui-accordion-header")}var J;if(H.fillSpace){J=this.element.parent().height();H.headers.each(function(){J-=E(this).outerHeight()});var I=0;H.headers.next().each(function(){I=Math.max(I,E(this).innerHeight()-E(this).height())}).height(J-I)}else{if(H.autoHeight){J=0;H.headers.next().each(function(){J=Math.max(J,E(this).outerHeight())}).height(J)}}this.element.attr("role","tablist");var G=this;H.headers.attr("role","tab").bind("keydown",function(L){return G._keydown(L)}).next().attr("role","tabpanel");H.headers.not(H.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();if(!H.active.length){H.headers.eq(0).attr("tabIndex","0")}else{H.active.attr("aria-expanded","true").attr("tabIndex","0").parent().andSelf().addClass(H.selectedClass)}if(!E.browser.safari){H.headers.find("a").attr("tabIndex","-1")}if(H.event){this.element.bind((H.event)+".accordion",F)}},destroy:function(){this.options.headers.parent().andSelf().removeClass(this.options.selectedClass);this.options.headers.prev(".ui-accordion-left").remove();this.options.headers.children(".ui-accordion-right").remove();this.options.headers.next().css("display","");if(this.options.fillSpace||this.options.autoHeight){this.options.headers.next().css("height","")}E.removeData(this.element[0],"accordion");this.element.removeClass("ui-accordion").unbind(".accordion")},_keydown:function(J){if(this.options.disabled||J.altKey||J.ctrlKey){return }var K=E.ui.keyCode;var I=this.options.headers.length;var G=this.options.headers.index(J.target);var H=false;switch(J.keyCode){case K.RIGHT:case K.DOWN:H=this.options.headers[(G+1)%I];break;case K.LEFT:case K.UP:H=this.options.headers[(G-1+I)%I];break;case K.SPACE:case K.ENTER:return F.call(this.element[0],{target:J.target})}if(H){E(J.target).attr("tabIndex","-1");E(H).attr("tabIndex","0");H.focus();return false}return true},activate:function(G){F.call(this.element[0],{target:C(this.options.headers,G)[0]})}});function B(H,G){return function(){return H.apply(G,arguments)}}function D(I){if(!E.data(this,"accordion")){return }var G=E.data(this,"accordion");var H=G.options;H.running=I?0:--H.running;if(H.running){return }if(H.clearStyle){H.toShow.add(H.toHide).css({height:"",overflow:""})}G._trigger("change",null,H.data)}function A(G,N,K,L,O){var Q=E.data(this,"accordion").options;Q.toShow=G;Q.toHide=N;Q.data=K;var H=B(D,this);E.data(this,"accordion")._trigger("changestart",null,Q.data);Q.running=N.size()===0?G.size():N.size();if(Q.animated){var J={};if(!Q.alwaysOpen&&L){J={toShow:E([]),toHide:N,complete:H,down:O,autoHeight:Q.autoHeight}}else{J={toShow:G,toHide:N,complete:H,down:O,autoHeight:Q.autoHeight}}if(!Q.proxied){Q.proxied=Q.animated}if(!Q.proxiedDuration){Q.proxiedDuration=Q.duration}Q.animated=E.isFunction(Q.proxied)?Q.proxied(J):Q.proxied;Q.duration=E.isFunction(Q.proxiedDuration)?Q.proxiedDuration(J):Q.proxiedDuration;var P=E.ui.accordion.animations,I=Q.duration,M=Q.animated;if(!P[M]){P[M]=function(R){this.slide(R,{easing:M,duration:I||700})}}P[M](J)}else{if(!Q.alwaysOpen&&L){G.toggle()}else{N.hide();G.show()}H(true)}N.prev().attr("aria-expanded","false").attr("tabIndex","-1");G.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()}function F(L){var J=E.data(this,"accordion").options;if(J.disabled){return false}if(!L.target&&!J.alwaysOpen){J.active.parent().andSelf().toggleClass(J.selectedClass);var I=J.active.next(),M={options:J,newHeader:E([]),oldHeader:J.active,newContent:E([]),oldContent:I},G=(J.active=E([]));A.call(this,G,I,M);return false}var K=E(L.target);K=E(K.parents(J.header)[0]||K);var H=K[0]==J.active[0];if(J.running||(J.alwaysOpen&&H)){return false}if(!K.is(J.header)){return }J.active.parent().andSelf().toggleClass(J.selectedClass);if(!H){K.parent().andSelf().addClass(J.selectedClass)}var G=K.next(),I=J.active.next(),M={options:J,newHeader:H&&!J.alwaysOpen?E([]):K,oldHeader:J.active,newContent:H&&!J.alwaysOpen?E([]):G,oldContent:I},N=J.headers.index(J.active[0])>J.headers.index(K[0]);J.active=H?E([]):K;A.call(this,G,I,M,H,N);return false}function C(H,G){return G?typeof G=="number"?H.filter(":eq("+G+")"):H.not(H.not(G)):G===false?E([]):H.filter(":eq(0)")}E.extend(E.ui.accordion,{version:"1.6",defaults:{autoHeight:true,alwaysOpen:true,animated:"slide",event:"click",header:"a",navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()},running:0,selectedClass:"selected"},animations:{slide:function(G,J){G=E.extend({easing:"swing",duration:300},G,J);if(!G.toHide.size()){G.toShow.animate({height:"show"},G);return }var I=G.toHide.height(),L=G.toShow.height(),N=L/I,K=G.toShow.outerHeight()-G.toShow.height(),H=G.toShow.css("marginBottom"),M=G.toShow.css("overflow");tmargin=G.toShow.css("marginTop");G.toShow.css({height:0,overflow:"hidden",marginTop:0,marginBottom:-K}).show();G.toHide.filter(":hidden").each(G.complete).end().filter(":visible").animate({height:"hide"},{step:function(O){var P=(I-O)*N;if(E.browser.msie||E.browser.opera){P=Math.ceil(P)}G.toShow.height(P)},duration:G.duration,easing:G.easing,complete:function(){if(!G.autoHeight){G.toShow.css("height","auto")}G.toShow.css({marginTop:tmargin,marginBottom:H,overflow:M});G.complete()}})},bounceslide:function(G){this.slide(G,{easing:G.down?"easeOutBounce":"swing",duration:G.down?1000:200})},easeslide:function(G){this.slide(G,{easing:"easeinout",duration:700})}}})})(jQuery);/*
+ * jQuery UI Dialog 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * ui.core.js
+ * ui.draggable.js
+ * ui.resizable.js
+ */
(function(B){var A={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"};B.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");this.options.title=this.options.title||this.originalTitle;var M=this,N=this.options,F=this.element.removeAttr("title").addClass("ui-dialog-content").wrap("
").wrap("
"),I=(this.uiDialogContainer=F.parent()).addClass("ui-dialog-container").css({position:"relative",width:"100%",height:"100%"}),E=(this.uiDialogTitlebar=B("
")).addClass("ui-dialog-titlebar").mousedown(function(){M.moveToTop()}).prependTo(I),J=B(' ').addClass("ui-dialog-titlebar-close").attr("role","button").appendTo(E),G=(this.uiDialogTitlebarCloseText=B(" ")).text(N.closeText).appendTo(J),L=N.title||" ",D=B.ui.dialog.getTitleId(this.element),C=B(" ").addClass("ui-dialog-title").attr("id",D).html(L).prependTo(E),K=(this.uiDialog=I.parent()).appendTo(document.body).hide().addClass("ui-dialog").addClass(N.dialogClass).css({position:"absolute",width:N.width,height:N.height,overflow:"hidden",zIndex:N.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(O){(N.closeOnEscape&&O.keyCode&&O.keyCode==B.ui.keyCode.ESCAPE&&M.close())}).attr({role:"dialog","aria-labelledby":D}).mouseup(function(){M.moveToTop()}),H=(this.uiDialogButtonPane=B("
")).addClass("ui-dialog-buttonpane").css({position:"absolute",bottom:0}).appendTo(K),J=B(".ui-dialog-titlebar-close",E).hover(function(){B(this).addClass("ui-dialog-titlebar-close-hover")},function(){B(this).removeClass("ui-dialog-titlebar-close-hover")}).mousedown(function(O){O.stopPropagation()}).click(function(){M.close();return false});E.find("*").add(E).disableSelection();(N.draggable&&B.fn.draggable&&this._makeDraggable());(N.resizable&&B.fn.resizable&&this._makeResizable());this._createButtons(N.buttons);this._isOpen=false;(N.bgiframe&&B.fn.bgiframe&&K.bgiframe());(N.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(){if(false===this._trigger("beforeclose",null,{options:this.options})){return }(this.overlay&&this.overlay.destroy());this.uiDialog.hide(this.options.hide).unbind("keypress.ui-dialog");this._trigger("close",null,{options:this.options});B.ui.dialog.overlay.resize();this._isOpen=false},isOpen:function(){return this._isOpen},moveToTop:function(F){if((this.options.modal&&!F)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",null,{options:this.options})}var E=this.options.zIndex,D=this.options;B(".ui-dialog:visible").each(function(){E=Math.max(E,parseInt(B(this).css("z-index"),10)||D.zIndex)});(this.overlay&&this.overlay.$el.css("z-index",++E));var C={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++E);this.element.attr(C);this._trigger("focus",null,{options:this.options})},open:function(){if(this._isOpen){return }this.overlay=this.options.modal?new B.ui.dialog.overlay(this):null;(this.uiDialog.next().length&&this.uiDialog.appendTo("body"));this._position(this.options.position);this.uiDialog.show(this.options.show);(this.options.autoResize&&this._size());this.moveToTop(true);(this.options.modal&&this.uiDialog.bind("keypress.ui-dialog",function(E){if(E.keyCode!=B.ui.keyCode.TAB){return }var D=B(":tabbable",this),F=D.filter(":first")[0],C=D.filter(":last")[0];if(E.target==C&&!E.shiftKey){setTimeout(function(){F.focus()},1)}else{if(E.target==F&&E.shiftKey){setTimeout(function(){C.focus()},1)}}}));this.uiDialog.find(":tabbable:first").focus();this._trigger("open",null,{options:this.options});this._isOpen=true},_createButtons:function(F){var E=this,C=false,D=this.uiDialogButtonPane;D.empty().hide();B.each(F,function(){return !(C=true)});if(C){D.show();B.each(F,function(G,H){B(' ').text(G).click(function(){H.apply(E.element[0],arguments)}).appendTo(D)})}},_makeDraggable:function(){var C=this,D=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content",helper:D.dragHelper,handle:".ui-dialog-titlebar",start:function(){C.moveToTop();(D.dragStart&&D.dragStart.apply(C.element[0],arguments))},drag:function(){(D.drag&&D.drag.apply(C.element[0],arguments))},stop:function(){(D.dragStop&&D.dragStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_makeResizable:function(F){F=(F===undefined?this.options.resizable:F);var C=this,E=this.options,D=typeof F=="string"?F:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",helper:E.resizeHelper,maxWidth:E.maxWidth,maxHeight:E.maxHeight,minWidth:E.minWidth,minHeight:E.minHeight,start:function(){(E.resizeStart&&E.resizeStart.apply(C.element[0],arguments))},resize:function(){(E.autoResize&&C._size.apply(C));(E.resize&&E.resize.apply(C.element[0],arguments))},handles:D,stop:function(){(E.autoResize&&C._size.apply(C));(E.resizeStop&&E.resizeStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_position:function(H){var D=B(window),E=B(document),F=E.scrollTop(),C=E.scrollLeft(),G=F;if(B.inArray(H,["center","top","right","bottom","left"])>=0){H=[H=="right"||H=="left"?H:"center",H=="top"||H=="bottom"?H:"middle"]}if(H.constructor!=Array){H=["center","middle"]}if(H[0].constructor==Number){C+=H[0]}else{switch(H[0]){case"left":C+=0;break;case"right":C+=D.width()-this.uiDialog.outerWidth();break;default:case"center":C+=(D.width()-this.uiDialog.outerWidth())/2}}if(H[1].constructor==Number){F+=H[1]}else{switch(H[1]){case"top":F+=0;break;case"bottom":F+=(B.browser.opera?window.innerHeight:D.height())-this.uiDialog.outerHeight();break;default:case"middle":F+=((B.browser.opera?window.innerHeight:D.height())-this.uiDialog.outerHeight())/2}}F=Math.max(F,G);this.uiDialog.css({top:F,left:C})},_setData:function(D,E){(A[D]&&this.uiDialog.data(A[D],E));switch(D){case"buttons":this._createButtons(E);break;case"closeText":this.uiDialogTitlebarCloseText.text(E);break;case"draggable":(E?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(E);break;case"position":this._position(E);break;case"resizable":var C=this.uiDialog,F=this.uiDialog.is(":data(resizable)");(F&&!E&&C.resizable("destroy"));(F&&typeof E=="string"&&C.resizable("option","handles",E));(F||this._makeResizable(E));break;case"title":B(".ui-dialog-title",this.uiDialogTitlebar).html(E||" ");break;case"width":this.uiDialog.width(E);break}B.widget.prototype._setData.apply(this,arguments)},_size:function(){var D=this.uiDialogContainer,G=this.uiDialogTitlebar,E=this.element,F=(parseInt(E.css("margin-top"),10)||0)+(parseInt(E.css("margin-bottom"),10)||0),C=(parseInt(E.css("margin-left"),10)||0)+(parseInt(E.css("margin-right"),10)||0);E.height(D.height()-G.outerHeight()-F);E.width(D.width()-C)}});B.extend(B.ui.dialog,{version:"1.6",defaults:{autoOpen:true,autoResize:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",draggable:true,height:200,minHeight:100,minWidth:150,modal:false,overlay:{},position:"center",resizable:true,stack:true,width:300,zIndex:1000},getter:"isOpen",uuid:0,getTitleId:function(C){return"ui-dialog-title-"+(C.attr("id")||++this.uuid)},overlay:function(C){this.$el=B.ui.dialog.overlay.create(C)}});B.extend(B.ui.dialog.overlay,{instances:[],events:B.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(C){return C+".dialog-overlay"}).join(" "),create:function(D){if(this.instances.length===0){setTimeout(function(){B("a, :input").bind(B.ui.dialog.overlay.events,function(){var F=false;var H=B(this).parents(".ui-dialog");if(H.length){var E=B(".ui-dialog-overlay");if(E.length){var G=parseInt(E.css("z-index"),10);E.each(function(){G=Math.max(G,parseInt(B(this).css("z-index"),10))});F=parseInt(H.css("z-index"),10)>G}else{F=true}}return F})},1);B(document).bind("keydown.dialog-overlay",function(E){(D.options.closeOnEscape&&E.keyCode&&E.keyCode==B.ui.keyCode.ESCAPE&&D.close())});B(window).bind("resize.dialog-overlay",B.ui.dialog.overlay.resize)}var C=B("
").appendTo(document.body).addClass("ui-dialog-overlay").css(B.extend({borderWidth:0,margin:0,padding:0,position:"absolute",top:0,left:0,width:this.width(),height:this.height()},D.options.overlay));(D.options.bgiframe&&B.fn.bgiframe&&C.bgiframe());this.instances.push(C);return C},destroy:function(C){this.instances.splice(B.inArray(this.instances,C),1);if(this.instances.length===0){B("a, :input").add([document,window]).unbind(".dialog-overlay")}C.remove()},height:function(){if(B.browser.msie&&B.browser.version<7){var D=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var C=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(D").addClass("ui-slider-handle").appendTo(B.element);if(this.id){D.attr("id",this.id)}return D[0]})}var C=function(D){this.element=A(D);this.element.data("mouse",this);this.options=B.options;this.element.bind("mousedown",function(){if(B.currentHandle){this.blur(B.currentHandle)}B._focus(this,true)});this._mouseInit()};A.extend(C.prototype,A.ui.mouse,{_mouseCapture:function(){return true},_mouseStart:function(D){return B._start.call(B,D,this.element[0])},_mouseDrag:function(D){return B._drag.call(B,D,this.element[0])},_mouseStop:function(D){return B._stop.call(B,D,this.element[0])},trigger:function(D){this._mouseDown(D)}});A(this.handle).each(function(){new C(this)}).wrap(' ').parent().bind("click",function(){return false}).bind("focus",function(D){B._focus(this.firstChild)}).bind("blur",function(D){B._blur(this.firstChild)}).bind("keydown",function(D){if(!B.options.noKeyboard){return B._keydown(D.keyCode,this.firstChild)}});this.element.bind("mousedown.slider",function(D){if(A(D.target).is(".ui-slider-handle")){return }B._click.apply(B,[D]);B.currentHandle.data("mouse").trigger(D);B.firstValue=B.firstValue+1});A.each(this.options.handles||[],function(D,E){B.moveTo(E.start,D,true)});if(!isNaN(this.options.startValue)){this.moveTo(this.options.startValue,0,true)}this.previousHandle=A(this.handle[0]);if(this.handle.length==2&&this.options.range){this._createRange()}},destroy:function(){this.element.removeClass("ui-slider ui-slider-disabled").removeData("slider").unbind(".slider");if(this.handle&&this.handle.length){this.handle.unwrap("a");this.handle.each(function(){var B=A(this).data("mouse");B&&B._mouseDestroy()})}this.generated&&this.generated.remove()},_start:function(B,C){var D=this.options;if(D.disabled){return false}this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(!this.currentHandle){this._focus(this.previousHandle,true)}this.offset=this.element.offset();this.handleOffset=this.currentHandle.offset();this.clickOffset={top:B.pageY-this.handleOffset.top,left:B.pageX-this.handleOffset.left};this.firstValue=this.value();this._propagate("start",B);this._drag(B,C);return true},_drag:function(C,E){var F=this.options;var B={top:C.pageY-this.offset.top-this.clickOffset.top,left:C.pageX-this.offset.left-this.clickOffset.left};if(!this.currentHandle){this._focus(this.previousHandle,true)}B.left=this._translateLimits(B.left,"x");B.top=this._translateLimits(B.top,"y");if(F.stepping.x){var D=this._convertValue(B.left,"x");D=this._round(D/F.stepping.x)*F.stepping.x;B.left=this._translateValue(D,"x")}if(F.stepping.y){var D=this._convertValue(B.top,"y");D=this._round(D/F.stepping.y)*F.stepping.y;B.top=this._translateValue(D,"y")}B.left=this._translateRange(B.left,"x");B.top=this._translateRange(B.top,"y");if(F.axis!="vertical"){this.currentHandle.css({left:B.left})}if(F.axis!="horizontal"){this.currentHandle.css({top:B.top})}this.currentHandle.data("mouse").sliderValue={x:this._round(this._convertValue(B.left,"x"))||0,y:this._round(this._convertValue(B.top,"y"))||0};if(this.rangeElement){this._updateRange()}this._propagate("slide",C);return false},_stop:function(B){this._propagate("stop",B);if(this.firstValue!=this.value()){this._propagate("change",B)}this._focus(this.currentHandle,true);return false},_round:function(B){return this.options.round?parseInt(B,10):parseFloat(B)},_setData:function(B,C){A.widget.prototype._setData.apply(this,arguments);if(/min|max|steps/.test(B)){this._initBoundaries()}if(B=="range"){C?this.handle.length==2&&this._createRange():this._removeRange()}},_initBoundaries:function(){var B=this.element[0],C=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};A.extend(C,{axis:C.axis||(B.offsetWidth").addClass("ui-slider-range").css({position:"absolute"}).appendTo(this.element);this._updateRange()},_removeRange:function(){this.rangeElement.remove();this.rangeElement=null},_updateRange:function(){var C=this.options.axis=="vertical"?"top":"left";var B=this.options.axis=="vertical"?"height":"width";this.rangeElement.css(C,(this._round(A(this.handle[0]).css(C))||0)+this._handleSize(0,this.options.axis=="vertical"?"y":"x")/2);this.rangeElement.css(B,(this._round(A(this.handle[1]).css(C))||0)-(this._round(A(this.handle[0]).css(C))||0))},_getRange:function(){return this.rangeElement?this._convertValue(this._round(this.rangeElement.css(this.options.axis=="vertical"?"height":"width")),this.options.axis=="vertical"?"y":"x"):null},_handleIndex:function(){return this.handle.index(this.currentHandle[0])},value:function(D,B){if(this.handle.length==1){this.currentHandle=this.handle}if(!B){B=this.options.axis=="vertical"?"y":"x"}var C=A(D!=undefined&&D!==null?this.handle[D]||D:this.currentHandle);if(C.data("mouse").sliderValue){return this._round(C.data("mouse").sliderValue[B])}else{return this._round(((this._round(C.css(B=="x"?"left":"top"))/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(D,B)))*this.options.realMax[B])+this.options.min[B])}},_convertValue:function(C,B){return this.options.min[B]+(C/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)))*this.options.realMax[B]},_translateValue:function(C,B){return((C-this.options.min[B])/this.options.realMax[B])*(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B))},_translateRange:function(D,B){if(this.rangeElement){if(this.currentHandle[0]==this.handle[0]&&D>=this._translateValue(this.value(1),B)){D=this._translateValue(this.value(1,B)-this._oneStep(B),B)}if(this.currentHandle[0]==this.handle[1]&&D<=this._translateValue(this.value(0),B)){D=this._translateValue(this.value(0,B)+this._oneStep(B),B)}}if(this.options.handles){var C=this.options.handles[this._handleIndex()];if(Dthis._translateValue(C.max,B)){D=this._translateValue(C.max,B)}}}return D},_translateLimits:function(C,B){if(C>=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)){C=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)}if(C<=0){C=0}return C},_handleSize:function(C,B){return A(C!=undefined&&C!==null?this.handle[C]:this.currentHandle)[0]["offset"+(B=="x"?"Width":"Height")]},_oneStep:function(B){return this.options.stepping[B]||1},_pageStep:function(B){return 10},moveTo:function(F,E,G){var H=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(E==undefined&&!this.currentHandle&&this.handle.length!=1){return false}if(E==undefined&&!this.currentHandle){E=0}if(E!=undefined){this.currentHandle=this.previousHandle=A(this.handle[E]||E)}if(F.x!==undefined&&F.y!==undefined){var B=F.x,I=F.y}else{var B=F,I=F}if(B!==undefined&&B.constructor!=Number){var D=/^\-\=/.test(B),C=/^\+\=/.test(B);if(D||C){B=this.value(null,"x")+this._round(B.replace(D?"=":"+=",""))}else{B=isNaN(this._round(B))?undefined:this._round(B)}}if(I!==undefined&&I.constructor!=Number){var D=/^\-\=/.test(I),C=/^\+\=/.test(I);if(D||C){I=this.value(null,"y")+this._round(I.replace(D?"=":"+=",""))}else{I=isNaN(this._round(I))?undefined:this._round(I)}}if(H.axis!="vertical"&&B!==undefined){if(H.stepping.x){B=this._round(B/H.stepping.x)*H.stepping.x}B=this._translateValue(B,"x");B=this._translateLimits(B,"x");B=this._translateRange(B,"x");H.animate?this.currentHandle.stop().animate({left:B},(Math.abs(parseInt(this.currentHandle.css("left"),10)-B))*(!isNaN(parseInt(H.animate,10))?H.animate:5)):this.currentHandle.css({left:B})}if(H.axis!="horizontal"&&I!==undefined){if(H.stepping.y){I=this._round(I/H.stepping.y)*H.stepping.y}I=this._translateValue(I,"y");I=this._translateLimits(I,"y");I=this._translateRange(I,"y");H.animate?this.currentHandle.stop().animate({top:I},(Math.abs(parseInt(this.currentHandle.css("top"),10)-I))*(!isNaN(parseInt(H.animate,10))?H.animate:5)):this.currentHandle.css({top:I})}if(this.rangeElement){this._updateRange()}this.currentHandle.data("mouse").sliderValue={x:this._round(this._convertValue(B,"x"))||0,y:this._round(this._convertValue(I,"y"))||0};if(!G){this._propagate("start",null);this._propagate("slide",null);this._propagate("stop",null);this._propagate("change",null)}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);this.element.triggerHandler(C=="slide"?C:"slide"+C,[B,this.ui()],this.options[C])},plugins:{},ui:function(B){return{options:this.options,handle:this.currentHandle,value:this.options.axis!="both"||!this.options.axis?this._round(this.value(null,this.options.axis=="vertical"?"y":"x")):{x:this._round(this.value(null,"x")),y:this._round(this.value(null,"y"))},range:this._getRange()}}});A.extend(A.ui.slider,{getter:"value",version:"1.6",defaults:{animate:false,distance:1,handle:".ui-slider-handle",round:true}})})(jQuery);/*
+ * jQuery UI Tabs 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ * ui.core.js
+ */
(function(A){A.widget("ui.tabs",{_init:function(){this._tabify(true)},destroy:function(){var B=this.options;this.element.unbind(".tabs").removeClass(B.navClass).removeData("tabs");this.$tabs.each(function(){var C=A.data(this,"href.tabs");if(C){this.href=C}var D=A(this).unbind(".tabs");A.each(["href","load","cache"],function(E,F){D.removeData(F+".tabs")})});this.$lis.add(this.$panels).each(function(){if(A.data(this,"destroy.tabs")){A(this).remove()}else{A(this).removeClass([B.selectedClass,B.deselectableClass,B.disabledClass,B.panelClass,B.hideClass].join(" "))}});if(B.cookie){this._cookie(null,B.cookie)}},_setData:function(B,C){if((/^selected/).test(B)){this.select(C)}else{this.options[B]=C;this._tabify()}},length:function(){return this.$tabs.length},_tabId:function(B){return B.title&&B.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+A.data(B)},_sanitizeSelector:function(B){return B.replace(/:/g,"\\:")},_cookie:function(){var B=this.cookie||(this.cookie="ui-tabs-"+A.data(this.element[0]));return A.cookie.apply(null,[B].concat(A.makeArray(arguments)))},_tabify:function(N){this.$lis=A("li:has(a[href])",this.element);this.$tabs=this.$lis.map(function(){return A("a",this)[0]});this.$panels=A([]);var O=this,C=this.options;this.$tabs.each(function(Q,P){if(P.hash&&P.hash.replace("#","")){O.$panels=O.$panels.add(O._sanitizeSelector(P.hash))}else{if(A(P).attr("href")!="#"){A.data(P,"href.tabs",P.href);A.data(P,"load.tabs",P.href);var S=O._tabId(P);P.href="#"+S;var R=A("#"+S);if(!R.length){R=A(C.panelTemplate).attr("id",S).addClass(C.panelClass).insertAfter(O.$panels[Q-1]||O.element);R.data("destroy.tabs",true)}O.$panels=O.$panels.add(R)}else{C.disabled.push(Q+1)}}});if(N){this.element.addClass(C.navClass);this.$panels.addClass(C.panelClass);if(C.selected===undefined){if(location.hash){this.$tabs.each(function(Q,P){if(P.hash==location.hash){C.selected=Q;return false}})}else{if(C.cookie){var I=parseInt(O._cookie(),10);if(I&&O.$tabs[I]){C.selected=I}}else{if(O.$lis.filter("."+C.selectedClass).length){C.selected=O.$lis.index(O.$lis.filter("."+C.selectedClass)[0])}}}}C.selected=C.selected===null||C.selected!==undefined?C.selected:0;C.disabled=A.unique(C.disabled.concat(A.map(this.$lis.filter("."+C.disabledClass),function(Q,P){return O.$lis.index(Q)}))).sort();if(A.inArray(C.selected,C.disabled)!=-1){C.disabled.splice(A.inArray(C.selected,C.disabled),1)}this.$panels.addClass(C.hideClass);this.$lis.removeClass(C.selectedClass);if(C.selected!==null){this.$panels.eq(C.selected).removeClass(C.hideClass);var E=[C.selectedClass];if(C.deselectable){E.push(C.deselectableClass)}this.$lis.eq(C.selected).addClass(E.join(" "));var J=function(){O._trigger("show",null,O.ui(O.$tabs[C.selected],O.$panels[C.selected]))};if(A.data(this.$tabs[C.selected],"load.tabs")){this.load(C.selected,J)}else{J()}}A(window).bind("unload",function(){O.$tabs.unbind(".tabs");O.$lis=O.$tabs=O.$panels=null})}else{C.selected=this.$lis.index(this.$lis.filter("."+C.selectedClass)[0])}if(C.cookie){this._cookie(C.selected,C.cookie)}for(var G=0,M;M=this.$lis[G];G++){A(M)[A.inArray(G,C.disabled)!=-1&&!A(M).hasClass(C.selectedClass)?"addClass":"removeClass"](C.disabledClass)}if(C.cache===false){this.$tabs.removeData("cache.tabs")}var B,H;if(C.fx){if(C.fx.constructor==Array){B=C.fx[0];H=C.fx[1]}else{B=H=C.fx}}function D(P,Q){P.css({display:""});if(A.browser.msie&&Q.opacity){P[0].style.removeAttribute("filter")}}var K=H?function(P,Q){Q.animate(H,H.duration||"normal",function(){Q.removeClass(C.hideClass);D(Q,H);O._trigger("show",null,O.ui(P,Q[0]))})}:function(P,Q){Q.removeClass(C.hideClass);O._trigger("show",null,O.ui(P,Q[0]))};var L=B?function(Q,P,R){P.animate(B,B.duration||"normal",function(){P.addClass(C.hideClass);D(P,B);if(R){K(Q,R,P)}})}:function(Q,P,R){P.addClass(C.hideClass);if(R){K(Q,R)}};function F(R,T,P,S){var Q=[C.selectedClass];if(C.deselectable){Q.push(C.deselectableClass)}T.addClass(Q.join(" ")).siblings().removeClass(Q.join(" "));L(R,P,S)}this.$tabs.unbind(".tabs").bind(C.event+".tabs",function(){var S=A(this).parents("li:eq(0)"),P=O.$panels.filter(":visible"),R=A(O._sanitizeSelector(this.hash));if((S.hasClass(C.selectedClass)&&!C.deselectable)||S.hasClass(C.disabledClass)||A(this).hasClass(C.loadingClass)||O._trigger("select",null,O.ui(this,R[0]))===false){this.blur();return false}C.selected=O.$tabs.index(this);if(C.deselectable){if(S.hasClass(C.selectedClass)){O.options.selected=null;S.removeClass([C.selectedClass,C.deselectableClass].join(" "));O.$panels.stop();L(this,P);this.blur();return false}else{if(!P.length){O.$panels.stop();var Q=this;O.load(O.$tabs.index(this),function(){S.addClass([C.selectedClass,C.deselectableClass].join(" "));K(Q,R)});this.blur();return false}}}if(C.cookie){O._cookie(C.selected,C.cookie)}O.$panels.stop();if(R.length){var Q=this;O.load(O.$tabs.index(this),P.length?function(){F(Q,S,P,R)}:function(){S.addClass(C.selectedClass);K(Q,R)})}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(A.browser.msie){this.blur()}return false});if(C.event!="click"){this.$tabs.bind("click.tabs",function(){return false})}},add:function(E,D,C){if(C==undefined){C=this.$tabs.length}var G=this.options;var I=A(G.tabTemplate.replace(/#\{href\}/g,E).replace(/#\{label\}/g,D));I.data("destroy.tabs",true);var H=E.indexOf("#")==0?E.replace("#",""):this._tabId(A("a:first-child",I)[0]);var F=A("#"+H);if(!F.length){F=A(G.panelTemplate).attr("id",H).addClass(G.hideClass).data("destroy.tabs",true)}F.addClass(G.panelClass);if(C>=this.$lis.length){I.appendTo(this.element);F.appendTo(this.element[0].parentNode)}else{I.insertBefore(this.$lis[C]);F.insertBefore(this.$panels[C])}G.disabled=A.map(G.disabled,function(K,J){return K>=C?++K:K});this._tabify();if(this.$tabs.length==1){I.addClass(G.selectedClass);F.removeClass(G.hideClass);var B=A.data(this.$tabs[0],"load.tabs");if(B){this.load(C,B)}}this._trigger("add",null,this.ui(this.$tabs[C],this.$panels[C]))},remove:function(B){var D=this.options,E=this.$lis.eq(B).remove(),C=this.$panels.eq(B).remove();if(E.hasClass(D.selectedClass)&&this.$tabs.length>1){this.select(B+(B+1=B?--G:G});this._tabify();this._trigger("remove",null,this.ui(E.find("a")[0],C[0]))},enable:function(B){var C=this.options;if(A.inArray(B,C.disabled)==-1){return }var D=this.$lis.eq(B).removeClass(C.disabledClass);if(A.browser.safari){D.css("display","inline-block");setTimeout(function(){D.css("display","block")},0)}C.disabled=A.grep(C.disabled,function(F,E){return F!=B});this._trigger("enable",null,this.ui(this.$tabs[B],this.$panels[B]))},disable:function(C){var B=this,D=this.options;if(C!=D.selected){this.$lis.eq(C).addClass(D.disabledClass);D.disabled.push(C);D.disabled.sort();this._trigger("disable",null,this.ui(this.$tabs[C],this.$panels[C]))}},select:function(B){if(typeof B=="string"){B=this.$tabs.index(this.$tabs.filter("[href$="+B+"]")[0])}this.$tabs.eq(B).trigger(this.options.event+".tabs")},load:function(G,K){var L=this,D=this.options,E=this.$tabs.eq(G),J=E[0],H=K==undefined||K===false,B=E.data("load.tabs");K=K||function(){};if(!B||!H&&A.data(J,"cache.tabs")){K();return }var M=function(N){var O=A(N),P=O.find("*:last");return P.length&&P.is(":not(img)")&&P||O};var C=function(){L.$tabs.filter("."+D.loadingClass).removeClass(D.loadingClass).each(function(){if(D.spinner){M(this).parent().html(M(this).data("label.tabs"))}});L.xhr=null};if(D.spinner){var I=M(J).html();M(J).wrapInner(" ").find("em").data("label.tabs",I).html(D.spinner)}var F=A.extend({},D.ajaxOptions,{url:B,success:function(P,N){A(L._sanitizeSelector(J.hash)).html(P);C();if(D.cache){A.data(J,"cache.tabs",true)}L._trigger("load",null,L.ui(L.$tabs[G],L.$panels[G]));try{D.ajaxOptions.success(P,N)}catch(O){}K()}});if(this.xhr){this.xhr.abort();C()}E.addClass(D.loadingClass);L.xhr=A.ajax(F)},url:function(C,B){this.$tabs.eq(C).removeData("cache.tabs").data("load.tabs",B)},ui:function(C,B){return{options:this.options,tab:C,panel:B,index:this.$tabs.index(C)}}});A.extend(A.ui.tabs,{version:"1.6",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,deselectable:false,deselectableClass:"ui-tabs-deselectable",disabled:[],disabledClass:"ui-tabs-disabled",event:"click",fx:null,hideClass:"ui-tabs-hide",idPrefix:"ui-tabs-",loadingClass:"ui-tabs-loading",navClass:"ui-tabs-nav",panelClass:"ui-tabs-panel",panelTemplate:"
",selectedClass:"ui-tabs-selected",spinner:"Loading…",tabTemplate:'#{label} '}});A.extend(A.ui.tabs.prototype,{rotation:null,rotate:function(C,F){F=F||false;var B=this,E=this.options.selected;function G(){B.rotation=setInterval(function(){E=++E')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('
'))}},_connectDatepicker:function(target,inst){var input=$(target);if(input.hasClass(this.markerClassName)){return }var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){input[isRTL?"before":"after"](''+appendText+" ")}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");var trigger=$(this._get(inst,"buttonImageOnly")?$(" ").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$(' ').addClass(this._triggerClass).html(buttonImage==""?buttonText:$(" ").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](trigger);trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return }divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$(' ');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){$target.siblings("."+this._appendClass).remove().end().siblings("."+this._triggerClass).remove().end().removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=false}).end().siblings("img."+this._triggerClass).css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){$target.children("."+this._disableClass).remove()}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=true}).end().siblings("img."+this._triggerClass).css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);var offset=inline.offset();var relOffset={left:0,top:0};inline.parents().each(function(){if($(this).css("position")=="relative"){relOffset=$(this).offset();return false}});$target.prepend('
')}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return }var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1]*$(".ui-datepicker",inst.dpDiv[0])[0].offsetWidth);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height});var numMonths=this._getNumberOfMonths(inst);inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var pos=inst.input?this._findPos(inst.input[0]):null;var browserWidth=window.innerWidth||(document.documentElement?document.documentElement.clientWidth:document.body.clientWidth);var browserHeight=window.innerHeight||(document.documentElement?document.documentElement.clientHeight:document.body.clientHeight);var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;if(this._get(inst,"isRTL")||(offset.left+inst.dpDiv.width()-scrollX)>browserWidth){offset.left=Math.max((isFixed?0:scrollX),pos[0]+(inst.input?inst.input.width():0)-(isFixed?scrollX:0)-inst.dpDiv.width()-(isFixed&&$.browser.opera?document.documentElement.scrollLeft:0))}else{offset.left-=(isFixed?scrollX:0)}if((offset.top+inst.dpDiv.height()-scrollY)>browserHeight){offset.top=Math.max((isFixed?0:scrollY),pos[1]-(isFixed?scrollY:0)-(this._inDialog?0:inst.dpDiv.height())-(isFixed&&$.browser.opera?document.documentElement.scrollTop:0))}else{offset.top-=(isFixed?scrollY:0)}return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return }var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect&&inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;inst.settings.prompt=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker");$("."+this._promptClass,inst.dpDiv).remove()},_checkExternalClick:function(event){if(!$.datepicker._curInst){return }var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);this._adjustInstDate(inst,offset,period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_changeFirstDay:function(id,day){var target=$(id);var inst=this._getInst(target[0]);inst.settings.firstDay=day;this._updateDatepicker(inst)},_selectDay:function(id,month,year,td){if($(td).hasClass(this._unselectableClass)){return }var target=$(id);var inst=this._getInst(target[0]);var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect){inst.stayOpen=!inst.stayOpen;if(inst.stayOpen){$(".ui-datepicker td",inst.dpDiv).removeClass(this._currentClass);$(td).addClass(this._currentClass)}}inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}else{if(rangeSelect){inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}else{if(rangeSelect){inst.selectedDay=inst.currentDay=inst.rangeStart.getDate();inst.selectedMonth=inst.currentMonth=inst.rangeStart.getMonth();inst.selectedYear=inst.currentYear=inst.rangeStart.getFullYear();inst.rangeStart=null;if(inst.inline){this._updateDatepicker(inst)}}}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"mandatory")){return }inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(this._get(inst,"rangeSelect")&&dateStr){dateStr=(inst.rangeStart?this._formatDate(inst,inst.rangeStart):dateStr)+this._get(inst,"rangeSeparator")+dateStr}if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof (inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=(isArray(date)?(!date[0]&&!date[1]?"":this.formatDate(altFormat,date[0],this._getFormatConfig(inst))+this._get(inst,"rangeSeparator")+this.formatDate(altFormat,date[1]||date[0],this._getFormatConfig(inst))):this.formatDate(altFormat,date,this._getFormatConfig(inst)));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDatenew Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)0&&iValue="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j0&&iValue-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat0){var settings=this._getFormatConfig(inst);if(dates.length>1){date=this.parseDate(dateFormat,dates[1],settings)||defaultDate;inst.endDay=date.getDate();inst.endMonth=date.getMonth();inst.endYear=date.getFullYear()}try{date=this.parseDate(dateFormat,dates[0],settings)||defaultDate}catch(event){this.log(event);date=defaultDate}}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates[0]?date.getDate():0);inst.currentMonth=(dates[0]?date.getMonth():0);inst.currentYear=(dates[0]?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&datemaxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(this._get(inst,"rangeSelect")){if(endDate){endDate=this._determineDate(endDate,null);inst.endDay=endDate.getDate();inst.endMonth=endDate.getMonth();inst.endYear=endDate.getFullYear()}else{inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst)+(!this._get(inst,"rangeSelect")?"":this._get(inst,"rangeSeparator")+this._formatDate(inst,inst.endDay,inst.endMonth,inst.endYear)))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));if(this._get(inst,"rangeSelect")){return[inst.rangeStart||startDate,(!inst.endYear?inst.rangeStart||startDate:this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)))]}else{return startDate}},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var showStatus=this._get(inst,"showStatus");var initStatus=this._get(inst,"initStatus")||" ";var isRTL=this._get(inst,"isRTL");var clear=(this._get(inst,"mandatory")?"":'");var controls=''+(isRTL?"":clear)+'
"+(isRTL?clear:"")+"
";var prompt=this._get(inst,"prompt");var closeAtTop=this._get(inst,"closeAtTop");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var showBigPrevNext=this._get(inst,"showBigPrevNext");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDrawmaxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prevBigText=(showBigPrevNext?this._get(inst,"prevBigText"):"");prevBigText=(!navigationAsDateFormat?prevBigText:this.formatDate(prevBigText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepBigMonths,1)),this._getFormatConfig(inst)));var prev=''+(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?(showBigPrevNext?"
"+prevBigText+" ":"")+"
"+prevText+" ":(hideIfNoPrevNext?"":(showBigPrevNext?"
"+prevBigText+" ":"")+"
"+prevText+" "))+"
";var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var nextBigText=(showBigPrevNext?this._get(inst,"nextBigText"):"");nextBigText=(!navigationAsDateFormat?nextBigText:this.formatDate(nextBigText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepBigMonths,1)),this._getFormatConfig(inst)));var next=''+(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?"
"+nextText+" "+(showBigPrevNext?"
"+nextBigText+" ":""):(hideIfNoPrevNext?"":"
"+nextText+" "+(showBigPrevNext?"
"+nextBigText+" ":"")))+"
";var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var html=(closeAtTop&&!inst.inline?controls:"")+''+(isRTL?next:prev)+(this._isInRange(inst,gotoDate)?'
":"")+(isRTL?prev:next)+"
"+(prompt?''+prompt+"
":"");var firstDay=parseInt(this._get(inst,"firstDay"));firstDay=(isNaN(firstDay)?0:firstDay);var changeFirstDay=this._get(inst,"changeFirstDay");var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var beforeShowDay=this._get(inst,"beforeShowDay");var highlightWeek=this._get(inst,"highlightWeek");var showOtherMonths=this._get(inst,"showOtherMonths");var showWeeks=this._get(inst,"showWeeks");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var weekStatus=this._get(inst,"weekStatus");var status=(showStatus?this._get(inst,"dayStatus")||initStatus:"");var dateStatus=this._get(inst,"statusForDate")||this.dateStatus;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);for(var row=0;row'+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,showStatus,initStatus,monthNames)+''+(showWeeks?""+this._get(inst,"weekHeader")+" ":"");for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;var dayStatus=(status.indexOf("DD")>-1?status.replace(/DD/,dayNames[day]):status.replace(/D/,dayNamesShort[day]));html+="=5?' class="ui-datepicker-week-end-cell"':"")+">"+(!changeFirstDay?"'+dayNamesMin[day]+(changeFirstDay?"":" ")+" "}html+=" ";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow'+(showWeeks?'"+calculateWeek(printDate)+" ":"");for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDatemaxDate);html+='=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?(highlightWeek?" onmouseover=\"jQuery(this).parent().addClass('"+this._weekOverClass+"');\" onmouseout=\"jQuery(this).parent().removeClass('"+this._weekOverClass+"');\"":""):" onmouseover=\"jQuery(this).addClass('"+this._dayOverClass+"')"+(highlightWeek?".parent().addClass('"+this._weekOverClass+"')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+(dateStatus.apply((inst.input?inst.input[0]:null),[printDate,inst])||initStatus)+"');")+'" onmouseout="jQuery(this).removeClass(\''+this._dayOverClass+"')"+(highlightWeek?".parent().removeClass('"+this._weekOverClass+"')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+initStatus+"');")+'" onclick="jQuery.datepicker._selectDay(\'#'+inst.id+"',"+drawMonth+","+drawYear+', this);"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():" "):(unselectable?printDate.getDate():""+printDate.getDate()+" "))+" ";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}html+=""}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}html+="
"}}html+=(showStatus?'
'+initStatus+"
":"")+(!closeAtTop&&!inst.inline?controls:"")+'
'+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,showStatus,initStatus,monthNames){minDate=(inst.rangeStart&&minDate&&selectedDate";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='"+monthNames[month]+" "}}monthHtml+=""}if(!showMonthAfterYear){html+=monthHtml+(secondary||changeMonth||changeYear?" ":"")}if(secondary||!changeYear){html+=drawYear}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=endYear=new Date().getFullYear();year+=parseInt(years[0],10);endYear+=parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='";for(;year<=endYear;year++){html+='"+year+" "}html+=" "}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?" ":"")+monthHtml}html+="";return html},_addStatus:function(showStatus,id,text,initStatus){return(showStatus?" onmouseover=\"jQuery('#ui-datepicker-status-"+id+"').html('"+(text||initStatus)+"');\" onmouseout=\"jQuery('#ui-datepicker-status-"+id+"').html('"+initStatus+"');\"":"")},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&datemaxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document.body).append($.datepicker.dpDiv).mousedown($.datepicker._checkExternalClick);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.6"})(jQuery);/*
+ * jQuery UI Effects 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
(function(C){C.effects=C.effects||{};C.extend(C.effects,{version:"1.6",save:function(F,G){for(var E=0;E');var I=F.parent();if(F.css("position")=="static"){I.css({position:"relative"});F.css({position:"relative"})}else{var H=F.css("top");if(isNaN(parseInt(H))){H="auto"}var G=F.css("left");if(isNaN(parseInt(G))){G="auto"}I.css({position:F.css("position"),top:H,left:G,zIndex:F.css("z-index")}).show();F.css({position:"relative",top:0,left:0})}I.css(E);return I},removeWrapper:function(E){if(E.parent().attr("id")=="fxWrapper"){return E.parent().replaceWith(E)}return E},setTransition:function(F,G,E,H){H=H||{};C.each(G,function(J,I){unit=F.cssUnit(I);if(unit[0]>0){H[I]=unit[0]*E+unit[1]}});return H},animateClass:function(G,H,J,I){var E=(typeof J=="function"?J:(I?I:null));var F=(typeof J=="object"?J:null);return this.each(function(){var O={};var M=C(this);var N=M.attr("style")||"";if(typeof N=="object"){N=N["cssText"]}if(G.toggle){M.hasClass(G.toggle)?G.remove=G.toggle:G.add=G.toggle}var K=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.addClass(G.add)}if(G.remove){M.removeClass(G.remove)}var L=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.removeClass(G.add)}if(G.remove){M.addClass(G.remove)}for(var P in L){if(typeof L[P]!="function"&&L[P]&&P.indexOf("Moz")==-1&&P.indexOf("length")==-1&&L[P]!=K[P]&&(P.match(/color/i)||(!P.match(/color/i)&&!isNaN(parseInt(L[P],10))))&&(K.position!="static"||(K.position=="static"&&!P.match(/left|top|bottom|right/)))){O[P]=L[P]}}M.animate(O,H,F,function(){if(typeof C(this).attr("style")=="object"){C(this).attr("style")["cssText"]="";C(this).attr("style")["cssText"]=N}else{C(this).attr("style",N)}if(G.add){C(this).addClass(G.add)}if(G.remove){C(this).removeClass(G.remove)}if(E){E.apply(this,arguments)}})})}});C.fn.extend({_show:C.fn.show,_hide:C.fn.hide,__toggle:C.fn.toggle,_addClass:C.fn.addClass,_removeClass:C.fn.removeClass,_toggleClass:C.fn.toggleClass,effect:function(E,G,F,H){return C.effects[E]?C.effects[E].call(this,{method:E,options:G||{},duration:F,callback:H}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._show.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="show";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._hide.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="hide";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))||(arguments[0].constructor==Function)){return this.__toggle.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="toggle";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},addClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{add:F},E,H,G]):this._addClass(F)},removeClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{remove:F},E,H,G]):this._removeClass(F)},toggleClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{toggle:F},E,H,G]):this._toggleClass(F)},morph:function(E,G,F,I,H){return C.effects.animateClass.apply(this,[{add:G,remove:E},F,I,H])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(E){var F=this.css(E),G=[];C.each(["em","px","%","pt"],function(H,I){if(F.indexOf(I)>0){G=[parseFloat(F),I]}});return G}});C.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(F,E){C.fx.step[E]=function(G){if(G.state==0){G.start=D(G.elem,E);G.end=B(G.end)}G.elem.style[E]="rgb("+[Math.max(Math.min(parseInt((G.pos*(G.end[0]-G.start[0]))+G.start[0]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[1]-G.start[1]))+G.start[1]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[2]-G.start[2]))+G.start[2]),255),0)].join(",")+")"}});function B(F){var E;if(F&&F.constructor==Array&&F.length==3){return F}if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return[parseInt(E[1]),parseInt(E[2]),parseInt(E[3])]}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return[parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55]}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return[parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16)]}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return[parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16)]}if(E=/rgba\(0, 0, 0, 0\)/.exec(F)){return A["transparent"]}return A[C.trim(F).toLowerCase()]}function D(G,E){var F;do{F=C.curCSS(G,E);if(F!=""&&F!="transparent"||C.nodeName(G,"body")){break}E="backgroundColor"}while(G=G.parentNode);return B(F)}var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};C.easing.jswing=C.easing.swing;C.extend(C.easing,{def:"easeOutQuad",swing:function(F,G,E,I,H){return C.easing[C.easing.def](F,G,E,I,H)},easeInQuad:function(F,G,E,I,H){return I*(G/=H)*G+E},easeOutQuad:function(F,G,E,I,H){return -I*(G/=H)*(G-2)+E},easeInOutQuad:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G+E}return -I/2*((--G)*(G-2)-1)+E},easeInCubic:function(F,G,E,I,H){return I*(G/=H)*G*G+E},easeOutCubic:function(F,G,E,I,H){return I*((G=G/H-1)*G*G+1)+E},easeInOutCubic:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G+E}return I/2*((G-=2)*G*G+2)+E},easeInQuart:function(F,G,E,I,H){return I*(G/=H)*G*G*G+E},easeOutQuart:function(F,G,E,I,H){return -I*((G=G/H-1)*G*G*G-1)+E},easeInOutQuart:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G+E}return -I/2*((G-=2)*G*G*G-2)+E},easeInQuint:function(F,G,E,I,H){return I*(G/=H)*G*G*G*G+E},easeOutQuint:function(F,G,E,I,H){return I*((G=G/H-1)*G*G*G*G+1)+E},easeInOutQuint:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G*G+E}return I/2*((G-=2)*G*G*G*G+2)+E},easeInSine:function(F,G,E,I,H){return -I*Math.cos(G/H*(Math.PI/2))+I+E},easeOutSine:function(F,G,E,I,H){return I*Math.sin(G/H*(Math.PI/2))+E},easeInOutSine:function(F,G,E,I,H){return -I/2*(Math.cos(Math.PI*G/H)-1)+E},easeInExpo:function(F,G,E,I,H){return(G==0)?E:I*Math.pow(2,10*(G/H-1))+E},easeOutExpo:function(F,G,E,I,H){return(G==H)?E+I:I*(-Math.pow(2,-10*G/H)+1)+E},easeInOutExpo:function(F,G,E,I,H){if(G==0){return E}if(G==H){return E+I}if((G/=H/2)<1){return I/2*Math.pow(2,10*(G-1))+E}return I/2*(-Math.pow(2,-10*--G)+2)+E},easeInCirc:function(F,G,E,I,H){return -I*(Math.sqrt(1-(G/=H)*G)-1)+E},easeOutCirc:function(F,G,E,I,H){return I*Math.sqrt(1-(G=G/H-1)*G)+E},easeInOutCirc:function(F,G,E,I,H){if((G/=H/2)<1){return -I/2*(Math.sqrt(1-G*G)-1)+E}return I/2*(Math.sqrt(1-(G-=2)*G)+1)+E},easeInElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K)==1){return E+L}if(!J){J=K*0.3}if(G").css({position:"absolute",visibility:"visible",left:-D*(G/E),top:-F*(C/I)}).parent().addClass("effects-explode").css({position:"absolute",overflow:"hidden",width:G/E,height:C/I,left:J.left+D*(G/E)+(B.options.mode=="show"?(D-Math.floor(E/2))*(G/E):0),top:J.top+F*(C/I)+(B.options.mode=="show"?(F-Math.floor(I/2))*(C/I):0),opacity:B.options.mode=="show"?0:1}).animate({left:J.left+D*(G/E)+(B.options.mode=="show"?0:(D-Math.floor(E/2))*(G/E)),top:J.top+F*(C/I)+(B.options.mode=="show"?0:(F-Math.floor(I/2))*(C/I)),opacity:B.options.mode=="show"?1:0},B.duration||500)}}setTimeout(function(){B.options.mode=="show"?H.css({visibility:"visible"}):H.css({visibility:"visible"}).hide();if(B.callback){B.callback.apply(H[0])}H.dequeue();A(".effects-explode").remove()},B.duration||500)})}})(jQuery);/*
+ * jQuery UI Effects Fold 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * effects.core.js
+ */
(function(A){A.effects.fold=function(B){return this.queue(function(){var E=A(this),J=["position","top","left"];var G=A.effects.setMode(E,B.options.mode||"hide");var N=B.options.size||15;var M=!(!B.options.horizFirst);A.effects.save(E,J);E.show();var D=A.effects.createWrapper(E).css({overflow:"hidden"});var H=((G=="show")!=M);var F=H?["width","height"]:["height","width"];var C=H?[D.width(),D.height()]:[D.height(),D.width()];var I=/([0-9]+)%/.exec(N);if(I){N=parseInt(I[1])/100*C[G=="hide"?0:1]}if(G=="show"){D.css(M?{height:0,width:N}:{height:N,width:0})}var L={},K={};L[F[0]]=G=="show"?C[0]:N;K[F[1]]=G=="show"?C[1]:0;D.animate(L,B.duration/2,B.options.easing).animate(K,B.duration/2,B.options.easing,function(){if(G=="hide"){E.hide()}A.effects.restore(E,J);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery);/*
+ * jQuery UI Effects Highlight 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * effects.core.js
+ */
(function(A){A.effects.highlight=function(B){return this.queue(function(){var E=A(this),D=["backgroundImage","backgroundColor","opacity"];var H=A.effects.setMode(E,B.options.mode||"show");var C=B.options.color||"#ffff99";var G=E.css("backgroundColor");A.effects.save(E,D);E.show();E.css({backgroundImage:"none",backgroundColor:C});var F={backgroundColor:G};if(H=="hide"){F["opacity"]=0}E.animate(F,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(H=="hide"){E.hide()}A.effects.restore(E,D);if(H=="show"&&A.browser.msie){this.style.removeAttribute("filter")}if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery);/*
+ * jQuery UI Effects Pulsate 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * effects.core.js
+ */
(function(A){A.effects.pulsate=function(B){return this.queue(function(){var D=A(this);var F=A.effects.setMode(D,B.options.mode||"show");var E=B.options.times||5;if(F=="hide"){E--}if(D.is(":hidden")){D.css("opacity",0);D.show();D.animate({opacity:1},B.duration/2,B.options.easing);E=E-2}for(var C=0;C').appendTo(document.body);if(B.options.className){D.addClass(B.options.className)}D.addClass(B.options.className);D.css({top:C.top,left:C.left,height:E.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:E.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth")),position:"absolute"});C=F.offset();animation={top:C.top,left:C.left,height:F.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:F.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth"))};D.animate(animation,B.duration,B.options.easing,function(){D.remove();if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery);
\ No newline at end of file
diff --git a/TracBooking/tracbooking/macros.py b/TracBooking/tracbooking/macros.py
new file mode 100644
index 0000000..b290412
--- /dev/null
+++ b/TracBooking/tracbooking/macros.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+from genshi.builder import tag
+from genshi import Markup
+from trac.wiki.macros import WikiMacroBase
+from trac.util.translation import _
+from trac.web.chrome import add_script
+from datetime import datetime, timedelta
+from pkg_resources import resource_filename
+
+class CountDownMacro(WikiMacroBase):
+
+ """Renders an overview of active RendezVouses"""
+
+ revision = "$Rev$"
+ url = "$URL$"
+ def expand_macro(self, formatter, name, content):
+ try:
+ event_datetime = datetime(*tuple(time.strptime("2010, 07, 16", "%Y, %m, %d"))[:3])
+ except Exception:
+ return ""
+ dt = event_datetime - datetime.now()
+ hours = "%d:%d" % (dt.seconds / 3600, (dt.seconds % 3600) / 60)
+ days = str(dt.days)
+ return Markup("""
+
+
+
+
CountDown
+ %s Tage
+ %s
+
+
""" % (days, hours))
diff --git a/TracBooking/tracbooking/model.py b/TracBooking/tracbooking/model.py
new file mode 100644
index 0000000..ce68d03
--- /dev/null
+++ b/TracBooking/tracbooking/model.py
@@ -0,0 +1,1308 @@
+# -*- coding: utf-8 -*-
+
+from trac.core import *
+from trac.perm import PermissionSystem
+from trac.db import Table, Column, Index
+from datetime import datetime
+from trac.util.datefmt import utc, to_timestamp
+from trac.util.text import to_unicode
+from trac.env import IEnvironmentSetupParticipant
+from tracbooking.utils import validate_id, make_hash
+
+__all__ = [
+ 'Attendee',
+ 'BookingOption',
+ 'AvailableOption',
+ 'BookingModelsupplier',
+ 'Event',
+ 'EventAccount',
+ 'Option2Event',
+ 'Supplier',
+ 'BookingReminder',
+ "AvailableOptionVariation",
+ "BookingOptionVariation"]
+
+class BookingOption(object):
+ def __init__(self, env, bo_id, a_id, ao_id, count, fetch_variations=False):
+ self.env = env
+ self.bo_id = int(bo_id)
+ self.a_id = int(a_id)
+ self.ao_id = int(ao_id)
+ self.count = int(count)
+ self.variations = []
+ if fetch_variations:
+ self.variations = BookingOptionVariation.fetch_by_attendee(env, a_id)
+
+ @staticmethod
+ def fetch_one(env, a_id, ao_id, fetch_variations=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT bo_id, a_id, ao_id, count " \
+ "FROM booking_option " \
+ "WHERE a_id=%s and ao_id=%s", (a_id, ao_id))
+ row = cursor.fetchone()
+ if not row:
+ return []
+ return BookingOption(env, fetch_variations=fetch_variations, *row)
+
+ @staticmethod
+ def fetch_by_attendee(env, a_id, fetch_variations=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT bo_id, a_id, ao_id, count FROM booking_option " \
+ "WHERE a_id=%s", (a_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ return [BookingOption(env, fetch_variations=fetch_variations, *row) for row in rows]
+
+ @staticmethod
+ def exists(env, a_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT COUNT(*) FROM booking_option " \
+ "WHERE o_id=%s;", (a_id,))
+ row = cursor.fetchone()
+ return row[0] > 0
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_option " \
+ "(a_id, ao_id, count) " \
+ "VALUES(%s, %s, %s);", (
+ self.a_id,
+ self.ao_id,
+ self.count))
+ db.commit()
+ self.bo_id = db.get_last_id(cursor, 'booking_option')
+
+ @staticmethod
+ def delete(env, a_id, ao_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM booking_option " \
+ "WHERE a_id =%s and ao_id=%s;", (a_id, ao_id))
+ db.commit()
+
+ @staticmethod
+ def delete_by_attendee(env, a_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM booking_option " \
+ "WHERE a_id =%s;", (a_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("UPDATE booking_option " \
+ "SET count=%s " \
+ "WHERE a_id=%s and ao_id=%s;", (
+ self.count,
+ self.a_id,
+ self.ao_id))
+ db.commit()
+
+class BookingOptionVariation(object):
+ def __init__(self, env, attendee_id, variation_id, ovi_id):
+ self.env = env
+ self.attendee_id = attendee_id
+ self.variation_id = variation_id
+ self.ovi_id = ovi_id
+
+ @staticmethod
+ def fetch_one(env, attendee_id, variation_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT attendee_id,variation_id,ovi_id " \
+ "FROM booking_option_variations " \
+ "WHERE attendee_id=%s AND variation_id=%s;", (attendee_id,variation_id))
+ row = cursor.fetchone()
+ return row and BookingOptionVariation(env, *row) or None
+
+ @staticmethod
+ def fetch_by_attendee(env, attendee_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT attendee_id,variation_id,ovi_id " \
+ "FROM booking_option_variations " \
+ "WHERE attendee_id=%s;", (attendee_id,))
+ return [BookingOptionVariation(env, *row) for row in cursor.fetchall()]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_option_variations " \
+ "(attendee_id,variation_id,ovi_id) " \
+ "VALUES(%s, %s, %s);", (
+ self.attendee_id,
+ self.variation_id,
+ self.ovi_id))
+ db.commit()
+
+ @staticmethod
+ def delete(self, env, bov_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM booking_option_variations " \
+ "WHERE attendee_id=%s and variation_id=%s;", (attendee_id,variation_id))
+ db.commit()
+
+ @staticmethod
+ def update(env, attendee_id, variation_id, ovi_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("UPDATE booking_option_variations " \
+ "SET ovi_id=%s WHERE attendee_id=%s and variation_id=%s;", (ovi_id, attendee_id, variation_id))
+ db.commit()
+
+class AvailableOption(object):
+ def __init__(self, env, ao_id, name, description, price, active, min_count, max_count, supplier_id, ext_id, stock_count, fetch_variations=True, attendee_id=None):
+ self.env = env
+ self.ao_id = ao_id
+ self.name = name
+ self.description = description
+ self.price = price
+ self.active = active
+ self.min_count = min_count
+ self.max_count = max_count
+ self.supplier_id = supplier_id
+ self.ext_id = ext_id
+ self.stock_count = stock_count
+ self.variations = fetch_variations and AvailableOptionVariation.fetch_all(env, ao_id, attendee_id=attendee_id) or []
+
+ @staticmethod
+ def fetch_one(env, ao_id=None, name=None, fetch_variations=True, attendee_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not name:
+ cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count
+ FROM booking_available_option
+ WHERE ao_id=%s""", (ao_id,))
+ else:
+ cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count
+ FROM booking_available_option
+ WHERE name=%s""", (name,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return AvailableOption(env, fetch_variations=fetch_variations, attendee_id=attendee_id, *row)
+
+ @staticmethod
+ def fetch_all(env, only_active=False, fetch_variations=True):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not only_active:
+ cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count
+ FROM booking_available_option;""")
+ else:
+ cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count
+ FROM booking_available_option where active=1;""")
+ return [AvailableOption(env, fetch_variations=fetch_variations, *row) for row in cursor.fetchall()]
+
+ @staticmethod
+ def fetch_by_event(env, e_id):
+ maps = Option2Event.fetch_by_event(env, e_id)
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ maps = [m.ao_id for m in maps]
+ s = """SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count
+ FROM booking_available_option where ao_id in %s;""" % str(tuple(maps))
+ cursor.execute(s)
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ return [AvailableOption(env, *row) for row in cursor.fetchall()]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""INSERT INTO booking_available_option
+ (name, description, price, active, min_count, max_count,supplier_id,ext_id,stock_count)
+ VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", (
+ self.name,
+ self.description,
+ self.price,
+ self.active,
+ self.min_count,
+ self.max_count,
+ self.supplier_id,
+ self.ext_id,
+ self.stock_count))
+ db.commit()
+ self.ao_id = db.get_last_id(cursor, 'booking_available_option')
+
+ @staticmethod
+ def delete(env, ao_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""DELETE FROM booking_available_option
+ WHERE ao_id =%s;""", (ao_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""UPDATE booking_available_option
+ SET name=%s,
+ description=%s,
+ price=%s,
+ active=%s,
+ min_count=%s,
+ max_count=%s,
+ supplier_id=%s,
+ ext_id=%s,
+ stock_count=%s
+ WHERE ao_id = %s;""", (
+ self.name,
+ self.description,
+ self.price,
+ self.active,
+ self.min_count,
+ self.max_count,
+ self.supplier_id,
+ self.ext_id,
+ self.stock_count,
+ self.ao_id))
+ db.commit()
+
+class AvailableOptionVariation(object):
+ def __init__(self, env, variation_id, option_id, name, attendee_id=None):
+ self.env = env
+ self.variation_id = variation_id
+ self.option_id = option_id
+ self.name = name
+ self.variations = AvailableOptionVariationItem.fetch_all(env, variation_id)
+ self.selected_data = None
+ if attendee_id:
+ selected = attendee_id and BookingOptionVariation.fetch_one(env, attendee_id, variation_id) or None
+ if selected:
+ self.selected_data = AvailableOptionVariationItem.fetch_one(env, selected.ovi_id)
+
+ @staticmethod
+ def fetch_one(env, variation_id=None, attendee_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not name:
+ cursor.execute("SELECT variation_id,option_id,name " \
+ "FROM booking_available_option_variations " \
+ "WHERE variation_id=%s", (variation_id,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return AvailableOptionVariation(env, attendee_id=attendee_id, *row)
+
+ @staticmethod
+ def fetch_all(env, option_id, attendee_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT variation_id,option_id,name " \
+ "FROM booking_available_option_variations " \
+ "WHERE option_id=%s", (option_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return None
+ return [AvailableOptionVariation(env, attendee_id=attendee_id, *row) for row in rows]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_available_option_variations " \
+ "(option_id, name) " \
+ "VALUES(%s, %s, %s)", (
+ self.option_id,
+ self.name))
+ db.commit()
+ self.variation_id = db.get_last_id(cursor, 'booking_available_option_variations')
+
+ @staticmethod
+ def delete(env, ovi_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM booking_available_option_variations " \
+ "WHERE variation_id =%s;", (variation_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("PDATE booking_available_option_variations " \
+ "SET option_id=%s, " \
+ "name=%s " \
+ "WHERE variation_id = %s;", (
+ self.option_id,
+ self.name,
+ self.variation_id))
+ db.commit()
+
+class AvailableOptionVariationItem(object):
+ def __init__(self, env, ovi_id, variation_id, name, value, description=""):
+ self.env = env
+ self.ovi_id = ovi_id
+ self.variation_id = variation_id
+ self.name = name
+ self.value = value
+ self.description = description
+
+ @staticmethod
+ def fetch_one(env, ovi_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT ovi_id,variation_id,name,value,description " \
+ "FROM booking_available_option_variation_items " \
+ "WHERE ovi_id=%s", (ovi_id,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return AvailableOptionVariationItem(env, *row)
+
+ @staticmethod
+ def fetch_all(env, variation_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT ovi_id,variation_id,name,value,description " \
+ "FROM booking_available_option_variation_items " \
+ "WHERE variation_id=%s", (variation_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return None
+ return [AvailableOptionVariationItem(env, *row) for row in rows]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_available_option_variation_items " \
+ "(variation_id, name, value) " \
+ "VALUES(%s, %s, %s, %s)", (
+ self.variation_id,
+ self.name,
+ self.value,
+ self.description))
+ db.commit()
+ self.ovi_id = db.get_last_id(cursor, 'booking_available_option_variation_items')
+
+ @staticmethod
+ def delete(env, ovi_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM booking_available_option_variation_items " \
+ "WHERE ovi_id =%s;", (ovi_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("UPDATE booking_available_option_variation_items " \
+ "SET variation_id=%s, " \
+ "name=%s, " \
+ "value=%s, " \
+ "description=%s " \
+ "WHERE ovi_id = %s;", (
+ self.variation_id,
+ self.name,
+ self.value,
+ self.description,
+ self.ovi_id))
+ db.commit()
+
+class Supplier(object):
+
+ """I hate this coding shit. sqlalchemy rulez!"""
+ def __init__(self, env, supplier_id, name, address, phone, email, fax):
+
+ self.env = env
+ self.supplier_id = int(supplier_id)
+ self.name = name
+ self.address = address
+ self.phone = phone
+ self.email = email
+ self.fax = fax
+
+ @staticmethod
+ def fetch_one(env, supplier_id=0, name=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not name:
+ cursor.execute("SELECT name, address, phone, email, fax " \
+ "FROM supplier " \
+ "WHERE supplier_id=%s", (supplier_id,))
+ else:
+ cursor.execute("SELECT name, address, phone, email, fax " \
+ "FROM supplier " \
+ "WHERE name=%s", (name,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return Supplier(env, *row)
+
+ @staticmethod
+ def fetch_all(env):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT supplier_id, name, address, phone, email, fax FROM supplier;")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ return [Supplier(env, *row) for row in rows]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO supplier " \
+ "(name, address, phone, email, fax) " \
+ "VALUES(%s, %s, %s, %s, %s)", (
+ self.supplier_id,
+ self.name,
+ self.address,
+ self.phone,
+ self.email,
+ self.fax))
+ db.commit()
+ self.supplier_id = db.get_last_id(cursor, 'supplier')
+
+ @staticmethod
+ def delete(env, a_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("DELETE FROM supplier WHERE supplier_id = %s;", (supplier_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("UPDATE supplier " \
+ "SET name=%s, " \
+ "address=%s, " \
+ "phone=%s, " \
+ "email=%s, " \
+ "fax=%s " \
+ "WHERE supplier_id=%s;", (
+ self.name,
+ self.address,
+ self.phone,
+ self.email,
+ self.fax,
+ self.supplier_id))
+ db.commit()
+
+
+class Attendee(object):
+
+ def __init__(self, env, a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount, fetch_options=False, fetch_variations=False):
+ self.env = env
+ self.a_id = int(a_id)
+ self.e_id = int(e_id)
+ self.ext_id = to_unicode(ext_id)
+ self.nick = to_unicode(nick)
+ self.email = to_unicode(email)
+ self.finished = int(bool(finished))
+ self.has_paid = int(bool(has_paid))
+ self.time = time
+ self.actual_amount = actual_amount
+ self.options = None
+ if fetch_options:
+ self.options = BookingOption.fetch_by_attendee(env, self.a_id, fetch_variations=fetch_variations)
+
+ @staticmethod
+ def fetch_one(env, a_id=0, nick=None, e_id=0, fetch_options=False, fetch_variations=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not nick:
+ cursor.execute("""SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount
+ FROM attendee
+ WHERE a_id=%s""", (a_id,))
+ else:
+ cursor.execute("""SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount
+ FROM attendee
+ WHERE nick=%s and e_id=%s""", (nick, e_id))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount = row
+ return Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.fromtimestamp(time, utc), actual_amount, fetch_options=fetch_options, fetch_variations=fetch_variations)
+
+ @staticmethod
+ def fetch_all(env, e_id=0, fetch_options=False, fetch_variations=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ s = "SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount FROM attendee %s;"
+ if e_id > 0:
+ s = s % "WHERE attendee.e_id=%s"
+ cursor.execute(s, (e_id,))
+ else:
+ cursor.execute(s % "")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ res = []
+ for row in rows:
+ a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount = row
+ res.append(Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.fromtimestamp(time, utc), actual_amount, fetch_options=fetch_options, fetch_variations=fetch_variations))
+ return res
+
+ @staticmethod
+ def fetch_all_sorted(env, e_id=0, fetch_options=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ s = "SELECT attendee.a_id, attendee.e_id, attendee.ext_id, attendee.nick, attendee.email, attendee.finished, attendee.has_paid, attendee.time, attendee.actual_amount, booking_event.name FROM attendee, booking_event WHERE attendee.e_id=booking_event.e_id %s ORDER BY booking_event.name;"
+ if e_id > 0:
+ s = s % "AND attendee.e_id=%s"
+ cursor.execute(s, (e_id,))
+ else:
+ cursor.execute(s % "")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ oldname = rows[0][-1]
+ curname = rows[0][-1]
+ res = []
+ tmp = []
+ for row in rows:
+ curname = row[-1]
+ if curname != oldname:
+ res.append(tmp)
+ tmp = []
+ a_id, e_id, ext_id, nick, email, finished, has_paid, time, name, actual_amount = row
+ a = Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.fromtimestamp(time, utc), actual_amount, fetch_options)
+ a.name = name
+ tmp.append(a)
+ oldname = curname
+ res.append(tmp)
+ return res
+
+ @staticmethod
+ def exists(env, nick):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""SELECT COUNT(*) FROM attendee
+ WHERE nick=%s;""", (nick,))
+ row = cursor.fetchone()
+ return row[0] > 0
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""INSERT INTO attendee
+ (e_id, ext_id, nick, email, finished, has_paid, time, actual_amount)
+ VALUES(%s, %s, %s, %s, %s, %s, %s, %s)""", (
+ self.e_id,
+ self.ext_id,
+ self.nick,
+ self.email,
+ self.finished,
+ self.has_paid,
+ to_timestamp(self.time),
+ self.actual_amount))
+ db.commit()
+ self.a_id = db.get_last_id(cursor, 'attendee')
+
+ @staticmethod
+ def delete(env, a_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""DELETE FROM attendee
+ WHERE a_id =%s;""", (a_id,))
+ db.commit()
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""UPDATE attendee
+ SET nick=%s,
+ email=%s,
+ finished=%s,
+ has_paid=%s,
+ actual_amount=%s
+ WHERE a_id=%s;""", (
+ self.nick,
+ self.email,
+ self.finished,
+ self.has_paid,
+ self.actual_amount,
+ self.a_id))
+ db.commit()
+
+ def calculate_fee(self):
+ cache = {}
+ res = 0.0
+ for i in self.options:
+ opt = AvailableOption.fetch_one(self.env, i.ao_id)
+ res += opt.price * i.count
+ return "%.2f" % res
+
+class EventAccount(object):
+ def __init__(self, env, ea_id, e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason):
+ self.env = env
+ self.ea_id = ea_id
+ self.e_id = e_id
+ self.account_owner = account_owner
+ self.account_no = account_no
+ self.bank_name = bank_name
+ self.bank_no = bank_no
+ self.first_reason = first_reason
+ self.second_reason = second_reason
+
+ @staticmethod
+ def fetch_by_event(env, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""SELECT *
+ FROM event_account
+ WHERE e_id=%s""", (e_id,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return EventAccount(env, *row)
+
+ @staticmethod
+ def copy_by_event(env, old_id, new_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT account_owner, account_no, bank_name, bank_no, first_reason, second_reason FROM event_account where e_id=%s;", (old_id,))
+ row = cursor.fetchone()
+ account_owner, account_no, bank_name, bank_no, first_reason, second_reason = row
+
+ cursor.execute("INSERT INTO event_account " \
+ "(e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason) " \
+ "VALUES(%s,%s,%s,%s,%s,%s,%s);", (
+ new_id,
+ account_owner,
+ account_no,
+ bank_name,
+ bank_no,
+ first_reason,
+ second_reason))
+
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO event_account " \
+ "(e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason) " \
+ "VALUES(%s, %s, %s, %s, %s, %s, %s)", (
+ self.e_id,
+ self.account_owner,
+ self.account_no,
+ self.bank_name,
+ self.bank_no,
+ self.first_reason,
+ self.second_reason))
+ db.commit()
+ self.a_id = db.get_last_id(cursor, 'event_account')
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("UPDATE event_account SET " \
+ "e_id=%s, " \
+ "account_owner=%s, " \
+ "account_no=%s, " \
+ "bank_name=%s, " \
+ "bank_no=%s, " \
+ "first_reason=%s, " \
+ "second_reason=%s;", (
+ self.e_id,
+ self.account_owner,
+ self.account_no,
+ self.bank_name,
+ self.bank_no,
+ self.first_reason,
+ self.second_reason))
+ db.commit()
+ self.ea_id = db.get_last_id(cursor, 'event_account')
+
+ def __zero__(self):
+ return self.ea_id != 0
+
+class Event(object):
+ def __init__(self, env, e_id, name, description, time_begin, time_end, register_deadline=datetime.now(utc), edit_deadline=datetime.now(utc), payment_deadline=datetime.now(utc), fetch_options=False, only_active=False, attendee_id=None):
+ self.env = env
+ self.e_id = e_id
+ self.name = name
+ self.description = description
+ self.time_begin = time_begin
+ self.time_end = time_end
+ self.register_deadline = register_deadline
+ self.edit_deadline = edit_deadline
+ self.payment_deadline = payment_deadline
+ self.options = []
+ if fetch_options:
+ relations = Option2Event.fetch_by_event(self.env, self.e_id)
+ for relation in relations:
+ option = AvailableOption.fetch_one(self.env, relation.ao_id, attendee_id=attendee_id)
+ if option:
+ if only_active and not option.active:
+ continue
+ self.options.append(option)
+
+ @staticmethod
+ def fetch_one(env, e_id=0, name=None, fetch_options=False, only_active=False, attendee_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if not name:
+ cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline " \
+ "FROM booking_event " \
+ "WHERE e_id=%s", (e_id,))
+ else:
+ cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline "
+ "FROM booking_event " \
+ "WHERE name=%s", (name,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row
+ return Event(env, e_id, name, description, datetime.fromtimestamp(time_begin, utc), datetime.fromtimestamp(time_end, utc), datetime.fromtimestamp(register_deadline, utc), datetime.fromtimestamp(edit_deadline, utc), datetime.fromtimestamp(payment_deadline, utc), fetch_options=fetch_options, only_active=only_active, attendee_id=attendee_id)
+
+ @staticmethod
+ def fetch_all(env, fetch_options=False, only_active=False, attendee_id=None):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline FROM booking_event;""")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ res = []
+ for row in rows:
+ e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row
+ res.append(Event(env, e_id, name, description, datetime.fromtimestamp(time_begin, utc), datetime.fromtimestamp(time_end, utc), datetime.fromtimestamp(register_deadline, utc), datetime.fromtimestamp(edit_deadline, utc), datetime.fromtimestamp(payment_deadline, utc), fetch_options=fetch_options, only_active=only_active, attendee_id=attendee_id))
+ return res
+
+ @staticmethod
+ def copy(env, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline " \
+ "FROM booking_event " \
+ "WHERE e_id=%s", (e_id,))
+
+ row = cursor.fetchone()
+ if not row:
+ return None
+ e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row
+ event = Event(env, e_id, "Kopie von " + name, description, datetime.fromtimestamp(time_begin, utc), datetime.fromtimestamp(time_end, utc), datetime.fromtimestamp(register_deadline, utc), datetime.fromtimestamp(edit_deadline, utc), datetime.fromtimestamp(payment_deadline, utc))
+ event.commit()
+ event_account = EventAccount.copy_by_event(env, e_id, event.e_id)
+
+ relations = Option2Event.fetch_by_event(env, e_id)
+ for relation in relations:
+ print "relation", relation.ao_id, event.e_id
+ Option2Event.copy_by_event(env, relation.ao_id, event.e_id)
+
+
+ def add_options(self, attendee_id):
+ self.options = list()
+ relations = Option2Event.fetch_by_event(self.env, self.e_id)
+ for relation in relations:
+ option = AvailableOption.fetch_one(self.env, relation.ao_id, attendee_id=attendee_id)
+ if option:
+ self.options.append(option)
+
+ @staticmethod
+ def exists(env, name):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT COUNT(e_id) FROM booking_event WHERE name=%s;", (name,))
+ row = cursor.fetchone()
+ return row[0] > 0
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_event " \
+ "(name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline) " \
+ "VALUES(%s, %s, %s, %s, %s, %s, %s)", (
+ self.name,
+ self.description,
+ to_timestamp(self.time_begin),
+ to_timestamp(self.time_end),
+ to_timestamp(self.register_deadline),
+ to_timestamp(self.edit_deadline),
+ to_timestamp(self.payment_deadline)))
+ db.commit()
+ self.e_id = db.get_last_id(cursor, 'booking_event')
+
+ @staticmethod
+ def delete(env, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ try:
+ cursor.execute("DELETE FROM booking_event WHERE e_id=%s;", (e_id,))
+ db.commit()
+ except Exception, e:
+ env.log.debug("Event delete failed\n%s" + str(e))
+ pass
+
+ def update(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("""UPDATE booking_event
+ SET name=%s,
+ description=%s,
+ time_begin=%s,
+ time_end=%s,
+ register_deadline=%s,
+ edit_deadline=%s,
+ payment_deadline=%s
+ WHERE e_id=%s;""", (
+ self.name,
+ self.description,
+ to_timestamp(self.time_begin),
+ to_timestamp(self.time_end),
+ to_timestamp(self.register_deadline),
+ to_timestamp(self.edit_deadline),
+ to_timestamp(self.payment_deadline),
+ self.e_id))
+ db.commit()
+
+ def __zero__(self):
+ return self.e_id != 0
+
+class BookingReminder(object):
+ def __init__(self, env, reminder_id, e_id, text, notify_on, was_send_on=None):
+ self.env = env
+ self.reminder_id = reminder_id
+ self.e_id = e_id
+ self.text = text
+ self.notify_on = notify_on
+ self.was_send_on = was_send_on
+
+ @staticmethod
+ def fetch_one(env, reminder_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT * FROM booking_reminder WHERE reminder_id=%s;", (reminder_id,))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return BookingReminder(env, *row)
+
+ @staticmethod
+ def fetch_all(env):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT * FROM booking_reminder;")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ return [BookingReminder(env, *row) for row in rows]
+
+ @staticmethod
+ def fetch_by_event(env, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if e_id:
+ cursor.execute("""SELECT *
+ FROM booking_reminder
+ WHERE e_id=%s""", (e_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ return [BookingReminder(env, *row) for row in rows]
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO booking_reminder " \
+ "(reminder_id, e_id, text, notify_on, was_send_on) " \
+ "VALUES(%s, %s,%s, %s,%s)", (
+ self.reminder_id,
+ self.e_id,
+ self.text,
+ self.notify_on,
+ self.was_send_on))
+ db.commit()
+ self.reminder_id = db.get_last_id(cursor, 'booking_reminder')
+
+ @staticmethod
+ def update(env, ao_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ try:
+ cursor.execute("UPDATE booking_reminder SET " \
+ "text=%s " \
+ "notify_on=%s " \
+ "was_send_on=%s " \
+ "WHERE reminder_id=%s and e_id=%s;",
+ (self.text, self.notify_on, self.was_send_on, self.reminder_id, self.e_id))
+ db.commit()
+ except Exception:
+ pass
+
+ @staticmethod
+ def delete(env, ao_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ try:
+ cursor.execute("DELETE FROM booking_reminder WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id,))
+ db.commit()
+ except Exception:
+ pass
+
+class Option2Event(object):
+
+ def __init__(self, env, ao_id, e_id):
+ self.env = env
+ self.ao_id = ao_id
+ self.e_id = e_id
+
+ @staticmethod
+ def fetch_one(env, ao_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT ao_id, e_id FROM option_to_event WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id))
+ row = cursor.fetchone()
+ if not row:
+ return None
+ return Option2Event(env, int(ao_id), int(e_id))
+
+ @staticmethod
+ def fetch_by_option(env, ao_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT ao_id, e_id " \
+ "FROM option_to_event " \
+ "WHERE ao_id=%s", (ao_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ res = []
+ for row in rows:
+ res.append(Option2Event(env, *row))
+ return res
+
+ @staticmethod
+ def fetch_by_event(env, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ if e_id:
+ cursor.execute("""SELECT ao_id, e_id
+ FROM option_to_event
+ WHERE e_id=%s""", (e_id,))
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ res = []
+ for row in rows:
+ res.append(Option2Event(env, *row))
+ return res
+
+ @staticmethod
+ def fetch_all(env, fetch=False):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("SELECT ao_id, e_id FROM option_to_event")
+ rows = cursor.fetchall()
+ if not rows:
+ return []
+ res = []
+ for ao_id, e_id in rows:
+ res.append(Option2Event(env, int(ao_id), int(e_id), fetch=fetch))
+ return res
+
+ @staticmethod
+ def copy_by_event(env, ao_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO option_to_event (ao_id, e_id) VALUES(%s, %s);", (ao_id, e_id))
+ db.commit()
+
+ def commit(self):
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute("INSERT INTO option_to_event " \
+ "(ao_id, e_id) " \
+ "VALUES(%s, %s)", (
+ self.ao_id,
+ self.e_id))
+ db.commit()
+ self.a_id = db.get_last_id(cursor, 'booking_event')
+
+ @staticmethod
+ def delete(env, ao_id, e_id):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ try:
+ cursor.execute("DELETE FROM option_to_event WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id,))
+ db.commit()
+ except Exception:
+ pass
+
+
+class BookingModelsupplier(Component):
+ implements(IEnvironmentSetupParticipant)
+ SCHEMA = [
+
+ Table('booking_event', key='e_id')[
+ Column('e_id', auto_increment=True),
+ Column('name'),
+ Column('description'),
+ Column('time_begin', type='int'),
+ Column('time_end', type='int'),
+ Column('register_deadline', type='int'),
+ Column('edit_deadline', type='int'),
+ Column('payment_deadline', type='int'),
+ Index(['name',])],
+
+ Table('event_account', key='ea_id')[
+ Column('ea_id', auto_increment=True),
+ Column('e_id', type='int'),
+ Column('account_owner'),
+ Column('account_no', type='int'),
+ Column('bank_name'),
+ Column('bank_no', type='int'),
+ Column('first_reason'),
+ Column('second_reason')],
+
+ Table('attendee', key='a_id')[
+ Column('a_id', auto_increment=True),
+ Column('e_id', type='int'),
+ Column('ext_id'),
+ Column('nick'),
+ Column('email'),
+ Column('finished', type='int'),
+ Column('has_paid', type='int'),
+ Column('time', type='int'),
+ Column('actual_amount', type='float'),
+ Index(['nick',]),
+ Index(['e_id',]),
+ Index(['ext_id',])],
+
+ # custom relation specification for event specific attendee attributes
+ Table('attendee_attributes', key='am_id')[
+ Column('am_id', auto_increment=True),
+ Column('e_id'),
+ Column('name'),
+ Column('type')],
+
+ # the actual values of attributes for event 'e_id' and attendee 'a_id'
+ Table('attendee_attribute_values', key='aam_id')[
+ Column('aam_id', auto_increment=True),
+ Column('eam_id', type='int'),
+ Column('a_id', type='int'),
+ Column('value')],
+
+ Table('supplier', key='supplier_id')[
+ Column('supplier_id', auto_increment=True),
+ Column('name'),
+ Column('address'),
+ Column('phone'),
+ Column('email'),
+ Column('fax'),
+ Index(['name',])],
+
+ Table('booking_available_option', key='ao_id')[
+ Column('ao_id', auto_increment=True),
+ Column('name'),
+ Column('description'),
+ Column('price', type='real'),
+ Column('active', type='int'),
+ Column('min_count', type='int'),
+ Column('max_count', type='int'),
+ Column('supplier_id', type='int'),
+ Column('ext_id', type='int'),
+ Column('stock_count', type='int')],
+
+ Table('booking_available_option_variations', key='variation_id')[
+ Column('variation_id', auto_increment=True),
+ Column('option_id'),
+ Column('name')],
+
+ Table('booking_available_option_variation_items', key='ovi_id')[
+ Column('ovi_id', auto_increment=True),
+ Column('variation_id'),
+ Column('name'),
+ Column('value'),
+ Column('description')],
+
+ Table('option_to_event', key=['ao_id', 'e_id'])[
+ Column('ao_id', type='int'),
+ Column('e_id', type='int')],
+
+ Table('booking_reminder', key='reminder_id')[
+ Column('reminder_id', type='int'),
+ Column('e_id', type='int'),
+ Column('text'),
+ Column('notify_on', type='int'),
+ Column('was_send_on', type='int')],
+
+ Table('booking_option', key=['a_id', 'ao_id'])[
+ Column('bo_id', auto_increment=True),
+ Column('a_id', type='int'),
+ Column('ao_id', type='int'),
+ Column('count', type='int')],
+
+ Table('booking_option_variations')[
+ Column('attendee_id', type='int'),
+ Column('variation_id', type='int'),
+ Column('ovi_id', type='int')]]
+
+ OptionVariationTrigger = "CREATE TRIGGER attendee_variation_trigger " \
+ "BEFORE DELETE ON attendee " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from booking_option_variations WHERE attendee_id = OLD.a_id; " \
+ "END;"
+
+ EventAttendeeTrigger = "CREATE TRIGGER event_attendee_trigger " \
+ "BEFORE DELETE ON booking_event " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from attendee WHERE e_id = OLD.e_id; " \
+ "END;"
+
+ EventAccountTrigger = "CREATE TRIGGER event_account_trigger " \
+ "BEFORE DELETE ON booking_event " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from event_account WHERE e_id = OLD.e_id; " \
+ "END;"
+
+ EventOption2EventTrigger = "CREATE TRIGGER event_option_to_event_trigger " \
+ "BEFORE DELETE ON booking_event " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from option_to_event WHERE e_id = OLD.e_id; " \
+ "END;"
+
+ EventBookingReminderTrigger = "CREATE TRIGGER event_booking_reminder_trigger " \
+ "BEFORE DELETE ON booking_event " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from booking_reminder WHERE e_id = OLD.e_id; " \
+ "END;"
+
+ AttendeeBookingOptionTrigger = "CREATE TRIGGER attendee_booking_option_trigger " \
+ "BEFORE DELETE ON attendee " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from booking_option WHERE a_id = OLD.a_id; " \
+ "END;"
+ AOptionOption2EventTrigger = "CREATE TRIGGER booking_available_option_option_to_event_trigger " \
+ "BEFORE DELETE ON booking_available_option " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from option_to_event WHERE ao_id = OLD.ao_id; " \
+ "END;"
+
+ AOptionBookingTrigger = "CREATE TRIGGER booking_available_option_booking_option_trigger " \
+ "BEFORE DELETE ON booking_available_option " \
+ "FOR EACH ROW BEGIN " \
+ "DELETE from booking_option WHERE ao_id = OLD.ao_id; " \
+ "END;"
+
+ def environment_created(self):
+
+ self._create_models(self.env.get_db_cnx())
+
+ def environment_needs_upgrade(self, db):
+ """First version - nothing to migrate, but possibly to create.
+ """
+
+ cursor = db.cursor()
+ try:
+ cursor.execute("select count(*) from attendee")
+ cursor.fetchone()
+ cursor.execute("select count(*) from event_account")
+ cursor.fetchone()
+ cursor.execute("select count(*) from booking_available_option")
+ cursor.fetchone()
+ cursor.execute("select count(*) from booking_option")
+ cursor.fetchone()
+ cursor.execute("select count(*) from booking_event")
+ cursor.fetchone()
+ cursor.execute("select count(*) from supplier")
+ cursor.fetchone()
+ cursor.execute("select count(*) from option_to_event")
+ cursor.fetchone()
+ return False
+ except:
+ db.rollback()
+ return True
+
+ def upgrade_environment(self, db):
+ """ nothing to do here for now
+ """
+ self._create_models(db)
+
+ def _create_models(self, db):
+
+ """Called when a new Trac environment is created."""
+
+ EVENT_DATA = (
+ (u'Matebestellung 2010-001',
+ u'',
+ to_timestamp(datetime(2010, 4, 24, 18, tzinfo=utc)),
+ to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc)),
+ to_timestamp(datetime(2010, 4, 29, 16, tzinfo=utc)),
+ to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc)),
+ to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc))),)
+
+ supplier_DATA = (
+ ('Getränke Rabe', "Hamm", "", "", ""))
+
+ OPTION_DATA = (
+ (u'Club Mate - 20 x 0.5L', u"""10 Liter frische leckere Club-Mate
+
+ 13.5 € Netto preis zzgl. 4.5 € Pfand
+
+ Falls Du Kisten zurückgeben willst, einfach die Anzahl der Rückgabekisten angeben""", 18.0, 1, 0, 0, 1, 0, 50),
+ (u'Matekiste Rückgabe', u'Nur komplette/vollständige Matekisten angeben', -4.5, 1, 0, 0, 1, 0, 1000),
+ )
+
+ AO_DATA = (
+ (1, 1),
+ (2, 1),
+ )
+
+
+ VARIATION_DATA = ()
+
+ ACCOUNT_DATA = (
+ (1, u'Chaostreff Dortmund', 4009368600, u'GLS-Bank', 43060967, u'Mate 2010/1', ''),
+ )
+
+ VARIATION_ITEM_DATA = ()
+
+ try:
+ try:
+ from trac.db import DatabaseManager
+ db_backend, _ = DatabaseManager(self.env)._get_connector()
+ except ImportError:
+ db_backend = self.env.get_db_cnx()
+
+ cursor = db.cursor()
+ for table in self.SCHEMA:
+ for stmt in db_backend.to_sql(table):
+ self.env.log.debug(stmt)
+ cursor.execute(stmt)
+ db.commit()
+
+ cursor.executemany("""INSERT INTO 'booking_event'
+ (name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline)
+ VALUES(%s, %s, %s, %s, %s, %s, %s)""", EVENT_DATA)
+
+ cursor.executemany("""INSERT INTO 'option_to_event'
+ (ao_id, e_id)
+ VALUES(%s, %s)""", AO_DATA)
+
+ cursor.executemany("""INSERT INTO 'event_account'
+ (e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason)
+ VALUES(%s, %s, %s, %s, %s, %s, %s)""", ACCOUNT_DATA)
+
+ #cursor.executemany("""INSERT INTO 'booking_available_option_variations'
+ #(variation_id, option_id, name)
+ #VALUES(%s, %s, %s)""", VARIATION_DATA)
+
+ #cursor.executemany("""INSERT INTO 'booking_available_option_variation_items'
+ #(ovi_id, variation_id, name, value, description)
+ #VALUES(%s, %s, %s, %s, %s)""", VARIATION_ITEM_DATA)
+
+ print OPTION_DATA
+ cursor.executemany("""INSERT INTO 'booking_available_option'
+ (name, description, price, active, min_count, max_count, supplier_id, ext_id, stock_count)
+ VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", OPTION_DATA)
+ cursor.execute(self.EventAttendeeTrigger)
+ cursor.execute(self.EventOption2EventTrigger)
+ cursor.execute(self.EventBookingReminderTrigger)
+ cursor.execute(self.AttendeeBookingOptionTrigger)
+ cursor.execute(self.AOptionBookingTrigger)
+ cursor.execute(self.AOptionOption2EventTrigger)
+ cursor.execute(self.OptionVariationTrigger)
+ db.commit()
+ except:
+ db.rollback()
+ raise
diff --git a/TracBooking/tracbooking/report.py b/TracBooking/tracbooking/report.py
new file mode 100644
index 0000000..17f4300
--- /dev/null
+++ b/TracBooking/tracbooking/report.py
@@ -0,0 +1,180 @@
+# -*- coding: utf-8 -*-
+
+import os
+from datetime import datetime
+
+from trac.util.datefmt import utc
+
+from tracbooking.model import Attendee, Event, EventAccount
+from tracbooking.utils import get_option_count
+
+
+def get_file():
+ import codecs
+ return codecs.open(u"/tmp/printout.txt", "wr", "utf-8")
+
+def add_doc(global_event, selected_tz, f):
+ #f.write(u".. header::\n")
+ #f.write(u" ###Page###\n")
+ #f.write(u" ###Title###\n")
+ dt = selected_tz.fromutc(datetime.now(utc)).strftime("%d.%m.%Y %H:%M")
+ d = u"Erstellt am: %s\n\n" % dt
+ f.write(d)
+
+ f.write(u"%s\n" % global_event.name)
+ f.write(u"%s\n\n" % ("=" * len(global_event.name)))
+
+
+def create_table(items, f):
+ l = list()
+ l.append((u"Artikel", u"Einzelpreis", u"Anzahl", u"Gesamtpreis"))
+ for i in items:
+ l.append((u"%s" % i[1], u"%.2f" % float(i[2]), u"%s" % i[3], u"%.2f" % float(i[4])))
+
+ widths = list()
+ for cell in xrange(4):
+ tmp = list()
+ for row in l:
+ tmp.append(len(row[cell]))
+ widths.append(max(tmp))
+
+ head = list()
+ for ix, j in enumerate(l[0]):
+ head.append(u" %s " % j.ljust(widths[ix]))
+ trenner = [u"=%s=" % (u"=" * i)
+ for i in widths]
+
+ trenner = u" ".join(trenner) + "\n"
+ f.write(trenner)
+ f.write(u" ".join(head) + "\n")
+ f.write(trenner)
+ for i in l[1:]:
+ t = list()
+ for ix, j in enumerate(i):
+ t.append(u" " + j.ljust(widths[ix]) + " ")
+ f.write(u" ".join(t) + u"\n")
+ indent = sum(widths[:3]) + 10
+ f.write(u"%s %s\n" % (
+ " Gesamt ".center(indent),
+ str("%.2f" % float(sum([item[4] for item in items]))).ljust(widths[3])))
+ f.write(u"%s %s\n\n" % (u"=" * indent, u"=" * (widths[3] + 2)))
+ f.write(u"\n")
+
+
+def add_summary(env, cursor, global_event, selected_tz, f):
+
+
+ query_old = "SELECT booking_option.ao_id,booking_available_option.name,booking_available_option.price," \
+ "SUM(booking_option.count),booking_available_option.price * SUM(booking_option.count)" \
+ "FROM booking_available_option,booking_option,option_to_event " \
+ "WHERE booking_available_option.ao_id = booking_option.ao_id AND " \
+ "booking_available_option.ao_id = option_to_event.ao_id AND " \
+ "option_to_event.e_id=%s GROUP BY booking_option.ao_id;"
+
+ query = "select " \
+ "booking_option.ao_id, " \
+ "booking_available_option.name, " \
+ "booking_available_option.price, " \
+ "SUM(booking_option.count), " \
+ "SUM(booking_option.count) * booking_available_option.price " \
+ "from " \
+ "booking_option,booking_available_option " \
+ "where " \
+ "booking_option.a_id IN (select a_id from attendee where e_id=%s) AND " \
+ "booking_option.ao_id = booking_available_option.ao_id " \
+ "group by " \
+ "booking_option.ao_id;"
+
+
+ cursor.execute(query, (global_event.e_id,))
+ items = cursor.fetchall()
+ create_table(items, f)
+
+def add_payment_info(attendee, account, f):
+ txt = "Unser Konto"
+ f.write(u"%s\n%s\n\n" % (txt, u"-" * len(txt)))
+
+ f.write(u" :Kontoinhaber: %s\n" % account.account_owner)
+ f.write(u" :Kontonummer: %s\n" % account.account_no)
+ f.write(u" :Blz: %s\n" % account.bank_no)
+ f.write(u" :Bank: %s\n" % account.bank_name)
+ f.write(u" :Betrag: %s\n" % attendee.calculate_fee())
+ f.write(u" :1. Überweisungszweck: %s\n" % account.first_reason)
+ f.write(u" :2. Überweisungszweck: %s\n" % ("%X" % attendee.a_id).rjust(4, "0"))
+ f.write(u"\n")
+
+
+def add_internal_attendee_data(attendee, f):
+ actual_amount = attendee.actual_amount and attendee.actual_amount or 0.0
+ f.write(u" :ID: %s\n" % ("%X" % attendee.a_id).rjust(4, "0"))
+ f.write(u" :Email: %s\n" % attendee.email)
+ f.write(u" :Soll-Betrag: %s\n" % attendee.calculate_fee())
+ f.write(u" :Ist-Betrag: %f\n" % actual_amount)
+ f.write(u" :Bezahlt: %s\n" % (u"Ja" if bool(attendee.has_paid) else u"Nein"))
+ f.write(u"\n")
+
+
+def add_attendee(global_event, attendee, f, internal=False):
+ global_event.add_options(attendee.a_id)
+
+ f.write(u"%s\n" % attendee.nick.replace("_", "\_"))
+ f.write(u"%s\n" % ("-" * len(attendee.nick)))
+
+ if internal:
+ add_internal_attendee_data(attendee, f)
+
+ items = []
+ for option in global_event.options:
+ get_option_count(attendee, option)
+ if not option.count:
+ continue
+
+ items.append([option.ao_id, option.name, option.price, option.count, option.price * option.count])
+
+ if items:
+ create_table(items, f)
+
+
+def add_attendees(env, cursor, global_event, selected_tz, f, internal=False):
+
+ attendees = Attendee.fetch_all(env, e_id=global_event.e_id, fetch_options=True)
+ attendees = sorted(attendees, key=lambda x: x.nick)
+
+ for attendee in attendees:
+ add_attendee(global_event, attendee, f, internal)
+
+
+def generate_pdf(f):
+ import rst2pdf.createpdf
+ f.close()
+
+ rst2pdf.createpdf.main(["/tmp/printout.txt", "-o" , "/tmp/printout.pdf"])
+ os.remove("/tmp/printout.txt")
+ tmp = open("/tmp/printout.pdf").read()
+ os.remove("/tmp/printout.pdf")
+ return tmp
+
+def create_report(env, e_id, selected_tz):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+ event = Event.fetch_one(env, e_id=e_id)
+ f = get_file()
+ add_doc(event, selected_tz, f)
+
+ add_summary(env, cursor, event, selected_tz, f)
+ add_attendees(env, cursor, event, selected_tz, f, True)
+ return generate_pdf(f)
+
+def create_attendee_report(env, event, attendee, selected_tz):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+
+ f = get_file()
+ add_doc(event, selected_tz, f)
+
+ my_attendee = Attendee.fetch_one(env, a_id=attendee.a_id, e_id=event.e_id, fetch_options=True)
+ account = EventAccount.fetch_by_event(env, event.e_id)
+ add_payment_info(my_attendee, account, f)
+ add_attendee(event, my_attendee, f)
+ return generate_pdf(f)
+
\ No newline at end of file
diff --git a/TracBooking/tracbooking/templates/admin_attendee_status_edit.html b/TracBooking/tracbooking/templates/admin_attendee_status_edit.html
new file mode 100644
index 0000000..06f615d
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_attendee_status_edit.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ Anmeldungsstatus für ${event.name}
+
+
+
+
+
Anmeldungsdaten von ${attendee.nick}
+
+
+
+
+
+ Verfügbare Artikel
+
+
+
+ Bestellte Artikel
+
+
+ Artikel Beschreibung Preis in € inkl. MwSt. Anzahl
+
+
+ ${option.name}
+ ${wiki_to_html(context, option.description)}
+ ${"%.2f" % option.price}
+ ${option.count and option.count or 0}
+
+ Summe: € ${fee}
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_attendees.html b/TracBooking/tracbooking/templates/admin_attendees.html
new file mode 100644
index 0000000..71c71e8
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_attendees.html
@@ -0,0 +1,52 @@
+
+
+
+
+ Teilnehmer verwalten für ${event.name}
+
+
+
+
+ Teilnehmer verwalten für ${event.name}
+
+
+
+ Bestellung auswählen
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_einkauf.html b/TracBooking/tracbooking/templates/admin_einkauf.html
new file mode 100644
index 0000000..b74ba45
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_einkauf.html
@@ -0,0 +1,39 @@
+
+
+
+
+ Bestellungen einsehen für ${eventname}
+
+
+
+
+
+
+
+ Name Einzelpreis € Anzahl Zusammen
+
+
+ ${item[1]} ${"%.2f" % float(item[2])} ${item[3]} ${"%.2f" % item[4]}
+
+
+
+ Gesamt Preis: ${sum([item[4] for item in items])}
+
+
+
+ Bestellung auswählen
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_events.html b/TracBooking/tracbooking/templates/admin_events.html
new file mode 100644
index 0000000..8978f6f
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_events.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+ Events verwalten
+
+
+ Events verwalten
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_options.html b/TracBooking/tracbooking/templates/admin_options.html
new file mode 100644
index 0000000..5850156
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_options.html
@@ -0,0 +1,70 @@
+
+
+
+
+ Optionen verwalten
+
+
+ Optionen verwalten
+
+
+
+
+
+
+
+
+ ${option.ao_id and "Editiere Option" or "Neue Option"}:
+
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_options_to_events.html b/TracBooking/tracbooking/templates/admin_options_to_events.html
new file mode 100644
index 0000000..3fcf221
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_options_to_events.html
@@ -0,0 +1,69 @@
+
+
+
+
+ $label_plural
+
+
+
+ Manage RendezVousTypes
+
+
+
+ Verknüpfe Option mit Event:
+
+
+ Option:
+
+ ${option.name}
+
+
+
+
+ Event:
+
+ ${event.name}
+
+
+
+
+
+ Grant permission to a RendezVousType.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/admin_reminder.html b/TracBooking/tracbooking/templates/admin_reminder.html
new file mode 100644
index 0000000..63395f2
--- /dev/null
+++ b/TracBooking/tracbooking/templates/admin_reminder.html
@@ -0,0 +1,63 @@
+
+
+
+
+ Benachrichtigungen verwalten
+
+
+
+
+ Benachrichtigungen verwalten für $eventname
+
+
+
+ Registrierte Benachrichtigungen: ${len(reminders)}
+
+
+
+
+
+
+
+
+ Neuer Reminder:
+
+ Erstelle neuen Reminder.
+
+
+
+
+
+
+ Event wählen
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/booking_accept.html b/TracBooking/tracbooking/templates/booking_accept.html
new file mode 100644
index 0000000..7ec85a4
--- /dev/null
+++ b/TracBooking/tracbooking/templates/booking_accept.html
@@ -0,0 +1,20 @@
+
+
+
+
+ Bitte bestätigen
+
+
+
+
$query
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/booking_events.html b/TracBooking/tracbooking/templates/booking_events.html
new file mode 100644
index 0000000..ec4a89a
--- /dev/null
+++ b/TracBooking/tracbooking/templates/booking_events.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ Übersicht Sammelbestellungen
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/booking_register.html b/TracBooking/tracbooking/templates/booking_register.html
new file mode 100644
index 0000000..40c1808
--- /dev/null
+++ b/TracBooking/tracbooking/templates/booking_register.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+ Anmeldung für ${event.name}
+
+
+
+
Teilnahme an '${event.name}'
+
+
${wiki_to_html(context, event.description, escape_newlines=preserve_newlines)}
+
Editierbar bis ${event.edit_deadline.strftime('%d.%m.%Y %H:%M')} Uhr.
+
Der Betrag deiner Bestellung muss spätestens am ${event.payment_deadline.strftime('%d.%m.%Y %H:%M')} Uhr auf unserem Konto eingegangen sein!!!
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/booking_status.html b/TracBooking/tracbooking/templates/booking_status.html
new file mode 100644
index 0000000..72a6189
--- /dev/null
+++ b/TracBooking/tracbooking/templates/booking_status.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+ Deine Artikel für ${event.name}
+
+
+
+
+
${event.name}
+
${wiki_to_html(context, event.description, escape_newlines=preserve_newlines)}
+
+
+
+
+
+ Bestellungen können verändert werden bis zum:
+ ${event.edit_deadline.strftime('%d.%m.%Y %H:%M')} Uhr.
+
+
+
+ Geld bitte auf unten angebenes Konto einzahlen bis zum:
+ ${event.payment_deadline.strftime('%d.%m.%Y %H:%M')} Uhr.
+
+
+ Der Liefertermin wird per Mail bekannt gegeben, sofern Du eine Mailaddresse angegeben hast.
+
+
+ Du kannst Deine Registrierung unten komplett löschen.
+
+
+ Wenn Du javascript angeschaltet hast, werden Änderungen beim Verlassen des Eingabefeldes automatisch gespeichert.
+Wenn Du javascript blockiert hast, musst Du nach Änderungen manuell auf den Speichern Button klicken.
+
+
+ Wenn Du mit Deiner Bestellung zufrieden bist, und die Bestellung abschliessen möchtest, dann drücke bitte
+ auf Abschliessen. Dann findest Du unter "Deine Daten" einen Link, mit dem Du eine Zusammenfassung Deiner Bestellung und alle relevanten
+ Daten zum bequemen Bezahlen Deines Anteiles als pdf herunterladen kannst.
+
+
+
+
+
+
Bezahlvorgang per Überweisung
+
+
+ Kontoinhaber
+ ${account_data.account_owner}
+
+
+ Konto
+ ${account_data.account_no}
+
+
+ Blz
+ ${account_data.bank_no}
+
+
+ Betrag
+ € ${fee}
+
+
+ Bank
+ ${account_data.bank_name}
+
+
+ 1. Überweisungszweck
+ ${account_data.first_reason}
+
+
+ 2. Überweisungszweck
+ ${("%X" % attendee.a_id).rjust(4, "0")}
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/booking_unregistered.html b/TracBooking/tracbooking/templates/booking_unregistered.html
new file mode 100644
index 0000000..e1e6402
--- /dev/null
+++ b/TracBooking/tracbooking/templates/booking_unregistered.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Registrierung gelöscht!
+
+
+
+
Deine Registrierung und alle dazugehörigen Daten sind erfolgreich gelöscht worden!
+
+
+
+
diff --git a/TracBooking/tracbooking/templates/userupload.html b/TracBooking/tracbooking/templates/userupload.html
new file mode 100644
index 0000000..f186118
--- /dev/null
+++ b/TracBooking/tracbooking/templates/userupload.html
@@ -0,0 +1,62 @@
+
+
+
+
+ Accounts: Configuration
+
+
+
+Manage Site Files
+
+
+
+
+ Upload File:
+
+ File:
+
+
+
+ The web server does not have sufficient permissions to
+ store files in your home directory.
+
+
+ Upload a file to your home directory.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TracBooking/tracbooking/utils.py b/TracBooking/tracbooking/utils.py
new file mode 100644
index 0000000..b489907
--- /dev/null
+++ b/TracBooking/tracbooking/utils.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+
+from sys import maxint
+from datetime import datetime, date, time
+from trac.util.datefmt import utc, to_timestamp, localtz, format_time, get_timezone, timezone
+from re import match, compile as re_compile
+
+class ValidationError(ValueError):
+ def __str__(self):
+ return "ValidationError: value out of bounds!"
+
+def validate_id(value):
+ if (0 > value > maxint):
+ raise ValidationError("invalid argument")
+
+def make_hash():
+ from random import sample
+ population = '123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
+ return "".join(sample(population, 4))
+
+def date_parse(foo):
+ groups = match("^(\d{1,2}).(\d{1,2}).(\d{4})$", foo).groups()
+ return date(int(groups[2]),int(groups[1]),int(groups[0]))
+
+def time_parse(foo):
+ timeM = re_compile("^(\d{1,2}):?(\d{2})$")
+ res = timeM.match(foo)
+ if not res:
+ raise ValueError("not valid time format")
+ h,m = res.groups()
+ return time(int(h),int(m))
+
+def validate_email(addr):
+ rfc822_specials = '()<>@,;:\\"[]'
+ # First we validate the name portion (name@domain)
+ c = 0
+ while c < len(addr):
+ if addr[c] == '"' and (not c or addr[c - 1] == '.' or addr[c - 1] == '"'):
+ c = c + 1
+ while c < len(addr):
+ if addr[c] == '"':
+ break
+ if addr[c] == '\\' and addr[c + 1] == ' ':
+ c = c + 2
+ continue
+ if ord(addr[c]) < 32 or ord(addr[c]) >= 127:
+ return 0
+ c = c + 1
+ else:
+ return False
+ if addr[c] == '@':
+ break
+ if addr[c] != '.':
+ return False
+ c = c + 1
+ continue
+ if addr[c] == '@':
+ break
+ if ord(addr[c]) <= 32 or ord(addr[c]) >= 127:
+ return False
+ if addr[c] in rfc822_specials:
+ return False
+ c = c + 1
+ if not c or addr[c - 1] == '.':
+ return False
+ # Next we validate the domain portion (name@domain)
+ domain = c = c + 1
+ if domain >= len(addr):
+ return False
+ count = 0
+ while c < len(addr):
+ if addr[c] == '.':
+ if c == domain or addr[c - 1] == '.':
+ return False
+ count = count + 1
+ if ord(addr[c]) <= 32 or ord(addr[c]) >= 127:
+ return False
+ if addr[c] in rfc822_specials:
+ return False
+ c = c + 1
+ return count >= 1
+
+def get_tz(session_tzname):
+ if session_tzname == 'UTC':
+ selected_tz = utc
+ else:
+ try:
+ selected_tz = timezone(session_tzname)
+ except Exception, e:
+ print e
+ selected_tz = utc
+ return session_tzname, selected_tz
+
+def get_option_count(a, aopt):
+ aopt.count = 0
+ print a, a.options
+ for i in a.options:
+ if i.ao_id == aopt.ao_id:
+ i.name = aopt.name
+ aopt.count = i.count
+ return
+
+
\ No newline at end of file
diff --git a/TracBooking/tracbooking/web_ui.py b/TracBooking/tracbooking/web_ui.py
new file mode 100644
index 0000000..46ab171
--- /dev/null
+++ b/TracBooking/tracbooking/web_ui.py
@@ -0,0 +1,507 @@
+# -*- coding: utf-8 -*-
+
+from datetime import datetime, timedelta
+from genshi.builder import tag
+from model import *
+from os import mkdir
+import os.path
+from pkg_resources import resource_filename
+from re import match, sub
+from trac.admin import IAdminPanelProvider
+from trac.config import *
+from trac.core import Component, implements, TracError
+import shutil
+import stat
+import time
+from threading import Thread, Lock
+
+from trac.perm import PermissionError, IPermissionRequestor
+from trac.util.datefmt import utc
+from trac.util.html import html
+from trac.util import Markup, pretty_size
+from trac.util.translation import _
+from trac.util.datefmt import utc, to_timestamp
+from trac.web import RequestDone
+
+from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet, add_script, add_warning, add_ctxtnav, add_notice
+from trac.web import IRequestHandler
+
+from tracbooking.report import create_attendee_report
+from tracbooking.utils import validate_id, make_hash, get_option_count, get_tz, validate_email
+
+__all__ = ['BookingComponent', 'UserUploadComponent']
+
+
+class BookingComponent(Component):
+
+ '''The web ui frontend or the rendezvous system'''
+
+ implements(INavigationContributor,
+ IRequestHandler,
+ IPermissionRequestor,
+ ITemplateProvider)
+
+ Option("booking", "account_owner", u"Chaostreff Dortmund")
+ Option("booking", "account", u"4009368600 ")
+ Option("booking", "bank_no", u"43060967 ")
+ Option("booking", "bank_name", u"GLS-Bank")
+ Option("booking", "first_reason", u"BBQ2010")
+
+ # IPermissionRequestor methods
+ def get_permission_actions(self):
+ '''returns all permissions this component provides'''
+ return ["BOOKING_VIEW", ("BOOKING_ADMIN", ("BOOKING_VIEW"))]
+
+ # INavigationContributor methods
+ def get_active_navigation_item(self, req):
+ return 'booking'
+
+ def get_navigation_items(self, req):
+ if not "BOOKING_VIEW" in req.perm:
+ return
+ yield ('mainnav', 'booking', html.A('Sammelbestellungen', href= req.href.booking()))
+
+ def match_request(self, req):
+
+ key = req.path_info
+ if key == '/booking':
+ return True
+ m = match(r'/booking/(\d+)$', key)
+ if m:
+ req.args['event_id'] = int(m.group(1))
+ return True
+ return False
+
+ def process_request(self, req):
+ req.perm.require("BOOKING_VIEW")
+ query = req.path_info
+ add_stylesheet (req, 'hw/css/booking.css')
+ if not req.args.has_key("event_id"):
+ return self._display_overview(req)
+
+ e_id = req.args["event_id"]
+ a = Attendee.fetch_one(self.env, nick=req.authname, e_id=e_id)
+ if a:
+ return self._process_status(req, a)
+ else:
+ if self.env.config.get("booking", "autoregister"):
+ event = Event.fetch_one(self.env, e_id)
+ nick = req.authname
+ rd = Attendee(self.env, 0, event.e_id, 0, nick, None, 0, 0, datetime.now(utc), 0)
+ rd.commit()
+ return self._process_status(req, rd)
+ return self._process_register(req)
+
+ # ITemplateProvider methods
+ # Used to add the plugin's templates and htdocs
+ def get_templates_dirs(self):
+ return [resource_filename(__name__, 'templates'),]
+
+ def get_htdocs_dirs(self):
+ """Return a list of directories with static resources (such as style
+ sheets, images, etc.)
+
+ Each item in the list must be a `(prefix, abspath)` tuple. The
+ `prefix` part defines the path in the URL that requests to these
+ resources are prefixed with.
+
+ The `abspath` is the absolute path to the directory containing the
+ resources on the local file system.
+ """
+ return [('hw', resource_filename(__name__, 'htdocs'))]
+
+ def _process_register(self, req):
+
+ '''process add,change,delete actions for dates'''
+ data = {"now" : datetime.now(utc)}
+ #a = Attendee.fetch_one(self.env, nick=req.authname)
+ #if a:
+ #req.redirect(req.href.booking("status"))
+ e_id = req.args["event_id"]
+ event = Event.fetch_one(self.env, e_id)
+ if not event:
+ raise TracError("Event konnte nicht gefunden werden")
+ data["event"] = event
+ if req.method == "POST":
+ if req.args.has_key("register"):
+ nick = req.authname
+ if req.args.has_key("email"):
+ email = req.args.get("email")
+ if email and not validate_email(email):
+ add_warning(req, u"email ungültig")
+ return "booking_register.html", data, None
+ rd = Attendee(self.env, 0, event.e_id, 0, nick, email, 0, 0, datetime.now(utc), 0)
+ rd.commit()
+ req.redirect(req.href.booking(e_id))
+ return 'booking_register.html', data, None
+
+ def _display_overview(self, req):
+ return "booking_events.html", {"events": Event.fetch_all(self.env)}, None
+
+ def _process_status(self, req, attendee):
+
+ '''display the status if already registered and optional features'''
+
+ add_stylesheet (req, 'hw/css/booking.css')
+ notice = "Bestellung erfolgreich gespeichert."
+ if req.session.has_key("notice"):
+ add_notice(req, req.session["notice"])
+ del req.session["notice"]
+ req.session.save()
+ #attendee.finished = False
+ #attendee.update()
+ if req.method == "POST":
+ if not attendee.finished:
+ failure = False
+ if req.args.has_key("unregister"):
+ return "booking_accept.html", {"query": u"Möchtest Du wirklich Deine Bestellung komplett löschen?", "query_true" : "unregister_true", "query_false" : "unregister_false"}, None
+ elif req.args.has_key("unregister_true"):
+ UserUploadComponent(self.env).clean_userdir(attendee)
+ Attendee.delete(self.env, attendee.a_id)
+ req.redirect(req.href.wiki())
+ elif req.args.has_key("unregister_false") or req.args.has_key("finish_false"):
+ pass
+ elif req.args.has_key("finish"):
+ return "booking_accept.html", {"query": u"Möchtest Du wirklich Deine Bestellung abschliessen?", "query_true" : "finish_true", "query_false" : "finish_false"}, None
+ elif req.args.has_key("finish_true"):
+ attendee.finished = True
+ attendee.update()
+ req.redirect(req.href.booking(req.args["event_id"]))
+ elif req.args.has_key("attendee-save"):
+ email = req.args["email"]
+ if not validate_email(email):
+ add_warning(req, u"email nicht gültig")
+ attendee.email = email
+ attendee.update()
+ req.session["notice"] = "Daten erfolgreich aktualisiert."
+ else:
+ args = req.args
+ for arg in args:
+ if arg.startswith("count"):
+ try:
+ prefix, ao_id = arg.split("_", 1)
+ ao_id = int(ao_id)
+ count = int(args[arg])
+ validate_id(count)
+ validate_id(ao_id)
+ except ValueError:
+ add_warning(req, u"Bitte für Anzahlfelder nur positive Zahen eingeben.")
+ failure = True
+ continue
+
+ aoption = AvailableOption.fetch_one(self.env, ao_id, fetch_variations=False)
+
+ if not aoption:
+ add_warning(req, u"Artikel %r nicht gefunden" % ao_id)
+ failure = True
+ continue
+ elif not aoption.active:
+ add_warning(req, u"Artikel %r nicht aktiviert" % ao_id)
+ failure = True
+ continue
+
+ if count < aoption.min_count:
+ add_warning(req, u"Artikel '%s' kann minimal '%d' Mal bestellt werden;-)" % (aoption.name, aoption.min_count))
+ failure = True
+ continue
+ elif aoption.max_count and count > aoption.max_count:
+ add_warning(req, u"Artikel '%s' kann maximal '%d' Mal bestellt werden;-)" % (aoption.name, aoption.max_count))
+ failure = True
+ continue
+
+ if not count:
+ BookingOption.delete(self.env, attendee.a_id, ao_id)
+ else:
+ opt = BookingOption.fetch_one(self.env, attendee.a_id, ao_id)
+ if not opt:
+ opt = BookingOption(self.env, 0, attendee.a_id, ao_id, count)
+ opt.commit()
+ else:
+ opt.count = count
+ opt.update()
+ #elif arg.startswith("var"):
+ #prefix, variation_id = arg.split("_", 1)
+ #try:
+ #variation_id = int(variation_id)
+ #validate_id(variation_id)
+ #value = int(args[arg])
+ #validate_id(value)
+ #except (ValueError,):
+ #add_warning(req, u"Bitte eine Zahl eingeben;-)")
+ #failure = True
+ #continue
+
+ #variation = BookingOptionVariation.fetch_one(self.env, attendee.a_id, variation_id)
+ #if not variation:
+ #b = BookingOptionVariation(self.env, attendee.a_id, variation_id, value)
+ #b.commit()
+ #else:
+ #BookingOptionVariation.update(self.env, attendee.a_id, variation_id, value)
+ print "before redirect"
+ if failure:
+ req.redirect(req.href.booking(req.args["event_id"]))
+ else:
+ req.session["notice"] = notice
+
+ req.redirect(req.href.booking(req.args["event_id"]))
+ elif req.args.has_key("download_invoice"):
+ e_id = req.args["event_id"]
+ event = Event.fetch_one(self.env, e_id)
+ session_tzname, selected_tz = get_tz(req.session.get('tz', self.env.config.get("trac", "default_timezone") or None))
+
+ data = create_attendee_report(self.env, event, attendee, selected_tz)
+ data_len = len(data)
+
+ req.send_response(200)
+ req.send_header("Content-Type", "text/pdf;charset=utf-8")
+ req.send_header("Content-Length", data_len)
+ req.send_header("Content-Disposition", 'filename=%s.pdf' % event.name.replace("/", "_").replace(u" ", u"_"))
+ req.end_headers()
+ req.write(data)
+ raise RequestDone
+ else:
+ raise Exception("unhandled state")
+ else:
+ attendee = Attendee.fetch_one(self.env, nick=req.authname, e_id=req.args["event_id"], fetch_options=True)
+ event = Event.fetch_one(self.env, e_id=req.args["event_id"], fetch_options=True, only_active=True, attendee_id=attendee.a_id)
+ if event.options:
+ for i in event.options:
+ get_option_count(attendee, i)
+ data = {"event" : event,
+ "attendee" : attendee,
+ "now" : datetime.now(utc),
+ "account_data" : EventAccount.fetch_by_event(self.env, event.e_id)}
+ return 'booking_status.html', data, None
+
+
+class UserUploadComponent(Component):
+ implements(IRequestHandler, IPermissionRequestor)
+
+ def match_request(self, req):
+ key = req.path_info
+ m = match(r'/upload/(\d+)$', key)
+ if m:
+ req.args['event_id'] = int(m.group(1))
+ return True
+ m = match(r'/showupload/(\d+)$', key)
+ if m:
+ req.args['attendee_id'] = int(m.group(1))
+ return True
+ return False
+
+ def process_request(self, req):
+ req.perm.require('USER_UPLOAD')
+ a = Attendee.fetch_one(self.env, e_id=req.args["attendee_id"], nick=req.authname)
+ if not a:
+ req.redirect(req, req.href.booking(req.args["event_id"]))
+ target_path = os.path.join(self.env.path, 'htdocs', 'attendees', a.ext_id)
+ readonly = False
+ if not os.path.exists(os.path.join(self.env.path, 'htdocs', 'attendees')):
+ os.mkdir(os.path.join(self.env.path, 'htdocs', 'attendees'))
+ if not os.path.exists(target_path):
+ os.mkdir(target_path)
+ if not (os.path.isdir(target_path) and os.access(target_path, os.F_OK + os.W_OK)):
+ readonly = True
+ if req.method == 'POST':
+ if req.args.has_key('delete'):
+ self._do_delete(req, target_path)
+ elif req.args.has_key('upload'):
+ self._do_upload(req, target_path)
+ else:
+ self.log.warning('Unknown POST request: %s', req.args)
+ req.redirect(self.env.href.upload(req.args["event_id"]))
+
+ data = {'readonly' : readonly}
+ self._render_view(req, data, target_path)
+ return 'userupload.html', data, None
+
+ def clean_userdir(self, attendee):
+ if not attendee:
+ return
+ target_path = os.path.join(self.env.path, 'htdocs', 'attendees', attendee.ext_id)
+ shutil.rmtree(target_path, True)
+
+ # IPermissionRequestor
+ def get_permission_actions(self):
+ return ['USER_UPLOAD',]
+
+ def _render_view(self, req, data, target_path):
+ """Display list of files in trac env htdocs dir"""
+
+ filelist = []
+ if os.path.exists(target_path) and os.path.isdir(target_path):
+ dlist = os.listdir(target_path)
+ for f in dlist:
+ fsize = os.stat(os.path.join(target_path, f))[stat.ST_SIZE]
+ filelist.append({'name' : f,
+ 'link' : Markup('%s ') % (self.env.href.showupload(req.authname), f),
+ 'size' : pretty_size(fsize)})
+ continue
+ data.update({'files' : filelist})
+ return
+
+ def _do_delete(self, req, target_path):
+ """Delete a file from htdocs"""
+ err_list = []
+ sel = req.args.get('sel')
+ sel = isinstance(sel, list) and sel or [sel]
+ for key in sel:
+ try:
+ os.unlink(os.path.join(target_path, key))
+ except OSError:
+ err_list.append(key)
+ continue
+ if err_list:
+ errmsg = "Unable to delete the following files:\n"
+ errmsg += '\n'.join(err_list)
+ raise TracError, errmsg
+
+ def _do_upload(self, req, target_path):
+ """Install a plugin."""
+ if not req.args.has_key('site_file'):
+ raise TracError('No file uploaded')
+ upload = req.args['site_file']
+ if not upload.filename:
+ raise TracError('No file uploaded')
+ upload_filename = upload.filename.replace('\\', '').replace(':', '').replace('/', '')
+ upload_filename = os.path.basename(upload_filename)
+ if not upload_filename:
+ raise TracError('No file uploaded')
+ a = Attendee.fetch_one(self.env, nick=req.authname, e_id=req.args["event_id"])
+ if not a:
+ req.redirect(req, req.href.booking(req.args["event_id"]))
+ file_path = os.path.join(target_path, upload_filename)
+ if os.path.exists(file_path):
+ raise TracError('A file/directory >>%s<< already exists' % upload_filename)
+ self.log.info('Installing plugin %s', upload_filename)
+ flags = os.O_CREAT + os.O_WRONLY + os.O_EXCL
+ try:
+ flags += os.O_BINARY
+ except AttributeError:
+ # OS_BINARY not available on every platform
+ pass
+ target_file = os.fdopen(os.open(file_path, flags), 'w')
+ try:
+ shutil.copyfileobj(upload.file, target_file)
+ self.log.info('File %s uploaded to %s', upload_filename,
+ target_path)
+ finally:
+ target_file.close()
+
+
+class UploadComponent(Component):
+ implements(IRequestHandler, IPermissionRequestor)
+
+ def match_request(self, req):
+ key = req.path_info
+ if key in ("/upload", "/showupload"):
+ return True
+ return False
+
+ def process_request(self, req):
+ req.perm.require('USER_UPLOAD')
+ target_path = os.path.join(self.env.path, 'htdocs', "data")
+ readonly = False
+ if not os.path.exists(target_path):
+ os.mkdir(target_path)
+ if not (os.path.isdir(target_path) and os.access(target_path, os.F_OK + os.W_OK)):
+ readonly = True
+ if req.method == 'POST':
+ if req.args.has_key('delete'):
+ self._do_delete(req, target_path)
+ elif req.args.has_key('upload'):
+ self._do_upload(req, target_path)
+ else:
+ self.log.warning('Unknown POST request: %s', req.args)
+ req.redirect(self.env.href.upload())
+
+ data = {'readonly' : readonly}
+ self._render_view(req, data, target_path)
+ return 'userupload.html', data, None
+
+ def clean_userdir(self, attendee):
+ if not attendee:
+ return
+ target_path = os.path.join(self.env.path, 'htdocs', 'attendees', attendee.ext_id)
+ shutil.rmtree(target_path, True)
+
+ # IPermissionRequestor
+ def get_permission_actions(self):
+ return ['USER_UPLOAD',]
+
+ def _render_view(self, req, data, target_path):
+ """Display list of files in trac env htdocs dir"""
+
+ filelist = []
+ if os.path.exists(target_path) and os.path.isdir(target_path):
+ dlist = os.listdir(target_path)
+ for f in dlist:
+ fsize = os.stat(os.path.join(target_path, f))[stat.ST_SIZE]
+ filelist.append({'name' : f,
+ 'link' : Markup('%s ') % (self.env.href.showupload(req.authname), f),
+ 'size' : pretty_size(fsize)})
+ continue
+ data.update({'files' : filelist})
+ return
+
+ def _do_delete(self, req, target_path):
+ """Delete a file from htdocs"""
+ err_list = []
+ sel = req.args.get('sel')
+ sel = isinstance(sel, list) and sel or [sel]
+ for key in sel:
+ try:
+ os.unlink(os.path.join(target_path, key))
+ except OSError:
+ err_list.append(key)
+ continue
+ if err_list:
+ errmsg = "Unable to delete the following files:\n"
+ errmsg += '\n'.join(err_list)
+ raise TracError, errmsg
+
+ def _do_upload(self, req, target_path):
+ """Install a plugin."""
+ if not req.args.has_key('site_file'):
+ raise TracError('No file uploaded')
+ upload = req.args['site_file']
+ if not upload.filename:
+ raise TracError('No file uploaded')
+ upload_filename = upload.filename.replace('\\', '').replace(':', '').replace('/', '')
+ upload_filename = os.path.basename(upload_filename)
+ if not upload_filename:
+ raise TracError('No file uploaded')
+ a = Attendee.fetch_one(self.env, nick=req.authname, e_id=req.args["event_id"])
+ if not a:
+ req.redirect(req, req.href.booking(req.args["event_id"]))
+ file_path = os.path.join(target_path, upload_filename)
+ if os.path.exists(file_path):
+ raise TracError('A file/directory >>%s<< already exists' % upload_filename)
+ self.log.info('Installing plugin %s', upload_filename)
+ flags = os.O_CREAT + os.O_WRONLY + os.O_EXCL
+ try:
+ flags += os.O_BINARY
+ except AttributeError:
+ # OS_BINARY not available on every platform
+ pass
+ target_file = os.fdopen(os.open(file_path, flags), 'w')
+ try:
+ shutil.copyfileobj(upload.file, target_file)
+ self.log.info('File %s uploaded to %s', upload_filename,
+ target_path)
+ finally:
+ target_file.close()
+
+
+#class TracSchedulerTest(Component):
+ #implements( IScheduledTask)
+ #def process_scheduled_task(self, parent):
+ #sqlString = "SELECT edit_deadline FROM booking_event;"
+ #rows = parent.queryDb(sqlString)
+ #n = datetime.now(utc)
+ #for i in rows:
+ #d = datetime.fromtimestamp(i[0], utc)
+ #dt = d - n
+ #if dt < timedelta(0,3600):
+ #parent.queryDb("UPDATE booking_available_option SET active=0 where ao_id in (1,2,3,7);", commit=True)
+ #parent.queryDb("UPDATE booking_available_option SET active=1 where ao_id in (4,5,6,8);", commit=True)