Merge branch 'master' into Kerl/messages

This commit is contained in:
Martin Pépin 2017-02-11 11:40:47 +01:00
commit 71fb020e10
50 changed files with 1880 additions and 14924 deletions

View file

@ -84,29 +84,30 @@ visualiser la dernière version du code.
Si vous optez pour une installation manuelle plutôt que d'utiliser Vagrant, il Si vous optez pour une installation manuelle plutôt que d'utiliser Vagrant, il
est fortement conseillé d'utiliser un environnement virtuel pour Python. est fortement conseillé d'utiliser un environnement virtuel pour Python.
Il vous faudra installer mercurial, pip, les librairies de développement de Il vous faudra installer pip, les librairies de développement de python, un
python, un client et un serveur MySQL ainsi qu'un serveur redis ; sous Debian et client et un serveur MySQL ainsi qu'un serveur redis ; sous Debian et dérivées
dérivées (Ubuntu, ...) : (Ubuntu, ...) :
sudo apt-get install mercurial python-pip python-dev libmysqlclient-dev sudo apt-get install python-pip python-dev libmysqlclient-dev redis-server
redis-server
Si vous décidez d'utiliser un environnement virtuel Python (virtualenv; Si vous décidez d'utiliser un environnement virtuel Python (virtualenv;
fortement conseillé), déplacez-vous dans le dossier où est installé GestioCOF fortement conseillé), déplacez-vous dans le dossier où est installé GestioCOF
(le dossier où se trouve ce README), et créez-le maintenant : (le dossier où se trouve ce README), et créez-le maintenant :
virtualenv env virtualenv env -p $(which python3)
Pour l'activer, il faut faire L'option `-p` sert à préciser l'exécutable python à utiliser. Vous devez choisir
python3, si c'est la version de python par défaut sur votre système, ceci n'est
pas nécessaire. Pour l'activer, il faut faire
. env/bin/activate . env/bin/activate
dans le même dossier. dans le même dossier.
Vous pouvez maintenant installer les dépendances Python depuis les fichiers Vous pouvez maintenant installer les dépendances Python depuis le fichier
`requirements.txt` et `requirements-devel.txt` : `requirements-devel.txt` :
pip install -r requirements.txt -r requirements-devel.txt pip install -r requirements-devel.txt
Copiez le fichier `cof/settings_dev.py` dans `cof/settings.py`. Copiez le fichier `cof/settings_dev.py` dans `cof/settings.py`.
@ -171,9 +172,10 @@ Il ne vous reste plus qu'à initialiser les modèles de Django avec la commande
python manage.py migrate python manage.py migrate
Une base de donnée pré-remplie est disponible en lançant la commande : Une base de donnée pré-remplie est disponible en lançant les commandes :
python manage.py loaddata users root bda gestion sites accounts groups articles python manage.py loaddata gestion sites accounts groups articles
python manage.py loaddevdata
Vous êtes prêts à développer ! Lancer GestioCOF en faisant Vous êtes prêts à développer ! Lancer GestioCOF en faisant

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
"""
Crée deux tirages de test et y inscrit les utilisateurs
"""
import os
import random
from django.utils import timezone
from django.contrib.auth.models import User
from gestioncof.management.base import MyBaseCommand
from bda.models import Tirage, Spectacle, Salle, Participant, ChoixSpectacle
from bda.views import do_tirage
# Où sont stockés les fichiers json
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'data')
class Command(MyBaseCommand):
help = "Crée deux tirages de test et y inscrit les utilisateurs."
def handle(self, *args, **options):
# ---
# Tirages
# ---
Tirage.objects.all().delete()
Tirage.objects.bulk_create([
Tirage(
title="Tirage de test 1",
ouverture=timezone.now()-timezone.timedelta(days=7),
fermeture=timezone.now(),
active=True
),
Tirage(
title="Tirage de test 2",
ouverture=timezone.now(),
fermeture=timezone.now()+timezone.timedelta(days=60),
active=True
)
])
tirages = Tirage.objects.all()
# ---
# Salles
# ---
locations = self.from_json('locations.json', DATA_DIR, Salle)
# ---
# Spectacles
# ---
def show_callback(show):
"""
Assigne un tirage, une date et un lieu à un spectacle et décide si
les places sont sur listing.
"""
show.tirage = random.choice(tirages)
show.listing = bool(random.randint(0, 1))
show.date = (
show.tirage.fermeture
+ timezone.timedelta(days=random.randint(60, 90))
)
show.location = random.choice(locations)
return show
shows = self.from_json(
'shows.json', DATA_DIR, Spectacle, show_callback
)
# ---
# Inscriptions
# ---
self.stdout.write("Inscription des utilisateurs aux tirages")
ChoixSpectacle.objects.all().delete()
choices = []
for user in User.objects.filter(profile__is_cof=True):
for tirage in tirages:
part, _ = Participant.objects.get_or_create(
user=user,
tirage=tirage
)
shows = random.sample(
list(tirage.spectacle_set.all()),
tirage.spectacle_set.count() // 2
)
for (rank, show) in enumerate(shows):
choices.append(ChoixSpectacle(
participant=part,
spectacle=show,
priority=rank + 1,
double_choice=random.choice(
['1', 'double', 'autoquit']
)
))
ChoixSpectacle.objects.bulk_create(choices)
self.stdout.write("- {:d} inscriptions générées".format(len(choices)))
# ---
# On lance le premier tirage
# ---
self.stdout.write("Lancement du premier tirage")
do_tirage(tirages[0], "dummy_token")

View file

@ -0,0 +1,26 @@
[
{
"name": "Cour\u00f4",
"address": "45 rue d'Ulm, cour\u00f4"
},
{
"name": "K-F\u00eat",
"address": "45 rue d'Ulm, escalier C, niveau -1"
},
{
"name": "Th\u00e9\u00e2tre",
"address": "45 rue d'Ulm, escalier C, niveau -1"
},
{
"name": "Cours Pasteur",
"address": "45 rue d'Ulm, cours pasteur"
},
{
"name": "Salle des actes",
"address": "45 rue d'Ulm, escalier A, niveau 1"
},
{
"name": "Amphi Rataud",
"address": "45 rue d'Ulm, NIR, niveau PB"
}
]

View file

@ -0,0 +1,100 @@
[
{
"description": "Jazz / Funk",
"title": "Un super concert",
"price": 10.0,
"slots_description": "Debout",
"slots": 5
},
{
"description": "Homemade",
"title": "Une super pi\u00e8ce",
"price": 10.0,
"slots_description": "Assises",
"slots": 60
},
{
"description": "Plein air, soleil, bonne musique",
"title": "Concert pour la f\u00eate de la musique",
"price": 5.0,
"slots_description": "Debout, attention \u00e0 la fontaine",
"slots": 30
},
{
"description": "Sous le regard s\u00e9v\u00e8re de Louis Pasteur",
"title": "Op\u00e9ra sans d\u00e9cors",
"price": 5.0,
"slots_description": "Assis sur l'herbe",
"slots": 20
},
{
"description": "Buffet \u00e0 la fin",
"title": "Concert Trouv\u00e8re",
"price": 20.0,
"slots_description": "Assises",
"slots": 15
},
{
"description": "Vive les maths",
"title": "Dessin \u00e0 la craie sur tableau noir",
"price": 10.0,
"slots_description": "Assises, tablette pour prendre des notes",
"slots": 30
},
{
"description": "Une pi\u00e8ce \u00e0 un personnage",
"title": "D\u00e9cors, d\u00e9montage en musique",
"price": 0.0,
"slots_description": "Assises",
"slots": 20
},
{
"description": "Annulera, annulera pas\u00a0?",
"title": "La Nuit",
"price": 27.0,
"slots_description": "",
"slots": 1000
},
{
"description": "Le boum fait sa carte blanche",
"title": "Turbomix",
"price": 10.0,
"slots_description": "Debout les mains en l'air",
"slots": 20
},
{
"description": "Unique repr\u00e9sentation",
"title": "Carinettes et trombone",
"price": 15.0,
"slots_description": "Chaises ikea",
"slots": 10
},
{
"description": "Suivi d'une jam session",
"title": "Percussion sur rondins",
"price": 5.0,
"slots_description": "B\u00fbches",
"slots": 14
},
{
"description": "\u00c9preuve sportive et artistique",
"title": "Bassin aux ernests, nage libre",
"price": 5.0,
"slots_description": "Humides",
"slots": 10
},
{
"description": "Sonore",
"title": "Chant du barde",
"price": 13.0,
"slots_description": "Ne venez pas",
"slots": 20
},
{
"description": "Cocorico",
"title": "Chant du coq",
"price": 4.0,
"slots_description": "bancs",
"slots": 15
}
]

View file

@ -118,6 +118,9 @@ class Spectacle(models.Model):
# On renvoie la liste des destinataires # On renvoie la liste des destinataires
return members.values() return members.values()
@property
def is_past(self):
return self.date < timezone.now()
class Quote(models.Model): class Quote(models.Model):
spectacle = models.ForeignKey(Spectacle) spectacle = models.ForeignKey(Spectacle)

File diff suppressed because one or more lines are too long

View file

@ -1,347 +0,0 @@
/*!
* jQuery UI 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI
*/
(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.15",
keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=
this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":
"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,
outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a,
"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&
a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&
c.ui.isOverAxis(b,e,i)}})}})(jQuery);
;/*!
* jQuery UI Widget 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Widget
*/
(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
;/*!
* jQuery UI Mouse 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Mouse
*
* Depends:
* jquery.ui.widget.js
*/
(function(b){b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=
a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,e=a.which==1,f=typeof this.options.cancel=="string"?b(a.target).closest(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==
false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(d){return c._mouseMove(d)};this._mouseUpDelegate=function(d){return c._mouseUp(d)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(b.browser.msie&&
!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
;/*
* jQuery UI Position 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Position
*/
(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
;/*
* jQuery UI Sortable 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Sortables
*
* Depends:
* jquery.ui.core.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
*/
(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable");
this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a===
"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&
!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);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");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};
this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=
document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);
return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<
b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-
b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,
a)}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(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],
e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();
c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):
this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,
dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},
toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||
this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();
var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},
_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();
if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),
this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),
this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&
this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=
this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=
d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||
0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",
a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-
f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=
this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==
""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=
this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a=
{top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),
10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?
document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),
10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=
this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&
this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();
var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-
this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-
this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],
this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]=
"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",
f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,
this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",
a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},
_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.15"})})(jQuery);
;/*
* jQuery UI Accordion 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Accordion
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
*/
(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=
this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),
e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||
e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",
"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.15",
animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);
f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",
paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
;/*
* jQuery UI Autocomplete 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Autocomplete
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.position.js
*/
(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.propAttr("readOnly"))){g=
false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=
a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&&
a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&
b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source=
this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();
this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||
b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var g=this;
d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery);
(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,
this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[d.fn.prop?"prop":"attr"]("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery);
;/*
* jQuery UI Dialog 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Dialog
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.button.js
* jquery.ui.draggable.js
* jquery.ui.mouse.js
* jquery.ui.position.js
* jquery.ui.resizable.js
*/
(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),
h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",
e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==
b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1;
d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===
f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,
function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('<button type="button"></button>').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,
originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",
f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):
[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);
if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):
e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=
this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-
b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.15",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=
a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
;/*
* jQuery UI Tabs 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Tabs
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
*/
(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.15"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
;/*
* jQuery UI Datepicker 1.8.15
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker
*
* Depends:
* jquery.ui.core.js
*/
(function(d,C){function M(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false,disabled:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=N(d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function N(a){return a.bind("mouseout",
function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.15"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},
setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,
"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",
function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c==
"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():
d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,
b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=
1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/
2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=
d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=
a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,
"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==
a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?
d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true),i=this._getMinMaxDate(e,"min"),g=this._getMinMaxDate(e,"max");H(e.settings,f);if(i!==null&&f.dateFormat!==C&&f.minDate===C)e.settings.minDate=this._formatDate(e,i);if(g!==null&&f.dateFormat!==C&&f.maxDate===C)e.settings.maxDate=this._formatDate(e,g);this._attachments(d(a),e);this._autoSize(e);this._setDate(e,h);this._updateAlternate(e);
this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");
b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv);c[0]&&d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]);if(a=d.datepicker._get(b,"onSelect")){c=d.datepicker._formatDate(b);a.apply(b.input?b.input[0]:null,[c,b])}else d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,
a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=
a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,
"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==C?a.keyCode:a.charCode);
return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",
a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");H(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=
d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,
c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing=true;d.effects&&
d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("."+
this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&
a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():
0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),
"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=
null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):
0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"?
"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);
this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,
"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b==
"")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1<a.length&&a.charAt(A+1)==p)&&A++;return p},m=function(p){var D=o(p);p=new RegExp("^\\d{1,"+
(p=="@"?14:p=="!"?20:p=="y"&&D?4:p=="o"?3:2)+"}");p=b.substring(q).match(p);if(!p)throw"Missing number at position "+q;q+=p[0].length;return parseInt(p[0],10)},n=function(p,D,K){p=d.map(o(p)?K:D,function(w,x){return[[x,w]]}).sort(function(w,x){return-(w[1].length-x[1].length)});var E=-1;d.each(p,function(w,x){w=x[1];if(b.substr(q,w.length).toLowerCase()==w.toLowerCase()){E=x[0];q+=w.length;return false}});if(E!=-1)return E+1;else throw"Unknown name at position "+q;},s=function(){if(b.charAt(q)!=a.charAt(A))throw"Unexpected literal at position "+
q;q++},q=0,A=0;A<a.length;A++)if(k)if(a.charAt(A)=="'"&&!o("'"))k=false;else s();else switch(a.charAt(A)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "'":if(o("'"))s();else k=true;break;default:s()}if(q<
b.length)throw"Extra/unparsed characters found in date: "+b.substring(q);if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},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",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&
a.charAt(k+1)==o)&&k++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},j=function(o,m,n,s){return i(o)?s[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5),3);
break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=
false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==C?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,
e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,
"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,
d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j,l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;
b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a));if(c=this._get(a,"onSelect")){e=this._formatDate(a);c.apply(a.input?a.input[0]:null,[e,a])}},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==
""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,
9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));
n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+B+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m,
g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+B+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&&
a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+B+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,s)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
B+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x<i[0];x++){var O=
"";this.maxRows=4;for(var G=0;G<i[1];G++){var P=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",y="";if(l){y+='<div class="ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&
x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var z=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+s[r]+'">'+q[r]+"</span></th>"}y+=z+"</tr></thead><tbody>";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,
z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q<z;Q++){y+="<tr>";var R=!j?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(r)+"</td>";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&r<k||o&&r>o;R+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(r.getTime()==
P.getTime()&&g==a.selectedMonth&&a._keyEvent||E.getTime()==r.getTime()&&E.getTime()==P.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!D?"":" "+I[1]+(r.getTime()==u.getTime()?" "+this._currentClass:"")+(r.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!F||D)&&I[2]?' title="'+I[2]+'"':"")+(L?"":' onclick="DP_jQuery_'+B+".datepicker._selectDay('#"+a.id+"',"+r.getMonth()+","+r.getFullYear()+', this);return false;"')+">"+(F&&!D?"&#xa0;":L?'<span class="ui-state-default">'+
r.getDate()+"</span>":'<a class="ui-state-default'+(r.getTime()==b.getTime()?" ui-state-highlight":"")+(r.getTime()==u.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+'" href="#">'+r.getDate()+"</a>")+"</td>";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+"</tr>"}g++;if(g>11){g=0;m++}y+="</tbody></table>"+(l?"</div>"+(i[0]>0&&G==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+B+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" >";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&
(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&l)?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,
e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+B+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" >";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?"&#xa0;":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+
(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input?
a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c,
e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,
"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this;
if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a==
"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.15";window["DP_jQuery_"+B]=d})(jQuery);
;

View file

@ -43,3 +43,6 @@ td {
margin: 10px 0px; margin: 10px 0px;
} }
.spectacle-passe {
opacity:0.5;
}

View file

@ -2,8 +2,10 @@
{% load staticfiles %} {% load staticfiles %}
{% block extra_head %} {% block extra_head %}
<script src="{% static 'bda/js/jquery-1.6.2.min.js'%}" type="text/javascript"></script> <script src="{% static 'js/jquery.min.js'%}" type="text/javascript"></script>
<script src="{% static 'bda/js/jquery-ui-1.8.15.custom.min.js' %}" type="text/javascript"></script> <script src="{% static 'js/jquery-ui.min.js' %}" type="text/javascript"></script>
<script src="{% static "js/jquery.ui.touch-punch.min.js" %}" type="text/javascript"></script>
<link type="text/css" rel="stylesheet" href="{% static "css/jquery-ui.min.css" %}" />
<link type="text/css" rel="stylesheet" href="{% static "css/bda.css" %}" /> <link type="text/css" rel="stylesheet" href="{% static "css/bda.css" %}" />
{% endblock %} {% endblock %}

View file

@ -1,6 +1,10 @@
{% extends "base_title.html" %} {% extends "base_title.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block extra_head %}
<link type="text/css" rel="stylesheet" href="{% static "css/bda.css" %}" />
{% endblock %}
{% block realcontent %} {% block realcontent %}
<h2><strong>{{tirage_name}}</strong></h2> <h2><strong>{{tirage_name}}</strong></h2>
<h3>Liste des spectacles</h3> <h3>Liste des spectacles</h3>
@ -17,9 +21,9 @@
</thead> </thead>
<tbody> <tbody>
{% for spectacle in object_list %} {% for spectacle in object_list %}
<tr class="clickable-row" data-href="{% url 'bda-spectacle' tirage_id spectacle.id %}"> <tr class="clickable-row {% if spectacle.is_past %}spectacle-passe{% endif %}" data-href="{% url 'bda-spectacle' tirage_id spectacle.id %}">
<td><a href="{% url 'bda-spectacle' tirage_id spectacle.id %}">{{ spectacle.title }} <span style="font-size:small;" class="glyphicon glyphicon-link" aria-hidden="true"></span></a></td> <td><a href="{% url 'bda-spectacle' tirage_id spectacle.id %}">{{ spectacle.title }} <span style="font-size:small;" class="glyphicon glyphicon-link" aria-hidden="true"></span></a></td>
<td data-sort-value="{{ spectacle.timestamp }}">{{ spectacle.date }}</td> <td data-sort-value="{{ spectacle.timestamp }}"">{{ spectacle.date }}</td>
<td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td> <td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td>
<td data-sort-value="{{ spectacle.price |stringformat:".3f" }}"> <td data-sort-value="{{ spectacle.price |stringformat:".3f" }}">
{{ spectacle.price |floatformat }}€ {{ spectacle.price |floatformat }}€

View file

@ -203,79 +203,96 @@ def inscription(request, tirage_id):
'tirage': tirage}) 'tirage': tirage})
def do_tirage(request, tirage_id): def do_tirage(tirage_elt, token):
tirage_elt = get_object_or_404(Tirage, id=tirage_id) """
form = TokenForm(request.POST) Fonction auxiliaire à la vue ``tirage`` qui lance effectivement le tirage
if not form.is_valid(): après qu'on a vérifié que c'est légitime et que le token donné en argument
return tirage(request, tirage_id) est correct.
Rend les résultats
"""
# Initialisation du dictionnaire data qui va contenir les résultats
start = time.time() start = time.time()
data = {} data = {
shows = tirage_elt.spectacle_set.select_related().all() 'shows': tirage_elt.spectacle_set.select_related().all(),
members = tirage_elt.participant_set.all() 'token': token,
choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt) \ 'members': tirage_elt.participant_set.all(),
.order_by('participant', 'priority').select_related().all() 'total_slots': 0,
algo = Algorithm(shows, members, choices) 'total_losers': 0,
results = algo(form.cleaned_data["token"]) 'total_sold': 0,
total_slots = 0 'total_deficit': 0,
total_losers = 0 'opera_deficit': 0,
}
# On lance le tirage
choices = (
ChoixSpectacle.objects
.filter(spectacle__tirage=tirage_elt)
.order_by('participant', 'priority')
.select_related().all()
)
results = Algorithm(data['shows'], data['members'], choices)(token)
# On compte les places attribuées et les déçus
for (_, members, losers) in results: for (_, members, losers) in results:
total_slots += len(members) data['total_slots'] += len(members)
total_losers += len(losers) data['total_losers'] += len(losers)
data["total_slots"] = total_slots
data["total_losers"] = total_losers # On calcule le déficit et les bénéfices pour le BdA
data["shows"] = shows # FIXME: le traitement de l'opéra est sale
data["token"] = form.cleaned_data["token"]
data["members"] = members
data["results"] = results
total_sold = 0
total_deficit = 0
opera_deficit = 0
for (show, members, _) in results: for (show, members, _) in results:
deficit = (show.slots - len(members)) * show.price deficit = (show.slots - len(members)) * show.price
total_sold += show.slots * show.price data['total_sold'] += show.slots * show.price
if deficit >= 0: if deficit >= 0:
if "Opéra" in show.location.name: if "Opéra" in show.location.name:
opera_deficit += deficit data['opera_deficit'] += deficit
total_deficit += deficit data['total_deficit'] += deficit
data["total_sold"] = total_sold - total_deficit data["total_sold"] -= data['total_deficit']
data["total_deficit"] = total_deficit
data["opera_deficit"] = opera_deficit # Participant objects are not shared accross spectacle results,
# so assign a single object for each Participant id
members_uniq = {}
members2 = {}
for (show, members, _) in results:
for (member, _, _, _) in members:
if member.id not in members_uniq:
members_uniq[member.id] = member
members2[member] = []
member.total = 0
member = members_uniq[member.id]
members2[member].append(show)
member.total += show.price
members2 = members2.items()
data["members2"] = sorted(members2, key=lambda m: m[0].user.last_name)
# ---
# À partir d'ici, le tirage devient effectif
# ---
# On suppression les vieilles attributions, on sauvegarde le token et on
# désactive le tirage
Attribution.objects.filter(spectacle__tirage=tirage_elt).delete()
tirage_elt.tokens += '{:s}\n"""{:s}"""\n'.format(
timezone.now().strftime("%y-%m-%d %H:%M:%S"),
token)
tirage_elt.enable_do_tirage = False
tirage_elt.save()
# On enregistre les nouvelles attributions
Attribution.objects.bulk_create([
Attribution(spectacle=show, participant=member)
for show, members, _ in results
for member, _, _, _ in members
])
# On inscrit à BdA-Revente ceux qui n'ont pas eu les places voulues
for (show, _, losers) in results:
for (loser, _, _, _) in losers:
loser.choicesrevente.add(show)
loser.save()
data["duration"] = time.time() - start data["duration"] = time.time() - start
if request.user.is_authenticated(): data["results"] = results
members2 = {} return data
# Participant objects are not shared accross spectacle results,
# so assign a single object for each Participant id
members_uniq = {}
for (show, members, _) in results:
for (member, _, _, _) in members:
if member.id not in members_uniq:
members_uniq[member.id] = member
members2[member] = []
member.total = 0
member = members_uniq[member.id]
members2[member].append(show)
member.total += show.price
members2 = members2.items()
data["members2"] = sorted(members2, key=lambda m: m[0].user.last_name)
# À partir d'ici, le tirage devient effectif
Attribution.objects.filter(spectacle__tirage=tirage_elt).delete()
tirage_elt.tokens += "%s\n\"\"\"%s\"\"\"\n" % (
timezone.now().strftime("%y-%m-%d %H:%M:%S"),
form.cleaned_data['token'])
tirage_elt.enable_do_tirage = False
tirage_elt.save()
Attribution.objects.bulk_create([
Attribution(spectacle=show, participant=member)
for show, members, _ in results
for member, _, _, _ in members])
# On inscrit à BdA-Revente ceux qui n'ont pas eu les places voulues
for (show, _, losers) in results:
for (loser, _, _, _) in losers:
loser.choicesrevente.add(show)
loser.save()
return render(request, "bda-attrib-extra.html", data)
else:
return render(request, "bda-attrib.html", data)
@buro_required @buro_required
@ -287,7 +304,8 @@ def tirage(request, tirage_id):
if request.POST: if request.POST:
form = TokenForm(request.POST) form = TokenForm(request.POST)
if form.is_valid(): if form.is_valid():
return do_tirage(request, tirage_id) results = do_tirage(tirage_elt, form.cleaned_data['token'])
return render(request, "bda-attrib-extra.html", results)
else: else:
form = TokenForm() form = TokenForm()
return render(request, "bda-token.html", {"form": form}) return render(request, "bda-token.html", {"form": form})

View file

@ -9,10 +9,6 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/ https://docs.djangoproject.com/en/1.8/ref/settings/
""" """
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os import os
@ -162,6 +158,8 @@ AUTHENTICATION_BACKENDS = (
'kfet.backends.GenericTeamBackend', 'kfet.backends.GenericTeamBackend',
) )
# LDAP_SERVER_URL = 'ldaps://ldap.spi.ens.fr:636'
# EMAIL_HOST="nef.ens.fr" # EMAIL_HOST="nef.ens.fr"
RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PUBLIC_KEY = "DUMMY"

View file

@ -4,10 +4,6 @@
Fichier principal de configuration des urls du projet GestioCOF Fichier principal de configuration des urls du projet GestioCOF
""" """
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import autocomplete_light import autocomplete_light
from django.conf import settings from django.conf import settings
@ -61,7 +57,8 @@ urlpatterns = [
name='password_change_done'), name='password_change_done'),
# Inscription d'un nouveau membre # Inscription d'un nouveau membre
url(r'^registration$', gestioncof_views.registration), url(r'^registration$', gestioncof_views.registration),
url(r'^registration/clipper/(?P<login_clipper>[\w-]+)$', url(r'^registration/clipper/(?P<login_clipper>[\w-]+)/'
r'(?P<fullname>.*)$',
gestioncof_views.registration_form2, name="clipper-registration"), gestioncof_views.registration_form2, name="clipper-registration"),
url(r'^registration/user/(?P<username>.+)$', url(r'^registration/user/(?P<username>.+)$',
gestioncof_views.registration_form2, name="user-registration"), gestioncof_views.registration_form2, name="user-registration"),

View file

@ -1,18 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division from ldap3 import Connection
from __future__ import print_function
from __future__ import unicode_literals
from django import shortcuts from django import shortcuts
from django.http import Http404 from django.http import Http404
from django.db.models import Q from django.db.models import Q
from django.contrib.auth.models import User from django.contrib.auth.models import User
from gestioncof.models import CofProfile, Clipper from django.conf import settings
from gestioncof.models import CofProfile
from gestioncof.decorators import buro_required from gestioncof.decorators import buro_required
class Clipper(object):
def __init__(self, clipper, fullname):
self.clipper = clipper
self.fullname = fullname
@buro_required @buro_required
def autocomplete(request): def autocomplete(request):
if "q" not in request.GET: if "q" not in request.GET:
@ -25,37 +30,51 @@ def autocomplete(request):
queries = {} queries = {}
bits = q.split() bits = q.split()
queries['members'] = CofProfile.objects.filter(Q(is_cof=True)) # Fetching data from User and CofProfile tables
queries['users'] = User.objects.filter(Q(profile__is_cof=False)) queries['members'] = CofProfile.objects.filter(is_cof=True)
queries['clippers'] = Clipper.objects queries['users'] = User.objects.filter(profile__is_cof=False)
for bit in bits: for bit in bits:
queries['members'] = queries['members'].filter( queries['members'] = queries['members'].filter(
Q(user__first_name__icontains=bit) Q(user__first_name__icontains=bit)
| Q(user__last_name__icontains=bit) | Q(user__last_name__icontains=bit)
| Q(user__username__icontains=bit) | Q(user__username__icontains=bit)
| Q(login_clipper__icontains=bit)) | Q(login_clipper__icontains=bit))
queries['users'] = queries['users'].filter( queries['users'] = queries['users'].filter(
Q(first_name__icontains=bit) Q(first_name__icontains=bit)
| Q(last_name__icontains=bit) | Q(last_name__icontains=bit)
| Q(username__icontains=bit)) | Q(username__icontains=bit))
queries['clippers'] = queries['clippers'].filter(
Q(fullname__icontains=bit)
| Q(username__icontains=bit))
queries['members'] = queries['members'].distinct() queries['members'] = queries['members'].distinct()
queries['users'] = queries['users'].distinct() queries['users'] = queries['users'].distinct()
usernames = list(queries['members'].values_list('login_clipper',
flat='True')) \
+ list(queries['users'].values_list('profile__login_clipper',
flat='True'))
queries['clippers'] = queries['clippers'] \
.exclude(username__in=usernames).distinct()
# add clippers
# Clearing redundancies
usernames = (
set(queries['members'].values_list('login_clipper', flat='True'))
| set(queries['users'].values_list('profile__login_clipper',
flat='True'))
)
# Fetching data from the SPI
if hasattr(settings, 'LDAP_SERVER_URL'):
# Fetching
ldap_query = '(|{:s})'.format(''.join(
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(**{"bit": bit})
for bit in bits]
))
with Connection(settings.LDAP_SERVER_URL) as conn:
conn.search(
'dc=spi,dc=ens,dc=fr', ldap_query,
attributes=['uid', 'cn']
)
queries['clippers'] = conn.entries
# Clearing redundancies
queries['clippers'] = [
Clipper(clipper.uid, clipper.cn)
for clipper in queries['clippers']
if str(clipper.uid) not in usernames
]
# Resulting data
data.update(queries) data.update(queries)
data['options'] = sum(len(query) for query in queries)
options = 0
for query in queries.values():
options += len(query)
data['options'] = options
return shortcuts.render(request, "autocomplete_user.html", data) return shortcuts.render(request, "autocomplete_user.html", data)

View file

@ -1,13 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import autocomplete_light import autocomplete_light
from django.contrib.auth.models import User from django.contrib.auth.models import User
autocomplete_light.register( autocomplete_light.register(
User, search_fields=('username', 'first_name', 'last_name'), User, search_fields=('username', 'first_name', 'last_name'),
autocomplete_js_attributes={'placeholder': 'membre...'}) attrs={'placeholder': 'membre...'}
)

View file

@ -152,156 +152,6 @@
"model": "gestioncof.petitcourssubject", "model": "gestioncof.petitcourssubject",
"pk": 4 "pk": 4
}, },
{
"fields": {
"matiere": 1,
"niveau": "college",
"user": 11,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 1
},
{
"fields": {
"matiere": 1,
"niveau": "lycee",
"user": 11,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 2
},
{
"fields": {
"matiere": 1,
"niveau": "prepa1styear",
"user": 11,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 3
},
{
"fields": {
"matiere": 1,
"niveau": "prepa2ndyear",
"user": 11,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 4
},
{
"fields": {
"matiere": 1,
"niveau": "licence3",
"user": 11,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 5
},
{
"fields": {
"matiere": 1,
"niveau": "prepa1styear",
"user": 43,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 6
},
{
"fields": {
"matiere": 1,
"niveau": "prepa2ndyear",
"user": 43,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 7
},
{
"fields": {
"matiere": 1,
"niveau": "licence3",
"user": 43,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 8
},
{
"fields": {
"matiere": 2,
"niveau": "college",
"user": 43,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 9
},
{
"fields": {
"matiere": 2,
"niveau": "lycee",
"user": 43,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 10
},
{
"fields": {
"matiere": 3,
"niveau": "lycee",
"user": 48,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 11
},
{
"fields": {
"matiere": 3,
"niveau": "prepa1styear",
"user": 48,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 12
},
{
"fields": {
"matiere": 3,
"niveau": "prepa2ndyear",
"user": 48,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 13
},
{
"fields": {
"matiere": 3,
"niveau": "licence3",
"user": 48,
"agrege": true
},
"model": "gestioncof.petitcoursability",
"pk": 14
},
{
"fields": {
"matiere": 4,
"niveau": "college",
"user": 10,
"agrege": false
},
"model": "gestioncof.petitcoursability",
"pk": 15
},
{ {
"fields": { "fields": {
"traitee": false, "traitee": false,

View file

@ -1,41 +0,0 @@
[
{
"fields": {
"username": "root",
"first_name": "super",
"last_name": "user",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": null,
"groups": [],
"user_permissions": [],
"password": "pbkdf2_sha256$12000$yRpkPuayQ8De$h6bDe+Q4kMikzwEbLNw2I9/V/1/v3F3yLIjEZIFSHrY=",
"email": "root@localhost",
"date_joined": "2016-06-15T17:50:57Z"
},
"model": "auth.user",
"pk": 62
},
{
"fields": {
"departement": "",
"type_cotiz": "normalien",
"petits_cours_remarques": "",
"is_buro": true,
"is_cof": true,
"mailing_cof": true,
"comments": "Super utilisateur",
"login_clipper": "",
"phone": "",
"num": 62,
"mailing_bda_revente": true,
"user": 62,
"petits_cours_accept": false,
"mailing_bda": true,
"occupation": "1A"
},
"model": "gestioncof.cofprofile",
"pk": 62
}
]

File diff suppressed because it is too large Load diff

View file

@ -378,12 +378,12 @@ EventFormset = formset_factory(AdminEventForm, BaseEventRegistrationFormset)
class CalendarForm(forms.ModelForm): class CalendarForm(forms.ModelForm):
subscribe_to_events = forms.BooleanField( subscribe_to_events = forms.BooleanField(
initial=True, initial=True,
label="Événements du COF.") label="Événements du COF")
subscribe_to_my_shows = forms.BooleanField( subscribe_to_my_shows = forms.BooleanField(
initial=True, initial=True,
label="Les spectacles pour lesquels j'ai obtenu une place.") label="Les spectacles pour lesquels j'ai obtenu une place")
other_shows = forms.ModelMultipleChoiceField( other_shows = forms.ModelMultipleChoiceField(
label="Spectacles supplémentaires.", label="Spectacles supplémentaires",
queryset=Spectacle.objects.filter(tirage__active=True), queryset=Spectacle.objects.filter(tirage__active=True),
widget=forms.CheckboxSelectMultiple, widget=forms.CheckboxSelectMultiple,
required=False) required=False)

View file

@ -0,0 +1,41 @@
"""
Un mixin à utiliser avec BaseCommand pour charger des objets depuis un json
"""
import os
import json
from django.core.management.base import BaseCommand
class MyBaseCommand(BaseCommand):
"""
Ajoute une méthode ``from_json`` qui charge des objets à partir d'un json.
"""
def from_json(self, filename, data_dir, klass,
callback=lambda obj: obj):
"""
Charge les objets contenus dans le fichier json référencé par
``filename`` dans la base de donnée. La fonction callback est appelées
sur chaque objet avant enregistrement.
"""
self.stdout.write("Chargement de {:s}".format(filename))
with open(os.path.join(data_dir, filename), 'r') as file:
descriptions = json.load(file)
objects = []
nb_new = 0
for description in descriptions:
qset = klass.objects.filter(**description)
try:
objects.append(qset.get())
except klass.DoesNotExist:
obj = klass(**description)
obj = callback(obj)
obj.save()
objects.append(obj)
nb_new += 1
self.stdout.write("- {:d} objets créés".format(nb_new))
self.stdout.write("- {:d} objets gardés en l'état"
.format(len(objects)-nb_new))
return objects

View file

@ -0,0 +1,109 @@
"""
Charge des données de test dans la BDD
- Utilisateurs
- Sondage
- Événement
- Petits cours
"""
import os
import random
from django.contrib.auth.models import User
from django.core.management import call_command
from gestioncof.management.base import MyBaseCommand
from gestioncof.petits_cours_models import (
PetitCoursAbility, PetitCoursSubject, LEVELS_CHOICES,
PetitCoursAttributionCounter
)
# Où sont stockés les fichiers json
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'data')
class Command(MyBaseCommand):
help = "Charge des données de test dans la BDD"
def add_arguments(self, parser):
"""
Permet de ne pas créer l'utilisateur "root".
"""
parser.add_argument(
'--no-root',
action='store_true',
dest='no-root',
default=False,
help='Ne crée pas l\'utilisateur "root"'
)
def handle(self, *args, **options):
# ---
# Utilisateurs
# ---
# Gaulois
gaulois = self.from_json('gaulois.json', DATA_DIR, User)
for user in gaulois:
user.profile.is_cof = True
user.profile.save()
# Romains
self.from_json('romains.json', DATA_DIR, User)
# Root
no_root = options.get('no-root', False)
if not no_root:
self.stdout.write("Création de l'utilisateur root")
root, _ = User.objects.get_or_create(
username='root',
first_name='super',
last_name='user',
email='root@localhost')
root.set_password('root')
root.is_staff = True
root.is_superuser = True
root.profile.is_cof = True
root.profile.is_buro = True
root.profile.save()
root.save()
# ---
# Petits cours
# ---
self.stdout.write("Inscriptions au système des petits cours")
levels = [id for (id, verbose) in LEVELS_CHOICES]
subjects = list(PetitCoursSubject.objects.all())
nb_of_teachers = 0
for user in gaulois:
if random.randint(0, 1):
nb_of_teachers += 1
# L'utilisateur reçoit les demandes de petits cours
user.profile.petits_cours_accept = True
user.save()
# L'utilisateur est compétent dans une matière
subject = random.choice(subjects)
if not PetitCoursAbility.objects.filter(
user=user,
matiere=subject).exists():
PetitCoursAbility.objects.create(
user=user,
matiere=subject,
niveau=random.choice(levels),
agrege=bool(random.randint(0, 1))
)
# On initialise son compteur d'attributions
PetitCoursAttributionCounter.objects.get_or_create(
user=user,
matiere=subject
)
self.stdout.write("- {:d} inscriptions".format(nb_of_teachers))
# ---
# Le BdA
# ---
call_command('loadbdadevdata')

View file

@ -0,0 +1,368 @@
[
{
"username": "Abraracourcix",
"email": "Abraracourcix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Abraracourcix"
},
{
"username": "Acidenitrix",
"email": "Acidenitrix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Acidenitrix"
},
{
"username": "Agecanonix",
"email": "Agecanonix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Agecanonix"
},
{
"username": "Alambix",
"email": "Alambix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Alambix"
},
{
"username": "Amerix",
"email": "Amerix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Amerix"
},
{
"username": "Amnesix",
"email": "Amnesix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Amnesix"
},
{
"username": "Aniline",
"email": "Aniline.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Aniline"
},
{
"username": "Aplusbegalix",
"email": "Aplusbegalix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Aplusbegalix"
},
{
"username": "Archeopterix",
"email": "Archeopterix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Archeopterix"
},
{
"username": "Assurancetourix",
"email": "Assurancetourix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Assurancetourix"
},
{
"username": "Asterix",
"email": "Asterix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Asterix"
},
{
"username": "Astronomix",
"email": "Astronomix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Astronomix"
},
{
"username": "Avoranfix",
"email": "Avoranfix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Avoranfix"
},
{
"username": "Barometrix",
"email": "Barometrix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Barometrix"
},
{
"username": "Beaufix",
"email": "Beaufix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Beaufix"
},
{
"username": "Berlix",
"email": "Berlix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Berlix"
},
{
"username": "Bonemine",
"email": "Bonemine.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Bonemine"
},
{
"username": "Boufiltre",
"email": "Boufiltre.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Boufiltre"
},
{
"username": "Catedralgotix",
"email": "Catedralgotix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Catedralgotix"
},
{
"username": "CesarLabeldecadix",
"email": "CesarLabeldecadix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "CesarLabeldecadix"
},
{
"username": "Cetautomatix",
"email": "Cetautomatix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Cetautomatix"
},
{
"username": "Cetyounix",
"email": "Cetyounix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Cetyounix"
},
{
"username": "Changeledix",
"email": "Changeledix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Changeledix"
},
{
"username": "Chanteclairix",
"email": "Chanteclairix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Chanteclairix"
},
{
"username": "Cicatrix",
"email": "Cicatrix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Cicatrix"
},
{
"username": "Comix",
"email": "Comix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Comix"
},
{
"username": "Diagnostix",
"email": "Diagnostix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Diagnostix"
},
{
"username": "Doublepolemix",
"email": "Doublepolemix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Doublepolemix"
},
{
"username": "Eponine",
"email": "Eponine.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Eponine"
},
{
"username": "Falbala",
"email": "Falbala.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Falbala"
},
{
"username": "Fanzine",
"email": "Fanzine.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Fanzine"
},
{
"username": "Gelatine",
"email": "Gelatine.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Gelatine"
},
{
"username": "Goudurix",
"email": "Goudurix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Goudurix"
},
{
"username": "Homeopatix",
"email": "Homeopatix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Homeopatix"
},
{
"username": "Idefix",
"email": "Idefix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Idefix"
},
{
"username": "Ielosubmarine",
"email": "Ielosubmarine.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Ielosubmarine"
},
{
"username": "Keskonrix",
"email": "Keskonrix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Keskonrix"
},
{
"username": "Lentix",
"email": "Lentix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Lentix"
},
{
"username": "Maestria",
"email": "Maestria.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Maestria"
},
{
"username": "MaitrePanix",
"email": "MaitrePanix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "MaitrePanix"
},
{
"username": "MmeAgecanonix",
"email": "MmeAgecanonix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "MmeAgecanonix"
},
{
"username": "Moralelastix",
"email": "Moralelastix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Moralelastix"
},
{
"username": "Obelix",
"email": "Obelix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Obelix"
},
{
"username": "Obelodalix",
"email": "Obelodalix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Obelodalix"
},
{
"username": "Odalix",
"email": "Odalix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Odalix"
},
{
"username": "Ordralfabetix",
"email": "Ordralfabetix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Ordralfabetix"
},
{
"username": "Orthopedix",
"email": "Orthopedix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Orthopedix"
},
{
"username": "Panoramix",
"email": "Panoramix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Panoramix"
},
{
"username": "Plaintcontrix",
"email": "Plaintcontrix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Plaintcontrix"
},
{
"username": "Praline",
"email": "Praline.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Praline"
},
{
"username": "Prefix",
"email": "Prefix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Prefix"
},
{
"username": "Prolix",
"email": "Prolix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Prolix"
},
{
"username": "Pronostix",
"email": "Pronostix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Pronostix"
},
{
"username": "Quatredeusix",
"email": "Quatredeusix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Quatredeusix"
},
{
"username": "Saingesix",
"email": "Saingesix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Saingesix"
},
{
"username": "Segregationnix",
"email": "Segregationnix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Segregationnix"
},
{
"username": "Septantesix",
"email": "Septantesix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Septantesix"
},
{
"username": "Tournedix",
"email": "Tournedix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Tournedix"
},
{
"username": "Tragicomix",
"email": "Tragicomix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Tragicomix"
},
{
"username": "Coriza",
"email": "Coriza.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Coriza"
},
{
"username": "Zerozerosix",
"email": "Zerozerosix.gaulois@ens.fr",
"last_name": "Gaulois",
"first_name": "Zerozerosix"
}
]

View file

@ -0,0 +1,614 @@
[
{
"username": "Abel",
"email": "Abel.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Abel"
},
{
"username": "Abelardus",
"email": "Abelardus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Abelardus"
},
{
"username": "Abrahamus",
"email": "Abrahamus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Abrahamus"
},
{
"username": "Acacius",
"email": "Acacius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Acacius"
},
{
"username": "Accius",
"email": "Accius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Accius"
},
{
"username": "Achaicus",
"email": "Achaicus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Achaicus"
},
{
"username": "Achill",
"email": "Achill.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Achill"
},
{
"username": "Achilles",
"email": "Achilles.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Achilles"
},
{
"username": "Achilleus",
"email": "Achilleus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Achilleus"
},
{
"username": "Acrisius",
"email": "Acrisius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Acrisius"
},
{
"username": "Actaeon",
"email": "Actaeon.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Actaeon"
},
{
"username": "Acteon",
"email": "Acteon.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Acteon"
},
{
"username": "Adalricus",
"email": "Adalricus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adalricus"
},
{
"username": "Adelfonsus",
"email": "Adelfonsus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adelfonsus"
},
{
"username": "Adelphus",
"email": "Adelphus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adelphus"
},
{
"username": "Adeodatus",
"email": "Adeodatus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adeodatus"
},
{
"username": "Adolfus",
"email": "Adolfus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adolfus"
},
{
"username": "Adolphus",
"email": "Adolphus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adolphus"
},
{
"username": "Adrastus",
"email": "Adrastus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adrastus"
},
{
"username": "Adrianus",
"email": "Adrianus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Adrianus"
},
{
"username": "\u00c6gidius",
"email": "\u00c6gidius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6gidius"
},
{
"username": "\u00c6lia",
"email": "\u00c6lia.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6lia"
},
{
"username": "\u00c6lianus",
"email": "\u00c6lianus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6lianus"
},
{
"username": "\u00c6milianus",
"email": "\u00c6milianus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6milianus"
},
{
"username": "\u00c6milius",
"email": "\u00c6milius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6milius"
},
{
"username": "Aeneas",
"email": "Aeneas.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aeneas"
},
{
"username": "\u00c6olus",
"email": "\u00c6olus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6olus"
},
{
"username": "\u00c6schylus",
"email": "\u00c6schylus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6schylus"
},
{
"username": "\u00c6son",
"email": "\u00c6son.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6son"
},
{
"username": "\u00c6sop",
"email": "\u00c6sop.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6sop"
},
{
"username": "\u00c6ther",
"email": "\u00c6ther.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6ther"
},
{
"username": "\u00c6tius",
"email": "\u00c6tius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "\u00c6tius"
},
{
"username": "Agapetus",
"email": "Agapetus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Agapetus"
},
{
"username": "Agapitus",
"email": "Agapitus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Agapitus"
},
{
"username": "Agapius",
"email": "Agapius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Agapius"
},
{
"username": "Agathangelus",
"email": "Agathangelus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Agathangelus"
},
{
"username": "Aigidius",
"email": "Aigidius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aigidius"
},
{
"username": "Aiolus",
"email": "Aiolus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aiolus"
},
{
"username": "Ajax",
"email": "Ajax.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Ajax"
},
{
"username": "Alair",
"email": "Alair.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alair"
},
{
"username": "Alaricus",
"email": "Alaricus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alaricus"
},
{
"username": "Albanus",
"email": "Albanus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Albanus"
},
{
"username": "Alberic",
"email": "Alberic.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alberic"
},
{
"username": "Albericus",
"email": "Albericus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Albericus"
},
{
"username": "Albertus",
"email": "Albertus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Albertus"
},
{
"username": "Albinus",
"email": "Albinus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Albinus"
},
{
"username": "Albus",
"email": "Albus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Albus"
},
{
"username": "Alcaeus",
"email": "Alcaeus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alcaeus"
},
{
"username": "Alcander",
"email": "Alcander.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alcander"
},
{
"username": "Alcimus",
"email": "Alcimus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alcimus"
},
{
"username": "Alcinder",
"email": "Alcinder.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alcinder"
},
{
"username": "Alerio",
"email": "Alerio.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alerio"
},
{
"username": "Alexandrus",
"email": "Alexandrus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alexandrus"
},
{
"username": "Alexis",
"email": "Alexis.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alexis"
},
{
"username": "Alexius",
"email": "Alexius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alexius"
},
{
"username": "Alexus",
"email": "Alexus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alexus"
},
{
"username": "Alfonsus",
"email": "Alfonsus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alfonsus"
},
{
"username": "Alfredus",
"email": "Alfredus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alfredus"
},
{
"username": "Almericus",
"email": "Almericus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Almericus"
},
{
"username": "Aloisius",
"email": "Aloisius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aloisius"
},
{
"username": "Aloysius",
"email": "Aloysius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aloysius"
},
{
"username": "Alphaeus",
"email": "Alphaeus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alphaeus"
},
{
"username": "Alpheaus",
"email": "Alpheaus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alpheaus"
},
{
"username": "Alpheus",
"email": "Alpheus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alpheus"
},
{
"username": "Alphoeus",
"email": "Alphoeus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alphoeus"
},
{
"username": "Alphonsus",
"email": "Alphonsus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alphonsus"
},
{
"username": "Alphonzus",
"email": "Alphonzus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alphonzus"
},
{
"username": "Alvinius",
"email": "Alvinius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alvinius"
},
{
"username": "Alvredus",
"email": "Alvredus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Alvredus"
},
{
"username": "Amadeus",
"email": "Amadeus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amadeus"
},
{
"username": "Amaliricus",
"email": "Amaliricus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amaliricus"
},
{
"username": "Amandus",
"email": "Amandus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amandus"
},
{
"username": "Amantius",
"email": "Amantius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amantius"
},
{
"username": "Amarandus",
"email": "Amarandus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amarandus"
},
{
"username": "Amaranthus",
"email": "Amaranthus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amaranthus"
},
{
"username": "Amatus",
"email": "Amatus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amatus"
},
{
"username": "Ambrosianus",
"email": "Ambrosianus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Ambrosianus"
},
{
"username": "Ambrosius",
"email": "Ambrosius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Ambrosius"
},
{
"username": "Amedeus",
"email": "Amedeus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amedeus"
},
{
"username": "Americus",
"email": "Americus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Americus"
},
{
"username": "Amlethus",
"email": "Amlethus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amlethus"
},
{
"username": "Amletus",
"email": "Amletus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amletus"
},
{
"username": "Amor",
"email": "Amor.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amor"
},
{
"username": "Ampelius",
"email": "Ampelius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Ampelius"
},
{
"username": "Amphion",
"email": "Amphion.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Amphion"
},
{
"username": "Anacletus",
"email": "Anacletus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anacletus"
},
{
"username": "Anastasius",
"email": "Anastasius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anastasius"
},
{
"username": "Anastatius",
"email": "Anastatius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anastatius"
},
{
"username": "Anastius",
"email": "Anastius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anastius"
},
{
"username": "Anatolius",
"email": "Anatolius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anatolius"
},
{
"username": "Androcles",
"email": "Androcles.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Androcles"
},
{
"username": "Andronicus",
"email": "Andronicus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Andronicus"
},
{
"username": "Anencletus",
"email": "Anencletus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anencletus"
},
{
"username": "Angelicus",
"email": "Angelicus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Angelicus"
},
{
"username": "Angelus",
"email": "Angelus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Angelus"
},
{
"username": "Anicetus",
"email": "Anicetus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Anicetus"
},
{
"username": "Antigonus",
"email": "Antigonus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Antigonus"
},
{
"username": "Antipater",
"email": "Antipater.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Antipater"
},
{
"username": "Antoninus",
"email": "Antoninus.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Antoninus"
},
{
"username": "Antonius",
"email": "Antonius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Antonius"
},
{
"username": "Aphrodisius",
"email": "Aphrodisius.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Aphrodisius"
},
{
"username": "Apollinaris",
"email": "Apollinaris.Romain@ens.fr",
"last_name": "Romain",
"first_name": "Apollinaris"
}
]

View file

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0008_py3'),
]
operations = [
migrations.DeleteModel(
name='Clipper',
),
]

View file

@ -1,9 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from django.db import models from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -264,15 +260,6 @@ class SurveyAnswer(models.Model):
self.survey.title) self.survey.title)
@python_2_unicode_compatible
class Clipper(models.Model):
username = models.CharField("Identifiant", max_length=20)
fullname = models.CharField("Nom complet", max_length=200)
def __str__(self):
return "Clipper %s" % self.username
@python_2_unicode_compatible @python_2_unicode_compatible
class CalendarSubscription(models.Model): class CalendarSubscription(models.Model):
token = models.UUIDField() token = models.UUIDField()

View file

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from captcha.fields import ReCaptchaField
from django import forms
from django.forms import ModelForm
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from django.contrib.auth.models import User
from gestioncof.petits_cours_models import PetitCoursDemande, PetitCoursAbility
class BaseMatieresFormSet(BaseInlineFormSet):
def clean(self):
super(BaseMatieresFormSet, self).clean()
if any(self.errors):
# Don't bother validating the formset unless each form is
# valid on its own
return
matieres = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
if not form.cleaned_data:
continue
matiere = form.cleaned_data['matiere']
niveau = form.cleaned_data['niveau']
delete = form.cleaned_data['DELETE']
if not delete and (matiere, niveau) in matieres:
raise forms.ValidationError(
"Vous ne pouvez pas vous inscrire deux fois pour la "
"même matiere avec le même niveau.")
matieres.append((matiere, niveau))
class DemandeForm(ModelForm):
captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'fr'})
def __init__(self, *args, **kwargs):
super(DemandeForm, self).__init__(*args, **kwargs)
self.fields['matieres'].help_text = ''
class Meta:
model = PetitCoursDemande
fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu',
'matieres', 'agrege_requis', 'niveau', 'remarques')
widgets = {'matieres': forms.CheckboxSelectMultiple}
MatieresFormSet = inlineformset_factory(
User,
PetitCoursAbility,
fields=("matiere", "niveau", "agrege"),
formset=BaseMatieresFormSet
)

View file

@ -1,14 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division from functools import reduce
from __future__ import print_function
from __future__ import unicode_literals
from django.db import models from django.db import models
from django.db.models import Min
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible
from django.utils.six.moves import reduce
def choices_length(choices): def choices_length(choices):
@ -24,7 +21,6 @@ LEVELS_CHOICES = (
) )
@python_2_unicode_compatible
class PetitCoursSubject(models.Model): class PetitCoursSubject(models.Model):
name = models.CharField(_("Matière"), max_length=30) name = models.CharField(_("Matière"), max_length=30)
users = models.ManyToManyField(User, related_name="petits_cours_matieres", users = models.ManyToManyField(User, related_name="petits_cours_matieres",
@ -38,7 +34,6 @@ class PetitCoursSubject(models.Model):
return self.name return self.name
@python_2_unicode_compatible
class PetitCoursAbility(models.Model): class PetitCoursAbility(models.Model):
user = models.ForeignKey(User) user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière")) matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière"))
@ -52,11 +47,11 @@ class PetitCoursAbility(models.Model):
verbose_name_plural = "Compétences des petits cours" verbose_name_plural = "Compétences des petits cours"
def __str__(self): def __str__(self):
return "%s - %s - %s" % (self.user.username, return "{:s} - {!s} - {:s}".format(
self.matiere, self.niveau) self.user.username, self.matiere, self.niveau
)
@python_2_unicode_compatible
class PetitCoursDemande(models.Model): class PetitCoursDemande(models.Model):
name = models.CharField(_("Nom/prénom"), max_length=200) name = models.CharField(_("Nom/prénom"), max_length=200)
email = models.CharField(_("Adresse email"), max_length=300) email = models.CharField(_("Adresse email"), max_length=300)
@ -70,7 +65,7 @@ class PetitCoursDemande(models.Model):
freq = models.CharField( freq = models.CharField(
_("Fréquence"), _("Fréquence"),
help_text=_("Indiquez ici la fréquence envisagée " help_text=_("Indiquez ici la fréquence envisagée "
+ "(hebdomadaire, 2 fois par semaine, ...)"), "(hebdomadaire, 2 fois par semaine, ...)"),
max_length=300, blank=True) max_length=300, blank=True)
lieu = models.CharField( lieu = models.CharField(
_("Lieu (si préférence)"), _("Lieu (si préférence)"),
@ -94,16 +89,42 @@ class PetitCoursDemande(models.Model):
blank=True, null=True) blank=True, null=True)
created = models.DateTimeField(_("Date de création"), auto_now_add=True) created = models.DateTimeField(_("Date de création"), auto_now_add=True)
def get_candidates(self, redo=False):
"""
Donne la liste des profs disponibles pour chaque matière de la demande.
- On ne donne que les agrégés si c'est demandé
- Si ``redo`` vaut ``True``, cela signifie qu'on retraite la demande et
il ne faut pas proposer à nouveau des noms qui ont déjà été proposés
"""
for matiere in self.matieres.all():
candidates = PetitCoursAbility.objects.filter(
matiere=matiere,
niveau=self.niveau,
user__profile__is_cof=True,
user__profile__petits_cours_accept=True
)
if self.agrege_requis:
candidates = candidates.filter(agrege=True)
if redo:
attrs = self.petitcoursattribution_set.filter(matiere=matiere)
already_proposed = [
attr.user
for attr in attrs
]
candidates = candidates.exclude(user__in=already_proposed)
candidates = candidates.order_by('?').select_related().all()
yield (matiere, candidates)
class Meta: class Meta:
verbose_name = "Demande de petits cours" verbose_name = "Demande de petits cours"
verbose_name_plural = "Demandes de petits cours" verbose_name_plural = "Demandes de petits cours"
def __str__(self): def __str__(self):
return "Demande %d du %s" % (self.id, return "Demande {:d} du {:s}".format(
self.created.strftime("%d %b %Y")) self.id, self.created.strftime("%d %b %Y")
)
@python_2_unicode_compatible
class PetitCoursAttribution(models.Model): class PetitCoursAttribution(models.Model):
user = models.ForeignKey(User) user = models.ForeignKey(User)
demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande")) demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande"))
@ -118,20 +139,40 @@ class PetitCoursAttribution(models.Model):
verbose_name_plural = "Attributions de petits cours" verbose_name_plural = "Attributions de petits cours"
def __str__(self): def __str__(self):
return "Attribution de la demande %d à %s pour %s" \ return "Attribution de la demande {:d} à {:s} pour {!s}".format(
% (self.demande.id, self.user.username, self.matiere) self.demande.id, self.user.username, self.matiere
)
@python_2_unicode_compatible
class PetitCoursAttributionCounter(models.Model): class PetitCoursAttributionCounter(models.Model):
user = models.ForeignKey(User) user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere")) matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere"))
count = models.IntegerField("Nombre d'envois", default=0) count = models.IntegerField("Nombre d'envois", default=0)
@classmethod
def get_uptodate(cls, user, matiere):
"""
Donne le compteur de l'utilisateur pour cette matière. Si le compteur
n'existe pas encore, il est initialisé avec le minimum des valeurs des
compteurs de tout le monde.
"""
counter, created = cls.objects.get_or_create(
user=user, matiere=matiere)
if created:
mincount = (
cls.objects.filter(matiere=matiere).exclude(user=user)
.aggregate(Min('count'))
['count__min']
)
counter.count = mincount
counter.save()
return counter
class Meta: class Meta:
verbose_name = "Compteur d'attribution de petits cours" verbose_name = "Compteur d'attribution de petits cours"
verbose_name_plural = "Compteurs d'attributions de petits cours" verbose_name_plural = "Compteurs d'attributions de petits cours"
def __str__(self): def __str__(self):
return "%d demandes envoyées à %s pour %s" \ return "{:d} demandes envoyées à {:s} pour {!s}".format(
% (self.count, self.user.username, self.matiere) self.count, self.user.username, self.matiere
)

View file

@ -1,33 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json
from datetime import datetime
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.core import mail from django.core import mail
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from django.forms import ModelForm
from django import forms
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.views.generic import ListView from django.views.generic import ListView, DetailView
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.template import loader from django.template import loader
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from django.db.models import Min
from gestioncof.models import CofProfile from gestioncof.models import CofProfile
from gestioncof.petits_cours_models import PetitCoursDemande, \ from gestioncof.petits_cours_models import (
PetitCoursAttribution, PetitCoursAttributionCounter, PetitCoursAbility, \ PetitCoursDemande, PetitCoursAttribution, PetitCoursAttributionCounter,
PetitCoursSubject PetitCoursAbility, PetitCoursSubject
)
from gestioncof.petits_cours_forms import DemandeForm, MatieresFormSet
from gestioncof.decorators import buro_required from gestioncof.decorators import buro_required
from gestioncof.shared import lock_table, unlock_tables from gestioncof.shared import lock_table, unlock_tables
from captcha.fields import ReCaptchaField
from datetime import datetime
import json
class DemandeListView(ListView): class DemandeListView(ListView):
model = PetitCoursDemande model = PetitCoursDemande
@ -37,47 +32,17 @@ class DemandeListView(ListView):
def get_queryset(self): def get_queryset(self):
return PetitCoursDemande.objects.order_by('traitee', '-id').all() return PetitCoursDemande.objects.order_by('traitee', '-id').all()
@method_decorator(buro_required)
def dispatch(self, *args, **kwargs):
return super(DemandeListView, self).dispatch(*args, **kwargs)
class DemandeDetailView(DetailView):
model = PetitCoursDemande
template_name = "gestioncof/details_demande_petit_cours.html"
context_object_name = "demande"
@buro_required def get_context_data(self, **kwargs):
def details(request, demande_id): context = super(DemandeDetailView, self).get_context_data(**kwargs)
demande = get_object_or_404(PetitCoursDemande, id=demande_id) obj = self.object
attributions = PetitCoursAttribution.objects.filter(demande=demande).all() context['attributions'] = obj.petitcoursattribution_set.all()
return render(request, "details_demande_petit_cours.html", return context
{"demande": demande,
"attributions": attributions})
def _get_attrib_counter(user, matiere):
counter, created = PetitCoursAttributionCounter \
.objects.get_or_create(user=user, matiere=matiere)
if created:
mincount = PetitCoursAttributionCounter.objects \
.filter(matiere=matiere).exclude(user=user).all() \
.aggregate(Min('count'))
counter.count = mincount['count__min']
counter.save()
return counter
def _get_demande_candidates(demande, redo=False):
for matiere in demande.matieres.all():
candidates = PetitCoursAbility.objects.filter(matiere=matiere,
niveau=demande.niveau)
candidates = candidates.filter(user__profile__is_cof=True,
user__profile__petits_cours_accept=True)
if demande.agrege_requis:
candidates = candidates.filter(agrege=True)
if redo:
attributions = PetitCoursAttribution.objects \
.filter(demande=demande, matiere=matiere).all()
for attrib in attributions:
candidates = candidates.exclude(user=attrib.user)
candidates = candidates.order_by('?').select_related().all()
yield (matiere, candidates)
@buro_required @buro_required
@ -91,12 +56,15 @@ def traitement(request, demande_id, redo=False):
proposed_for = {} proposed_for = {}
unsatisfied = [] unsatisfied = []
attribdata = {} attribdata = {}
for matiere, candidates in _get_demande_candidates(demande, redo): for matiere, candidates in demande.get_candidates(redo):
if candidates: if candidates:
tuples = [] tuples = []
for candidate in candidates: for candidate in candidates:
user = candidate.user user = candidate.user
tuples.append((candidate, _get_attrib_counter(user, matiere))) tuples.append((
candidate,
PetitCoursAttributionCounter.get_uptodate(user, matiere)
))
tuples = sorted(tuples, key=lambda c: c[1].count) tuples = sorted(tuples, key=lambda c: c[1].count)
candidates, _ = zip(*tuples) candidates, _ = zip(*tuples)
candidates = candidates[0:min(3, len(candidates))] candidates = candidates[0:min(3, len(candidates))]
@ -167,7 +135,7 @@ def _traitement_other_preparing(request, demande):
proposed_for = {} proposed_for = {}
attribdata = {} attribdata = {}
errors = [] errors = []
for matiere, candidates in _get_demande_candidates(demande, redo): for matiere, candidates in demande.get_candidates(redo):
if candidates: if candidates:
candidates = dict([(candidate.user.id, candidate.user) candidates = dict([(candidate.user.id, candidate.user)
for candidate in candidates]) for candidate in candidates])
@ -175,17 +143,19 @@ def _traitement_other_preparing(request, demande):
proposals[matiere] = [] proposals[matiere] = []
for choice_id in range(min(3, len(candidates))): for choice_id in range(min(3, len(candidates))):
choice = int( choice = int(
request.POST["proposal-%d-%d" % (matiere.id, choice_id)]) request.POST["proposal-{:d}-{:d}"
.format(matiere.id, choice_id)]
)
if choice == -1: if choice == -1:
continue continue
if choice not in candidates: if choice not in candidates:
errors.append("Choix invalide pour la proposition %d" errors.append("Choix invalide pour la proposition {:d}"
"en %s" % (choice_id + 1, matiere)) "en {!s}".format(choice_id + 1, matiere))
continue continue
user = candidates[choice] user = candidates[choice]
if user in proposals[matiere]: if user in proposals[matiere]:
errors.append("La proposition %d en %s est un doublon" errors.append("La proposition {:d} en {!s} est un doublon"
% (choice_id + 1, matiere)) .format(choice_id + 1, matiere))
continue continue
proposals[matiere].append(user) proposals[matiere].append(user)
attribdata[matiere.id].append(user.id) attribdata[matiere.id].append(user.id)
@ -194,12 +164,13 @@ def _traitement_other_preparing(request, demande):
else: else:
proposed_for[user].append(matiere) proposed_for[user].append(matiere)
if not proposals[matiere]: if not proposals[matiere]:
errors.append("Aucune proposition pour %s" % (matiere,)) errors.append("Aucune proposition pour {!s}".format(matiere))
elif len(proposals[matiere]) < 3: elif len(proposals[matiere]) < 3:
errors.append("Seulement %d proposition%s pour %s" errors.append("Seulement {:d} proposition{:s} pour {!s}"
% (len(proposals[matiere]), .format(
"s" if len(proposals[matiere]) > 1 else "", len(proposals[matiere]),
matiere)) "s" if len(proposals[matiere]) > 1 else "",
matiere))
else: else:
unsatisfied.append(matiere) unsatisfied.append(matiere)
return _finalize_traitement(request, demande, proposals, proposed_for, return _finalize_traitement(request, demande, proposals, proposed_for,
@ -216,12 +187,15 @@ def _traitement_other(request, demande, redo):
proposed_for = {} proposed_for = {}
unsatisfied = [] unsatisfied = []
attribdata = {} attribdata = {}
for matiere, candidates in _get_demande_candidates(demande, redo): for matiere, candidates in demande.get_candidates(redo):
if candidates: if candidates:
tuples = [] tuples = []
for candidate in candidates: for candidate in candidates:
user = candidate.user user = candidate.user
tuples.append((candidate, _get_attrib_counter(user, matiere))) tuples.append((
candidate,
PetitCoursAttributionCounter.get_uptodate(user, matiere)
))
tuples = sorted(tuples, key=lambda c: c[1].count) tuples = sorted(tuples, key=lambda c: c[1].count)
candidates, _ = zip(*tuples) candidates, _ = zip(*tuples)
attribdata[matiere.id] = [] attribdata[matiere.id] = []
@ -310,37 +284,11 @@ def _traitement_post(request, demande):
}) })
class BaseMatieresFormSet(BaseInlineFormSet):
def clean(self):
super(BaseMatieresFormSet, self).clean()
if any(self.errors):
# Don't bother validating the formset unless each form is
# valid on its own
return
matieres = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
if not form.cleaned_data:
continue
matiere = form.cleaned_data['matiere']
niveau = form.cleaned_data['niveau']
delete = form.cleaned_data['DELETE']
if not delete and (matiere, niveau) in matieres:
raise forms.ValidationError(
"Vous ne pouvez pas vous inscrire deux fois pour la "
"même matiere avec le même niveau.")
matieres.append((matiere, niveau))
@login_required @login_required
def inscription(request): def inscription(request):
profile, created = CofProfile.objects.get_or_create(user=request.user) profile, created = CofProfile.objects.get_or_create(user=request.user)
if not profile.is_cof: if not profile.is_cof:
return redirect("cof-denied") return redirect("cof-denied")
MatieresFormSet = inlineformset_factory(User, PetitCoursAbility,
fields=("matiere", "niveau",
"agrege",),
formset=BaseMatieresFormSet)
success = False success = False
if request.method == "POST": if request.method == "POST":
formset = MatieresFormSet(request.POST, instance=request.user) formset = MatieresFormSet(request.POST, instance=request.user)
@ -351,10 +299,14 @@ def inscription(request):
profile.save() profile.save()
lock_table(PetitCoursAttributionCounter, PetitCoursAbility, User, lock_table(PetitCoursAttributionCounter, PetitCoursAbility, User,
PetitCoursSubject) PetitCoursSubject)
abilities = PetitCoursAbility.objects \ abilities = (
.filter(user=request.user).all() PetitCoursAbility.objects.filter(user=request.user).all()
)
for ability in abilities: for ability in abilities:
_get_attrib_counter(ability.user, ability.matiere) PetitCoursAttributionCounter.get_uptodate(
ability.user,
ability.matiere
)
unlock_tables() unlock_tables()
success = True success = True
formset = MatieresFormSet(instance=request.user) formset = MatieresFormSet(instance=request.user)
@ -366,20 +318,6 @@ def inscription(request):
"remarques": profile.petits_cours_remarques}) "remarques": profile.petits_cours_remarques})
class DemandeForm(ModelForm):
captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'fr'})
def __init__(self, *args, **kwargs):
super(DemandeForm, self).__init__(*args, **kwargs)
self.fields['matieres'].help_text = ''
class Meta:
model = PetitCoursDemande
fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu',
'matieres', 'agrege_requis', 'niveau', 'remarques')
widgets = {'matieres': forms.CheckboxSelectMultiple}
@csrf_exempt @csrf_exempt
def demande(request): def demande(request):
success = False success = False

View file

@ -1073,6 +1073,12 @@ tr.awesome{
padding: 20px; padding: 20px;
} }
.petitcours-raw {
padding:20px;
background:#fff;
}
/* Messages */ /* Messages */
.messages .alert .close { .messages .alert .close {

File diff suppressed because one or more lines are too long

13
gestioncof/static/js/jquery-ui.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,11 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

View file

@ -15,7 +15,7 @@
{% if clippers %} {% if clippers %}
<li class="autocomplete-header">Utilisateurs <tt>clipper</tt></li> <li class="autocomplete-header">Utilisateurs <tt>clipper</tt></li>
{% for clipper in clippers %}{% if forloop.counter < 5 %} {% for clipper in clippers %}{% if forloop.counter < 5 %}
<li class="autocomplete-value"><a href="{% url 'clipper-registration' clipper.username %}">{{ clipper|highlight_clipper:q }}</a></li> <li class="autocomplete-value"><a href="{% url 'clipper-registration' clipper.clipper clipper.fullname %}">{{ clipper|highlight_clipper:q }}</a></li>
{% elif forloop.counter == 5 %}<li class="autocomplete-more">...</a>{% endif %}{% endfor %} {% elif forloop.counter == 5 %}<li class="autocomplete-more">...</a>{% endif %}{% endfor %}
{% endif %} {% endif %}

View file

@ -1,11 +1,19 @@
{% extends "base.html" %}
{% load bootstrap %}
{% block content %}
<div class="petitcours-raw">
{% if success %} {% if success %}
<p class="success">Votre demande a été enregistrée avec succès !</p> <p class="success">Votre demande a été enregistrée avec succès !</p>
{% else %} {% else %}
<form id="demandecours" method="post" action="{% url "gestioncof.petits_cours_views.demande_raw" %}"> <form id="demandecours" method="post" action="{% url "gestioncof.petits_cours_views.demande_raw" %}">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form | bootstrap }}
</table> </table>
<input type="submit" class="btn-submit" value="Enregistrer" /> <input type="submit" class="btn-submit" value="Enregistrer" />
</form> </form>
{% endif %} {% endif %}
</div>
{% endblock %}

View file

@ -1,4 +1,5 @@
{% extends "base_title.html" %} {% extends "base_title.html" %}
{% load bootstrap %}
{% block realcontent %} {% block realcontent %}
@ -28,8 +29,21 @@ souscrire aux événements du COF et/ou aux spectacles BdA.
<form action="" method="post"> <form action="" method="post">
{% csrf_token %} {% csrf_token %}
{{ form.as_p }} {{ form | bootstrap }}
<input type="submit" value="Enregistrer" class="btn btn-primary" /> <p>
<button type="button" class="btn btn-default" onClick="select(true)">Tout sélectionner</button>
<button type="button" class="btn btn-default" onClick="select(false)">Tout désélectionner</button>
</p>
<input type="submit" value="Enregistrer" class="btn btn-primary center-block" />
</form> </form>
<script language="JavaScript">
function select(check) {
checkboxes = document.getElementsByName("other_shows");
for(var i=0, n=checkboxes.length;i<n;i++) {
checkboxes[i].checked = check;
}
}
</script>
{% endblock %} {% endblock %}

View file

@ -2,11 +2,11 @@
{% load staticfiles %} {% load staticfiles %}
{% block extra_head %} {% block extra_head %}
<link href="{% static "grappelli/jquery/ui/css/custom-theme/jquery-ui-1.8.custom.css" %}" rel="stylesheet" type="text/css" media="screen" title="no title" charset="utf-8" /> <script src="{% static "js/jquery.min.js" %}" type="text/javascript"></script>
<script src="{% static "grappelli/jquery/jquery-1.6.2.min.js" %}" type="text/javascript"></script> <script src="{% static "js/jquery-ui.min.js" %}" type="text/javascript"></script>
<script src="{% static "grappelli/jquery/ui/js/jquery-ui-1.8.15.custom.min.js" %}" type="text/javascript"></script> <script src="{% static "js/jquery.ui.touch-punch.min.js" %}" type="text/javascript"></script>
<link href="{% static "grappelli/css/tools.css" %}" rel="stylesheet" type="text/css" /> <link type="text/css" rel="stylesheet" href="{% static "css/jquery-ui.min.css" %}" />
<link href="{% static "grappelli/css/jquery-ui-grappelli-extensions.css" %}" rel="stylesheet" type="text/css" />
{% endblock %} {% endblock %}
{% block realcontent %} {% block realcontent %}

View file

@ -17,7 +17,7 @@
$(document).ready(function() { $(document).ready(function() {
$('input#search_autocomplete').yourlabsAutocomplete({ $('input#search_autocomplete').yourlabsAutocomplete({
url: '{% url 'gestioncof.autocomplete.autocomplete' %}', url: '{% url 'gestioncof.autocomplete.autocomplete' %}',
minimumCharacters: 1, minimumCharacters: 3,
id: 'search_autocomplete', id: 'search_autocomplete',
choiceSelector: 'li:has(a)', choiceSelector: 'li:has(a)',
placeholder: "Chercher un utilisateur par nom, prénom ou identifiant clipper", placeholder: "Chercher un utilisateur par nom, prénom ou identifiant clipper",

View file

@ -43,7 +43,7 @@ def highlight_user(user, q):
@register.filter @register.filter
def highlight_clipper(clipper, q): def highlight_clipper(clipper, q):
if clipper.fullname: if clipper.fullname:
text = "%s (<tt>%s</tt>)" % (clipper.fullname, clipper.username) text = "%s (<tt>%s</tt>)" % (clipper.fullname, clipper.clipper)
else: else:
text = clipper.username text = clipper.clipper
return highlight_text(text, q) return highlight_text(text, q)

View file

@ -1,12 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from gestioncof.petits_cours_views import DemandeListView from gestioncof.petits_cours_views import DemandeListView, DemandeDetailView
from gestioncof import views, petits_cours_views from gestioncof import views, petits_cours_views
from gestioncof.decorators import buro_required
export_patterns = [ export_patterns = [
url(r'^members$', views.export_members), url(r'^members$', views.export_members),
@ -24,10 +21,11 @@ petitcours_patterns = [
name='petits-cours-demande'), name='petits-cours-demande'),
url(r'^demande-raw$', petits_cours_views.demande_raw, url(r'^demande-raw$', petits_cours_views.demande_raw,
name='petits-cours-demande-raw'), name='petits-cours-demande-raw'),
url(r'^demandes$', DemandeListView.as_view(), url(r'^demandes$',
buro_required(DemandeListView.as_view()),
name='petits-cours-demandes-list'), name='petits-cours-demandes-list'),
url(r'^demandes/(?P<demande_id>\d+)$', url(r'^demandes/(?P<pk>\d+)$',
petits_cours_views.details, buro_required(DemandeDetailView.as_view()),
name='petits-cours-demande-details'), name='petits-cours-demande-details'),
url(r'^demandes/(?P<demande_id>\d+)/traitement$', url(r'^demandes/(?P<demande_id>\d+)/traitement$',
petits_cours_views.traitement, petits_cours_views.traitement,

View file

@ -22,7 +22,7 @@ from gestioncof.models import Event, EventRegistration, EventOption, \
from gestioncof.models import EventCommentField, EventCommentValue, \ from gestioncof.models import EventCommentField, EventCommentValue, \
CalendarSubscription CalendarSubscription
from gestioncof.shared import send_custom_mail from gestioncof.shared import send_custom_mail
from gestioncof.models import CofProfile, Clipper, Club from gestioncof.models import CofProfile, Club
from gestioncof.decorators import buro_required, cof_required from gestioncof.decorators import buro_required, cof_required
from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \ from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \
SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \ SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \
@ -334,11 +334,11 @@ def registration_set_ro_fields(user_form, profile_form):
@buro_required @buro_required
def registration_form2(request, login_clipper=None, username=None): def registration_form2(request, login_clipper=None, username=None,
fullname=None):
events = Event.objects.filter(old=False).all() events = Event.objects.filter(old=False).all()
member = None member = None
if login_clipper: if login_clipper:
clipper = get_object_or_404(Clipper, username=login_clipper)
try: # check if the given user is already registered try: # check if the given user is already registered
member = User.objects.get(username=login_clipper) member = User.objects.get(username=login_clipper)
username = member.username username = member.username
@ -349,8 +349,8 @@ def registration_form2(request, login_clipper=None, username=None):
user_form = RegistrationUserForm(initial={ user_form = RegistrationUserForm(initial={
'username': login_clipper, 'username': login_clipper,
'email': "%s@clipper.ens.fr" % login_clipper}) 'email': "%s@clipper.ens.fr" % login_clipper})
if clipper.fullname: if fullname:
bits = clipper.fullname.split(" ") bits = fullname.split(" ")
user_form.fields['first_name'].initial = bits[0] user_form.fields['first_name'].initial = bits[0]
if len(bits) > 1: if len(bits) > 1:
user_form.fields['last_name'].initial = " ".join(bits[1:]) user_form.fields['last_name'].initial = " ".join(bits[1:])
@ -425,12 +425,12 @@ def registration(request):
try: try:
member = User.objects.get(username=username) member = User.objects.get(username=username)
user_form = RegistrationUserForm(request_dict, instance=member) user_form = RegistrationUserForm(request_dict, instance=member)
except User.DoesNotExist: if member.profile.login_clipper:
try: login_clipper = member.profile.login_clipper
clipper = Clipper.objects.get(username=username) else:
login_clipper = clipper.username
except Clipper.DoesNotExist:
user_form.force_long_username() user_form.force_long_username()
except User.DoesNotExist:
user_form.force_long_username()
else: else:
user_form.force_long_username() user_form.force_long_username()

View file

@ -1,16 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, import ldap3
print_function, unicode_literals)
from builtins import *
from django.shortcuts import render from django.shortcuts import render
from django.http import Http404 from django.http import Http404
from django.db.models import Q from django.db.models import Q
from gestioncof.models import User, Clipper from django.conf import settings
from gestioncof.models import User
from kfet.decorators import teamkfet_required from kfet.decorators import teamkfet_required
from kfet.models import Account from kfet.models import Account
class Clipper(object):
def __init__(self, clipper, fullname):
self.clipper = clipper
self.fullname = fullname
@teamkfet_required @teamkfet_required
def account_create(request): def account_create(request):
if "q" not in request.GET: if "q" not in request.GET:
@ -25,58 +32,67 @@ def account_create(request):
queries = {} queries = {}
search_words = q.split() search_words = q.split()
# Fetching data from User, CofProfile and Account tables
queries['kfet'] = Account.objects queries['kfet'] = Account.objects
queries['users_cof'] = User.objects.filter(Q(profile__is_cof = True)) queries['users_cof'] = User.objects.filter(profile__is_cof = True)
queries['users_notcof'] = User.objects.filter(Q(profile__is_cof = False)) queries['users_notcof'] = User.objects.filter(profile__is_cof = False)
queries['clippers'] = Clipper.objects
for word in search_words: for word in search_words:
queries['kfet'] = queries['kfet'].filter( queries['kfet'] = queries['kfet'].filter(
Q(cofprofile__user__username__icontains = word) Q(cofprofile__user__username__icontains = word)
| Q(cofprofile__user__first_name__icontains = word) | Q(cofprofile__user__first_name__icontains = word)
| Q(cofprofile__user__last_name__icontains = word) | Q(cofprofile__user__last_name__icontains = word)
) )
queries['users_cof'] = queries['users_cof'].filter( queries['users_cof'] = queries['users_cof'].filter(
Q(username__icontains = word) Q(username__icontains = word)
| Q(first_name__icontains = word) | Q(first_name__icontains = word)
| Q(last_name__icontains = word) | Q(last_name__icontains = word)
) )
queries['users_notcof'] = queries['users_notcof'].filter( queries['users_notcof'] = queries['users_notcof'].filter(
Q(username__icontains = word) Q(username__icontains = word)
| Q(first_name__icontains = word) | Q(first_name__icontains = word)
| Q(last_name__icontains = word) | Q(last_name__icontains = word)
) )
queries['clippers'] = queries['clippers'].filter(
Q(username__icontains = word)
| Q(fullname__icontains = word)
)
# Clearing redundancies
queries['kfet'] = queries['kfet'].distinct() queries['kfet'] = queries['kfet'].distinct()
usernames = set(
usernames = list( \
queries['kfet'].values_list('cofprofile__user__username', flat=True)) queries['kfet'].values_list('cofprofile__user__username', flat=True))
queries['kfet'] = [
(account, account.cofprofile.user)
for account in queries['kfet']
]
queries['kfet'] = [ (account, account.cofprofile.user) \ queries['users_cof'] = \
for account in queries['kfet'] ]
queries['users_cof'] = \
queries['users_cof'].exclude(username__in=usernames).distinct() queries['users_cof'].exclude(username__in=usernames).distinct()
queries['users_notcof'] = \ queries['users_notcof'] = \
queries['users_notcof'].exclude(username__in=usernames).distinct() queries['users_notcof'].exclude(username__in=usernames).distinct()
usernames |= set(
usernames += list( \
queries['users_cof'].values_list('username', flat=True)) queries['users_cof'].values_list('username', flat=True))
usernames += list( \ usernames |= set(
queries['users_notcof'].values_list('username', flat=True)) queries['users_notcof'].values_list('username', flat=True))
queries['clippers'] = \ # Fetching data from the SPI
queries['clippers'].exclude(username__in=usernames).distinct() if hasattr(settings, 'LDAP_SERVER_URL'):
# Fetching
ldap_query = '(|{:s})'.format(''.join(
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(**{"bit": bit}) for bit in bits]
))
with Connection(settings.LDAP_SERVER_URL) as conn:
conn.search(
'dc=spi,dc=ens,dc=fr', ldap_query,
attributes=['uid', 'cn']
)
queries['clippers'] = conn.entries
# Clearing redundancies
queries['clippers'] = [
Clipper(clipper.uid, clipper.cn)
for clipper in queries['clippers']
if str(clipper.uid) not in usernames
]
# Resulting data
data.update(queries) data.update(queries)
data['options'] = sum([len(query) for query in queries])
options = 0
for query in queries.values():
options += len(query)
data['options'] = options
return render(request, "kfet/account_create_autocomplete.html", data) return render(request, "kfet/account_create_autocomplete.html", data)

View file

@ -36,7 +36,7 @@
<li class="user_category"><span class="text">Utilisateurs clipper</span></li> <li class="user_category"><span class="text">Utilisateurs clipper</span></li>
{% for clipper in clippers %} {% for clipper in clippers %}
<li> <li>
<a href="{% url "kfet.account.create.fromclipper" clipper.username %}"> <a href="{% url "kfet.account.create.fromclipper" clipper.clipper clipper.fullname%}">
{{ clipper|highlight_clipper:q }} {{ clipper|highlight_clipper:q }}
</a> </a>
</li> </li>

View file

@ -35,7 +35,8 @@ urlpatterns = [
name = 'kfet.account.create_special'), name = 'kfet.account.create_special'),
url(r'^accounts/new/user/(?P<username>.+)$', views.account_create_ajax, url(r'^accounts/new/user/(?P<username>.+)$', views.account_create_ajax,
name = 'kfet.account.create.fromuser'), name = 'kfet.account.create.fromuser'),
url(r'^accounts/new/clipper/(?P<login_clipper>.+)$', views.account_create_ajax, url(r'^accounts/new/clipper/(?P<login_clipper>[\w-]+)/(?P<fullname>.*)$',
views.account_create_ajax,
name = 'kfet.account.create.fromclipper'), name = 'kfet.account.create.fromclipper'),
url(r'^accounts/new/empty$', views.account_create_ajax, url(r'^accounts/new/empty$', views.account_create_ajax,
name = 'kfet.account.create.empty'), name = 'kfet.account.create.empty'),

View file

@ -22,7 +22,7 @@ from django.db.models import F, Sum, Prefetch, Count, Func
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.utils import timezone from django.utils import timezone
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from gestioncof.models import CofProfile, Clipper from gestioncof.models import CofProfile
from kfet.decorators import teamkfet_required from kfet.decorators import teamkfet_required
from kfet.models import (Account, Checkout, Article, Settings, AccountNegative, from kfet.models import (Account, Checkout, Article, Settings, AccountNegative,
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory, CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
@ -222,19 +222,20 @@ def account_form_set_readonly_fields(user_form, cof_form):
cof_form.fields['login_clipper'].widget.attrs['readonly'] = True cof_form.fields['login_clipper'].widget.attrs['readonly'] = True
cof_form.fields['is_cof'].widget.attrs['disabled'] = True cof_form.fields['is_cof'].widget.attrs['disabled'] = True
def get_account_create_forms(request=None, username=None, login_clipper=None): def get_account_create_forms(request=None, username=None, login_clipper=None,
fullname=None):
user = None user = None
clipper = None clipper = False
if login_clipper and (login_clipper == username or not username): if login_clipper and (login_clipper == username or not username):
# à partir d'un clipper # à partir d'un clipper
# le user associé à ce clipper ne devrait pas encore exister # le user associé à ce clipper ne devrait pas encore exister
clipper = get_object_or_404(Clipper, username = login_clipper) clipper = True
try: try:
# Vérification que clipper ne soit pas déjà dans User # Vérification que clipper ne soit pas déjà dans User
user = User.objects.get(username=login_clipper) user = User.objects.get(username=login_clipper)
# Ici, on nous a menti, le user existe déjà # Ici, on nous a menti, le user existe déjà
username = user.username username = user.username
clipper = None clipper = False
except User.DoesNotExist: except User.DoesNotExist:
# Clipper (sans user déjà existant) # Clipper (sans user déjà existant)
@ -242,9 +243,9 @@ def get_account_create_forms(request=None, username=None, login_clipper=None):
user_initial = { user_initial = {
'username' : login_clipper, 'username' : login_clipper,
'email' : "%s@clipper.ens.fr" % login_clipper} 'email' : "%s@clipper.ens.fr" % login_clipper}
if clipper.fullname: if fullname:
# Prefill du nom et prénom # Prefill du nom et prénom
names = clipper.fullname.split() names = fullname.split()
# Le premier, c'est le prénom # Le premier, c'est le prénom
user_initial['first_name'] = names[0] user_initial['first_name'] = names[0]
if len(names) > 1: if len(names) > 1:
@ -308,8 +309,11 @@ def get_account_create_forms(request=None, username=None, login_clipper=None):
@login_required @login_required
@teamkfet_required @teamkfet_required
def account_create_ajax(request, username=None, login_clipper=None): def account_create_ajax(request, username=None, login_clipper=None,
forms = get_account_create_forms(request=None, username=username, login_clipper=login_clipper) fullname=None):
forms = get_account_create_forms(
request=None, username=username, login_clipper=login_clipper,
fullname=fullname)
return render(request, "kfet/account_create_form.html", { return render(request, "kfet/account_create_form.html", {
'account_form' : forms['account_form'], 'account_form' : forms['account_form'],
'cof_form' : forms['cof_form'], 'cof_form' : forms['cof_form'],

View file

@ -3,5 +3,6 @@
source ~/venv/bin/activate source ~/venv/bin/activate
python manage.py migrate python manage.py migrate
python manage.py loaddata users root bda gestion sites python manage.py loaddata gestion sites
python manage.py loaddevdata
python manage.py collectstatic --noinput python manage.py collectstatic --noinput

View file

@ -17,4 +17,5 @@ asgi-redis==0.14.0
statistics==1.0.3.5 statistics==1.0.3.5
future==0.15.2 future==0.15.2
django-widget-tweaks==1.4.1 django-widget-tweaks==1.4.1
ldap3
git+https://github.com/Aureplop/channels.git#egg=channels git+https://github.com/Aureplop/channels.git#egg=channels

View file

@ -1,34 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings")
from gestioncof.models import Clipper
current = {}
print("[ FETCHING ]")
for clipper in Clipper.objects.all():
current[clipper.username] = clipper
print("[ SYNCING ]")
for line in sys.stdin:
bits = line.split(":")
username = bits[0]
fullname = bits[4]
if username in current:
clipper = current[username]
if clipper.fullname != fullname:
clipper.fullname = fullname
clipper.save()
print("Updated", username)
else:
clipper = Clipper(username=username, fullname=fullname)
clipper.save()
print("Created", username)
print("[ DONE ]")

View file

@ -1,2 +0,0 @@
#!/bin/sh
ssh cof@sas.eleves.ens.fr ypcat passwd | python sync_clipper.py