wip: Global user interface improvment

* Use of jQuery in place of Mootools
* Most of the custom mootools plugins have been ported to jQuery
* Use of bootstrap from Twitter in place of the old CSS
* Most of the admin templates have been reworked
* The sievefilters extension has been ported
* The postfix autoreply extension is almost done
* more...

see #204
This commit is contained in:
Antoine Nguyen
2012-03-19 15:13:01 +01:00
parent 97d3996d2e
commit a295aa1ab6
130 changed files with 4255 additions and 6725 deletions
+385 -219
View File
@@ -1,15 +1,25 @@
# coding: utf-8
from django import forms
from django.contrib.auth.models import Group
from modoboa.admin.models import *
from django.utils.translation import ugettext as _, ugettext_noop
from django.http import QueryDict
from modoboa.admin.templatetags.admin_extras import gender
from modoboa.lib import tables
from modoboa.lib.emailutils import split_mailbox
from modoboa.lib.permissions import get_account_roles
from modoboa.lib.formutils import *
from modoboa.lib.permissions import *
class DomainForm(forms.ModelForm, DynamicForm):
aliases = DomainNameField(
label=ugettext_noop("Alias(es)"),
required=False,
help_text=ugettext_noop("Alias(es) of this domain")
)
class DomainForm(forms.ModelForm):
class Meta:
model = Domain
fields = ("name", "quota", "enabled")
fields = ("name", "quota", "aliases", "enabled")
def __init__(self, *args, **kwargs):
self.oldname = None
@@ -17,240 +27,235 @@ class DomainForm(forms.ModelForm):
self.oldname = kwargs["instance"].name
super(DomainForm, self).__init__(*args, **kwargs)
def save(self, force_insert=False, force_update=False, commit=True):
if len(args) and isinstance(args[0], QueryDict):
self._load_from_qdict(args[0], "aliases", DomainNameField)
elif kwargs.has_key("instance"):
d = kwargs["instance"]
for pos, dalias in enumerate(d.domainalias_set.all()):
name = "aliases_%d" % (pos + 1)
self._create_field(forms.CharField, name, dalias.name, 3)
def clean(self):
super(DomainForm, self).clean()
if len(self._errors):
raise forms.ValidationError(self._errors)
cleaned_data = self.cleaned_data
name = cleaned_data["name"]
try:
DomainAlias.objects.get(name=name)
except DomainAlias.DoesNotExist:
pass
else:
self._errors["name"] = self.error_class([_("An alias with this name already exists")])
del cleaned_data["name"]
errors = []
for k in cleaned_data.keys():
if not k.startswith("aliases"):
continue
if cleaned_data[k] == "":
del cleaned_data[k]
continue
try:
Domain.objects.get(name=cleaned_data[k])
except Domain.DoesNotExist:
pass
else:
self._errors[k] = self.error_class([_("A domain with this name already exists")])
del cleaned_data[k]
return cleaned_data
def save(self, user, commit=True):
d = super(DomainForm, self).save(commit=False)
if commit:
if self.oldname is not None and d.name != self.oldname:
if not d.rename_dir(self.oldname):
raise AdminError(_("Failed to rename domain, check permissions"))
d.save()
for k, v in self.cleaned_data.iteritems():
if not k.startswith("aliases"):
continue
if v in ["", None]:
continue
try:
d.domainalias_set.get(name=v)
except DomainAlias.DoesNotExist:
pass
else:
continue
events.raiseEvent("CanCreate", user, "domain_aliases")
al = DomainAlias(name=v, target=d, enabled=d.enabled)
al.save()
grant_access_to_object(user, al, is_owner=True)
events.raiseEvent("DomainAliasCreated", user, al)
for dalias in d.domainalias_set.all():
if not len(filter(lambda name: self.cleaned_data[name] == dalias.name,
self.cleaned_data.keys())):
events.raiseEvent("DomainAliasDeleted", dalias)
ungrant_access_to_object(dalias)
dalias.delete()
return d
class ProxyForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super(ProxyForm, self).__init__(*args, **kwargs)
if not user.is_superuser:
self._domains = user.get_domains()
else:
self._domains = None
class DomainAliasForm(ProxyForm):
class Meta:
model = DomainAlias
fields = ('name', 'target', 'enabled')
def __init__(self, *args, **kwargs):
super(DomainAliasForm, self).__init__(*args, **kwargs)
if self._domains is not None:
#self.fields["target"].queryset = Domain.objects.filter(pk=self._domain.id)
self.fields["target"].queryset = self._domains
class MailboxForm(ProxyForm):
name = forms.CharField(
label=ugettext_noop("Name"), max_length=100,
help_text=ugettext_noop("First name and last name of mailbox owner")
class DlistForm(forms.ModelForm, DynamicForm):
email = forms.EmailField(
label=ugettext_noop("Email address"),
help_text=ugettext_noop("")
)
recipients = forms.EmailField(
label=ugettext_noop("Recipients"), required=False,
help_text=ugettext_noop("Mailbox(es) this alias will point to")
)
quota = forms.IntegerField(label=ugettext_noop("Quota"), required=False,
help_text=ugettext_noop("Mailbox quota in MB (default to domain quota if blank)"))
enabled = forms.BooleanField(label=gender("Enabled", "f"), required=False,
initial=True,
help_text=ugettext_noop("Check to activate this mailbox"))
class Meta:
model = Mailbox
fields = ('domain', 'address')
def __init__(self, *args, **kwargs):
super(MailboxForm, self).__init__(*args, **kwargs)
for f in ['name', 'address', 'quota']:
self.fields[f].widget.attrs['size'] = 14
if self._domains is not None:
self.fields["domain"].queryset = self._domains
#self.fields["domain"].queryset = Domain.objects.filter(pk=self._domain.id)
#self.fields["domain"].initial = self._domain
if kwargs.has_key("instance"):
mb = kwargs["instance"]
self.fields['name'].initial = unicode(mb.user)
self.fields['quota'].initial = mb.quota
self.fields['enabled'].initial = mb.user.is_active
def clean_address(self):
if self.cleaned_data["address"].find('@') != -1:
return self.cleaned_data["address"].rsplit("@", 1)[0]
return self.cleaned_data["address"]
def commit_save(self, mb, **kwargs):
mb.save(name=self.cleaned_data["name"],
enabled=self.cleaned_data["enabled"],
quota=self.cleaned_data["quota"],
**kwargs)
def save(self, force_insert=False, force_update=False, commit=True):
m = super(MailboxForm, self).save(commit=False)
if commit:
self.commit_save(m)
return m
class MailboxWithPasswordForm(MailboxForm):
password1 = forms.CharField(label=ugettext_noop("Password"),
widget=forms.PasswordInput(render_value=True),
help_text=ugettext_noop("Password used to log in"))
password2 = forms.CharField(label=ugettext_noop("Confirmation"),
widget=forms.PasswordInput(render_value=True),
help_text=ugettext_noop("Password confirmation"))
def __init__(self, *args, **kwargs):
super(MailboxWithPasswordForm, self).__init__(*args, **kwargs)
for f in ['password1', 'password2']:
self.fields[f].widget.attrs['size'] = 14
self.fields.keyOrder = ['name', 'domain', 'address', 'quota',
'password1', 'password2', 'enabled']
def clean_password2(self):
if self.cleaned_data["password1"] != self.cleaned_data["password2"]:
raise forms.ValidationError(_("Passwords mismatch"))
return self.cleaned_data["password2"]
def commit_save(self, mb):
super(MailboxWithPasswordForm, self).commit_save(
mb, password=self.cleaned_data["password1"]
)
class AliasForm(ProxyForm):
targets = forms.CharField(label=ugettext_noop("Target(s)"), required=False,
help_text=ugettext_noop("Mailbox(es) this alias will point to"))
def __init__(self, *args, **kwargs):
super(AliasForm, self).__init__(*args, **kwargs)
self.fields['address'].widget.attrs['size'] = 14
# This part is a little bit tricky. As 'domain' is not a
# member of Alias, we need to fill it manually. if
# self._domain exists, it means a DomainAdmin is going to
# create a new alias, we know how to fill the fields.
# if self._domain is not None:
# self.fields["domain"].queryset = Domain.objects.filter(pk=self._domain.id)
if self._domains is not None:
self.fields["domain"].queryset = self._domains
# if 'instance' exists, it means we are modifying an existing
# record, we need to select the right value for 'domain' and
# to fill the first "targets" input (because it is created by the
# Form object, not by us).
#domain = None
# if self._domain:
# domain = self._domain
if kwargs.has_key("instance"):
# if self._domain is None:
# domain = kwargs["instance"].domain
self.fields["targets"].initial = kwargs["instance"].first_target()
# if domain is not None:
# self.fields["domain"].initial = domain
self.fields.keyOrder = ['address', 'domain', 'enabled', 'targets']
class Meta:
model = Alias
fields = ('address', 'domain', 'enabled')
fields = ("enabled",)
def clean_address(self):
if self.cleaned_data["address"].find('@') != -1:
return self.cleaned_data["address"].rsplit("@", 1)[0]
return self.cleaned_data["address"]
def __init__(self, *args, **kwargs):
super(DlistForm, self).__init__(*args, **kwargs)
self.fields.keyOrder = ['email', 'recipients', 'enabled']
def set_targets(self, user, values):
"""Targets dispatching
if len(args) and isinstance(args[0], QueryDict):
self._load_from_qdict(args[0], "recipients", forms.EmailField)
elif kwargs.has_key("instance"):
dlist = kwargs["instance"]
self.fields["email"].initial = dlist.full_address
cpt = 1
for mb in dlist.mboxes.all():
name = "recipients_%d" % (cpt)
self._create_field(forms.EmailField, name, mb.full_address, 2)
cpt += 1
for addr in dlist.extmboxes.split(','):
if addr == "":
continue
name = "recipients_%d" % (cpt)
self._create_field(forms.EmailField, name, addr, 2)
cpt += 1
We make a difference between 'local' targets (the ones hosted
by Modoboa) and 'external targets.
def clean_email(self):
localpart, domname = split_mailbox(self.cleaned_data["email"])
try:
Domain.objects.get(name=domname)
except Domain.DoesNotExist:
raise forms.ValidationError(_("Domain does not exist"))
return self.cleaned_data["email"]
def set_recipients(self, user):
"""Recipients dispatching
We make a difference between 'local' recipients (the ones hosted
by Modoboa) and 'external' recipients.
"""
self.ext_targets = []
self.int_targets = []
self.ext_rcpts = []
self.int_rcpts = []
total = 0
for addr in values:
if addr == "":
for k, v in self.cleaned_data.iteritems():
if not k.startswith("recipients"):
continue
local_part, domname = split_mailbox(addr)
if v == "":
continue
local_part, domname = split_mailbox(v)
if domname is None:
raise AdminError("%s %s" % (_("Invalid mailbox"), addr))
raise AdminError("%s %s" % (_("Invalid mailbox"), v))
try:
domain = Domain.objects.get(name=domname)
except Domain.DoesNotExist:
domain = None
if domain:
if not user.is_owner(domain):
raise PermDeniedException(addr)
raise PermDeniedException(v)
try:
mb = Mailbox.objects.get(domain=domain, address=local_part)
except Mailbox.DoesNotExist:
raise AdminError(_("Mailbox %s does not exist" % addr))
self.int_targets += [mb]
raise AdminError(_("Mailbox %s does not exist" % v))
self.int_rcpts += [mb]
total += 1
continue
self.ext_targets += [addr]
self.ext_rcpts += [v]
total += 1
def save(self, force_insert=False, force_update=False, commit=True):
a = super(AliasForm, self).save(commit=False)
if total == 0:
raise AdminError(_("No recipient defined"))
if total < 2:
raise AdminError(_("A distribution list must contain at least two recipients"))
def save(self, commit=True):
dlist = super(DlistForm, self).save(commit=False)
localpart, domname = split_mailbox(self.cleaned_data["email"])
dlist.address = localpart
dlist.domain = Domain.objects.get(name=domname)
if commit:
a.save(self.int_targets, self.ext_targets)
dlist.save(self.int_rcpts, self.ext_rcpts)
self.save_m2m()
return a
return dlist
class SuperAdminForm(forms.Form):
def __init__(self, user, *args, **kwargs):
super(SuperAdminForm, self).__init__(*args, **kwargs)
class ImportDataForm(forms.Form):
sourcefile = forms.FileField(label=_("Select a file"))
sepcar = forms.CharField(label=_("Separator"), max_length=1, required=False)
self.fields["user"] = \
forms.ModelChoiceField([], label=_("User"), required=True,
empty_label=_("Select a user"),
help_text=_("Select a user in the list"))
self.fields["user"].queryset = User.objects.exclude(pk__in=[1, user.id])
def __init__(self, *args, **kwargs):
super(ImportDataForm, self).__init__(*args, **kwargs)
self.fields["sepcar"].widget.attrs = {"class" : "span1"}
class DomainAdminForm(forms.Form):
createfrom = forms.ChoiceField(
choices=[("new", ugettext_noop("Create a new account")),
("select", ugettext_noop("Promote an existing account"))],
widget=forms.RadioSelect)
def clean_sepcar(self):
if self.cleaned_data["sepcar"] == "":
return ";"
return str(self.cleaned_data["sepcar"])
domain = forms.ModelChoiceField(
queryset=Domain.objects.all(),
label=_("Domain"),
required=True,
empty_label=ugettext_noop("Select a domain"),
help_text=ugettext_noop("Select a domain in the list")
)
user = forms.ChoiceField(
label=ugettext_noop("User"), required=True,
choices=[("", ugettext_noop("Empty"))],
help_text=ugettext_noop("Select a user in the list"))
class UserForm(forms.ModelForm):
createmb = forms.BooleanField(
label=ugettext_noop("Create mailbox"), required=False,
help_text=ugettext_noop("Create a mailbox for this user using the given address")
class AccountFormGeneral(forms.ModelForm):
role = forms.ChoiceField(
choices=[('', ugettext_noop("Choose"))]
)
class Meta:
model = User
fields = ("username", "first_name", "last_name", "email")
fields = ("username", "first_name", "last_name", "role", "is_active")
def save(self, commit=True, group=None):
user = super(UserForm, self).save(commit=False)
if self.cleaned_data.has_key("password1"):
user.set_password(self.cleaned_data["password1"])
def __init__(self, user, *args, **kwargs):
super(AccountFormGeneral, self).__init__(*args, **kwargs)
self.user = user
if user.belongs_to_group("DomainAdmins"):
del self.fields["role"]
return
self.fields["role"].choices = \
[('', ugettext_noop("Choose"))] + get_account_roles(user)
if kwargs.has_key("instance"):
u = kwargs["instance"]
if u.is_superuser:
role = "SuperAdmins"
else:
try:
role = u.groups.all()[0].name
except IndexError:
pass
self.fields["role"].initial = role
def save(self, commit=True):
account = super(AccountFormGeneral, self).save(commit=False)
if commit:
user.save()
if group:
user.groups.add(Group.objects.get(name=group))
user.save()
return user
account.save()
if self.cleaned_data.has_key("role"):
role = self.cleaned_data["role"]
else:
role = "SimpleUsers"
if role == "SuperAdmins":
account.is_superuser = True
else:
account.is_superuser = False
account.groups.clear()
account.groups.add(Group.objects.get(name=role))
account.save()
return account
class UserWithPasswordForm(UserForm):
class AccountFormGeneralPwd(AccountFormGeneral):
password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(
label=ugettext_noop("Confirmation"),
@@ -258,6 +263,11 @@ class UserWithPasswordForm(UserForm):
help_text=ugettext_noop("Enter the same password as above, for verification.")
)
class Meta:
model = User
fields = ("username", "first_name", "last_name",
"password1", "password2", "role", "is_active")
def clean_password2(self):
password1 = self.cleaned_data.get("password1", "")
password2 = self.cleaned_data["password2"]
@@ -265,38 +275,194 @@ class UserWithPasswordForm(UserForm):
raise forms.ValidationError(_("The two password fields didn't match."))
return password2
class DomainAdminPromotionForm(forms.Form):
name = forms.CharField(
label=ugettext_noop("Name"),
help_text=ugettext_noop("The username/email address/name of the account to promote")
def save(self, commit=True, **kwargs):
user = super(AccountFormGeneralPwd, self).save(**kwargs)
if self.cleaned_data.has_key("password1"):
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class AccountFormMail(forms.Form, DynamicForm):
# FIXME
# * ajout du quota
# * Renommage de boite ?
email = forms.EmailField(label=_("E-mail"), required=False)
aliases = forms.EmailField(
label=ugettext_noop("Alias(es)"),
required=False,
help_text=ugettext_noop("Alias(es) of this mailbox")
)
def clean_name(self):
def __init__(self, *args, **kwargs):
if kwargs.has_key("instance"):
self.mb = kwargs["instance"]
del kwargs["instance"]
super(AccountFormMail, self).__init__(*args, **kwargs)
if not hasattr(self, "mb") or self.mb is None:
return
self.fields["email"].required = True
for pos, alias in enumerate(self.mb.alias_set.all()):
if len(alias.get_recipients()) >= 2:
continue
name = "aliases_%d" % (pos + 1)
self._create_field(forms.EmailField, name, alias.full_address)
self.fields["email"].initial = self.mb.full_address
if len(args) and isinstance(args[0], QueryDict):
self._load_from_qdict(args[0], "aliases", forms.EmailField)
def save(self, user, account):
if self.cleaned_data["email"] == "":
return None
locpart, domname = split_mailbox(self.cleaned_data["email"])
try:
u = User.objects.get(username=self.cleaned_data["name"])
except User.DoesNotExist:
raise forms.ValidationError(_("Unknown user"))
return self.cleaned_data["name"]
domain = Domain.objects.get(name=domname)
except Domain.DoesNotExist:
raise AdminError(_("Domain does not exist"))
class AssignDomainsForm(forms.Form):
domains = forms.ModelMultipleChoiceField(
queryset=None,
label=ugettext_noop("Domains"),
required=True,
help_text=ugettext_noop("Select one or more domains in the list")
if not user.can_access(domain):
raise PermDeniedException(_("You don't have access to this domain"))
if not hasattr(self, "mb") or self.mb is None:
try:
self.mb = Mailbox.objects.get(address=locpart, domain=domain)
except Mailbox.DoesNotExist:
events.raiseEvent("CanCreate", user, "mailboxes")
self.mb = Mailbox()
self.mb.save_from_user(locpart, domain, account)
grant_access_to_object(user, self.mb, is_owner=True)
events.raiseEvent("CreateMailbox", user, self.mb)
else:
if self.cleaned_data["email"] != self.mb.full_address:
if self.mb.rename_dir(domname, locpart):
self.mb.domain = domain
self.mb.address = locpart
self.mb.save()
else:
raise AdminError(_("Failed to rename mailbox, check permissions"))
account.email = self.cleaned_data["email"]
account.save()
for name, value in self.cleaned_data.iteritems():
if not name.startswith("aliases"):
continue
if value == "":
continue
local_part, domname = split_mailbox(value)
try:
self.mb.alias_set.get(address=local_part, domain__name=domname)
except Alias.DoesNotExist:
pass
else:
continue
events.raiseEvent("CanCreate", user, "mailbox_aliases")
al = Alias(address=local_part, enabled=account.is_active)
al.domain = Domain.objects.get(name=domname)
al.save([self.mb], [])
grant_access_to_object(user, al, is_owner=True)
events.raiseEvent("MailboxAliasCreated", user, al)
for alias in self.mb.alias_set.all():
if len(alias.get_recipients()) >= 2:
continue
if not len(filter(lambda name: self.cleaned_data[name] == alias.full_address,
self.cleaned_data.keys())):
events.raiseEvent("MailboxAliasDeleted", alias)
ungrant_access_to_object(alias)
alias.delete()
return self.mb
class AccountPermissionsForm(forms.Form, DynamicForm):
domains = DomainNameField(
label=ugettext_noop("Domain(s)"),
required=False,
help_text=ugettext_noop("Domain(s) that user administrates")
)
def __init__(self, user, domadmin, *args, **kwargs):
super(AssignDomainsForm, self).__init__(*args, **kwargs)
self.fields["domains"].queryset = user.get_domains()
self.fields["domains"].initial = domadmin.get_domains()
def __init__(self, *args, **kwargs):
if kwargs.has_key("instance"):
self.account = kwargs["instance"]
del kwargs["instance"]
super(AccountPermissionsForm, self).__init__(*args, **kwargs)
class ImportDataForm(forms.Form):
sourcefile = forms.FileField(label=_("Select a file"))
sepcar = forms.CharField(label=_("Separator"), max_length=1, required=False)
if not hasattr(self, "account") or self.account is None:
return
for pos, domain in enumerate(self.account.get_domains()):
name = "domains_%d" % (pos + 1)
self._create_field(DomainNameField, name, domain.name)
if len(args) and isinstance(args[0], QueryDict):
self._load_from_qdict(args[0], "domains", DomainNameField)
def clean_sepcar(self):
if self.cleaned_data["sepcar"] == "":
return ";"
return self.cleaned_data["sepcar"]
def save(self):
current_domains = map(lambda dom: dom.name, self.account.get_domains())
for name, value in self.cleaned_data.iteritems():
if not name.startswith("domains"):
continue
if value in ["", None]:
continue
if not value in current_domains:
domain = Domain.objects.get(name=value)
grant_access_to_object(self.account, domain)
for domain in self.account.get_domains():
if not len(filter(lambda name: self.cleaned_data[name] == domain.name,
self.cleaned_data.keys())):
ungrant_access_to_object(domain, self.account)
class AccountForm(TabForms):
def __init__(self, user, *args, **kwargs):
self.user = user
self.forms = [
dict(id="general", title=_("General"), cls=AccountFormGeneralPwd,
new_args=[user], mandatory=True),
dict(id="mail", title=_("Mail"), formtpl="admin/mailform.html",
cls=AccountFormMail),
dict(id="perms", title=_("Permissions"), formtpl="admin/permsform.html",
cls=AccountPermissionsForm)
]
cbargs = [user]
if kwargs.has_key("instances"):
cbargs += [kwargs["instances"]["general"]]
self.forms += events.raiseQueryEvent("ExtraAccountForm", *cbargs)
super(AccountForm, self).__init__(*args, **kwargs)
def check_perms(self, account):
if account.is_superuser:
return False
return account.has_perm("admin.view_domain")
def _before_is_valid(self, form):
if form["id"] == "general":
return True
if hasattr(self, "check_%s" % form["id"]):
if not getattr(self, "check_%s" % form["id"])(self.account):
return False
return True
if False in events.raiseQueryEvent("CheckExtraAccountForm", self.account, form):
return False
return True
def save_general_form(self):
self.account = self.forms[0]["instance"].save()
def save(self):
"""Custom save method
As forms interact with each other, it is simpler to make
custom code to save them.
"""
self.forms[1]["instance"].save(self.user, self.account)
if len(self.forms) <= 2:
return
for f in self.forms[2:]:
f["instance"].save()
+6 -96
View File
@@ -1,10 +1,8 @@
# coding: utf-8
from functools import wraps
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from models import *
from modoboa.lib.webutils import _render_error, _render
from modoboa.lib.webutils import _render
from modoboa.lib import parameters
from modoboa.admin.tables import *
from exceptions import *
@@ -36,98 +34,10 @@ def render_listing(request, objtype, tplname="admin/listing.html",
except ValueError:
page = 1
try:
kwargs["objects"] = paginator.page(page)
kwargs["page"] = paginator.page(page)
except (EmptyPage, PageNotAnInteger):
kwargs["objects"] = paginator.page(paginator.num_pages)
kwargs["last_page"] = paginator.num_pages
kwargs["total"] = paginator.count
kwargs["table"] = tblclass(request, kwargs["objects"].object_list)
kwargs["page"] = paginator.page(paginator.num_pages)
kwargs["table"] = tblclass(request, kwargs["page"].object_list)
kwargs["selection"] = objtype
return _render(request, tplname, kwargs)
def grant_access_to_object(user, obj, is_owner=False):
"""Grant access to an object for a given user
There are two different cases where we want to grant access to an
object for a specific user:
* He is the owner (he's just created the object)
* He is going to administrate the object (but he is not the owner)
:param user: a ``User`` object
:param obj: an admin. object (Domain, Mailbox, ...)
:param is_owner: the user is the unique object's owner
"""
ct = get_content_type(obj)
try:
entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
entry.is_owner = is_owner
entry.save()
except ObjectAccess.DoesNotExist:
pass
else:
return
try:
objaccess = ObjectAccess(user=user, content_type=ct,
object_id=obj.id, is_owner=is_owner)
objaccess.save()
except IntegrityError, e:
raise AdminError(_("Failed to grant access (%s)" % str(e)))
def ungrant_access_to_object(obj, user=None):
"""Ungrant access to an object for a specific user
If no user is provided, all entries referencing this object are
deleted from the database.
:param obj: an object inheriting from ``models.Model``
:param user: a ``User`` object
"""
ct = get_content_type(obj)
if user:
try:
ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
except ObjectAccess.DoesNotExist:
pass
else:
ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
def get_object_owner(obj):
"""Return the unique owner of this object
:param obj: an object inheriting from ``model.Model``
:return: a ``User`` object
"""
ct = get_content_type(obj)
try:
entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
except ObjectAccess.DoesNotExist:
return None
return entry.user
def check_domain_access(f):
"""Decorator to check if the current user can access a domain
This decorator only applies to url that contain a 'domid' or
'mbid' parameter. (for a direct access)
Raise a ``PermDeniedError`` if the current user can't view the
requested object.
"""
@wraps(f)
def dec(request, **kwargs):
if not request.user.is_superuser:
domain = None
domid = request.GET.get("domid", None)
if domid:
domain = Domain.objects.get(pk=domid)
else:
mbid = request.GET.get("mbid", None)
if mbid:
domain = Mailbox.objects.get(pk=mbid).domain
if domain and not request.user.can_access(domain):
raise PermDeniedError(_("You can't access this domain"))
return f(request, **kwargs)
return dec
+1 -1
View File
@@ -93,4 +93,4 @@ class Migration(DataMigration):
}
}
complete_apps = ['admin']
complete_apps = ['admin', 'contenttypes']
@@ -0,0 +1,121 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding unique constraint on 'Alias', fields ['domain', 'address']
db.create_unique('admin_alias', ['domain_id', 'address'])
def backwards(self, orm):
# Removing unique constraint on 'Alias', fields ['domain', 'address']
db.delete_unique('admin_alias', ['domain_id', 'address'])
models = {
'admin.alias': {
'Meta': {'unique_together': "(('address', 'domain'),)", 'object_name': 'Alias'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'extmboxes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mboxes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['admin.Mailbox']", 'symmetrical': 'False'})
},
'admin.domain': {
'Meta': {'object_name': 'Domain'},
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'quota': ('django.db.models.fields.IntegerField', [], {})
},
'admin.domainalias': {
'Meta': {'object_name': 'DomainAlias'},
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"})
},
'admin.extension': {
'Meta': {'object_name': 'Extension'},
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
},
'admin.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}),
'gid': ('django.db.models.fields.IntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'quota': ('django.db.models.fields.IntegerField', [], {}),
'uid': ('django.db.models.fields.IntegerField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'admin.objectaccess': {
'Meta': {'unique_together': "(('user', 'content_type', 'object_id'),)", 'object_name': 'ObjectAccess'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'admin.objectdates': {
'Meta': {'object_name': 'ObjectDates'},
'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'admin.user': {
'Meta': {'object_name': 'User', 'db_table': "'auth_user'", '_ormbases': ['auth.User'], 'proxy': 'True'}
},
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['admin']
+99 -64
View File
@@ -24,15 +24,6 @@ try:
except ImportError:
ldap_available = False
def get_content_type(obj):
"""Simple function that use the right method to retrieve a content type
:param obj: a django model
:return: a ``ContentType`` object
"""
return obj.get_content_type() if hasattr(obj, "get_content_type") \
else ContentType.objects.get_for_model(obj)
class User(DUser):
"""Proxy for the ``User`` model.
@@ -50,6 +41,37 @@ class User(DUser):
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
def delete(self, fromuser, keep_mb_dir, *args, **kwargs):
"""Custom delete method
"""
from modoboa.lib.permissions import \
get_object_owner, grant_access_to_object, ungrant_access_to_object
if not fromuser.can_access(self):
raise PermDeniedException(_("You don't have access to this account"))
if fromuser == self:
raise AdminError(_("You can't delete your own account"))
if self.has_mailbox:
mb = self.mailbox_set.all()[0]
if not fromuser.can_access(mb.domain):
raise PermDeniedException(_("You don't have access to this domain"))
events.raiseEvent("DeleteMailbox", mb)
ungrant_access_to_object(mb)
mb.delete(keepdir=keep_mb_dir)
owner = get_object_owner(self)
for ooentry in self.objectaccess_set.all():
if ooentry.is_owner:
if ooentry.content_object is not None:
grant_access_to_object(owner, ooentry.content_object, True)
else:
print "ORPHELIN!!!"
ooentry.delete()
events.raiseEvent("AccountDeleted", self)
ungrant_access_to_object(self)
super(User, self).delete(*args, **kwargs)
@staticmethod
def get_content_type():
"""An uggly hack to retrieve the appropriate content_type!
@@ -130,6 +152,27 @@ class User(DUser):
return "%s %s" % (self.first_name, self.last_name)
return self.username
@property
def identity(self):
if self.email != "":
return self.email
return self.username
@property
def name_or_rcpt(self):
if self.first_name != "":
return "%s %s" % (self.first_name, self.last_name)
return "----"
@property
def group(self):
if self.is_superuser:
return "SuperAdmin"
try:
return self.groups.all()[0].name
except IndexError:
return "?"
def belongs_to_group(self, name):
"""Simple shortcut to check if this user is a member of a
specific group.
@@ -216,6 +259,8 @@ class User(DUser):
:param obj: an object inheriting from ``models.Model``
:return: a boolean
"""
from modoboa.lib.permissions import get_content_type
ct = get_content_type(obj)
try:
ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id)
@@ -233,6 +278,8 @@ class User(DUser):
:param obj: a admin object
:return: a boolean
"""
from modoboa.lib.permissions import get_content_type
if self.is_superuser:
return True
@@ -360,8 +407,8 @@ class Domain(DatesAware):
# Not very optimized but currently, this is the simple way
# I've found to delete all related objects (mailboxes, users
# and aliases)!
for mb in self.mailbox_set.all():
mb.delete(keepdir=keepdir)
# for mb in self.mailbox_set.all():
# mb.delete(keepdir=keepdir)
super(Domain, self).delete(*args, **kwargs)
if not keepdir:
self.delete_dir()
@@ -379,14 +426,19 @@ class DomainAlias(DatesAware):
help_text=ugettext_noop("The alias name"))
target = models.ForeignKey(Domain, verbose_name=ugettext_noop('target'),
help_text=ugettext_noop("The domain this alias points to"))
enabled = models.BooleanField(ugettext_noop('enabled'),
help_text=ugettext_noop("Check to activate this alias"))
enabled = models.BooleanField(
ugettext_noop('enabled'),
help_text=ugettext_noop("Check to activate this alias")
)
class Meta:
permissions = (
("view_domaliases", "View domain aliases"),
)
def __unicode__(self):
return self.name
class Mailbox(DatesAware):
address = models.CharField(
ugettext_noop('address'), max_length=100,
@@ -456,13 +508,14 @@ class Mailbox(DatesAware):
% (abspath, self.mdirroot, dir, sdir))
return True
def rename_dir(self, domain, newaddress):
def rename_dir(self, newdomain, newaddress):
if parameters.get_admin("CREATE_DIRECTORIES") == "yes":
if self.domain.name == domain and newaddress == self.address:
return True
path = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), domain)
oldpath = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), self.domain.name)
newpath = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), newdomain)
code = exec_as_vuser("mv %s/%s %s/%s" \
% (path, self.address, path, newaddress))
% (oldpath, self.address, newpath, newaddress))
if code:
self.path = "%s/" % newaddress
return code
@@ -498,8 +551,8 @@ class Mailbox(DatesAware):
user.set_password(kwargs["password"])
try:
user.save()
except IntegrityError:
raise AdminError(_("Mailbox with this address already exists"))
except IntegrityError, e:
raise AdminError(_("Account '%s' already exists" % user.username))
self.user = user
if len(user.groups.all()) == 0:
@@ -538,7 +591,6 @@ class Mailbox(DatesAware):
:param domain: the associated Domain object
:param user: the associated User object
"""
self.name = "%s %s" % (user.first_name, user.last_name)
self.address = localpart
self.domain = domain
self.user = user
@@ -556,7 +608,7 @@ class Mailbox(DatesAware):
self.gid = v_gid
else:
self.gid = pwd.getpwnam(parameters.get_admin("VIRTUAL_GID")).pw_gid
self.quota = self.domain.quota
self.quota = self.domain.quota
super(Mailbox, self).save()
def create_from_csv(self, user, line):
@@ -591,18 +643,21 @@ class Mailbox(DatesAware):
alias.mboxes.remove(self)
if len(alias.mboxes.all()) == 0:
alias.delete()
self.user.delete()
super(Mailbox, self).delete(*args, **kwargs)
if not keepdir:
self.delete_dir()
class Alias(DatesAware):
address = models.CharField(ugettext_noop('address'), max_length=254,
help_text=ugettext_noop("The alias address (without the domain part). For a 'catch-all' address, just enter an * character."))
address = models.CharField(
ugettext_noop('address'), max_length=254,
help_text=ugettext_noop("The alias address (without the domain part). For a 'catch-all' address, just enter an * character.")
)
domain = models.ForeignKey(Domain)
mboxes = models.ManyToManyField(Mailbox, verbose_name=ugettext_noop('mailboxes'),
help_text=ugettext_noop("The mailboxes this alias points to"))
mboxes = models.ManyToManyField(
Mailbox, verbose_name=ugettext_noop('mailboxes'),
help_text=ugettext_noop("The mailboxes this alias points to")
)
extmboxes = models.TextField(blank=True)
enabled = models.BooleanField(ugettext_noop('enabled'),
help_text=ugettext_noop("Check to activate this alias"))
@@ -611,64 +666,43 @@ class Alias(DatesAware):
permissions = (
("view_aliases", "View aliases"),
)
unique_together = (("address", "domain"),)
@property
def full_address(self):
return "%s@%s" % (self.address, self.domain.name)
@property
def targets(self):
ret = "<br/>".join(map(lambda m: str(m), self.mboxes.all()))
ret += "<br/>" + self.repr_extmboxes()
return ret
def identity(self):
return self.full_address
def save(self, int_targets, ext_targets, *args, **kwargs):
if len(ext_targets):
self.extmboxes = ",".join(ext_targets)
@property
def name_or_rcpt(self):
return "%s, ..." % self.get_recipients()[0]
def save(self, int_rcpts, ext_rcpts, *args, **kwargs):
if len(ext_rcpts):
self.extmboxes = ",".join(ext_rcpts)
else:
self.extmboxes = ""
super(Alias, self).save(*args, **kwargs)
curmboxes = self.mboxes.all()
for t in int_targets:
for t in int_rcpts:
if not t in curmboxes:
self.mboxes.add(t)
for t in curmboxes:
if not t in int_targets:
if not t in int_rcpts:
self.mboxes.remove(t)
def first_target(self):
"""Return the first target of this alias
It is taken from internal addresses, or external addresses.
"""
if len(self.mboxes.all()):
return self.mboxes.all()[0]
if len(self.extmboxes):
return self.extmboxes.split(",")[0]
return None
def get_targets(self):
"""Return a list containing targeted mailboxes
def get_recipients(self):
"""Return a the recipients list
Internal and external addresses are mixed into a single list.
"""
result = []
if len(self.mboxes.all()):
for mb in self.mboxes.all()[1:]:
result += [mb.full_address]
if len(self.extmboxes):
result += self.extmboxes.split(",")
else:
result = self.extmboxes.split(",")[1:]
result = map(lambda mb: mb.full_address, self.mboxes.all())
result += self.extmboxes.split(',')
return result
def repr_extmboxes(self):
"""Return external targets as a string
A ready to print representation of external targets.
"""
return "<br/>".join(self.extmboxes.split(","))
def ui_disabled(self, user):
if user.is_superuser:
return False
@@ -699,11 +733,12 @@ class Extension(models.Model):
module.destroy()
def on(self):
self.load()
self.init()
self.enabled = True
self.save()
self.load()
self.init()
extdir = "%s/extensions/%s" % (settings.MODOBOA_DIR, self.name)
scriptdir = "%s/%s" % (extdir, "scripts")
if os.path.exists(scriptdir):
-133
View File
@@ -1,133 +0,0 @@
# coding: utf-8
import datetime
from django.utils.translation import ugettext as _, ugettext_noop
from django.contrib.auth.models import Group
from modoboa.lib.webutils import _render, getctx, _render_to_string
from modoboa.lib import events
from forms import *
from models import User
from tables import SuperAdminsTable, DomainAdminsTable
from lib import grant_access_to_object, ungrant_access_to_object
class Permissions(object):
submit_label = ugettext_noop("Add")
formtpl = 'admin/add_permission.html'
@staticmethod
def is_authorized(user):
return user.is_superuser
def get_add_form(self, request):
raise NotImplementedError
def add(self, request):
raise NotImplementedError
def delete(self, request, selection):
raise NotImplementedError
def get(self, request):
raise NotImplementedError
def _render_form(self, request, form, instring=False):
ctx = dict(form=form, title=self.title, submit_label=self.submit_label,
role=self.role)
if instring:
return _render_to_string(request, self.formtpl, ctx)
return _render(request, self.formtpl, ctx)
class SuperAdminsPerms(Permissions):
title = ugettext_noop("Add super administrator")
role = "super_admins"
def get_add_form(self, request):
form = SuperAdminForm(request.user)
return self._render_form(request, form)
def add(self, request):
form = SuperAdminForm(request.user, request.POST)
if form.is_valid():
user = User.objects.get(pk=request.POST["user"])
user.is_superuser = True
user.date_joined = datetime.datetime.now()
events.raiseEvent("SuperAdminPromotion", user)
user.groups.clear()
user.save()
return True, None
content = self._render_form(request, form, True)
return False, getctx("ko", content=content)
def delete(self, selection):
for s in selection:
user = User.objects.get(pk=int(s))
if user.username == "admin":
continue
user.is_superuser = False
user.save()
def get(self, request):
admins = User.objects.filter(is_superuser=True)
return SuperAdminsTable(request, admins).render()
class DomainAdminsPerms(Permissions):
title = ugettext_noop("Add domain administrator")
role = "domain_admins"
formtpl = 'admin/add_domain_admin.html'
@staticmethod
def is_authorized(user):
return user.has_perm("admin.view_domains")
def get_add_form(self, request):
form = DomainAdminForm()
return self._render_form(request, form)
def delete(self, selection):
dagrp = Group.objects.get(name="DomainAdmins")
sugrp = Group.objects.get(name="SimpleUsers")
for uid in selection:
u = User.objects.get(pk=uid)
u.groups.remove(dagrp)
u.save()
events.raiseEvent("DomainAdminDeleted", u)
if not len(u.mailbox_set.all()):
ungrant_access_to_object(u)
u.delete()
else:
u.groups.add(sugrp)
def get(self, request):
domainadmins = User.objects.filter(groups__name="DomainAdmins")
domainadmins = filter(lambda da: request.user.is_owner(da), domainadmins)
return DomainAdminsTable(request, domainadmins).render()
def get_perms_class(user, role):
"""Retrieves the class associated to a given role
The provided user must have the required permission to retrieve
this class.
If "role" is one of those provided by the admin component, its
class is directly returned. Otherwise, a "PermsGetClass" event is
raised to check if one of the active plugins provide the desired
class.
:param user: a User object
:param role: the role to look for
"""
parts = role.split("_")
cname = ""
for p in parts:
cname += p.capitalize()
cname += "Perms"
if globals().has_key(cname):
if globals()[cname].is_authorized(user):
return globals()[cname]
return None
res = events.raiseQueryEvent("PermsGetClass", role)
if not len(res):
return None
return res[0]
+42 -111
View File
@@ -26,7 +26,7 @@ class DomainsTable(tables.Table):
cols_order = ["name", "creation", "modified",
"domaliases", "mboxes", "mbaliases",
"quota", "enabled", "actions"]
"quota", "actions"]
def __init__(self, request, doms):
super(DomainsTable, self).__init__(request)
@@ -38,91 +38,10 @@ class DomainsTable(tables.Table):
def parse_enabled(self, value):
return _("yes") if value else _("no")
class DomaliasesTable(tables.Table):
tableid = "objects_table"
idkey = "id"
name = tables.Column("name", label=ugettext_noop("Name"))
target = tables.Column("target", label=ugettext_noop("Targeted domain"))
creation = tables.Column("creation", label=ugettext_noop("Created"), width="170px")
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
width="170px")
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
align="center")
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
width="50px", align="center",
defvalue=domalias_actions)
cols_order = ["name", "target", "creation",
"modified", "enabled", "actions"]
def __init__(self, request, domaliases):
super(DomaliasesTable, self).__init__(request)
self.populate(self._rows_from_model(domaliases))
def parse_enabled(self, value):
return _("yes") if value else _("no")
class MailboxesTable(tables.Table):
tableid = "objects_table"
idkey = "id"
address = tables.Column("full_address", label=ugettext_noop("Address"))
name = tables.Column("user", label=ugettext_noop("Name"))
creation = tables.Column("creation", label=ugettext_noop("Created"),
width="160px")
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
width="160px")
aliases = tables.Column("alias_count", label=ugettext_noop("Aliases"), width="70px",
align="center")
quota = tables.Column("quota", label=ugettext_noop("Quota"),
width="50px", align="center")
enabled = tables.Column("enabled", label=gender("Enabled", "f"), width="50px",
align="center")
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
width="70px", align="center", defvalue=mailbox_actions)
cols_order = ["address", "name", "creation", "modified", "aliases",
"quota", "enabled", "actions"]
def __init__(self, request, mailboxes):
super(MailboxesTable, self).__init__(request)
self.populate(self._rows_from_model(mailboxes))
def parse_quota(self, value):
return "%s %s" % (value, _("MB"))
def parse_enabled(self, value):
return _("yes") if value else _("no")
def parse_name(self, user):
return "%s %s" % (user.first_name, user.last_name)
class MbaliasesTable(tables.Table):
tableid = "objects_table"
idkey = "id"
address = tables.Column("full_address", label=ugettext_noop("Address"))
targets = tables.Column("targets", label=ugettext_noop("Target(s)"), safe=True)
creation = tables.Column("creation", label=ugettext_noop("Created"), width="170px")
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
width="170px")
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
align="center")
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"), width="50px",
align="center", defvalue=mbalias_actions)
cols_order = ["address", "targets", "creation", "modified", "enabled", "actions"]
def __init__(self, request, aliases):
super(MbaliasesTable, self).__init__(request)
self.populate(self._rows_from_model(aliases))
def rowoptions(self, request, alias):
return "{ui_disabled : '%s'}" % alias.ui_disabled(request.user)
def parse_enabled(self, value):
return _("yes") if value else _("no")
def row_class(self, request, domain):
if not domain.enabled:
return "muted"
return ""
class ExtensionsTable(tables.Table):
idkey = "id"
@@ -133,43 +52,55 @@ class ExtensionsTable(tables.Table):
cols_order = ["selection", "name", "version", "descr"]
class SuperAdminsTable(tables.Table):
class AccountsTable(tables.Table):
idkey = "id"
selection = tables.SelectionColumn("selection", width="4%")
username = tables.Column("username", label=ugettext_noop("User name"))
first_name = tables.Column("first_name", label=ugettext_noop("First name"))
last_name = tables.Column("last_name", label=ugettext_noop("Last name"))
date_joined = tables.Column("date_joined", label=ugettext_noop("Defined"))
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="10%")
cols_order = ["selection", "username", "first_name", "last_name",
"date_joined", "enabled"]
def __init__(self, request, users):
super(SuperAdminsTable, self).__init__(request)
self.populate(self._rows_from_model(users))
def parse_enabled(self, value):
return _("yes") if value else _("no")
class DomainAdminsTable(tables.Table):
idkey = "id"
selection = tables.SelectionColumn("selection", width="4%")
username = tables.Column("username", label=ugettext_noop("User name"))
first_name = tables.Column("first_name", label=ugettext_noop("First name"))
last_name = tables.Column("last_name", label=ugettext_noop("Last name"))
date_joined = tables.Column("date_joined", label=ugettext_noop("Defined"))
enabled = tables.Column("is_active", label=gender("Enabled", "m"), width="10%")
role = tables.Column("group", label=ugettext_noop("Role"))
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
width="70px", align="center",
defvalue=domain_admin_actions)
defvalue=account_actions)
cols_order = ["selection", "username", "first_name",
"last_name", "date_joined", "enabled", "actions"]
cols_order = ["username", "first_name", "last_name", "date_joined",
"role", "actions"]
def __init__(self, request, users):
super(DomainAdminsTable, self).__init__(request)
super(AccountsTable, self).__init__(request)
self.populate(self._rows_from_model(users))
def parse_is_active(self, value):
return _("yes") if value else _("no")
def parse_group(self, value):
if value == "SimpleUsers":
return "U"
return value[:1]
def row_class(self, request, obj):
if not obj.is_active:
return "muted"
return ""
class IdentitiesTable(tables.Table):
idkey = "id"
identity = tables.Column("identity", label=ugettext_noop("Email/Username"))
name_or_rcpt = tables.Column("name_or_rcpt", label=ugettext_noop("Fullname/Recipient"))
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
width="70px", align="center",
defvalue=identity_actions)
cols_order = ["identity", "name_or_rcpt", "actions"]
def __init__(self, request, identities):
super(IdentitiesTable, self).__init__(request)
self.populate(self._rows_from_model(identities, True))
def row_class(self, request, obj):
if obj.__class__.__name__ == "User" and not obj.is_active:
return "muted"
if not obj.enabled:
return "muted"
return ""
+109 -184
View File
@@ -13,15 +13,7 @@ genders = {
}
@register.simple_tag
def admin_menu(user):
# entries = [
# {"name" : "admin",
# "img" : static_url('pics/admin.png'),
# "label" : _("Admin"),
# "class" : "topdropdown",
# "menu" : []
# }
# ]
def admin_menu(selection, user):
entries = []
if user.has_perm("admin.view_domains"):
entries += [
@@ -30,21 +22,14 @@ def admin_menu(user):
"label" : _("Domains"),
"img" : static_url("pics/domains.png")}
]
elif user.has_perm("admin.view_mailboxes"):
entries += [
{"name" : "mailboxes",
"url" : reverse(admin.views.domains),
"label" : _("Mailboxes"),
"img" : static_url("pics/mailbox.png")}
]
entries += \
events.raiseQueryEvent("AdminMenuDisplay", "top_menu", user)
if user.has_perm("auth.view_permissions"):
if user.has_perm("auth.add_user") or user.has_perm("admin.add_mailbox"):
entries += [
{"name" : "permissions",
"url" : reverse(admin.views.permissions),
"label" : _("Accounts"),
"img" : static_url("pics/permissions.png")}
{"name" : "identities",
"url" : reverse(admin.views.identities),
"label" : _("Identities")},
]
if user.is_superuser:
entries += [
@@ -57,193 +42,127 @@ def admin_menu(user):
if not len(entries):
return ""
return render_to_string("common/menulist.html",
{"entries" : entries, "user" : user})
{"entries" : entries, "selection" : selection, "user" : user})
@register.simple_tag
def settings_menu(selection, user):
entries = [
{"name" : "parameters",
"url" : reverse(admin.views.viewparameters),
"img" : static_url("pics/domains.png"),
"label" : _("Parameters")},
{"name" : "extensions",
"url" : reverse(admin.views.viewextensions),
"label" : _("Extensions"),
"img" : static_url("pics/extensions.png")},
{"name" : "parameters",
"url" : reverse(admin.views.viewparameters),
"img" : static_url("pics/domains.png"),
"label" : _("Parameters")},
]
return render_to_string('common/menu.html',
{"selection" : selection, "entries" : entries,
"user" : user})
def dommenu_entry(name, label, img, listurl, newurl):
result = {"name" : name,
"label" : label,
"img" : img,
"url" : listurl,
"class" : "menubardropdown",
}
return result
return render_to_string('common/menu.html', {
"entries" : entries,
"css" : "nav nav-list",
"selection" : selection,
"user" : user
})
@register.simple_tag
def domains_menu(selection, user, domid):
args = domid != "" and ("?domid=%s" % domid) or ""
entries = []
if selection == "stats":
disabled = True
else:
disabled = False
entries += [
{"name" : "actions",
"label" : _("Actions"),
"img" : static_url("pics/tools.png"),
"class" : "menubardropdown",
"menu" : [
{"name" : "new",
"label" : _("New"),
"img" : static_url("pics/add.png"),
"disabled" : disabled},
{"name" : "remove",
"label" : _("Remove"),
"img" : static_url("pics/remove.png"),
"disabled" : disabled
},
{"name" : "import",
"label" : _("Import data"),
"img" : static_url("pics/import.png"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:370,y:250}}",
"url" : reverse(admin.views.importdata)}
]
},
]
entries += [{"separator" : True}]
if user.has_perm("admin.view_domains"):
entries += dommenu_entry("domains", _("Domains"),
static_url("pics/domains.png"),
reverse(admin.views.domains),
reverse(admin.views.newdomain)),
entries += [
dommenu_entry("domaliases", _("Domain aliases"), static_url("pics/alias.png"),
reverse(admin.views.domaliases) + args,
reverse(admin.views.newdomalias) + args),
dommenu_entry("mailboxes", _("Mailboxes"), static_url("pics/mailbox.png"),
reverse(admin.views.mailboxes) + args,
reverse(admin.views.newmailbox) + args),
dommenu_entry("mbaliases", _("Mailbox aliases"), static_url("pics/alias.png"),
reverse(admin.views.mbaliases) + args,
reverse(admin.views.newmbalias) + args),
]
entries += events.raiseQueryEvent("AdminMenuDisplay", "admin_menu_box", user)
return render_to_string('common/menu.html',
{"entries" : entries,
"selection" : selection,
"user" : user})
@register.simple_tag
def permissions_menu(user):
def domains_menu(selection, user):
entries = [
{"name" : "addperm",
"label" : _("Add permission"),
"img" : static_url("pics/add.png"),
"url" : reverse(admin.views.add_permission)},
{"name" : "delperms",
"label" : _("Remove permissions"),
"img" : static_url("pics/remove.png"),
"url" : reverse(admin.views.delete_permissions)},
{"name" : "newdomain",
"label" : _("New domain"),
"img" : "icon-plus",
"modal" : True,
"modalcb" : "domainform_cb",
"url" : reverse("modoboa.admin.views.newdomain")},
{"name" : "import",
"label" : _("Import"),
"img" : "icon-folder-open",
"url" : reverse(admin.views.import_domains),
"modal" : True,
"modalcb" : "importform_cb"}
]
return render_to_string('common/menu.html',
{"entries" : entries, "user" : user})
return render_to_string('common/menu.html', {
"entries" : entries,
"css" : "nav nav-list",
"selection" : selection,
"user" : user
})
@register.simple_tag
def identities_menu(user):
entries = [
{"name" : "newaccount",
"label" : _("New account"),
"img" : "icon-plus",
"modal" : True,
"modalcb" : "newaccount_cb",
"url" : reverse(admin.views.newaccount)},
{"name" : "newdlist",
"label" : _("New distribution list"),
"img" : "icon-plus",
"modal" : True,
"modalcb" : "dlistform_cb",
"url" : reverse(admin.views.newdlist)},
{"name" : "import",
"label" : _("Import"),
"img" : "icon-folder-open",
"url" : reverse(admin.views.import_identities),
"modal" : True,
"modalcb" : "importform_cb"}
]
return render_to_string('common/menu.html', {
"entries" : entries,
"css" : "nav nav-list",
"user" : user
})
@register.simple_tag
def domain_actions(user, domid):
actions = [
{"name" : "editdomain",
"url" : reverse(admin.views.editdomain, args=[domid]),
"img" : static_url("pics/edit.png"),
"img" : "icon-edit",
"title" : _("Edit domain"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:310,y:190}}"},
{"name" : "domaliases",
"url" : reverse(admin.views.domaliases) + "?domid=%s" % domid,
"img" : static_url("pics/alias.png"),
"title" : _("View aliases of this domain")}
"modal" : True,
"modalcb" : "domainform_cb"},
{"name" : "deldomain",
"url" : reverse(admin.views.deldomain) + "?selection=%s" % domid,
"img" : "icon-remove"},
]
if user.has_perm('admin.view_domains'):
actions += [
{"name" : "viewadmins",
"url" : reverse(admin.views.view_domain_admins, args=[domid]),
"img" : static_url("pics/administrators.png"),
"title" : _("View administrators of this domain"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:310,y:190}}"},
]
return render_actions(actions)
@register.simple_tag
def domalias_actions(user, aid):
def account_actions(user, accountid):
actions = [
{"name" : "editalias",
"url" : reverse(admin.views.editdomalias, args=[aid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit alias"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:310,y:190}}"}
{"name" : "editaccount",
"url" : reverse(admin.views.editaccount, args=[accountid]),
"img" : "icon-edit",
"modal" : True,
"modalcb" : "editaccount_cb",
"title" : _("Edit account")},
{"name" : "delaccount",
"url" : reverse(admin.views.delaccount) + "?selection=%s" % accountid,
"img" : "icon-remove",
"title" : _("Delete this account")},
]
return render_actions(actions)
@register.simple_tag
def mailbox_actions(user, mboxid):
def identity_actions(user, iid):
name, objid = iid.split(':')
if name == "User":
return account_actions(user, objid)
actions = [
{"name" : "editmailbox",
"url" : reverse(admin.views.editmailbox, args=[mboxid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit mailbox"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:310,y:320}}"},
{"name" : "aliases",
"url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mboxid,
"img" : static_url("pics/alias.png"),
"title" : _("View this mailbox aliases")},
]
return render_actions(actions)
@register.simple_tag
def domain_admin_actions(user, daid):
from modoboa.admin.models import User
actions = [
{"name" : "editdomainadmin",
"url" : reverse(admin.views.edit_domain_admin, args=[daid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit domain admin"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:350,y:320}}"},
{"name" : "assigndomains",
"url" : reverse(admin.views.assign_domains_to_admin, args=[daid]),
"img" : static_url("pics/domains.png"),
"title" : _("Assign domain(s) to this administrator"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:350,y:320}}"},
]
actions += events.raiseQueryEvent("DomainAdminActions", User.objects.get(pk=daid))
return render_actions(actions)
@register.simple_tag
def mbalias_actions(user, aliasid):
from modoboa.admin.models import Alias
alias = Alias.objects.get(pk=aliasid)
if alias.ui_disabled(user):
return "--"
actions = [
{"name" : "editmbalias",
"url" : reverse(admin.views.editmbalias, args=[aliasid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit mailbox alias"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:320,y:300}}"}
{"name" : "editdlist",
"url" : reverse(admin.views.editdlist, args=[objid]),
"img" : "icon-edit",
"modal" : True,
"modalcb" : "dlistform_cb",
"title" : _("Edit distribution list")},
{"name" : "deldlist",
"url" : reverse(admin.views.deldlist) + "?selection=%s" % objid,
"img" : "icon-remove",
"title" : _("Delete this distribution list")},
]
return render_actions(actions)
@@ -255,9 +174,11 @@ def loadadminextmenu(user):
@register.simple_tag
def param(app, definition):
result = """<div class='row'>
<label>%s</label>""" % (definition.has_key("label") \
and _(definition["label"]) or definition["name"])
result = """<div class='control-group'>
<label class="param-label">%s</label>
<div class="param-controls">""" \
% (definition.has_key("label") and _(definition["label"])
or definition["name"])
name = "%s.%s" % (app, definition["name"])
value = definition.has_key("value") \
and definition["value"] or definition["deflt"]
@@ -290,10 +211,14 @@ def param(app, definition):
if definition.has_key("help"):
result += """
<a href='%s' onclick='return false;' class='Tips' title='%s'>
<img src='%s' border='0' />
</a>""" % (_(definition["help"]), _("Help"), static_url("pics/info.png"))
<p class="help-block">%s</p>
""" % definition["help"]
# result += """
# <a href='%s' onclick='return false;' class='Tips' title='%s'>
# <img src='%s' border='0' />
# </a>""" % (_(definition["help"]), _("Help"), static_url("pics/info.png"))
result += """
</div>
</div>
"""
return result
+14 -23
View File
@@ -4,40 +4,31 @@ urlpatterns = patterns(
'modoboa.admin.views',
url(r'^$', 'domains', name="index"),
url(r'^domains/$', 'domains', name="domains"),
(r'^domains/list/$', 'domains_list'),
(r'^domains/new/', 'newdomain'),
(r'^domains/(?P<dom_id>\d+)/edit/$', 'editdomain'),
(r'^domains/delete/$', 'deldomain'),
(r'^domains/import/$', 'importdata'),
(r'^domains/import/$', 'import_domains'),
(r'^domaliases/$', "domaliases"),
(r'^domaliases/new/', 'newdomalias'),
(r'^domaliases/edit/(?P<alias_id>\d+)/', 'editdomalias'),
(r'^domaliases/delete/$', 'deldomalias'),
(r'^mailboxes/$', 'mailboxes'),
(r'^mailboxes/new/$', 'newmailbox'),
(r'^mailboxes/edit/(?P<mbox_id>\d+)/$', 'editmailbox'),
(r'^mailboxes/delete/$', 'delmailbox'),
(r'^mailboxes/search/$', 'mailboxes_search'),
(r'^mbaliases/$', 'mbaliases'),
(r'^mbaliases/new/$', 'newmbalias'),
(r'^mbaliases/edit/(?P<alias_id>\d+)/$', 'editmbalias'),
(r'^mbaliases/delete/$', 'delmbalias'),
(r'^settings/$', 'viewparameters'),
(r'^settings/parameters/$', 'viewparameters'),
(r'^settings/parameters/save/$', 'saveparameters'),
(r'^settings/extensions/$', 'viewextensions'),
(r'^settings/extensions/save/$', 'saveextensions'),
(r'^permissions/$', 'permissions'),
(r'^permissions/add/$', 'add_permission'),
(r'^permissions/domainadmin/new/$', 'create_domain_admin'),
(r'^permissions/domainadmin/edit/(?P<da_id>\d+)/$', 'edit_domain_admin'),
(r'^permissions/domainadmin/promote/$', 'domain_admin_promotion'),
(r'^permissions/domainadmin/assign/(?P<da_id>\d+)/$', 'assign_domains_to_admin'),
(r'^permissions/domainadmins/(?P<dom_id>\d+)/$', 'view_domain_admins'),
(r'^permissions/searchaccount/$', 'search_account'),
(r'^permissions/delete/$', 'delete_permissions'),
(r'^identities/$', 'identities'),
(r'^identities/import/$', 'import_identities'),
(r'^accounts/list/$', 'accounts_list'),
(r'^accounts/new/$', 'newaccount'),
(r'^accounts/edit/(?P<accountid>\d+)/$', 'editaccount'),
(r'^accounts/delete/$', 'delaccount'),
(r'^distriblists/new/$', 'newdlist'),
(r'^distriblists/edit/(?P<dlist_id>\d+)/$', 'editdlist'),
(r'^distriblists/delete/$', 'deldlist'),
)
+253 -485
View File
@@ -1,61 +1,61 @@
# -*- coding: utf-8 -*-
# coding: utf-8
from django.http import HttpResponse, HttpResponseRedirect
from django.utils import simplejson
from django.utils.translation import ugettext as _, ungettext
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators \
import login_required, permission_required, user_passes_test
from django.db.models import Q
from django.contrib.auth.models import Group
from django.contrib import messages
from django.db import transaction, IntegrityError, transaction
from django.db import transaction, IntegrityError
from lib import *
from lib import render_listing
from forms import *
from modoboa import admin, userprefs
from models import *
from modoboa.admin.permissions import *
from models import *
from modoboa.admin.tables import *
from modoboa.lib import events, parameters
from modoboa.lib.exceptions import *
from modoboa.lib.webutils \
import _render, ajax_response, ajax_simple_response, getctx
import _render, ajax_response, ajax_simple_response
from modoboa.lib.emailutils import split_mailbox
from modoboa.lib.models import Parameter
import copy
from modoboa.lib.permissions import *
@login_required
def domains(request):
if not request.user.has_perm("admin.view_domains"):
if request.user.has_perm("admin.view_mailboxes"):
return HttpResponseRedirect(reverse(mailboxes))
return HttpResponseRedirect(reverse(identities))
return HttpResponseRedirect(reverse(userprefs.views.preferences))
domains = request.user.get_domains()
for dom in domains:
dom.mbalias_counter = len(Alias.objects.filter(domain=dom.id))
deloptions = {"keepdir" : _("Do not delete domain directory")}
return render_listing(request, "domains",
"admin/domains.html",
title=_("Available domains"),
objects=domains,
rel="310 190",
deloptions=deloptions)
objects=domains)
def _validate_domain(request, form, successmsg, commonctx,
callback=None, tplname="admin/adminform.html"):
"""Domain validation
@login_required
@permission_required("admin.view_domains")
def domains_list(request):
doms = map(lambda dom: dom.name, request.user.get_domains())
return ajax_simple_response(doms)
def _validate_domain(request, form, successmsg, commonctx, tplname,
callback=None):
"""Domain form validation
Common function shared between creation and modification actions.
"""
error = None
if form.is_valid():
try:
domain = form.save()
domain = form.save(request.user)
except AdminError, e:
error = str(e)
except IntegrityError:
error = _("Domain with this name already defined")
error = _("An alias with this name already exists")
else:
if callback is not None:
callback(request.user, domain)
@@ -69,7 +69,7 @@ def _validate_domain(request, form, successmsg, commonctx,
@login_required
@permission_required("admin.add_domain")
@transaction.commit_on_success
def newdomain(request, tplname="admin/adminform.html"):
def newdomain(request):
events.raiseEvent("CanCreate", request.user, "domains")
def newdomain_cb(user, domain):
grant_access_to_object(user, domain, is_owner=True)
@@ -82,15 +82,15 @@ def newdomain(request, tplname="admin/adminform.html"):
if request.method == "POST":
form = DomainForm(request.POST)
return _validate_domain(request, form, _("Domain created"), commonctx,
newdomain_cb)
"admin/domainform.html",
callback=newdomain_cb)
form = DomainForm()
commonctx["form"] = form
return _render(request, tplname, commonctx)
return _render(request, "common/generic_modal_form.html", commonctx)
@login_required
@permission_required("admin.change_domain")
def editdomain(request, dom_id, tplname="admin/adminform.html"):
def editdomain(request, dom_id, tplname="admin/domainform.html"):
domain = Domain.objects.get(pk=dom_id)
if not request.user.is_owner(domain):
raise PermDeniedException(_("You can't edit this domain"))
@@ -101,7 +101,7 @@ def editdomain(request, dom_id, tplname="admin/adminform.html"):
"formid" : "domform"}
if request.method == "POST":
form = DomainForm(request.POST, instance=domain)
return _validate_domain(request, form, _("Domain modified"), commonctx)
return _validate_domain(request, form, _("Domain modified"), commonctx, tplname)
form = DomainForm(instance=domain)
commonctx["form"] = form
@@ -120,11 +120,13 @@ def deldomain(request):
mb = None
for dom in Domain.objects.filter(id__in=selection):
if not request.user.is_owner(dom):
if not request.user.can_access(dom):
raise PermDeniedException(_("You can't delete this domain"))
if mb and mb.domain == dom:
raise AdminError(_("You can't delete your own domain"))
events.raiseEvent("DomainAliasDeleted", dom.domainalias_set.all())
events.raiseEvent("DeleteMailbox", dom.mailbox_set.all())
events.raiseEvent("DeleteDomain", dom)
ungrant_access_to_object(dom)
dom.delete(keepdir=keepdir)
@@ -133,126 +135,6 @@ def deldomain(request):
messages.info(request, msg, fail_silently=True)
return ajax_response(request)
@login_required
@permission_required("admin.view_domaliases")
@check_domain_access
def domaliases(request):
if request.GET.has_key("domid"):
domain = Domain.objects.get(pk=request.GET["domid"])
domaliases = DomainAlias.objects.filter(target=request.GET["domid"])
else:
domain = None
domaliases = request.user.get_domaliases()
return render_listing(request, "domaliases",
title=_("Domain aliases"),
rel="310 190",
objects=domaliases)
@login_required
@permission_required("admin.add_domainalias")
@transaction.commit_on_success
def newdomalias(request, tplname="admin/adminform.html"):
events.raiseEvent("CanCreate", request.user, "domain_aliases")
commonctx = {"title" : _("New domain alias"),
"submit_label" : _("Create"),
"action" : reverse(newdomalias),
"formid" : "domaliasform"}
if request.method == "POST":
form = DomainAliasForm(request.user, request.POST)
error = None
if form.is_valid():
domalias = form.save(commit=False)
if Domain.objects.filter(name=domalias.name):
error = _("A domain with this name already exists")
else:
try:
domalias.save()
except IntegrityError:
error = _("Alias with this name already exists")
else:
grant_access_to_object(request.user, domalias, is_owner=True)
events.raiseEvent("DomainAliasCreated", request.user, domalias)
messages.info(request, _("Domain alias created"), fail_silently=True)
return ajax_response(request, url=reverse(admin.views.domaliases))
commonctx["form"] = form
commonctx["error"] = error
return ajax_response(request, status="ko", template=tplname, **commonctx)
form = DomainAliasForm(request.user)
if request.GET.has_key("domid"):
form.fields["target"].initial = request.GET["domid"]
commonctx["form"] = form
return _render(request, tplname, commonctx)
@login_required
@permission_required("admin.change_domainalias")
def editdomalias(request, alias_id, tplname="admin/adminform.html"):
domalias = DomainAlias.objects.get(pk=alias_id)
if not request.user.is_owner(domalias.target):
raise PermDeniedException(_("You do not have access to this domain"))
commonctx = {"title" : _("Domain alias editing"),
"submit_label" : _("Update"),
"action" : reverse(editdomalias, args=[alias_id]),
"formid" : "domaliasform"}
if request.method == "POST":
form = DomainAliasForm(request.user, request.POST, instance=domalias)
error = None
if form.is_valid():
ndomalias = form.save(commit=False)
if Domain.objects.filter(name=ndomalias.name):
error = _("A domain with this name already exists")
else:
try:
ndomalias.save()
except IntegrityError:
error = _("Alias with this name already exists")
else:
messages.info(request, _("Domain alias updated"), fail_silently=True)
return ajax_response(request, url=reverse(admin.views.domaliases))
commonctx["form"] = form
commonctx["error"] = error
return ajax_response(request, status="ko", template=tplname, **commonctx)
form = DomainAliasForm(request.user, instance=domalias)
commonctx["form"] = form
return _render(request, tplname, commonctx)
@login_required
@permission_required("admin.delete_domainalias")
@transaction.commit_on_success
def deldomalias(request):
selection = request.GET["selection"].split(",")
for daid in selection:
domalias = DomainAlias.objects.get(pk=daid)
if not request.user.is_owner(domalias.target):
raise PermDeniedException(_("You don't have acces to this domain"))
events.raiseEvent("DomainAliasDeleted", domalias)
ungrant_access_to_object(domalias)
domalias.delete()
msg = ungettext("Domain alias deleted", "Domain aliases deleted", len(selection))
messages.info(request, msg, fail_silently=True)
return ajax_response(request)
@login_required
@permission_required("admin.view_mailboxes")
@check_domain_access
def mailboxes(request):
title = _("Available mailboxes")
if request.GET.has_key("domid"):
domain = Domain.objects.get(pk=request.GET["domid"])
mboxes = Mailbox.objects.filter(domain=domain.id)
title += " (%s)" % domain.name
else:
mboxes = request.user.get_mailboxes()
domain = None
deloptions = {"keepdir" : _("Do not delete mailbox directory")}
return render_listing(request, "mailboxes",
title=title,
rel="310 320",
objects=mboxes, domain=domain, deloptions=deloptions)
@login_required
@permission_required("admin.view_mailboxes")
@check_domain_access
@@ -271,135 +153,14 @@ def mailboxes_search(request):
result = map(lambda mb: mb.full_address, mboxes)
return ajax_simple_response(result)
@login_required
@permission_required("admin.add_mailbox")
@transaction.commit_on_success
def newmailbox(request, tplname="admin/adminform.html"):
events.raiseEvent("CanCreate", request.user, "mailboxes")
commonctx = {"title" : _("New mailbox"),
"submit_label" : _("Create"),
"action" : reverse(newmailbox),
"formid" : "mboxform"}
if request.method == "POST":
form = MailboxWithPasswordForm(request.user, request.POST)
error = None
if form.is_valid():
if not request.user.is_superuser:
if not request.user.can_access(form.cleaned_data["domain"]):
raise PermDeniedException(_("You do not have access to this domain"))
try:
mb = form.save()
except AdminError as e:
error = str(e)
else:
grant_access_to_object(request.user, mb, is_owner=True)
grant_access_to_object(request.user, mb.user, is_owner=True)
events.raiseEvent("CreateMailbox", request.user, mb)
messages.info(request, _("Mailbox created"),
fail_silently=True)
return ajax_response(request, url=reverse(admin.views.mailboxes) + "?domid=%d" % mb.domain.id)
commonctx["form"] = form
commonctx["error"] = error
return ajax_response(request, status="ko", template=tplname, **commonctx)
form = MailboxWithPasswordForm(request.user)
commonctx["form"] = form
return _render(request, tplname, commonctx)
@login_required
@permission_required("admin.change_mailbox")
def editmailbox(request, mbox_id=None, tplname="admin/adminform.html"):
mb = Mailbox.objects.get(pk=mbox_id)
if not request.user.can_access(mb.domain):
raise PermDeniedException(_("You do not have access to this domain"))
commonctx = {"title" : _("Mailbox editing"),
"submit_label" : _("Create"),
"action" : reverse(editmailbox, args=[mbox_id]),
"formid" : "mboxform"}
if request.method == "POST":
if request.POST.get("password1", "") != "" or \
request.POST.get("password2", "") != "":
formclass = MailboxWithPasswordForm
else:
formclass = MailboxForm
oldmb = copy.deepcopy(mb)
form = formclass(request.user, request.POST, instance=mb)
error = None
if form.is_valid():
try:
mb = form.save(commit=False)
except AdminError, inst:
error = str(inst)
else:
if oldmb.rename_dir(mb.domain.name, mb.address):
form.commit_save(mb)
events.raiseEvent("ModifyMailbox", mb, oldmb)
messages.info(request, _("Mailbox modified"),
fail_silently=True)
return ajax_response(request, url=reverse(admin.views.mailboxes) + "?domid=%d" % mb.domain.id)
error = _("Failed to rename mailbox, check permissions")
commonctx["form"] = form
commonctx["error"] = error
return ajax_response(request, status="ko", template=tplname, **commonctx)
form = MailboxWithPasswordForm(request.user, instance=mb)
commonctx["form"] = form
return _render(request, tplname, commonctx)
@login_required
@permission_required("admin.delete_mailbox")
@transaction.commit_on_success
def delmailbox(request):
selection = request.GET["selection"].split(",")
error = None
keepdir = True if request.GET.get("keepdir", "false") == "true" else False
usermb = request.user.mailbox_set.all()[0] \
if len(request.user.mailbox_set.all()) else None
for mb in Mailbox.objects.filter(id__in=selection):
if not request.user.can_access(mb.domain):
raise PermDeniedException(_("You don't have access to this domain"))
if usermb and usermb == mb:
raise AdminError(_("You can't delete your own mailbox"))
events.raiseEvent("DeleteMailbox", mb)
ungrant_access_to_object(mb)
ungrant_access_to_object(mb.user)
mb.delete(keepdir=keepdir)
msg = ungettext("Mailbox deleted", "Mailboxes deleted", len(selection))
messages.info(request, msg, fail_silently=True)
return ajax_response(request)
@login_required
@permission_required("admin.view_aliases")
@check_domain_access
def mbaliases(request):
if request.GET.has_key("domid"):
aliases = Alias.objects.filter(domain=request.GET["domid"])
elif request.GET.has_key("mbid"):
aliases = Alias.objects.filter(mboxes__id=request.GET["mbid"]).distinct()
else:
aliases = request.user.get_mbaliases()
return render_listing(request, "mbaliases",
title=_("Mailbox aliases"),
rel="320 300",
objects=aliases)
def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=None):
"""Mailbox alias validation
def _validate_dlist(request, form, successmsg, tplname, commonctx, callback=None):
"""Distribution list validation
Common function shared between creation and modification actions.
"""
error = None
if form.is_valid():
if not request.POST.has_key("targets"):
raise AdminError(_("No target defined"))
form.set_targets(request.user, request.POST.getlist("targets"))
form.set_recipients(request.user)
try:
alias = form.save()
except IntegrityError:
@@ -408,8 +169,8 @@ def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=No
if callback:
callback(request.user, alias)
messages.info(request, successmsg, fail_silently=True)
return ajax_response(request, url=reverse(admin.views.mbaliases))
messages.info(request, successmsg)
return ajax_response(request, url=reverse(admin.views.identities))
if request.POST.has_key("targets"):
targets = request.POST.getlist("targets")
@@ -422,218 +183,184 @@ def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=No
@login_required
@permission_required("admin.add_alias")
@transaction.commit_on_success
def newmbalias(request, tplname="admin/mbaliasform.html"):
def newdlist(request, tplname="common/generic_modal_form.html"):
events.raiseEvent("CanCreate", request.user, "mailbox_aliases")
commonctx = {"title" : _("New mailbox alias"),
commonctx = {"title" : _("New distribution list"),
"submit_label" : _("Create"),
"action" : reverse(newmbalias),
"formid" : "mbaliasform"}
"action" : reverse(newdlist),
"formid" : "dlistform"}
if request.method == "POST":
def callback(user, mbalias):
grant_access_to_object(user, mbalias, is_owner=True)
events.raiseEvent("MailboxAliasCreated", user, mbalias)
def callback(user, dlist):
grant_access_to_object(user, dlist, is_owner=True)
events.raiseEvent("MailboxAliasCreated", user, dlist)
form = AliasForm(request.user, request.POST)
return _validate_mbalias(request, form, _("Mailbox alias created"),
tplname, commonctx, callback)
form = DlistForm(request.POST)
return _validate_dlist(request, form, _("Distribution list created"),
tplname, commonctx, callback)
form = AliasForm(request.user)
form = DlistForm()
commonctx["form"] = form
commonctx["noerrors"] = True
return _render(request, tplname, commonctx)
return _render(request, "common/generic_modal_form.html", commonctx)
@login_required
@permission_required("admin.change_alias")
def editmbalias(request, alias_id, tplname="admin/mbaliasform.html"):
alias = Alias.objects.get(pk=alias_id)
if not request.user.is_owner(alias.domain):
def editdlist(request, dlist_id, tplname="admin/dlistform.html"):
dlist = Alias.objects.get(pk=dlist_id)
if not request.user.is_owner(dlist.domain):
raise PermDeniedException(_("You do not have access to this domain"))
commonctx = {"title" : _("Mailbox alias editing"),
commonctx = {"title" : dlist.full_address,
"submit_label" : _("Update"),
"action" : reverse(editmbalias, args=[alias.id]),
"formid" : "mbaliasform"}
"action" : reverse(editdlist, args=[dlist.id]),
"formid" : "dlistform"}
if request.method == "POST":
form = AliasForm(request.user, request.POST, instance=alias)
return _validate_mbalias(request, form, _("Mailbox alias modified"),
tplname, commonctx)
form = DlistForm(request.POST, instance=dlist)
return _validate_dlist(request, form, _("Distribution list modified"),
tplname, commonctx)
form = AliasForm(request.user, instance=alias)
form = DlistForm(instance=dlist)
commonctx["form"] = form
commonctx["targets"] = alias.get_targets()
return _render(request, tplname, commonctx)
@login_required
@permission_required("admin.delete_alias")
@transaction.commit_on_success
def delmbalias(request):
def deldlist(request):
selection = request.GET["selection"].split(",")
for mbaid in selection:
mbalias = Alias.objects.get(pk=mbaid)
if not request.user.is_owner(mbalias.domain):
for dlist_id in selection:
dlist = Alias.objects.get(pk=dlist_id)
if not request.user.is_owner(dlist.domain):
raise PermDeniedException(_("You do not have access to this domain"))
events.raiseEvent("MailboxAliasDeleted", mbalias)
ungrant_access_to_object(mbalias)
mbalias.delete()
events.raiseEvent("MailboxAliasDeleted", dlist)
ungrant_access_to_object(dlist)
dlist.delete()
msg = ungettext("Alias deleted", "Aliases deleted", len(selection))
messages.info(request, msg, fail_silently=True)
msg = ungettext("Distribution list deleted",
"Distribution lists deleted", len(selection))
messages.info(request, msg)
return ajax_response(request)
@login_required
@permission_required("auth.view_permissions")
def permissions(request, tplname='admin/permissions.html'):
permtables = []
if request.user.is_superuser:
permtables += [
{"id" : "super_admins",
"title" : _("Super administrators"),
"rel" : "300 140",
"content" : SuperAdminsPerms().get(request)}
]
permtables += events.raiseQueryEvent("PermsGetTables", request)
permtables += [
{"id" : "domain_admins",
"title" : _("Domain administrators"),
"rel" : "350 100",
"content" : DomainAdminsPerms().get(request)}
]
return _render(request, tplname, {
"permtables" : permtables
})
@user_passes_test(lambda u: u.has_perm("auth.add_user") or u.has_perm("admin.add_mailbox"))
def identities(request, tplname='admin/identities.html'):
accounts_list = []
for account in User.objects.all():
if request.user.can_access(account) or \
account.has_mailbox and request.user.can_access(account.mailbox_set.all()[0].domain):
accounts_list += [account]
for mbalias in Alias.objects.all():
if len(mbalias.get_recipients()) > 2:
accounts_list += [mbalias]
return render_listing(request, "identities", tplname, objects=accounts_list)
@login_required
@permission_required("auth.view_permissions")
def add_permission(request):
role = request.method == "GET" and request.GET["role"] or request.POST["role"]
pclass = get_perms_class(request.user, role)
if pclass is None:
messages.error(request, _("Permission denied!"),
fail_silently=True)
else:
events.raiseEvent("CanCreate", request.user, role)
pobj = pclass()
if request.method == "GET":
return pobj.get_add_form(request)
status, data = pobj.add(request)
if not status:
return HttpResponse(simplejson.dumps(data), mimetype="application/json")
try:
msg = pobj.add_success_msg
except AttributeError:
msg = _("Permission added")
messages.info(request, msg, fail_silently=True)
return ajax_response(request, url=reverse(admin.views.permissions))
def accounts_list(request):
accs = User.objects.filter(is_superuser=False).exclude(groups__name='SimpleUsers')
res = map(lambda a: a.username, accs.all())
return ajax_simple_response(res)
@login_required
@permission_required("auth.view_permissions")
def create_domain_admin(request, tplname="admin/create_domain_admin.html"):
events.raiseEvent("CanCreate", request.user, "domain_admins")
if request.method == "POST":
form = UserWithPasswordForm(request.POST)
if form.is_valid():
user = form.save(group="DomainAdmins")
grant_access_to_object(request.user, user, is_owner=True)
events.raiseEvent("DomainAdminCreated", user)
messages.info(request, _("Domain admin created"), fail_silently=True)
return ajax_response(request, url=reverse(admin.views.permissions))
return ajax_response(request, status="ko", template=tplname, form=form)
form = UserWithPasswordForm()
return ajax_response(request, template=tplname, form=form)
@login_required
@permission_required("auth.view_permissions")
def edit_domain_admin(request, da_id, tplname="admin/adminform.html"):
ctx = dict(title=_("Edit domain admin"),
action=reverse(edit_domain_admin, args=[da_id]),
formid="eda_form",
submit_label=_("Update"))
u = User.objects.get(pk=da_id, groups__name="DomainAdmins")
if request.method == "POST":
if request.POST.get("password1", "") != "" and \
request.POST.get("password2", "") != "":
form = UserWithPasswordForm(request.POST, instance=u)
else:
form = UserForm(request.POST, instance=u)
if form.is_valid():
form.save()
if form.cleaned_data["createmb"]:
pass
messages.info(request, _("Domain admin updated"), fail_silently=True)
return ajax_response(request,
url=reverse("modoboa.admin.views.permissions"))
ctx.update(form=form)
return ajax_response(request, status="ko", template=tplname, **ctx)
form = UserWithPasswordForm(instance=u)
ctx.update(form=form)
return _render(request, tplname, ctx)
@login_required
@permission_required("auth.view_permissions")
def domain_admin_promotion(request, tplname="admin/domain_admin_promotion.html"):
if request.method == "POST":
form = DomainAdminPromotionForm(request.POST)
if form.is_valid():
u = User.objects.get(username=form.cleaned_data["name"])
u.groups.add(Group.objects.get(name="DomainAdmins"))
u.save()
if not request.user.can_access(u):
# The only case where we need to grant access to the
# object is when ``u`` has been create by a super
# admin
grant_access_to_object(request.user, u, is_owner=True)
events.raiseEvent("DomainAdminCreated", u)
messages.info(request, _("Domain admin added"), fail_silently=True)
return ajax_response(request, url=reverse(admin.views.permissions))
return ajax_response(request, status="ko", template=tplname, form=form)
form = DomainAdminPromotionForm()
return ajax_response(request, template=tplname, form=form)
@login_required
@permission_required("auth.view_permissions")
@transaction.commit_on_success
def assign_domains_to_admin(request, da_id, tplname="admin/adminform.html"):
da = User.objects.get(pk=da_id)
ctx = dict(title=_("Assign domains to %s" % da.username),
action=reverse(assign_domains_to_admin, args=[da_id]),
formid="assignform",
submit_label=_("Assign"))
def newaccount(request, tplname='admin/newaccount.html'):
from modoboa.lib.formutils import CreationWizard
def create_account(steps):
"""Account creation callback
Called when all the creation steps have been validated.
:param steps: the steps data
"""
genform = steps[0]["form"]
genform.is_valid()
account = genform.save()
grant_access_to_object(request.user, account, is_owner=True)
events.raiseEvent("AccountCreated", account)
mailform = steps[1]["form"]
mailform.save(request.user, account)
ctx = dict(
title=_("New account"),
action=reverse(newaccount),
formid="newaccount_form",
submit_label=_("Create")
)
cwizard = CreationWizard(create_account)
cwizard.add_step(AccountFormGeneralPwd,
buttons=[dict(classes="btn-inverse next", label=_("Next"))],
new_args=[request.user])
cwizard.add_step(AccountFormMail,
buttons=[dict(classes="btn-primary submit", label=_("Create")),
dict(classes="btn-inverse prev", label=_("Previous"))])
if request.method == "POST":
form = AssignDomainsForm(request.user, da, request.POST)
if form.is_valid():
current_domains = da.get_domains()
for domain in form.cleaned_data["domains"]:
if not domain in current_domains:
grant_access_to_object(da, domain)
else:
current_domains.remove(domain)
for domain in current_domains:
ungrant_access_to_object(domain, da)
msg = ungettext("Domain assigned", "Domains assigned",
len(form.cleaned_data["domains"]))
messages.info(request, msg)
return ajax_response(request, url=reverse(admin.views.permissions))
ctx.update(form=form)
retcode, data = cwizard.validate_step(request)
if retcode == -1:
raise AdminError(data)
if retcode == 1:
return ajax_simple_response(dict(status="ok"))
if retcode == 2:
messages.info(request, _("Account created"))
return ajax_simple_response(dict(status="ok"))
ctx.update(steps=cwizard.steps)
return ajax_response(request, status="ko", template=tplname, **ctx)
form = AssignDomainsForm(request.user, da)
ctx.update(form=form)
cwizard.create_forms()
ctx.update(steps=cwizard.steps)
return _render(request, tplname, ctx)
@login_required
@permission_required("auth.view_permissions")
def view_domain_admins(request, dom_id, tplname="admin/view_domain_admins.html"):
domain = Domain.objects.get(pk=dom_id)
return _render(request, tplname, {
"domain" : domain
})
@transaction.commit_on_success
def editaccount(request, accountid, tplname="common/tabforms.html"):
account = User.objects.get(pk=accountid)
mb = account.mailbox_set.all()[0] if account.has_mailbox else None
instances = dict(general=account, mail=mb, perms=account)
events.raiseEvent("FillAccountInstances", request.user, account, instances)
ctx = dict(
title=account.username,
action=reverse(editaccount, args=[accountid]),
submit_label=_("Update")
)
if request.method == "POST":
classes = {}
if request.POST.get("password1", "") == "" \
and request.POST.get("password2", "") == "":
classes["general"] = AccountFormGeneral
form = AccountForm(request.user, request.POST,
instances=instances, classes=classes)
account.oldgroup = account.group
if form.is_valid(mandatory_only=True):
form.save_general_form()
if form.is_valid(optional_only=True):
events.raiseEvent("AccountModified", account, form.account)
form.save()
messages.info(request, _("Account updated"))
return ajax_simple_response(dict(status="ok"))
transaction.rollback()
ctx["tabs"] = form
return ajax_response(request, status="ko", template=tplname, **ctx)
ctx["tabs"] = AccountForm(request.user, instances=instances)
return _render(request, tplname, ctx)
@login_required
@user_passes_test(lambda u: u.has_perm("auth.delete_user") or \
u.has_perm("admin.delete_mailbox"))
@transaction.commit_on_success
def delaccount(request):
selection = request.GET["selection"].split(",")
keepdir = True if request.GET.get("keepdir", "false") == "true" else False
for account in User.objects.filter(id__in=selection):
account.delete(request.user, keepdir)
msg = ungettext("Account deleted", "Accounts deleted", len(selection))
messages.info(request, msg, fail_silently=True)
return ajax_response(request)
@login_required
@permission_required("auth.view_permissions")
@@ -654,19 +381,6 @@ def search_account(request):
result = map(lambda u: u.username, users.all())
return ajax_simple_response(result)
@login_required
def delete_permissions(request):
pclass = get_perms_class(request.user, request.GET["role"])
if pclass is None:
ctx = getctx("ko", message=_("Permission denied!"))
else:
selection = request.GET["selection"].split(",")
pobj = pclass()
pobj.delete(selection)
ctx = getctx("ok", content=pobj.get(request),
message=_("Permissions removed"))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
@user_passes_test(lambda u: u.is_superuser)
def viewparameters(request, tplname='admin/parameters.html'):
@@ -688,6 +402,7 @@ def viewparameters(request, tplname='admin/parameters.html'):
gparams += [tmp]
return _render(request, tplname, {
"selection" : "parameters",
"gparams" : gparams
})
@@ -699,7 +414,7 @@ def saveparameters(request):
continue
app, name = pname.split('.')
parameters.save_admin(name, v, app=app)
return ajax_response(request)
return ajax_simple_response(dict(status="ok", message=_("Parameters saved")))
@login_required
@user_passes_test(lambda u: u.is_superuser)
@@ -720,6 +435,7 @@ def viewextensions(request, tplname='admin/extensions.html'):
tbl = ExtensionsTable(request, exts)
return _render(request, tplname, {
"selection" : "extensions",
"extensions" : tbl
})
@@ -741,40 +457,92 @@ def saveextensions(request):
for ext in actived_exts:
if not ext in found:
ext.off()
messages.info(request, _("Modifications applied."), fail_silently=True)
return HttpResponseRedirect(reverse(admin.views.viewextensions))
@login_required
@permission_required("admin.add_mailbox")
@transaction.commit_on_success
def importdata(request, tplname="admin/import.html"):
if request.method == "POST":
error = None
form = ImportDataForm(request.POST, request.FILES)
if form.is_valid():
import csv
return ajax_simple_response(dict(
status="ok", message=_("Modifications applied."), reload=True
))
def import_domain(user, row):
pass
def import_account(user, row):
"""Specific code for accounts import"""
mb = Mailbox()
mb.create_from_csv(user, row)
events.raiseEvent("AccountCreated", user, mb.user)
events.raiseEvent("CreateMailbox", user, mb)
grant_access_to_object(user, mb.user)
grant_access_to_object(user, mb)
def importdata(request, typ):
"""Generic import function
As the process of importing data from a CSV file is the same
whatever the type, we do a maximum of the work here.
:param request: a ``Request`` instance
:param typ: a string indicating the object type being imported
:return: a ``Response`` instance
"""
error = None
form = ImportDataForm(request.POST, request.FILES)
if form.is_valid():
import csv
try:
reader = csv.reader(request.FILES['sourcefile'],
delimiter=form.cleaned_data['sepcar'])
except Exception, e:
error = str(e)
if error is None:
fct = globals()["import_%s" % typ]
try:
cpt = 0
for row in reader:
mb = Mailbox()
mb.create_from_csv(request.user, row)
events.raiseEvent("CreateMailbox", request.user, mb)
fct(request.user, row)
cpt += 1
messages.info(request, _("%d mailboxes imported successfully" % cpt))
messages.info(request, _("%d %s imported successfully" % (cpt, typ)))
return _render(request, "admin/import_done.html", {
"status" : "ok", "msg" : ""
})
except ModoboaException, e:
error = str(e)
return _render(request, "admin/import_done.html", {
"status" : "ko", "msg" : error
})
return _render(request, "admin/import_done.html", {
"status" : "ko", "msg" : error
})
form = ImportDataForm()
ctx = dict(title=_("Import data"), action="", formid="importform",
enctype="multipart/form-data", form=form, submit_label=_("Import"))
return _render(request, tplname, ctx)
@login_required
@transaction.commit_on_success
def import_identities(request):
if request.method == "POST":
return importdata(request, "account")
ctx = dict(
title=_("Import identities"),
submit_label=_("Import"),
action=reverse(import_identities),
formid="importform",
enctype="multipart/form-data",
target="import_target",
form=ImportDataForm()
)
return _render(request, "admin/importform.html", ctx)
@login_required
@transaction.commit_on_success
def import_domains(request):
if request.method == "POST":
return importdata(request, "domain")
ctx = dict(
title=_("Import domains"),
submit_label=_("Import"),
action=reverse(import_domains),
formid="importform",
enctype="multipart/form-data",
target="import_target",
form=ImportDataForm()
)
return _render(request, "admin/importform.html", ctx)
+9 -3
View File
@@ -2,6 +2,12 @@ from django import forms
from django.utils.translation import ugettext as _
class LoginForm(forms.Form):
username = forms.CharField(label=_("Username"))
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput,
help_text=_("Password used to authenticate"))
username = forms.CharField(
label=_("Username"),
widget=forms.TextInput()
)
password = forms.CharField(
label=_("Password"),
widget=forms.PasswordInput(),
help_text=_("Password used to authenticate")
)
+39 -4
View File
@@ -9,10 +9,10 @@ from django.db import IntegrityError
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_noop as _, ugettext
from django.core.urlresolvers import reverse
from modoboa.lib import events, parameters
from modoboa.lib import events
from modoboa.lib.webutils import static_url
from modoboa.admin.models import User
from models import *
from forms import ResourcePoolForm
import permissions
import controls
import views
@@ -20,6 +20,8 @@ import views
baseurl = "limits"
def init():
from modoboa.admin.models import User
ct = ContentType.objects.get(app_label="admin", model="domain")
dagrp = Group.objects.get(name="DomainAdmins")
for pname in ["view_domains", "add_domain", "change_domain", "delete_domain"]:
@@ -59,9 +61,9 @@ def infos():
"url" : baseurl
}
@events.observe('AdminFooterDisplay')
#@events.observe('AdminFooterDisplay')
def display_pool_usage(user, objtype):
if user.id == 1:
if user.is_superuser:
return []
if objtype == "domaliases":
objtype = "domain_aliases"
@@ -89,3 +91,36 @@ def get_da_actions(user):
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:330,y:280}}"},
]
@events.observe("ExtraAccountForm")
def extra_account_form(user, account=None):
if not user.is_superuser and not user.belongs_to_group("Resellers"):
return []
if account:
if not account.belongs_to_group("Resellers") and \
not account.belongs_to_group("DomainAdmins"):
return []
return [
dict(
id="resources", title=_("Resources"), cls=ResourcePoolForm
)
]
@events.observe("CheckExtraAccountForm")
def check_form_access(account, form):
if form["id"] != "resources":
return [True]
if not account.belongs_to_group("Resellers") and \
not account.belongs_to_group("DomainAdmins"):
return [False]
return [True]
@events.observe("FillAccountInstances")
def fill_account_instances(user, account, instances):
if not user.is_superuser and not user.belongs_to_group("Resellers"):
return
if not account.belongs_to_group("Resellers") and \
not account.belongs_to_group("DomainAdmins"):
return
instances["resources"] = account
+75 -33
View File
@@ -4,13 +4,10 @@
----------------------------------------------------------------------------
"""
from modoboa.admin.models import Mailbox
from modoboa.admin.lib import \
get_object_owner, grant_access_to_object, \
ungrant_access_to_object
from modoboa.lib import events
from lib import *
from models import *
from modoboa.lib.permissions import get_object_owner
def check_limit(user, lname):
"""Check if a user has reached a defined limit
@@ -40,6 +37,22 @@ def dec_limit(user, lname):
except LimitsPool.DoesNotExist:
pass
def move_pool_resource(owner, user):
try:
pool = user.limitspool
except LimitsPool.DoesNotExist:
return
if not owner.is_superuser:
for lname in reseller_limits_tpl:
l = user.limitspool.get_limit(lname)
if l.maxvalue < 0:
continue
ol = owner.limitspool.get_limit(lname)
ol.curvalue += l.curvalue
ol.maxvalue += l.maxvalue
ol.save()
user.limitspool.delete()
@events.observe('CreateDomain')
def inc_nb_domains(user, domain):
@@ -61,18 +74,29 @@ def inc_nb_domaliases(user, domalias):
inc_limit(user, 'domain_aliases_limit')
@events.observe('DomainAliasDeleted')
def dec_nb_domaliases(domainalias):
owner = get_object_owner(domainalias)
dec_limit(owner, 'domain_aliases_limit')
def dec_nb_domaliases(domainaliases):
from modoboa.admin.models import DomainAlias
if isinstance(domainaliases, DomainAlias):
domainaliases = [domainaliases]
for domainalias in domainaliases:
owner = get_object_owner(domainalias)
dec_limit(owner, 'domain_aliases_limit')
@events.observe('CreateMailbox')
def inc_nb_mailboxes(user, mailbox):
inc_limit(user, 'mailboxes_limit')
@events.observe('DeleteMailbox')
def dec_nb_mailboxes(mailbox):
owner = get_object_owner(mailbox)
dec_limit(owner, 'mailboxes_limit')
def dec_nb_mailboxes(mailboxes):
from modoboa.admin.models import Mailbox
if isinstance(mailboxes, Mailbox):
mailboxes = [mailboxes]
for mailbox in mailboxes:
owner = get_object_owner(mailbox)
dec_limit(owner, 'mailboxes_limit')
# FIXME: Gestion des alias ici
@events.observe('MailboxAliasCreated')
def inc_nb_mbaliases(user, mailboxalias):
@@ -87,30 +111,48 @@ def dec_nb_mbaliases(mailboxalias):
def can_create_new_object(user, objtype):
check_limit(user, '%s_limit' % objtype)
@events.observe("DomainAdminCreated")
@events.observe("AccountCreated")
def create_pool(user):
owner = get_object_owner(user)
inc_limit(owner, 'domain_admins_limit')
p = LimitsPool(user=user)
p.save()
p.create_limits()
if not owner.is_superuser and \
not owner.belongs_to_group("Resellers"):
return
@events.observe("DomainAdminDeleted", "SuperAdminPromotion")
def move_pool_resource(user):
owner = get_object_owner(user)
if not owner.is_superuser:
if user.belongs_to_group("DomainAdmins"):
check_limit(owner, 'domain_admins_limit')
inc_limit(owner, 'domain_admins_limit')
if user.belongs_to_group("DomainAdmins") or \
user.belongs_to_group("Resellers"):
p = LimitsPool(user=user)
p.save()
p.create_limits()
@events.observe("AccountModified")
def on_account_modified(old, new):
owner = get_object_owner(old)
if owner.group not in ["SuperAdmins", "Resellers"]:
return
if not new.group in ["DomainAdmins", "Resellers"]:
move_pool_resource(owner, new)
if old.oldgroup == "DomainAdmins":
if new.group != "DomainAdmins":
dec_limit(owner, 'domain_admins_limit')
return
if new.group == "DomainAdmins":
check_limit(owner, 'domain_admins_limit')
inc_limit(owner, 'domain_admins_limit')
@events.observe("AccountDeleted")
def on_account_deleted(account):
owner = get_object_owner(account)
if not owner.group in ["SuperAdmins", "Resellers"]:
return
move_pool_resource(owner, account)
if account.group == "DomainAdmins":
dec_limit(owner, 'domain_admins_limit')
for ooentry in user.objectaccess_set.all():
if ooentry.is_owner:
grant_access_to_object(owner, ooentry.content_object, True)
ooentry.delete()
for lname in reseller_limits_tpl:
l = user.limitspool.get_limit(lname)
ol = owner.limitspool.get_limit(lname)
ol.curvalue += l.curvalue
ol.maxvalue += l.maxvalue
ol.save()
user.limitspool.delete()
+16 -27
View File
@@ -3,33 +3,10 @@
from django import forms
from django.utils.translation import ugettext_noop as _
from django.contrib.auth.models import User, Group
from modoboa.admin.forms import UserForm, UserWithPasswordForm
from modoboa.admin.lib import get_object_owner
from models import *
from lib import *
class ResellerForm(UserForm):
def __init__(self, *args, **kwargs):
super(ResellerForm, self).__init__(*args, **kwargs)
del self.fields["createmb"]
def save(self, commit=True, group=None):
user = super(ResellerForm, self).save(commit, group)
if commit:
try:
pool = user.limitspool
except LimitsPool.DoesNotExist:
pool = LimitsPool()
pool.user = user
pool.save()
pool.create_limits()
return user
class ResellerWithPasswordForm(ResellerForm, UserWithPasswordForm):
pass
class ResellerPoolForm(forms.Form):
class ResourcePoolForm(forms.Form):
domain_admins_limit = forms.IntegerField(
ugettext_noop("Max domain admins"),
help_text=ugettext_noop("Maximum number of domain administrators that can be created by this user")
@@ -43,6 +20,16 @@ class ResellerPoolForm(forms.Form):
mailbox_aliases_limit = forms.IntegerField(ugettext_noop("Max mailbox aliases"),
help_text=ugettext_noop("Maximum number of mailbox aliases that can be created by this user"))
def __init__(self, *args, **kwargs):
if kwargs.has_key("instance"):
self.account = kwargs["instance"]
del kwargs["instance"]
super(ResourcePoolForm, self).__init__(*args, **kwargs)
if hasattr(self, "account"):
if not self.account.belongs_to_group("Resellers"):
del self.fields["domain_admins_limit"]
self.load_from_user(self.account)
def check_limit_value(self, lname):
if self.cleaned_data[lname] < -1:
raise forms.ValidationError(_("Invalid limit"))
@@ -84,12 +71,14 @@ class ResellerPoolForm(forms.Form):
ol.maxvalue -= newvalue
ol.save()
def save_new_limits(self, pool):
owner = get_object_owner(pool.user)
def save(self):
from modoboa.lib.permissions import get_object_owner
owner = get_object_owner(self.account)
for lname in reseller_limits_tpl:
if not self.cleaned_data.has_key(lname):
continue
l = pool.limit_set.get(name=lname)
l = self.account.limitspool.limit_set.get(name=lname)
if not owner.is_superuser:
self.allocate_from_pool(l, owner.limitspool)
l.maxvalue = self.cleaned_data[lname]
+5 -48
View File
@@ -1,53 +1,10 @@
# coding: utf-8
from django.utils.translation import ugettext as _, ugettext_noop
from modoboa.admin.permissions import Permissions
from modoboa.admin.lib import grant_access_to_object, ungrant_access_to_object
from modoboa.admin.models import User, ObjectAccess
from modoboa.lib import events
from modoboa.lib.webutils import _render, _render_to_string
from tables import *
from forms import *
class ResellersPerms(Permissions):
title = ugettext_noop("New reseller")
role = "resellers"
add_success_msg = ugettext_noop("Reseller added")
def get_add_form(self, request):
form = ResellerWithPasswordForm()
return self._render_form(request, form)
def add(self, request):
form = ResellerWithPasswordForm(request.POST)
error = None
if form.is_valid():
r = form.save(group="Resellers")
grant_access_to_object(request.user, r, True)
return True, None
content = self._render_form(request, form, True)
return False, dict(status="ko", content=content)
def delete(self, selection):
for u in User.objects.filter(id__in=selection):
ungrant_access_to_object(u)
u.delete()
def get(self, request):
resellers = User.objects.filter(groups__name="Resellers")
return ResellersTable(request, resellers).render()
@events.observe('PermsGetTables')
def get_resellers_table(request):
if not request.user.is_superuser:
return []
return [{"id" : "resellers",
"title" : _("Resellers"),
"rel" : "350 300",
"content" : ResellersPerms().get(request)}]
@events.observe("PermsGetClass")
def get_perms_class(role):
if role != "resellers":
return []
return [ResellersPerms]
@events.observe("GetExtraRoles")
def get_extra_roles(user):
if user.is_superuser:
return [("Resellers", _("Reseller")),]
return []
+46 -10
View File
@@ -21,6 +21,23 @@ def infos():
"url" : "postfix_autoreply"
}
def init():
from modoboa.admin.models import Domain
for dom in Domain.objects.all():
try:
trans = Transport.objects.get(domain="autoreply.%s" % dom.name)
except Transport.DoesNotExist:
onCreateDomain(None, dom)
else:
continue
for mb in dom.mailbox_set.all():
try:
alias = Alias.objects.get(full_address=mb.full_address)
except Alias.DoesNotExist:
onCreateMailbox(None, mb)
def load():
parameters.register_admin(
"AUTOREPLIES_TIMEOUT",
@@ -48,10 +65,9 @@ def menu(target, user):
return [
{"name" : "autoreply",
"url" : reverse(views.autoreply),
"img" : static_url("pics/auto-reply.png"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:440,y:400}}",
"label" : ugettext("Auto-reply message")}
"label" : ugettext("Auto-reply message"),
"modal": True,
"modalcb" : "arform_cb"}
]
@events.observe("CreateDomain")
@@ -75,12 +91,18 @@ def onCreateMailbox(user, mailbox):
alias.save()
@events.observe("DeleteMailbox")
def onDeleteMailbox(mailbox):
try:
alias = Alias.objects.get(full_address=mailbox.full_address)
alias.delete()
except Alias.DoesNotExist:
pass
def onDeleteMailbox(mailboxes):
from modoboa.admin.models import Mailbox
if isinstance(mailboxes, Mailbox):
mailboxes = [mailboxes]
for mailbox in mailboxes:
try:
alias = Alias.objects.get(full_address=mailbox.full_address)
except Alias.DoesNotExist:
pass
else:
alias.delete()
@events.observe("ModifyMailbox")
def onModifyMailbox(mailbox, oldmailbox):
@@ -91,3 +113,17 @@ def onModifyMailbox(mailbox, oldmailbox):
alias.autoreply_address = \
"%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name)
alias.save()
@events.observe("GetStaticContent")
def get_static_content(target):
if target != "userprefs":
return []
return """<script type="text/javascript">
function arform_cb() {
$('#id_untildate').datepicker();
$(".submit").one('click', function(e) {
simple_ajax_form_post(e, arform_cb);
});
}
</script>
"""
+4 -7
View File
@@ -4,18 +4,15 @@ from django.utils.translation import ugettext as _
import datetime
class ARmessageForm(forms.ModelForm):
untildate = forms.DateField(label=_('Until'), required=False,
help_text=_("Activate your auto reply until this date"))
untildate = forms.DateField(
label=_('Until'), required=False,
help_text=_("Activate your auto reply until this date")
)
class Meta:
model = ARmessage
fields = ('subject', 'content', 'enabled')
def __init__(self, *args, **kwargs):
super(ARmessageForm, self).__init__(*args, **kwargs)
self.fields['subject'].widget.attrs['size'] = 40
self.fields['content'].widget.attrs['cols'] = 50
def clean_untildate(self):
if self.cleaned_data["untildate"] is not None:
if self.cleaned_data["untildate"] < datetime.date.today():
@@ -1,42 +1,15 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css"
href="{{ MEDIA_URL }}css/calendar.css" />
<script type="text/javascript" src="{{ MEDIA_URL }}js/calendar.js"></script>
<style type="text/css">
#id_subject {
width: 250px;
}
#id_content {
width: 250px;
}
</style>
<script type="text/javascript">
window.addEvent("domready", function() {
var cal = new Calendar({id_untildate: "Y-m-d"}, {tweak: {x: -100, y:-100}});
var form = new Form();
form.register_error_callback("armform", function() {
new Calendar({id_untildate: "Y-m-d"}, {
tweak: {x: -100, y:-100}
});
});
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{% trans "Auto-reply message" %}</h1></div>
<form action="{% url modoboa.extensions.postfix_autoreply.views.autoreply %}"
method="POST" id="armform" name="armform" class="simple">
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{% trans 'Update' %}" />
</div>
</form>
{% endblock %}
<div class="modal-header">
<a class="close" data-dismiss="modal">x</a>
<h3>{% trans "Auto-reply message" %}</h3>
</div>
<div class="modal-body">
{% if error %}<div class="alert alert-error">{{ error }}</div>{% endif %}
<form class="form-horizontal" action="{% url modoboa.extensions.postfix_autoreply.views.autoreply %}" method="POST">
{% include "common/genericform.html" %}
</form>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-primary submit">{% trans "Update" %}</a>
<a class="btn" data-dismiss="modal">{% trans "Close" %}</a>
</div>
+13 -10
View File
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# coding: utf-8
from django.http import HttpResponse
from django.utils import simplejson
from django.contrib.auth.decorators \
@@ -14,7 +13,13 @@ from models import *
@login_required
@needs_mailbox()
def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
def autoreply(request, tplname="common/generic_modal_form.html"):
ctx = dict(
title=_("Auto-reply message"),
action=reverse(autoreply),
formid="arform",
submit_label=_("Update")
)
mb = Mailbox.objects.get(user=request.user.id)
try:
arm = ARmessage.objects.get(mbox=mb.id)
@@ -33,15 +38,13 @@ def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
arm.untildate = form.cleaned_data["untildate"]
arm.mbox = mb
arm.save()
messages.info(request, _("Auto reply message updated successfully."),
fail_silently=True)
messages.info(request, _("Auto reply message updated successfully."))
return ajax_response(request, url=reverse(userprefs.views.index))
return ajax_response(request, status="ko", template=tplname,
form=form, error=error)
ctx.update(form=form, error=error)
return ajax_response(request, status="ko", template=tplname, **ctx)
form = ARmessageForm(instance=arm)
if arm is not None:
form.fields['untildate'].initial = arm.untildate
return _render(request, tplname, {
"form" : form
})
ctx.update(form=form)
return _render(request, tplname, ctx)
+2 -2
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# coding: utf-8
from django.utils.translation import ugettext_noop as _, ugettext
from django.core.urlresolvers import reverse
from modoboa.lib import events, parameters
@@ -55,7 +55,7 @@ def menu(target, user):
{"name" : "sievefilters",
"label" : ugettext("Message filters"),
"url" : reverse(views.index),
"img" : static_url("pics/filters.png")}
"img" : "icon-check"}
]
@events.observe("Userlogout")
+45 -6
View File
@@ -1,6 +1,10 @@
from django import forms
from django.http import QueryDict
from django.utils.translation import ugettext as _, ugettext_noop
from django.forms.widgets import RadioFieldRenderer, RadioSelect, RadioInput
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.utils.encoding import force_unicode
from modoboa.admin.templatetags.admin_extras import gender
class FiltersSetForm(forms.Form):
@@ -9,17 +13,52 @@ class FiltersSetForm(forms.Form):
initial=False,
help_text=ugettext_noop("Check to activate this filters set"))
class CustomRadioInput(RadioInput):
def __unicode__(self):
return self.render()
def render(self, name=None, value=None, attrs=None, choices=()):
name = name or self.name
value = value or self.value
attrs = attrs or self.attrs
if 'id' in self.attrs:
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
else:
label_for = ''
choice_label = conditional_escape(force_unicode(self.choice_label))
return mark_safe(
u'<label%s class="radio inline">%s %s</label>' \
% (label_for, self.tag(), choice_label)
)
class CustomRadioFieldRenderer(RadioFieldRenderer):
def __iter__(self):
for i, choice in enumerate(self.choices):
yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)
def __getitem__(self, idx):
choice = self.choices[idx]
return CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, idx)
def render(self):
return mark_safe(u'\n'.join([force_unicode(w) for w in self]))
class CustomRadioSelect(RadioSelect):
renderer = CustomRadioFieldRenderer
class FilterForm(forms.Form):
def __init__(self, conditions, actions, request, *args, **kwargs):
super(FilterForm, self).__init__(*args, **kwargs)
self.fields["name"] = forms.CharField(label=_("Name"))
self.fields["match_type"] = forms.ChoiceField(choices=[("allof", _("All of the following")),
("anyof", _("Any of the following")),
("all", _("All messages"))],
initial="anyof",
widget=forms.RadioSelect)
self.fields["match_type"] = forms.ChoiceField(
choices=[("allof", _("All of the following")),
("anyof", _("Any of the following")),
("all", _("All messages"))],
initial="anyof",
widget=CustomRadioSelect(attrs={"class" : "radio inline"})
)
self.header_operators = [("contains", _("contains"), "string"),
("notcontains", _("does not contain"), "string"),
("is", _("is"), "string"),
+5 -1
View File
@@ -42,6 +42,8 @@ class SieveClient(object):
self.msc = None
def refresh(self, user, password):
import ssl
if self.msc is not None:
try:
self.msc.capability()
@@ -51,7 +53,7 @@ class SieveClient(object):
return
try:
ret, msg = self.login(user, password)
except Error, e:
except (Error, ssl.SSLError), e:
raise ConnectionError(e)
if not ret:
raise ConnectionError(msg)
@@ -74,6 +76,8 @@ class SieveClient(object):
return fs
def pushscript(self, name, content, active=False):
if type(content) is unicode:
content = str(content)
if not self.msc.havespace(name, len(content)):
error = "%s (%s)" % (_("Not enough space on server"), self.msc.errmsg)
raise SieveClientError(error)
+1 -51
View File
@@ -1,43 +1,6 @@
#fsets_list {
margin-left: 5px;
float: left;
display: inline;
}
#fset_menu {
position: absolute;
top: 0px;
left: 10px;
}
#set_content {
position: absolute;
left: 10px;
right: 10px;
top: 0px;
bottom: 10px;
padding: 0;
}
#set_content h1 {
padding: 2px 5px;
margin: 0;
font-size: 1.2em;
background: #CEDBEC;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#fsets_bar {
margin-left: 10px;
width: 250px;
}
#set_content textarea {
margin: 0;
width: 100%;
height: 100%;
padding: 2px;
height: 500px;
}
#set_content label {
@@ -54,14 +17,6 @@
bottom: 0px;
}
#feditor {
position: absolute;
left: 190px;
right: 10px;
top: 0px;
bottom: 0px;
}
#id_content {
width: 95% !important;
height: 270px;
@@ -143,11 +98,6 @@ div.item input, div.item select {
margin: 0 2px;
}
#condlist label {
margin: 0 !important;
padding: 0;
}
ul.errors {
list-style: none;
display: inline;
@@ -0,0 +1,328 @@
(function($) {
var DynamicCondition = function(element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.dyncondition.defaults, options);
this.fields_cnt = 1;
this.nextid = 1;
var $addlink = $('<a />', {
href: '#',
id: this.$element.attr("id") + '_rmbtn',
html: '<i class="icon-plus"></i>'
});
$("select[name*=cond_target_]").change($.proxy(this.target_change, this));
$addlink.click($.proxy(this.addfields, this));
this.$element.append($addlink);
for (var cpt = 1; true; cpt++) {
var $div = $("#condition_" + cpt);
if (!$div.length) {
break;
}
$div.append(this.newrmlink());
this.nextid++;
this.fields_cnt++;
}
};
DynamicCondition.prototype = {
constructor: DynamicCondition,
loadoperators: function($container, tpl) {
$container.empty();
for (var ocpt = 0; ocpt < tpl.operators.length; ocpt++) {
var $opt = $("<option />", {
value: tpl["operators"][ocpt][0],
html: tpl["operators"][ocpt][1]
});
$container.append($opt);
}
},
removefields: function(e) {
var $link = $(e.target).parent();
var id = $link.attr("id");
e.preventDefault();
$("#" + id.replace("_rmbtn", "")).remove();
this.fields_cnt--;
},
newrmlink: function() {
return $('<a />', {
href: '#',
id: 'condition_' + this.nextid + '_rmbtn',
html: '<i class="icon-remove"></i>'
}).click($.proxy(this.removefields, this));
},
addfields: function(e) {
e.preventDefault();
var $div = $("<div />", {
id: "condition_" + this.nextid, 'class': "item"
});
var $condtarget = $("<select />", {
id: "id_cond_target_" + this.nextid,
name: "cond_target_" + this.nextid
}).change($.proxy(this.target_change, this));
var $condoperator = $("<select />", {
id: "id_cond_operator_" + this.nextid,
name: "cond_operator_" + this.nextid
});
var $condvalue = $("<input />", {
id: "id_cond_value_" + this.nextid,
name: "cond_value_" + this.nextid,
type: "text"
});
var $rmlink = this.newrmlink();
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
var tpl = this.options.templates[cpt];
var $opt = $("<option />", {
value: tpl.name,
html: tpl.label
});
$condtarget.append($opt);
if (tpl.name != this.options.defaultcond) {
continue;
}
this.loadoperators($condoperator, tpl);
}
$div.append($condtarget, $condoperator, $condvalue, $rmlink);
this.$element.after($div);
this.nextid++;
this.fields_cnt++;
},
target_change: function(e) {
var $target = $(e.target);
var parts = $target.attr("name").split("_");
var $container = $("#id_cond_operator_" + parts[2]);
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
var tpl = this.options.templates[cpt];
if (tpl.name != $target.attr("value")) {
continue;
}
this.loadoperators($container, tpl);
break;
}
},
counter: function() {
return this.fields_cnt;
}
};
$.fn.dyncondition = function(method) {
return this.each(function() {
var $this = $(this),
data = $this.data('dyncondition'),
options = typeof method === "object" && method;
if (!data) {
$this.data('dyncondition', new DynamicCondition(this, options));
}
if (typeof method === "string") {
data[method]();
}
});
};
$.fn.dyncondition.defaults = {
defaultcond: "Subject",
templates: []
};
})(jQuery);
/*
* Dynamic actions class
*/
(function($) {
var DynamicAction = function(element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.dynaction.defaults, options);
this.nextid = 1;
this.fields_cnt = 1;
var $addlink = $('<a />', {
href: '#',
id: this.$element.attr("id") + '_rmbtn',
html: '<i class="icon-plus"></i>'
});
$("select[name*=action_name_]").change($.proxy(this.name_change, this));
$addlink.click($.proxy(this.addfields, this));
this.$element.append($addlink);
for (var cpt = 1; true; cpt++) {
var $div = $("#action_" + cpt);
if (!$div.length) {
break;
}
$div.append(this.newrmlink());
this.nextid++;
this.fields_cnt++;
}
$("#id_action_arg_0_0").find("option").each(function() {
var $this = $(this),
cpt = 1,
start = 0,
value = $this.attr("value");
while (true) {
var id = value.indexOf(".", start);
if (id == -1) {
break;
}
$this.css("margin-left", (cpt * 20) + "px");
cpt++;
start = id + 1;
}
});
this.$fdoptions = $("#id_action_arg_0_0").find("option");
};
DynamicAction.prototype = {
constructor: DynamicAction,
loadargs: function(id, tpl) {
var res = [];
for (var acpt = 0; acpt < tpl.args.length; acpt++) {
var argname = "action_arg_" + id + "_" + acpt;
var $child = null;
if (tpl.args[acpt].type == "list") {
$child = $("<select />", {id: "id_" + argname, name: argname});
if (tpl.args[acpt].vloader != undefined) {
this[tpl.args[acpt].vloader]($child);
}
} else if (tpl.args[acpt].type == "string") {
$child = $("<input />", {
type: "text",
id: "id_" + argname,
name: argname
});
}
res.push($child);
}
return res;
},
deletePrevArgs: function(id) {
for (var cpt = 0; true; cpt++) {
var $arg = $("#id_action_arg_" + id + "_" + cpt);
if (!$arg.length) {
break;
}
$arg.remove();
}
},
name_change: function(e) {
var $target = $(e.target);
var parts = $target.attr("name").split("_");
var $pos = $("#action_" + parts[2] + "_rmbtn");
e.preventDefault();
this.deletePrevArgs(parts[2]);
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
var tpl = this.options.templates[cpt];
if (tpl.name != $target.attr("value")) {
continue;
}
$.each(this.loadargs(parts[2], tpl), function(idx, arg) {
$pos.before(arg);
});
}
},
newrmlink: function() {
return $('<a />', {
href: '#',
id: 'action_' + this.nextid + '_rmbtn',
html: '<i class="icon-remove"></i>'
}).click($.proxy(this.removefields, this));
},
addfields: function(e) {
e.preventDefault();
var $div = $("<div />", {id: "action_" + this.nextid, "class": "item"});
var $actioname = $("<select />", {
id: "id_action_name_" + this.nextid,
name: "action_name_" + this.nextid
});
var $rmlink = this.newrmlink();
var args = null;
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
var tpl = this.options.templates[cpt];
var $opt = $("<option />", {
value: tpl.name,
html: tpl.label
});
$actioname.append($opt);
if (tpl.name != this.options.defaultaction) {
continue;
}
args = this.loadargs(this.nextid, tpl);
}
$div.append($actioname);
$actioname.change($.proxy(this.name_change, this));
$.each(args, function(idx, element) {
$div.append(element);
});
$div.append($rmlink);
this.$element.after($div);
this.nextid++;
this.fields_cnt++;
},
removefields: function(e) {
var $link = $(e.target).parent();
var id = $link.attr("id");
e.preventDefault();
$("#" + id.replace("_rmbtn", "")).remove();
this.fields_cnt--;
},
userfolders: function($container) {
this.$fdoptions.each(function() {
$container.append($(this).clone());
});
}
};
$.fn.dynaction = function(method) {
return this.each(function() {
var $this = $(this),
data = $this.data('dynaction'),
options = typeof method === "object" && method;
if (!data) {
$this.data('dynaction', new DynamicAction(this, options));
}
if (typeof method === "string") {
data[method]();
}
});
};
$.fn.dynaction.defaults = {
defaultaction: "fileinto",
templates: [],
ufolders_url: null
};
})(jQuery);
+142 -85
View File
@@ -10,41 +10,40 @@ var curscript = null;
*
*/
function removefilter(evt) {
evt.stop();
evt.preventDefault();
if (!confirm(gettext("Remove this filter?"))) {
return;
}
new Request.JSON.mdb({
url: this.get("href"),
onSuccess: function(response) {
var $this = $(this);
$.ajax({
url: $this.attr("href"),
dataType: 'json',
success: function(response) {
if (response.status == "ok") {
current_anchor.update(true);
infobox.info(response.respmsg);
infobox.hide(1);
history.update(true);
$("body").notify('success', response.respmsg, 2000);
} else {
infobox.error(response.respmsg);
$("body").notify('error', response.respmsg);
}
}
}).get();
});
}
/*
* Handler listening for the "change" event on the filters sets list.
*/
function changefs(evt) {
evt.stop();
current_anchor.baseurl(this.get("value")).update();
evt.preventDefault();
history.baseurl($(this).attr("value")).update();
}
/*
* Initializes buttons located inside the filters list
*/
function init_filters_list() {
SqueezeBox.assign($("filters_list").getElements('a[class=boxed]'), {
parse: 'rel'
});
$$("a[name=togglestate]").addEvent("click", toggle_filter_state);
$$("a[name*=movefilter_]").addEvent("click", move_filter);
$("a[name=togglestate]").click(toggle_filter_state);
$("a[name*=movefilter_]").click(move_filter);
}
/*
@@ -53,17 +52,21 @@ function init_filters_list() {
* It updates the middle DIV and initializes the user interface.
*/
function loadfs(response) {
curscript = current_anchor.getbaseurl();
$("curfset").set("value", curscript);
$("set_content").set("html", response.content);
parse_menubar("fset_menu");
if ($defined($("filters_list"))) {
curscript = history.getbaseurl();
$("#curfset").attr("value", curscript);
$("#set_content").html(response.content);
if ($("#filters_list") != undefined) {
init_filters_list();
}
$$("a[name=removefilter]").addEvent("click", removefilter);
$$("a[name=activatefs]").addEvent("click", activatefs);
$$("a[name=savefs]").addEvent("click", savefs);
$$("a[name=removefs]").addEvent("click", removefs);
if ($("#fsetmenu").length) {
$("#fsetmenu").remove();
}
$("#menu").after($(response.menu));
$("a[name=removefilter]").click(removefilter);
$("a[name=activatefs]").click(activatefs);
$("a[name=savefs]").click(savefs);
$("a[name=removefs]").click(removefs);
}
/*
@@ -72,25 +75,23 @@ function loadfs(response) {
* (remove, activate)
*/
function send_command(cmd, extracb) {
new Request.JSON.mdb({
$.ajax({
url: cmd,
onSuccess: function(response) {
dataType: 'json',
success: function(response) {
if (response.status == "ko") {
infobox.calcsize(300);
infobox.error(response.respmsg);
$("body").notify('error', response.respmsg);
} else {
if ($defined(extracb)) {
extracb();
if (extracb != undefined) {
extracb(response);
}
if (!response.norefresh) {
current_anchor.update(true);
history.update(true);
}
infobox.calcsize();
infobox.info(response.respmsg);
infobox.hide(2);
$("body").notify('success', response.respmsg, 2000);
}
}
}).get();
});
}
/*
@@ -98,11 +99,11 @@ function send_command(cmd, extracb) {
* validate any new asked action. (activate, save, remove)
*/
function check_prereqs(evt, msg) {
evt.stop();
evt.preventDefault();
if (!curscript) {
return false;
}
if ($defined(msg) && !confirm(msg)) {
if (msg != undefined && !confirm(msg)) {
return false;
}
return true;
@@ -116,21 +117,21 @@ function savefs(evt) {
if (!check_prereqs(evt, gettext("Save changes?"))) {
return;
}
new Request.JSON.mdb({
url: $("feditor").get("action"),
method: $("feditor").get("method"),
data: $("feditor").toQueryString(),
onSuccess: function(response) {
var $editor = $("#feditor");
$.ajax({
url: $editor.attr("action"),
type: $editor.attr("method"),
dataType: 'json',
data: $editor.serialize(),
success: function(response) {
if (response.status == "ko") {
infobox.calcsize(300);
infobox.error(response.respmsg);
$("body").notify('error', response.respmsg);
} else {
infobox.calcsize();
infobox.info(response.respmsg);
infobox.hide(2);
$("body").notify('success', response.respmsg, 2000);
}
}
}).send();
});
}
/*
@@ -143,14 +144,11 @@ function removefs(evt) {
if (!check_prereqs(evt, gettext("Remove filters set?"))) {
return;
}
send_command(this.get("href"), function() {
$("curfset").getElements("option[value=" + curscript + "]").destroy();
if (!$("curfset").getElements("option[value=" + curscript + "]").length) {
current_anchor.reset().update();
location.reload();
} else {
current_anchor.reset();
}
send_command($(this).attr("href"), function(response) {
var $curfset = $("#curfset");
$curfset.find("option[value=" + curscript + "]").remove();
history.baseurl(response.newfs, 1);
});
}
@@ -158,46 +156,105 @@ function removefs(evt) {
* Activate the current filters set.
*/
function activatefs(evt) {
var $this = $(this);
if (!check_prereqs(evt, gettext("Activate this filters set?"))) {
return;
}
send_command(
this.get("href"),
function() {
$("curfset").getElements("option").each(function(item) {
if (item.get("value") == curscript) {
item.set("html", curscript + " (" + gettext("active") + ")");
} else {
item.set("html", item.get("value"));
}
});
}
);
send_command($this.attr("href"), function(response) {
$("#curfset").find("option").each(function(index, element) {
var $element = $(element);
($element.attr("value") == curscript)
? $element.html(curscript + " (" + gettext("active") + ")")
: $element.html($element.attr("value"));
});
});
}
/*
* Enable/Disable a specific filter
*/
function toggle_filter_state(event) {
event.stop();
new Request.JSON.mdb({
url: this.get("href"),
onSuccess: function(response) {
var $this = $(this);
event.preventDefault();
$.ajax({
url: $this.attr("href"),
dataType: 'json',
success: function(response) {
if (response.status == "ok") {
this.set("html", response.label);
this.set("class", "");
this.addClass(response.color);
$this.html(response.label);
$this.attr("class", "");
$this.addClass(response.color);
} else {
infobox.error(respmsg.respmsg);
$("body").notify('error', response.respmsg);
}
}.bind(this)
}).get();
}
});
}
function move_filter(event) {
event.stop();
new Request.JSON.mdb({
url: this.get("href"),
onSuccess: function(response) {
$("filters_list").set("html", response.content);
var $this = $(this);
event.preventDefault();
$.ajax({
url: $this.attr('href'),
dataType: 'json',
success: function(response) {
$("#set_content").html(response.content);
init_filters_list();
}
}).get();
});
}
function filterset_created(data) {
var name = data.url;
var option = $('<option value="' + name + '">' + name + '</option>');
var curfset = $(parent.document).find("#curfset");
curfset.append(option);
curfset.attr("value", name);
if ($("#id_active").checked) {
curfset.find("option").each(function(index, element) {
var $element = $(element);
if ($element.attr("value") == name) {
$element.html(name + " (" + gettext("active") + ")");
} else {
$element.html($element.attr("value"));
}
});
}
history.baseurl(data.url, 1).update(1);
}
function filtersetform_cb() {
$(".submit").one('click', function(e) {
simple_ajax_form_post(e, {
reload_on_success: false,
error_cb: filtersetform_cb,
success_cb: filterset_created
});
});
}
/*
* From here: specific functions used by the user-friendly form to
* create/edit filters.
*/
function fetch_templates(url, container) {
if (container) {
return container;
}
var result;
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function(data) { result = data; }
});
return result;
}
@@ -1,96 +1,23 @@
{% extends "layout_simple.html" %}
{% load i18n sfilters_tags %}
{% block html_head %}
{{ block.super }}
<script type="text/javascript" src="{{ MEDIA_URL }}js/form.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/dynamic_textinput.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/dynamic_fields.js"></script>
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
<script type="text/javascript">
var cond_templates = null;
var action_templates = null;
var da = null;
var dc = null;
function matchtype_cb(event) {
if (this.get("value") == "all") {
$$("#condlist div[class=item]").slide("out");
} else {
$("hide").setStyle("display", "block");
$$("#condlist div[class=item]").slide("in");
}
}
function initform() {
var clist = $$("select[name*=cond_target_]");
var alist = $$("select[name*=action_name_]");
dc = new DynamicCondition(clist, {
templates: cond_templates,
parentContainer: $("condlist")
});
da = new DynamicAction(alist, {
templates: action_templates,
ufolders_url: "{% url modoboa.extensions.sievefilters.views.get_user_folders %}"
});
clist.addEvent("change", dc.onTargetChange.bind(dc));
alist.addEvent("change", da.onNameChange.bind(da));
$$("input[name=match_type]").addEvent("click", matchtype_cb);
}
$(document).addEvent("domready", function() {
var form = new Form();
new Request.JSON({
url: "{% url modoboa.extensions.sievefilters.views.get_templates 'condition' %}",
onSuccess: function(response) {
cond_templates = response;
}
}).get();
new Request.JSON({
url: "{% url modoboa.extensions.sievefilters.views.get_templates 'action' %}",
onSuccess: function(response) {
action_templates = response;
initform();
}
}).get();
form.register_error_callback("filterform", initform);
form.register_extra_data_callback("filterform", function() {
return "conds=" + dc.fields_cnt + "&actions=" + da.fields_cnt;
});
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
<form action="{{ actionurl }}" method="POST" id="filterform" name="filterform">
{% extends "common/generic_modal_form.html" %}
{% load i18n libextras sfilters_tags %}
{% block formbody %}
{% if oldname %}<input type="hidden" name="oldname" value="{{ oldname }}" />{% endif %}
<label for="id_{{ form.name.html_name }}">{% trans form.name.label %}</label>:
{{ form.name }}{% display_errors form.name.errors %}
<h2>{% trans "Conditions" %}</h2>
{% render_field form.name %}
<h6>{% trans "Conditions" %}</h6>
<div id="condlist">
<div id="matchtype">
<label>{% trans "Match type" %}:</label>
{{ form.match_type }}{% display_errors form.match_type.errors %}
<div class="spacer"></div>
{% render_field form.match_type %}
</div>
<div class="spacer"></div>
<div id="hide" style="display:{{ hidestyle }}">
{% for ec in conds_nb %}
{% display_condition form ec %}
{% endfor %}
</div>
</div>
<h2>{% trans "Actions" %}</h2>
<h6>{% trans "Actions" %}</h6>
<div id="actionlist">
{% for ea in actions_nb %}
{% display_action form ea %}
{% endfor %}
</div>
<input type="submit" id="submit" name="submit" value='{% trans "Save" %}' />
</form>
</div>
{% endblock %}
@@ -1,28 +0,0 @@
{% load i18n sfilters_tags %}
<h1>{% trans "Filters" %}</h1>
<p>
{% if fs.filters %}
<table>
<tr>
<th width="10%">{% trans "Actions" %}</th>
<th>{% trans "Name" %}</th>
<th width="5%">{% trans "Active" %}</th>
</tr>
{% for filter in fs.filters %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{% filter_actions fs.name filter forloop.counter forloop.last %}</td>
<td>{{ filter.name }}</td>
<td>
<a name="togglestate"
class={% if filter.enabled %}"green"{% else %}"red"{% endif %}
href="{% url modoboa.extensions.sievefilters.views.toggle_filter_state fs.name filter.name %}">
{{ filter.enabled|yesno }}
</a>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="info">{% trans "No filter defined yet" %}</div>
{% endif %}
</p>
@@ -1,8 +1,25 @@
{% load sfilters_tags i18n %}
<div id="fset_menu" class="leftbox">
<h1>{% trans "Actions" %}</h1>
{% fset_menu "gui" fs.name %}
</div>
<div id="filters_list">
{% include "sievefilters/filters.html" %}
</div>
{% load i18n sfilters_tags %}
{% if fs.filters %}
<table class="table table-striped table-bordered">
<tr>
<th width="10%">{% trans "Actions" %}</th>
<th>{% trans "Name" %}</th>
<th width="5%">{% trans "Active" %}</th>
</tr>
{% for filter in fs.filters %}
<tr>
<td>{% filter_actions fs.name filter forloop.counter forloop.last %}</td>
<td>{{ filter.name }}</td>
<td>
<a name="togglestate"
class={% if filter.enabled %}"green"{% else %}"red"{% endif %}
href="{% url modoboa.extensions.sievefilters.views.toggle_filter_state fs.name filter.name %}">
{{ filter.enabled|yesno }}
</a>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="alert alert-info">{% trans "No filter defined yet" %}</div>
{% endif %}
@@ -1,41 +1,77 @@
{% extends "nlayout.html" %}
{% load i18n libextras sfilters_tags %}
{% extends "twocols.html" %}
{% load i18n sfilters_tags %}
{% block html_head %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/anchor_nav.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/lib.js"></script>
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
<script type="text/javascript" src="{{ MEDIA_URL }}js/history.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/lib.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/dynamic_input.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/jquery.dynfields.js"></script>
<script type="text/javascript">
var current_anchor = new AnchorNavigation("{{ default_script }}", {
var history = new History({
deflocation: "{{ default_script }}",
defcallback: loadfs
});
var cond_templates = null;
var action_templates = null;
$(document).addEvent("domready", function() {
$("curfset").addEvent("change", changefs);
function filterform_cb() {
cond_templates = fetch_templates("{% url modoboa.extensions.sievefilters.views.get_templates 'condition' %}", cond_templates);
action_templates = fetch_templates("{% url modoboa.extensions.sievefilters.views.get_templates 'action' %}", action_templates);
var $dc = $("#condition_0").dyncondition({
templates: cond_templates
}).data('dyncondition');
var $da = $("#action_0").dynaction({
templates: action_templates,
ufolders_url: "{% url modoboa.extensions.sievefilters.views.get_user_folders %}"
}).data('dynaction');
$("input[name=match_type]").click(function(e) {
if ($(this).attr("value") == "all") {
$("div[id*=condition]").hide();
} else {
$("div[id*=condition]").show();
}
});
$(".submit").one('click', function(e) {
var counters = "conds=" + $dc.fields_cnt + "&actions=" + $da.fields_cnt;
simple_ajax_form_post(e, {
error_cb: filterform_cb,
reload_mode: 'history',
extradata: counters
});
});
}
$(document).ready(function() {
$("#curfset").change(changefs);
});
</script>
{% endblock %}
{% block middletitle %}{% trans "Message filters" %}{% endblock %}
{% block menu %}
<div id="fsets_list">
<label>{% trans "Filters sets" %}</label>
<select id="curfset">
{% if active_script %}
<option value="{{ active_script }}">{{ active_script }} ({% trans "active" %})</option>
{% endif %}
{% for script in scripts %}
<option value="{{ script }}">{{ script }}</option>
{% endfor %}
</select>
{% block leftcol %}
<div class="well sidebar-nav">
<ul id="menu" class="nav nav-list">
<li class="nav-header">{% trans "Filter sets" %}</li>
<li>
<select id="curfset" class="span2">
{% if active_script %}
<option value="{{ active_script }}">{{ active_script }} ({% trans "active" %})</option>
{% endif %}
{% for script in scripts %}
<option value="{{ script }}">{{ script }}</option>
{% endfor %}
</select>
</li>
{% sfilters_menu user %}
</ul>
</div>
<ul>{% sfilters_menu user %}</ul>
{% endblock %}
{% block content %}
{% if messages %}
{% display_messages messages %}
{% endif %}
{% block apparea %}
<div id="set_content">
{% if not active_script and not scripts %}
<div class="info">{% trans "No filters set defined yet. You must create one in order to define filters." %}</div>
<div class="alert alert-info">{% trans "No filters set defined yet. You must create one in order to define filters." %}</div>
{% endif %}
</div>
{% endblock %}
@@ -1,41 +0,0 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).addEvent("domready", function() {
var form = new Form();
form.register_success_callback("newfiltersset", function(response) {
var name = response.url;
var option = new Element("option", {value: name, html: name});
var curfset = $(parent.document).getElementById("curfset");
option.inject(curfset);
curfset.set("value", name);
if ($("id_active").checked) {
curfset.getElements("option").each(function(item) {
if (item.get("value") == name) {
item.set("html", name + " (" + gettext("active") + ")");
} else {
item.set("html", item.get("value"));
}
});
}
});
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
{% if error %}<div id="error" class="error">{{ error }}</div>{% endif %}
<form action="{% url modoboa.extensions.sievefilters.views.new_filters_set %}"
method="POST" id="{{ fname }}" name="{{ fname }}">
{% include "common/genericform.html" %}
<div id="submit_container">
<input type="submit" name="submit" value='{{ submit_label }}'/>
</div>
</form>
{% endblock %}
@@ -1,8 +1,3 @@
{% load i18n sfilters_tags %}
<div id="fset_menu" class="leftbox">
<h1>{% trans "Actions" %}</h1>
{% fset_menu "raw" name %}
</div>
<form action="{% url modoboa.extensions.sievefilters.views.savefs name %}"
method="POST" id="feditor" name="feditor">
<textarea id="scriptcontent" name="scriptcontent">{{ scriptcontent }}</textarea>
@@ -2,7 +2,6 @@ from django import template
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from modoboa.extensions.sievefilters import views
from modoboa.lib.webutils import render_actions
register = template.Library()
@@ -13,11 +12,11 @@ from modoboa.lib.webutils import static_url
def sfilters_menu(user):
entries = [
{"name" : "newfilterset",
"img" : static_url("pics/add.png"),
"img" : "icon-plus",
"label" : _("New filters set"),
"url" : reverse(views.new_filters_set),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:300,y:170}}"
"url" : reverse("modoboa.extensions.sievefilters.views.new_filters_set"),
"modal" : True,
"modalcb" : "filtersetform_cb"
}
]
@@ -30,65 +29,74 @@ def fset_menu(mode, setname):
if mode == "gui":
entries += [
{"name" : "newfilter",
"img" : static_url("pics/add.png"),
"img" : "icon-plus",
"label" : _("New filter"),
"url" : reverse(views.newfilter, args=[setname]),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:700,y:400}}"},
"url" : reverse("modoboa.extensions.sievefilters.views.newfilter",
args=[setname]),
"modal" : True,
"autowidth" : True,
"modalcb" : "filterform_cb"}
]
if mode == "raw":
entries += [
{"name" : "savefs",
"img" : static_url("pics/save.png"),
"img" : "icon-download-alt",
"label" : _("Save filters set"),
"url" : reverse(views.savefs, args=[setname])},
"url" : reverse("modoboa.extensions.sievefilters.views.savefs",
args=[setname])},
]
entries += [
{"name" : "activatefs",
"img" : static_url("pics/active.png"),
"img" : "icon-ok",
"label" : _("Activate filters set"),
"url" : reverse(views.activate_filters_set, args=[setname])},
"url" : reverse("modoboa.extensions.sievefilters.views.activate_filters_set",
args=[setname])},
{"name" : "removefs",
"img" : static_url("pics/remove.png"),
"img" : "icon-remove",
"label" : _("Remove filters set"),
"url" : reverse(views.remove_filters_set, args=[setname])},
"url" : reverse("modoboa.extensions.sievefilters.views.remove_filters_set",
args=[setname])},
{"name" : "downloadfs",
"img" : static_url("pics/download.png"),
"img" : "icon-download",
"label" : _("Download"),
"url" : reverse(views.download_filters_set, args=[setname])}
"url" : reverse("modoboa.extensions.sievefilters.views.download_filters_set",
args=[setname])}
]
return render_to_string('common/menu.html',
return render_to_string('common/menulist.html',
{"entries" : entries})
@register.simple_tag
def filter_actions(setname, f, position, islast):
actions = [
{"name" : "editfilter",
"url" : reverse(views.editfilter, args=[setname, f["name"]]),
"img" : static_url("pics/edit.png"),
"url" : reverse("modoboa.extensions.sievefilters.views.editfilter",
args=[setname, f["name"]]),
"img" : "icon-edit",
"title" : _("Edit filter"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:650,y:400}}"},
"modal" : True,
"modalcb" : "filterform_cb"},
{"name" : "removefilter",
"url" : reverse(views.removefilter, args=[setname, f["name"]]),
"img" : static_url("pics/remove.png"),
"url" : reverse("modoboa.extensions.sievefilters.views.removefilter",
args=[setname, f["name"]]),
"img" : "icon-remove",
"title" : _("Remove this filter")}
]
if position != 1:
actions += [
{"name" : "movefilter_up",
"url" : reverse(views.move_filter_up, args=[setname, f["name"]]),
"img" : static_url("pics/moveup.png"),
"url" : reverse("modoboa.extensions.sievefilters.views.move_filter_up",
args=[setname, f["name"]]),
"img" : "icon-arrow-up",
"title" : _("Move this filter up")}
]
if not islast:
actions += [
{"name" : "movefilter_down",
"url" : reverse(views.move_filter_down, args=[setname, f["name"]]),
"img" : static_url("pics/movedown.png"),
"url" : reverse("modoboa.extensions.sievefilters.views.move_filter_down",
args=[setname, f["name"]]),
"img" : "icon-arrow-down",
"title" : _("Move this filter down")},
]
return render_actions(actions)
@@ -114,11 +122,12 @@ def display_condition(form, cnt):
operator = form["cond_operator_%d" % cnt]
value = form["cond_value_%d" % cnt]
t = template.Template("""
<div class="item">
<div id="condition_{{ idx }}" class="item">
{{ tfield }}{{ofield}}{{ vfield }}{{ verrors }}
</div>
""")
return t.render(template.Context({
"idx" : cnt,
"tfield" : target,
"ofield" : operator,
"vfield" : value,
@@ -140,11 +149,12 @@ def display_action(form, cnt):
except KeyError:
break
t = template.Template("""
<div class="item">
<div id="action_{{ idx }}" class="item">
{{ afield }}{% for v in values %}{{ v }}{% endfor %}{{ verrors }}
</div>
""")
return t.render(template.Context({
"idx" : cnt,
"afield" : action, "values" : values,
"verrors" : display_errors(verrors)
}))
+35 -14
View File
@@ -1,6 +1,7 @@
# coding: utf-8
from sievelib.managesieve import Error
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
@@ -12,6 +13,7 @@ from modoboa.lib.connections import ConnectionError
from modoboa.auth.lib import get_password
from lib import *
from forms import *
from templatetags.sfilters_tags import fset_menu
@login_required
@needs_mailbox()
@@ -26,6 +28,7 @@ def index(request, tplname="sievefilters/index.html"):
active_script, scripts = sc.listscripts()
except Error, e:
return _render_error(request, user_context={"error" : e})
if active_script is None:
active_script = ""
default_script = "%s/" % scripts[0] if len(scripts) else ""
@@ -73,10 +76,18 @@ def getfs(request, name):
return ajax_response(request, "ko", respmsg=error)
if editormode == "raw":
return ajax_response(request, template="sievefilters/rawfilter.html",
name=name, scriptcontent=content)
return ajax_response(request, template="sievefilters/guieditor.html",
fs=content)
htmlcontent = render_to_string("sievefilters/rawfilter.html", dict(
name=name, scriptcontent=content
))
else:
htmlcontent = render_to_string("sievefilters/guieditor.html", dict(
fs=content
))
menu = '<ul id="fsetmenu" class="nav nav-list"><li class="nav-header">%s</li>%s</ul>' % \
(_("Actions"), fset_menu(editormode, name))
resp = dict(status="ok", menu=menu, content=htmlcontent)
return ajax_simple_response(resp)
def build_filter_ctx(ctx, form):
ctx["form"] = form
@@ -111,8 +122,11 @@ def submitfilter(request, setname, okmsg, tplname, tplctx, update=False, sc=None
@login_required
@needs_mailbox()
def newfilter(request, setname, tplname="sievefilters/filter.html"):
ctx = {"title" : _("New filter"),
"actionurl" : reverse(newfilter, args=[setname])}
ctx = dict(
title=_("New filter"),
action=reverse(newfilter, args=[setname]),
submit_label=_("Create")
)
if request.method == "POST":
return submitfilter(request, setname, _("Filter created"), tplname, ctx)
@@ -124,9 +138,12 @@ def newfilter(request, setname, tplname="sievefilters/filter.html"):
@login_required
@needs_mailbox()
def editfilter(request, setname, fname, tplname="sievefilters/filter.html"):
ctx = {"title" : _("Edit filter"),
"actionurl" : reverse(editfilter, args=[setname, fname])}
def editfilter(request, setname, fname, tplname="sievefilters/filter2.html"):
ctx = dict(
title=_("Edit filter"),
action=reverse(editfilter, args=[setname, fname]),
submit_label=_("Update")
)
sc = SieveClient(user=request.user.username,
password=request.session["password"])
if request.method == "POST":
@@ -169,10 +186,11 @@ def savefs(request, name):
@login_required
@needs_mailbox()
def new_filters_set(request, tplname="sievefilters/newfiltersset.html"):
def new_filters_set(request, tplname="common/generic_modal_form.html"):
ctx = {"title" : _("Create a new filters set"),
"fname" : "newfiltersset",
"formid" : "newfiltersset",
"submit_label" : _("Create"),
"action" : reverse(new_filters_set),
"withmenu" : False,
"withunseen" : False}
if request.method == "POST":
@@ -206,8 +224,11 @@ def remove_filters_set(request, name):
try:
sc.deletescript(name)
except SieveClientError, e:
return ajax_response(request, "ko", respmsg=str(e))
return ajax_response(request, respmsg=_("Filters set deleted"))
return ajax_simple_response(dict(status="ko", respmsg=str(e)))
acs, scripts = sc.listscripts()
return ajax_simple_response(dict(
status="ok", respmsg=_("Filters set deleted"), newfs=acs
))
@login_required
@needs_mailbox()
@@ -272,7 +293,7 @@ def move_filter(request, setname, fname, direction):
sc.pushscript(setname, str(fset))
except (SieveClientError), e:
return ajax_response(request, "ko", respmsg=str(e))
return ajax_response(request, template="sievefilters/filters.html", fs=fset)
return ajax_response(request, template="sievefilters/guieditor.html", fs=fset)
@login_required
@needs_mailbox()
+1 -1
View File
@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _, ugettext_noop
from django.utils import simplejson
from modoboa.lib.webutils import _render, _render_to_string, getctx
from modoboa.admin.lib import check_domain_access
from modoboa.lib.permissions import check_domain_access
from modoboa.admin.models import Domain, Mailbox
from django.contrib.auth.decorators \
import login_required, user_passes_test, permission_required
+9 -6
View File
@@ -13,8 +13,6 @@ import inspect
import re
events = [
"SuperAdminPromotion",
"CanCreate",
"CreateDomain",
@@ -30,17 +28,22 @@ events = [
"MailboxAliasCreated",
"MailboxAliasDeleted",
"DomainAdminCreated",
"AccountCreated",
"AccountModified",
"AccountDeleted",
"DomainAdminActions",
"DomainAdminDeleted",
"PasswordChange",
"UserMenuDisplay",
"AdminMenuDisplay",
"GetStaticContent",
"ExtraAccountForm",
"CheckExtraAccountForm",
"FillAccountInstances",
"PermsGetTables",
"PermsGetClass",
"GetExtraRoles",
"ExtEnabled",
"ExtDisabled",
+165
View File
@@ -0,0 +1,165 @@
# coding: utf-8
import re
from django.utils.translation import ugettext as _
from django import forms
from django.forms.widgets import MultiWidget, TextInput
from django.forms.fields import MultiValueField
from django.core.exceptions import ValidationError
class CreationWizard(object):
def __init__(self, done_cb):
self.steps = []
self.done_cb = done_cb
def add_step(self, cls, buttons, new_args=None):
self.steps += [dict(cls=cls, buttons=buttons, new_args=new_args)]
def create_forms(self, data=None):
for step in self.steps:
args = []
if step.has_key("new_args") and step["new_args"]:
args += step["new_args"]
if data:
args.append(data)
step["form"] = step["cls"](*args)
def validate_step(self, request):
stepid = request.POST.get("stepid", None)
if stepid is None:
return -1, _("Invalid request")
stepid = stepid.replace("step", "")
stepid = int(stepid) - 1
if stepid < 0 or stepid >= len(self.steps):
return -1, _("Invalid request")
self.create_forms(request.POST)
if self.steps[stepid]["form"].is_valid():
if stepid == len(self.steps) - 1:
self.done_cb(self.steps)
return 2, None
return 1, None
return 0, stepid
class DynamicForm(object):
def _create_field(self, typ, name, value=None, pos=None):
self.fields[name] = typ(label="", required=False)
if value is not None:
self.fields[name].initial = value
if pos:
self.fields.keyOrder.remove(name)
self.fields.keyOrder.insert(pos, name)
def _load_from_qdict(self, qdict, pattern, typ):
expr = re.compile(r'%s_\d+' % pattern)
values = []
for k, v in qdict.iteritems():
if k == pattern or expr.match(k):
values.append((k, v))
ndata = self.data.copy()
values.reverse()
for v in values:
if self.fields.has_key(v[0]):
continue
self._create_field(typ, v[0])
ndata[v[0]] = v[1]
self.data = ndata
class TabForms(object):
"""
Simple forms container
This class tries to encapsulate multiple forms that will be
displayed using tabs. It is different from a classical formset
because it can contain different forms.
"""
def __init__(self, data=None, instances=None, classes=None):
to_remove = []
for fd in self.forms:
args = []
kwargs = {}
if fd.has_key("new_args"):
args += fd["new_args"]
if data:
args.append(data)
if instances:
if hasattr(self, "check_%s" % fd["id"]):
if not getattr(self, "check_%s" % fd["id"])(instances[fd["id"]]):
to_remove += [fd]
continue
kwargs["instance"] = instances[fd["id"]]
if classes and classes.has_key(fd["id"]):
fd["instance"] = classes[fd["id"]](*args, **kwargs)
else:
fd["instance"] = fd["cls"](*args, **kwargs)
map(lambda fd: self.forms.remove(fd), to_remove)
self.active_id = self.forms[0]["id"]
def _before_is_valid(self, form):
return True
def is_valid(self, mandatory_only=False, optional_only=False):
to_remove = []
for f in self.forms:
if mandatory_only and \
(not f.has_key("mandatory") or not f["mandatory"]):
continue
elif optional_only and \
(f.has_key("mandatory") and f["mandatory"]):
continue
if not self._before_is_valid(f):
to_remove.append(f)
continue
if not f["instance"].is_valid():
self.active_id = f["id"]
return False
map(lambda fd: self.forms.remove(fd), to_remove)
return True
def save(self, *args, **kwargs):
raise RuntimeError
def remove_tab(self, tabid):
for f in self.forms:
if f["id"] == tabid:
self.forms.remove(f)
break
def __iter__(self):
return self.forward()
def forward(self):
for form in self.forms:
yield form
#
# Custom fields from here
#
def is_valid_host(host):
"""IDN compatible domain validator
"""
host = host.encode('idna').lower()
if not hasattr(is_valid_host, '_re'):
import re
is_valid_host._re = re.compile(r'^([0-9a-z][-\w]*[0-9a-z]\.)+[a-z0-9\-]{2,15}$')
return bool(is_valid_host._re.match(host))
def validate_domain_name(value):
if not is_valid_host(value):
raise ValidationError(_('Enter a valid domain name'), 'invalid')
class DomainNameField(forms.CharField):
"""
A subclass of CharField that only accepts a valid domain name.
"""
default_error_messages = {
'invalid' : _('Enter a valid domain name')
}
default_validators = [validate_domain_name]
def clean(self, value):
value = self.to_python(value).strip()
return super(DomainNameField, self).clean(value)
+118
View File
@@ -0,0 +1,118 @@
# coding: utf-8
from functools import wraps
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from modoboa.admin.models import ObjectAccess
import events
def get_content_type(obj):
"""Simple function that use the right method to retrieve a content type
:param obj: a django model
:return: a ``ContentType`` object
"""
return obj.get_content_type() if hasattr(obj, "get_content_type") \
else ContentType.objects.get_for_model(obj)
def get_account_roles(user):
"""Return the list of supported account roles
This list can be extended by extensions which listen to the
``GetExtraRoles`` event.
:return: list of strings
"""
std_roles = [("SimpleUsers", _("Simple user"))]
if user.is_superuser:
std_roles += [("SuperAdmins", _("Super administrator"))]
if user.has_perm("admin.add_domain"):
std_roles += [("DomainAdmins", _("Domain administrator"))]
std_roles += events.raiseQueryEvent("GetExtraRoles", user)
return sorted(std_roles, key=lambda role: role[1])
def grant_access_to_object(user, obj, is_owner=False):
"""Grant access to an object for a given user
There are two different cases where we want to grant access to an
object for a specific user:
* He is the owner (he's just created the object)
* He is going to administrate the object (but he is not the owner)
:param user: a ``User`` object
:param obj: an admin. object (Domain, Mailbox, ...)
:param is_owner: the user is the unique object's owner
"""
ct = get_content_type(obj)
try:
entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
entry.is_owner = is_owner
entry.save()
except ObjectAccess.DoesNotExist:
pass
else:
return
try:
objaccess = ObjectAccess(user=user, content_type=ct,
object_id=obj.id, is_owner=is_owner)
objaccess.save()
except IntegrityError, e:
raise AdminError(_("Failed to grant access (%s)" % str(e)))
def ungrant_access_to_object(obj, user=None):
"""Ungrant access to an object for a specific user
If no user is provided, all entries referencing this object are
deleted from the database.
:param obj: an object inheriting from ``models.Model``
:param user: a ``User`` object
"""
ct = get_content_type(obj)
if user:
try:
ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
except ObjectAccess.DoesNotExist:
pass
else:
ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
def get_object_owner(obj):
"""Return the unique owner of this object
:param obj: an object inheriting from ``model.Model``
:return: a ``User`` object
"""
ct = get_content_type(obj)
try:
entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
except ObjectAccess.DoesNotExist:
return None
return entry.user
def check_domain_access(f):
"""Decorator to check if the current user can access a domain
This decorator only applies to url that contain a 'domid' or
'mbid' parameter. (for a direct access)
Raise a ``PermDeniedError`` if the current user can't view the
requested object.
"""
@wraps(f)
def dec(request, **kwargs):
if not request.user.is_superuser:
domain = None
domid = request.GET.get("domid", None)
if domid:
domain = Domain.objects.get(pk=domid)
else:
mbid = request.GET.get("mbid", None)
if mbid:
domain = Mailbox.objects.get(pk=mbid).domain
if domain and not request.user.can_access(domain):
raise PermDeniedError(_("You can't access this domain"))
return f(request, **kwargs)
return dec
+9 -6
View File
@@ -155,13 +155,15 @@ class Table(object):
self.rows += [nrow]
trcpt += 1
def _rows_from_model(self, objects):
def _rows_from_model(self, objects, include_type_in_id=False):
rows = []
for obj in objects:
nrow = {}
try:
idkey = getattr(self, "idkey")
nrow[idkey] = getattr(obj, idkey)
if include_type_in_id:
nrow[idkey] = "%s:%s" % (obj.__class__.__name__, nrow[idkey])
except AttributeError:
pass
for c in self.columns:
@@ -169,10 +171,11 @@ class Table(object):
nrow[c.name] = getattr(obj, c.name)
except AttributeError:
pass
try:
nrow["options"] = getattr(self, "rowoptions")(self.request, obj)
except AttributeError:
pass
for meth in ["options", "class"]:
try:
nrow[meth] = getattr(self, "row_%s" % meth)(self.request, obj)
except AttributeError:
pass
rows += [nrow]
return rows
@@ -188,7 +191,7 @@ class Table(object):
def render(self):
if len(self.rows):
t = Template("""
<table id="{{ tableid }}">
<table id="{{ tableid }}" class="table table-striped table-bordered">
{% include "common/table_head.html" %}
{% include "common/table_body.html" %}
</table>
+60 -43
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# coding: utf-8
import os
from django.conf import settings
from django import template
@@ -44,15 +44,20 @@ def display_messages(msgs):
for m in msgs:
level = m.tags
text += unicode(m) + "\\\n"
if level == "info":
level = "success"
timeout = "2000"
else:
timeout = "undefined"
return """
<script type="text/javascript">
window.addEvent("domready", function() {
infobox.%s("%s");
infobox.hide(2);
});
$(document).ready(function() {
$('body').notify('%s', '%s', %s);
});
</script>
""" % (level, text)
""" % (level, text, timeout)
@register.simple_tag
def load_optionalmenu(user):
@@ -61,41 +66,53 @@ def load_optionalmenu(user):
{"entries" : menu, "user" : user})
@register.simple_tag
def user_menu(user):
entries = [
{"name" : "user",
"img" : static_url('pics/administrators.png'),
"label" : user.fullname,
"class" : "topdropdown",
"menu" : [
{"name" : "changepwd",
"url" : reverse("modoboa.userprefs.views.changepassword"),
"img" : static_url("pics/edit.png"),
"label" : _("Change password"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:360,y:200},closeBtn:true}"},
{"name" : "preferences",
"img" : static_url("pics/user.png"),
"label" : _("Preferences"),
"url" : reverse("modoboa.userprefs.views.preferences")},
{"name" : "logout",
"url" : reverse("modoboa.auth.views.dologout"),
"label" : _("Logout"),
"img" : static_url("pics/logout.png")}
]
}
]
if user.belongs_to_group('SimpleUsers'):
entries[0]["menu"] += [{
"name" : "setforwards",
"url" : reverse("modoboa.userprefs.views.setforward"),
"img" : static_url("pics/alias.png"),
"label" : _("Forward"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:360,y:350},closeBtn:true}"
}]
def render_form(form, tpl=None):
if tpl is not None:
return render_to_string(tpl, dict(form=form))
entries[0]["menu"] += events.raiseQueryEvent("UserMenuDisplay", "options_menu", user)
ret = ""
for field in form:
ret += "%s\n" % render_field(field)
return ret
return render_to_string("common/menulist.html",
{"entries" : entries, "user" : user})
@register.simple_tag
def render_field(field):
return render_to_string("common/generic_field.html", dict(
field=field
))
@register.simple_tag
def render_fields_group(form, pattern):
from django.forms import forms
first = forms.BoundField(form, form.fields[pattern], pattern)
label = first.label
group = [first]
cpt = 1
haserror = len(first.errors) != 0
while True:
fname = "%s_%d" % (pattern, cpt)
if not form.fields.has_key(fname):
break
bfield = forms.BoundField(form, form.fields[fname], fname)
if len(bfield.errors):
haserror = True
group += [bfield]
cpt += 1
return render_to_string("common/generic_fields_group.html", dict(
label=label, group=group, haserror=haserror
))
@register.simple_tag
def pagination_bar(page):
return render_to_string("common/pagination_bar.html", dict(
page=page
))
@register.simple_tag
def alert(msg, typ):
return """<div class="alert alert-%s">
<a class="close" data-dismiss="alert">×</a>
%s
</div>""" % (typ, msg)
+4 -2
View File
@@ -37,9 +37,11 @@ def _render_error(request, errortpl="error", user_context={}):
def render_actions(actions):
t = template.Template("""
{% for a in actions %}
<a href="{{ a.url }}" name="{{ a.name }}" class="{{ a.class }}" rel="{{ a.rel }}"
<a href="{{ a.url }}" name="{{ a.name }}"
{% if a.modal %}data-toggle="ajaxmodal"{% endif %}
{% if a.modalcb %}modalcb="{{ a.modalcb }}"{% endif %}
{% if a.confirm %}onclick="return confirm('{{ a.confirm }}')"{% endif %}>
<img src="{{ a.img }}" border="0" title="{{ a.title }}" /></a>
<i class="{{ a.img }}" title="{{ a.title }}"></i></a>
{% endfor %}
""")
return t.render(template.Context({
-50
View File
@@ -1,50 +0,0 @@
ul.autocompleter-choices
{
position: absolute;
margin: 0;
padding: 0;
list-style: none;
border: 1px solid #7c7c7c;
border-left-color: #c3c3c3;
border-right-color: #c3c3c3;
border-bottom-color: #ddd;
background-color: #fff;
text-align: left;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
z-index: 50;
background-color: #fff;
}
ul.autocompleter-choices li
{
position: relative;
margin: -2px 0 0 0;
padding: 0.2em 1.5em 0.2em 1em;
display: block;
float: none !important;
cursor: pointer;
font-weight: normal;
white-space: nowrap;
font-size: 1em;
line-height: 1.5em;
}
ul.autocompleter-choices li.autocompleter-selected
{
background-color: #444;
color: #fff;
}
ul.autocompleter-choices span.autocompleter-queried
{
display: inline;
float: none;
font-weight: bold;
margin: 0;
padding: 0;
}
ul.autocompleter-choices li.autocompleter-selected span.autocompleter-queried
{
color: #9FCFFF;
}
-141
View File
@@ -1,141 +0,0 @@
/**
* SqueezeBox - Expandable Lightbox
*
* Allows to open various content as modal,
* centered and animated box.
*
* @version 1.1 rc4
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
#sbox-overlay {
position: absolute;
background-color: #000;
left: 0px;
top: 0px;
zoom: 1;
}
#sbox-window {
position: absolute;
background-color: #fff;
text-align: left;
overflow: visible;
padding: 10px;
/* invalid values, but looks smoother! */
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#sbox-btn-close {
position: absolute;
width: 30px;
height: 30px;
right: -15px;
top: -15px;
background: url(closebox.png) no-repeat center;
border: none;
}
.sbox-window-ie6 #sbox-btn-close {
background-image: url(closebox.gif);
}
.sbox-loading #sbox-content {
background-image: url(spinner.gif);
background-repeat: no-repeat;
background-position: center;
}
#sbox-content {
clear: both;
overflow: auto;
background-color: #fff;
height: 100%;
width: 100%;
}
.sbox-content-image#sbox-content {
overflow: visible;
}
#sbox-image {
display: block;
}
.sbox-content-image img {
display: block;
width: 100%;
height: 100%;
}
.sbox-content-iframe#sbox-content {
overflow: visible;
}
/* Hides scrollbars */
.body-overlayed {
overflow: hidden;
}
/* Hides flash (Firefox problem) and selects (IE) */
.body-overlayed embed, .body-overlayed object, .body-overlayed select {
visibility: hidden;
}
#sbox-window embed, #sbox-window object, #sbox-window select {
visibility: visible;
}
/* Shadows */
.sbox-bg {
position: absolute;
width: 33px;
height: 40px;
}
.sbox-bg-n {
left: 0;
top: -40px;
width: 100%;
background: url(bg_n.png) repeat-x;
}
.sbox-bg-ne {
right: -33px;
top: -40px;
background: url(bg_ne.png) no-repeat;
}
.sbox-bg-e {
right: -33px;
top: 0;
height: 100%;
background: url(bg_e.png) repeat-y;
}
.sbox-bg-se {
right: -33px;
bottom: -40px;
background: url(bg_se.png) no-repeat;
}
.sbox-bg-s {
left: 0;
bottom: -40px;
width: 100%;
background: url(bg_s.png) repeat-x;
}
.sbox-bg-sw {
left: -33px;
bottom: -40px;
background: url(bg_sw.png) no-repeat;
}
.sbox-bg-w {
left: -33px;
top: 0;
height: 100%;
background: url(bg_w.png) repeat-y;
}
.sbox-bg-nw {
left: -33px;
top: -40px;
background: url(bg_nw.png) no-repeat;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 B

File diff suppressed because one or more lines are too long
+632
View File
@@ -0,0 +1,632 @@
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
audio:not([controls]){display:none;}
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
a:hover,a:active{outline:0;}
sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
sup{top:-0.5em;}
sub{bottom:-0.25em;}
img{max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;}
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
button,input{*overflow:visible;line-height:normal;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;}
input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
textarea{overflow:auto;vertical-align:top;}
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";}
.clearfix:after{clear:both;}
body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;}
a{color:#0088cc;text-decoration:none;}
a:hover{color:#005580;text-decoration:underline;}
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";}
.row:after{clear:both;}
[class*="span"]{float:left;margin-left:20px;}
.span1{width:60px;}
.span2{width:140px;}
.span3{width:220px;}
.span4{width:300px;}
.span5{width:380px;}
.span6{width:460px;}
.span7{width:540px;}
.span8{width:620px;}
.span9{width:700px;}
.span10{width:780px;}
.span11{width:860px;}
.span12,.container{width:940px;}
.offset1{margin-left:100px;}
.offset2{margin-left:180px;}
.offset3{margin-left:260px;}
.offset4{margin-left:340px;}
.offset5{margin-left:420px;}
.offset6{margin-left:500px;}
.offset7{margin-left:580px;}
.offset8{margin-left:660px;}
.offset9{margin-left:740px;}
.offset10{margin-left:820px;}
.offset11{margin-left:900px;}
.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";}
.row-fluid:after{clear:both;}
.row-fluid>[class*="span"]{float:left;margin-left:2.127659574%;}
.row-fluid>[class*="span"]:first-child{margin-left:0;}
.row-fluid>.span1{width:6.382978723%;}
.row-fluid>.span2{width:14.89361702%;}
.row-fluid>.span3{width:23.404255317%;}
.row-fluid>.span4{width:31.914893614%;}
.row-fluid>.span5{width:40.425531911%;}
.row-fluid>.span6{width:48.93617020799999%;}
.row-fluid>.span7{width:57.446808505%;}
.row-fluid>.span8{width:65.95744680199999%;}
.row-fluid>.span9{width:74.468085099%;}
.row-fluid>.span10{width:82.97872339599999%;}
.row-fluid>.span11{width:91.489361693%;}
.row-fluid>.span12{width:99.99999998999999%;}
.container{width:940px;margin-left:auto;margin-right:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";}
.container:after{clear:both;}
.container-fluid{padding-left:20px;padding-right:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";}
.container-fluid:after{clear:both;}
p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;}
.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;}
h1,h2,h3,h4,h5,h6{margin:0;font-weight:bold;color:#333333;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;}
h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;}
h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;}
h3{line-height:27px;font-size:18px;}h3 small{font-size:14px;}
h4,h5,h6{line-height:18px;}
h4{font-size:14px;}h4 small{font-size:12px;}
h5{font-size:12px;}
h6{font-size:11px;color:#999999;text-transform:uppercase;}
.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;}
.page-header h1{line-height:1;}
ul,ol{padding:0;margin:0 0 9px 25px;}
ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
ul{list-style:disc;}
ol{list-style:decimal;}
li{line-height:18px;}
ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
dl{margin-bottom:18px;}
dt,dd{line-height:18px;}
dt{font-weight:bold;}
dd{margin-left:9px;}
hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
strong{font-weight:bold;}
em{font-style:italic;}
.muted{color:#999999;}
abbr{font-size:90%;text-transform:uppercase;border-bottom:1px dotted #ddd;cursor:help;}
blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;}
blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
blockquote.pull-right{float:right;padding-left:0;padding-right:15px;border-left:0;border-right:5px solid #eeeeee;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
q:before,q:after,blockquote:before,blockquote:after{content:"";}
address{display:block;margin-bottom:18px;line-height:18px;font-style:normal;}
small{font-size:100%;}
cite{font-style:normal;}
code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
code{padding:3px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;}
pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;}pre.prettyprint{margin-bottom:18px;}
pre code{padding:0;color:inherit;background-color:transparent;border:0;}
.pre-scrollable{max-height:340px;overflow-y:scroll;}
form{margin:0 0 18px;}
fieldset{padding:0;margin:0;border:0;}
legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #eee;}legend small{font-size:13.5px;color:#999999;}
label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px;}
input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;}
label{display:block;margin-bottom:5px;color:#333333;}
input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.uneditable-textarea{width:auto;height:auto;}
label input,label textarea,label select{display:block;}
input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border:0 \9;}
input[type="image"]{border:0;}
input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:#ffffff;background-color:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;}
select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;}
input[type="file"]{line-height:18px \9;}
select{width:220px;background-color:#ffffff;}
select[multiple],select[size]{height:auto;}
input[type="image"]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
textarea{height:auto;}
input[type="hidden"]{display:none;}
.radio,.checkbox{padding-left:18px;}
.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;}
.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}
.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}
.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}
input,textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;}
input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);outline:0;outline:thin dotted \9;}
input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
.input-mini{width:60px;}
.input-small{width:90px;}
.input-medium{width:150px;}
.input-large{width:210px;}
.input-xlarge{width:270px;}
.input-xxlarge{width:530px;}
input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{float:none;margin-left:0;}
input.span1,textarea.span1,.uneditable-input.span1{width:50px;}
input.span2,textarea.span2,.uneditable-input.span2{width:130px;}
input.span3,textarea.span3,.uneditable-input.span3{width:210px;}
input.span4,textarea.span4,.uneditable-input.span4{width:290px;}
input.span5,textarea.span5,.uneditable-input.span5{width:370px;}
input.span6,textarea.span6,.uneditable-input.span6{width:450px;}
input.span7,textarea.span7,.uneditable-input.span7{width:530px;}
input.span8,textarea.span8,.uneditable-input.span8{width:610px;}
input.span9,textarea.span9,.uneditable-input.span9{width:690px;}
input.span10,textarea.span10,.uneditable-input.span10{width:770px;}
input.span11,textarea.span11,.uneditable-input.span11{width:850px;}
input.span12,textarea.span12,.uneditable-input.span12{width:930px;}
input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#f5f5f5;border-color:#ddd;cursor:not-allowed;}
.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;}
.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;}
.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;}
.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #ddd;}
.uneditable-input{display:block;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
:-moz-placeholder{color:#999999;}
::-webkit-input-placeholder{color:#999999;}
.help-block{display:block;margin-top:5px;margin-bottom:0;color:#999999;}
.help-inline{display:inline-block;*display:inline;*zoom:1;margin-bottom:9px;vertical-align:middle;padding-left:5px;}
.input-prepend,.input-append{margin-bottom:5px;*zoom:1;}.input-prepend:before,.input-append:before,.input-prepend:after,.input-append:after{display:table;content:"";}
.input-prepend:after,.input-append:after{clear:both;}
.input-prepend input,.input-append input,.input-prepend .uneditable-input,.input-append .uneditable-input{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{position:relative;z-index:2;}
.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;}
.input-prepend .add-on,.input-append .add-on{float:left;display:block;width:auto;min-width:16px;height:18px;margin-right:-1px;padding:4px 5px;font-weight:normal;line-height:18px;color:#999999;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#f5f5f5;border:1px solid #ccc;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;}
.input-prepend .add-on{*margin-top:1px;}
.input-append input,.input-append .uneditable-input{float:left;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
.input-append .uneditable-input{border-left-color:#eee;border-right-color:#ccc;}
.input-append .add-on{margin-right:0;margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}
.input-append input:first-child{*margin-left:-160px;}.input-append input:first-child+.add-on{*margin-left:-21px;}
.search-query{padding-left:14px;padding-right:14px;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;}
.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input{display:inline-block;margin-bottom:0;}
.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}
.form-search label,.form-inline label,.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{display:inline-block;}
.form-search .input-append .add-on,.form-inline .input-prepend .add-on,.form-search .input-append .add-on,.form-inline .input-prepend .add-on{vertical-align:middle;}
.form-search .radio,.form-inline .radio,.form-search .checkbox,.form-inline .checkbox{margin-bottom:0;vertical-align:middle;}
.control-group{margin-bottom:9px;}
legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;}
.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";}
.form-horizontal .control-group:after{clear:both;}
.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right;}
.form-horizontal .controls{margin-left:160px;}
.form-horizontal .form-actions{padding-left:160px;}
table{max-width:100%;border-collapse:collapse;border-spacing:0;}
.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #ddd;}
.table th{font-weight:bold;}
.table thead th{vertical-align:bottom;}
.table thead:first-child tr th,.table thead:first-child tr td{border-top:0;}
.table tbody+tbody{border-top:2px solid #ddd;}
.table-condensed th,.table-condensed td{padding:4px 5px;}
.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapsed;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th+th,.table-bordered td+td,.table-bordered th+td,.table-bordered td+th{border-left:1px solid #ddd;}
.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;}
.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;}
.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;}
.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;}
.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}
.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;}
table .span1{float:none;width:44px;margin-left:0;}
table .span2{float:none;width:124px;margin-left:0;}
table .span3{float:none;width:204px;margin-left:0;}
table .span4{float:none;width:284px;margin-left:0;}
table .span5{float:none;width:364px;margin-left:0;}
table .span6{float:none;width:444px;margin-left:0;}
table .span7{float:none;width:524px;margin-left:0;}
table .span8{float:none;width:604px;margin-left:0;}
table .span9{float:none;width:684px;margin-left:0;}
table .span10{float:none;width:764px;margin-left:0;}
table .span11{float:none;width:844px;margin-left:0;}
table .span12{float:none;width:924px;margin-left:0;}
[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;*margin-right:.3em;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;}
.icon-white{background-image:url("../img/glyphicons-halflings-white.png");}
.icon-glass{background-position:0 0;}
.icon-music{background-position:-24px 0;}
.icon-search{background-position:-48px 0;}
.icon-envelope{background-position:-72px 0;}
.icon-heart{background-position:-96px 0;}
.icon-star{background-position:-120px 0;}
.icon-star-empty{background-position:-144px 0;}
.icon-user{background-position:-168px 0;}
.icon-film{background-position:-192px 0;}
.icon-th-large{background-position:-216px 0;}
.icon-th{background-position:-240px 0;}
.icon-th-list{background-position:-264px 0;}
.icon-ok{background-position:-288px 0;}
.icon-remove{background-position:-312px 0;}
.icon-zoom-in{background-position:-336px 0;}
.icon-zoom-out{background-position:-360px 0;}
.icon-off{background-position:-384px 0;}
.icon-signal{background-position:-408px 0;}
.icon-cog{background-position:-432px 0;}
.icon-trash{background-position:-456px 0;}
.icon-home{background-position:0 -24px;}
.icon-file{background-position:-24px -24px;}
.icon-time{background-position:-48px -24px;}
.icon-road{background-position:-72px -24px;}
.icon-download-alt{background-position:-96px -24px;}
.icon-download{background-position:-120px -24px;}
.icon-upload{background-position:-144px -24px;}
.icon-inbox{background-position:-168px -24px;}
.icon-play-circle{background-position:-192px -24px;}
.icon-repeat{background-position:-216px -24px;}
.icon-refresh{background-position:-240px -24px;}
.icon-list-alt{background-position:-264px -24px;}
.icon-lock{background-position:-287px -24px;}
.icon-flag{background-position:-312px -24px;}
.icon-headphones{background-position:-336px -24px;}
.icon-volume-off{background-position:-360px -24px;}
.icon-volume-down{background-position:-384px -24px;}
.icon-volume-up{background-position:-408px -24px;}
.icon-qrcode{background-position:-432px -24px;}
.icon-barcode{background-position:-456px -24px;}
.icon-tag{background-position:0 -48px;}
.icon-tags{background-position:-25px -48px;}
.icon-book{background-position:-48px -48px;}
.icon-bookmark{background-position:-72px -48px;}
.icon-print{background-position:-96px -48px;}
.icon-camera{background-position:-120px -48px;}
.icon-font{background-position:-144px -48px;}
.icon-bold{background-position:-167px -48px;}
.icon-italic{background-position:-192px -48px;}
.icon-text-height{background-position:-216px -48px;}
.icon-text-width{background-position:-240px -48px;}
.icon-align-left{background-position:-264px -48px;}
.icon-align-center{background-position:-288px -48px;}
.icon-align-right{background-position:-312px -48px;}
.icon-align-justify{background-position:-336px -48px;}
.icon-list{background-position:-360px -48px;}
.icon-indent-left{background-position:-384px -48px;}
.icon-indent-right{background-position:-408px -48px;}
.icon-facetime-video{background-position:-432px -48px;}
.icon-picture{background-position:-456px -48px;}
.icon-pencil{background-position:0 -72px;}
.icon-map-marker{background-position:-24px -72px;}
.icon-adjust{background-position:-48px -72px;}
.icon-tint{background-position:-72px -72px;}
.icon-edit{background-position:-96px -72px;}
.icon-share{background-position:-120px -72px;}
.icon-check{background-position:-144px -72px;}
.icon-move{background-position:-168px -72px;}
.icon-step-backward{background-position:-192px -72px;}
.icon-fast-backward{background-position:-216px -72px;}
.icon-backward{background-position:-240px -72px;}
.icon-play{background-position:-264px -72px;}
.icon-pause{background-position:-288px -72px;}
.icon-stop{background-position:-312px -72px;}
.icon-forward{background-position:-336px -72px;}
.icon-fast-forward{background-position:-360px -72px;}
.icon-step-forward{background-position:-384px -72px;}
.icon-eject{background-position:-408px -72px;}
.icon-chevron-left{background-position:-432px -72px;}
.icon-chevron-right{background-position:-456px -72px;}
.icon-plus-sign{background-position:0 -96px;}
.icon-minus-sign{background-position:-24px -96px;}
.icon-remove-sign{background-position:-48px -96px;}
.icon-ok-sign{background-position:-72px -96px;}
.icon-question-sign{background-position:-96px -96px;}
.icon-info-sign{background-position:-120px -96px;}
.icon-screenshot{background-position:-144px -96px;}
.icon-remove-circle{background-position:-168px -96px;}
.icon-ok-circle{background-position:-192px -96px;}
.icon-ban-circle{background-position:-216px -96px;}
.icon-arrow-left{background-position:-240px -96px;}
.icon-arrow-right{background-position:-264px -96px;}
.icon-arrow-up{background-position:-289px -96px;}
.icon-arrow-down{background-position:-312px -96px;}
.icon-share-alt{background-position:-336px -96px;}
.icon-resize-full{background-position:-360px -96px;}
.icon-resize-small{background-position:-384px -96px;}
.icon-plus{background-position:-408px -96px;}
.icon-minus{background-position:-433px -96px;}
.icon-asterisk{background-position:-456px -96px;}
.icon-exclamation-sign{background-position:0 -120px;}
.icon-gift{background-position:-24px -120px;}
.icon-leaf{background-position:-48px -120px;}
.icon-fire{background-position:-72px -120px;}
.icon-eye-open{background-position:-96px -120px;}
.icon-eye-close{background-position:-120px -120px;}
.icon-warning-sign{background-position:-144px -120px;}
.icon-plane{background-position:-168px -120px;}
.icon-calendar{background-position:-192px -120px;}
.icon-random{background-position:-216px -120px;}
.icon-comment{background-position:-240px -120px;}
.icon-magnet{background-position:-264px -120px;}
.icon-chevron-up{background-position:-288px -120px;}
.icon-chevron-down{background-position:-313px -119px;}
.icon-retweet{background-position:-336px -120px;}
.icon-shopping-cart{background-position:-360px -120px;}
.icon-folder-close{background-position:-384px -120px;}
.icon-folder-open{background-position:-408px -120px;}
.icon-resize-vertical{background-position:-432px -119px;}
.icon-resize-horizontal{background-position:-456px -118px;}
.dropdown{position:relative;}
.dropdown-toggle{*margin-bottom:-3px;}
.dropdown-toggle:active,.open .dropdown-toggle{outline:0;}
.caret{display:inline-block;width:0;height:0;text-indent:-99999px;*text-indent:0;vertical-align:top;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000000;opacity:0.3;filter:alpha(opacity=30);content:"\2193";}
.dropdown .caret{margin-top:8px;margin-left:2px;}
.dropdown:hover .caret,.open.dropdown .caret{opacity:1;filter:alpha(opacity=100);}
.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;_width:160px;padding:4px 0;margin:0;list-style:none;background-color:#ffffff;border-color:#ccc;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:1px;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;}.dropdown-menu.bottom-up{top:auto;bottom:100%;margin-bottom:2px;}
.dropdown-menu .divider{height:1px;margin:5px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;}
.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#555555;white-space:nowrap;}
.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;}
.dropdown.open{*z-index:1000;}.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);}
.dropdown.open .dropdown-menu{display:block;}
.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;}
.collapse{-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;position:relative;overflow:hidden;height:0;}.collapse.in{height:auto;}
.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;opacity:0.4;filter:alpha(opacity=40);cursor:pointer;}
.btn{display:inline-block;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(top, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);cursor:pointer;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);*margin-left:.3em;}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;}
.btn:active,.btn.active{background-color:#cccccc \9;}
.btn:first-child{*margin-left:0;}
.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}
.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;outline:0;}
.btn.disabled,.btn[disabled]{cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
.btn-large [class^="icon-"]{margin-top:1px;}
.btn-small{padding:5px 9px;font-size:11px;line-height:16px;}
.btn-small [class^="icon-"]{margin-top:-1px;}
.btn-mini{padding:2px 6px;font-size:11px;line-height:14px;}
.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);color:#ffffff;}
.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-dark.active{color:rgba(255, 255, 255, 0.75);}
.btn-primary{background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-ms-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(top, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0044cc;}
.btn-primary:active,.btn-primary.active{background-color:#003399 \9;}
.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;}
.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;}
.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;}
.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;}
.btn-success:active,.btn-success.active{background-color:#408140 \9;}
.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;}
.btn-info:active,.btn-info.active{background-color:#24748c \9;}
.btn-inverse{background-color:#393939;background-image:-moz-linear-gradient(top, #454545, #262626);background-image:-ms-linear-gradient(top, #454545, #262626);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#454545), to(#262626));background-image:-webkit-linear-gradient(top, #454545, #262626);background-image:-o-linear-gradient(top, #454545, #262626);background-image:linear-gradient(top, #454545, #262626);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545', endColorstr='#262626', GradientType=0);border-color:#262626 #262626 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#262626;}
.btn-inverse:active,.btn-inverse.active{background-color:#0c0c0c \9;}
button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;}
button.btn.large,input[type="submit"].btn.large{*padding-top:7px;*padding-bottom:7px;}
button.btn.small,input[type="submit"].btn.small{*padding-top:3px;*padding-bottom:3px;}
.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";}
.btn-group:after{clear:both;}
.btn-group:first-child{*margin-left:0;}
.btn-group+.btn-group{margin-left:5px;}
.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;}
.btn-group .btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.btn-group .btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
.btn-group .btn:last-child,.btn-group .dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
.btn-group .btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active{z-index:2;}
.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}
.btn-group .dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:5px;*padding-bottom:5px;}
.btn-group.open{*z-index:1000;}.btn-group.open .dropdown-menu{display:block;margin-top:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);}
.btn .caret{margin-top:7px;margin-left:0;}
.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);}
.btn-primary .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);}
.btn-small .caret{margin-top:4px;}
.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.alert,.alert-heading{color:#c09853;}
.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;}
.alert-success{background-color:#dff0d8;border-color:#d6e9c6;}
.alert-success,.alert-success .alert-heading{color:#468847;}
.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;}
.alert-danger,.alert-error,.alert-danger .alert-heading,.alert-error .alert-heading{color:#b94a48;}
.alert-info{background-color:#d9edf7;border-color:#bce8f1;}
.alert-info,.alert-info .alert-heading{color:#3a87ad;}
.alert-block{padding-top:14px;padding-bottom:14px;}
.alert-block>p,.alert-block>ul{margin-bottom:0;}
.alert-block p+p{margin-top:5px;}
.nav{margin-left:0;margin-bottom:18px;list-style:none;}
.nav>li>a{display:block;}
.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;}
.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;}
.nav li+.nav-header{margin-top:9px;}
.nav-list{padding-left:14px;padding-right:14px;margin-bottom:0;}
.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}
.nav-list>li>a{padding:3px 15px;}
.nav-list .active>a,.nav-list .active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;}
.nav-list [class^="icon-"]{margin-right:2px;}
.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";}
.nav-tabs:after,.nav-pills:after{clear:both;}
.nav-tabs>li,.nav-pills>li{float:left;}
.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;}
.nav-tabs{border-bottom:1px solid #ddd;}
.nav-tabs>li{margin-bottom:-1px;}
.nav-tabs>li>a{padding-top:9px;padding-bottom:9px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;}
.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}
.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
.nav-pills .active>a,.nav-pills .active>a:hover{color:#ffffff;background-color:#0088cc;}
.nav-stacked>li{float:none;}
.nav-stacked>li>a{margin-right:0;}
.nav-tabs.nav-stacked{border-bottom:0;}
.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}
.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}
.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;}
.nav-pills.nav-stacked>li>a{margin-bottom:3px;}
.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;}
.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu{margin-top:1px;border-width:1px;}
.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;margin-top:6px;}
.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;}
.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;}
.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;}
.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;}
.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret{border-top-color:#ffffff;opacity:1;filter:alpha(opacity=100);}
.tabs-stacked .open>a:hover{border-color:#999999;}
.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";}
.tabbable:after{clear:both;}
.tab-content{overflow:hidden;}
.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0;}
.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;}
.tab-content>.active,.pill-content>.active{display:block;}
.tabs-below .nav-tabs{border-top:1px solid #ddd;}
.tabs-below .nav-tabs>li{margin-top:-1px;margin-bottom:0;}
.tabs-below .nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below .nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;}
.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover{border-color:transparent #ddd #ddd #ddd;}
.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li{float:none;}
.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;}
.tabs-left .nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;}
.tabs-left .nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
.tabs-left .nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;}
.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;}
.tabs-right .nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;}
.tabs-right .nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.tabs-right .nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;}
.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;}
.navbar{overflow:visible;margin-bottom:18px;}
.navbar-inner{padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);}
.btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);}.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled]{background-color:#222222;}
.btn-navbar:active,.btn-navbar.active{background-color:#080808 \9;}
.btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);}
.btn-navbar .icon-bar+.icon-bar{margin-top:3px;}
.nav-collapse.collapse{height:auto;}
.navbar .brand:hover{text-decoration:none;}
.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#ffffff;}
.navbar .navbar-text{margin-bottom:0;line-height:40px;color:#999999;}.navbar .navbar-text a:hover{color:#ffffff;background-color:transparent;}
.navbar .btn,.navbar .btn-group{margin-top:5px;}
.navbar .btn-group .btn{margin-top:0;}
.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";}
.navbar-form:after{clear:both;}
.navbar-form input,.navbar-form select{display:inline-block;margin-top:5px;margin-bottom:0;}
.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;}
.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;}
.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;}
.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;color:rgba(255, 255, 255, 0.75);background:#666;background:rgba(255, 255, 255, 0.3);border:1px solid #111;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query :-moz-placeholder{color:#eeeeee;}
.navbar-search .search-query::-webkit-input-placeholder{color:#eeeeee;}
.navbar-search .search-query:hover{color:#ffffff;background-color:#999999;background-color:rgba(255, 255, 255, 0.5);}
.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}
.navbar-fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030;}
.navbar-fixed-top .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;}
.navbar .nav.pull-right{float:right;}
.navbar .nav>li{display:block;float:left;}
.navbar .nav>li>a{float:none;padding:10px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}
.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;}
.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;}
.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;}
.navbar .nav.pull-right{margin-left:10px;margin-right:0;}
.navbar .dropdown-menu{margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;}
.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;}
.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret{border-top-color:#ffffff;}
.navbar .nav .active .caret{opacity:1;filter:alpha(opacity=100);}
.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle{background-color:transparent;}
.navbar .nav .active>.dropdown-toggle:hover{color:#ffffff;}
.navbar .nav.pull-right .dropdown-menu{left:auto;right:0;}.navbar .nav.pull-right .dropdown-menu:before{left:auto;right:12px;}
.navbar .nav.pull-right .dropdown-menu:after{left:auto;right:13px;}
.breadcrumb{padding:7px 14px;margin:0 0 18px;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline-block;text-shadow:0 1px 0 #ffffff;}
.breadcrumb .divider{padding:0 5px;color:#999999;}
.breadcrumb .active a{color:#333333;}
.pagination{height:36px;margin:18px 0;}
.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}
.pagination li{display:inline;}
.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;}
.pagination a:hover,.pagination .active a{background-color:#f5f5f5;}
.pagination .active a{color:#999999;cursor:default;}
.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;}
.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}
.pagination-centered{text-align:center;}
.pagination-right{text-align:right;}
.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";}
.pager:after{clear:both;}
.pager li{display:inline;}
.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
.pager a:hover{text-decoration:none;background-color:#f5f5f5;}
.pager .next a{float:right;}
.pager .previous a{float:left;}
.modal-open .dropdown-menu{z-index:2050;}
.modal-open .dropdown.open{*z-index:2050;}
.modal-open .popover{z-index:2060;}
.modal-open .tooltip{z-index:2070;}
.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;}
.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);}
.modal{position:fixed;top:50%;left:50%;z-index:1050;max-height:500px;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}
.modal.fade.in{top:50%;}
.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;}
.modal-body{padding:15px;}
.modal-body .modal-form{margin-bottom:0;}
.modal-footer{padding:14px 15px 15px;margin-bottom:0;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";}
.modal-footer:after{clear:both;}
.modal-footer .btn{float:right;margin-left:5px;margin-bottom:0;}
.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);}
.tooltip.top{margin-top:-2px;}
.tooltip.right{margin-left:2px;}
.tooltip.bottom{margin-top:2px;}
.tooltip.left{margin-left:-2px;}
.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.tooltip-arrow{position:absolute;width:0;height:0;}
.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;}
.popover.right{margin-left:5px;}
.popover.bottom{margin-top:5px;}
.popover.left{margin-left:-5px;}
.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
.popover .arrow{position:absolute;width:0;height:0;}
.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);}
.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;}
.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;}
.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";}
.thumbnails:after{clear:both;}
.thumbnails>li{float:left;margin:0 0 18px 20px;}
.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);}
a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}
.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;}
.thumbnail .caption{padding:9px;}
.label{padding:2px 4px 3px;font-size:11.049999999999999px;font-weight:bold;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.label:hover{color:#ffffff;text-decoration:none;}
.label-important{background-color:#b94a48;}
.label-important:hover{background-color:#953b39;}
.label-warning{background-color:#f89406;}
.label-warning:hover{background-color:#c67605;}
.label-success{background-color:#468847;}
.label-success:hover{background-color:#356635;}
.label-info{background-color:#3a87ad;}
.label-info:hover{background-color:#2d6987;}
@-webkit-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;}
.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;}
.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}
.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);}
.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);}
.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);}
.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.accordion{margin-bottom:18px;}
.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.accordion-heading{border-bottom:0;}
.accordion-heading .accordion-toggle{display:block;padding:8px 15px;}
.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;}
.carousel{position:relative;margin-bottom:18px;line-height:1;}
.carousel-inner{overflow:hidden;width:100%;position:relative;}
.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;}
.carousel .item>img{display:block;line-height:1;}
.carousel .active,.carousel .next,.carousel .prev{display:block;}
.carousel .active{left:0;}
.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;}
.carousel .next{left:100%;}
.carousel .prev{left:-100%;}
.carousel .next.left,.carousel .prev.right{left:0;}
.carousel .active.left{left:-100%;}
.carousel .active.right{left:100%;}
.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;}
.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);}
.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);}
.carousel-caption h4,.carousel-caption p{color:#ffffff;}
.hero-unit{padding:60px;margin-bottom:30px;background-color:#f5f5f5;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;}
.hero-unit p{font-size:18px;font-weight:200;line-height:27px;}
.pull-right{float:right;}
.pull-left{float:left;}
.hide{display:none;}
.show{display:block;}
.invisible{visibility:hidden;}
-207
View File
@@ -1,207 +0,0 @@
body {
font-family: arial, helvetica, verdana, tahoma, sans-serif;
font-size: 0.9em;
margin: 0 auto;
padding: 0;
}
div.row {
clear: both;
padding-top: 10px;
padding-left: 20px;
}
div.row label {
float: left;
width: 120px;
padding: 3px 0;
margin-right: 5px;
}
input {
border: 1px solid #cccccc;
color: inherit;
background-color: #eee;
padding: 2px;
}
input[type=text], input[type=password] {
width: 140px;
}
/*input:hover {
color: inherit;
background-color: #ffffcc;
}*/
input:focus {
color: inherit;
background-color: #ffffcc;
}
textarea {
border: 1px solid #cccccc;
background-color: #eee;
width: 300px;
font-family: inherit;
font-size: inherit;
}
select {
width: 145px;
background-color: #eee;
border: 1px solid #cccccc;
}
td.odd {
background: #F7F9Fb;
}
td.even {
}
.title {
float: left;
width: 100%;
margin-bottom: 5px;
}
.title img {
float: left;
margin: 1px 3px;;
}
.title h1 {
float: left;
margin: 5px;
font-size: medium;
font-weight: bold;
}
.lastrow {
margin-top: 20px;
}
.errorlist ul {
float: left;
list-style: none;
}
.errorlist li {
margin-left: 10px;
float: left;
display: inline;
color: red;
}
.error {
margin-left: 20px;
color: red;
font-size: small;
font-weight: bold;
}
.center {
text-align: center;
}
#id_username {
width: 120px;
}
#id_password {
width: 120px;
}
/* Mootools tooltips */
.tip {
display: none;
position: absolute;
color: #fff;
z-index: 2;
border: 1px solid #cccccc;
}
.tip-title {
font-weight: bold;
font-size: 11px;
margin: 0;
color: #9FD4FF;
padding: 8px 8px 4px;
background: #eee;
}
.tip-text {
font-size: 0.9em;
padding: 4px 8px 8px;
background: #eee;
color: black;
}
.spacer {
clear: both;
}
ul {
list-style: none;
padding: 0;
}
li {
display: inline;
}
/*
* clearfix related
*/
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
overflow: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
overflow: visible;
}
/*
* Domain admin form
*/
#createfrom {
margin: 10px auto;
width: auto;
}
#permform > #id_name {
width: 180px;
}
/*
* Assign domains form
*/
#assignform #id_domains {
width: 310px;
height: 200px;
}
/*
* Domain admins list
*/
#domainadmins {
width: 100%;
height: 140px;
}
-91
View File
@@ -1,91 +0,0 @@
/*
Document : calendar.css
Created on : 29.07.2009
Author : jens klose
Description:
example styles for calendar
*/
.calendarForm{
float:right;
}
.calendar{
font-family:verdana,sans-serif;
font-size:10px;
float:None;
}
button.calendar{
position:relative;
top:-3px;
left:1px;
background-color:transparent;
background-image:url(../pics/calendar.gif);
border:none;
margin: 0px;
padding:0px;
margin-right:3px;
cursor:pointer;
width:20px;
height:20px;
}
input.calendar{
cursor:pointer;
border: 1px solid #87847F;
height:12px;
width:100px;
color: #87847F;
}
div.calendar{
background:white;
border: 1px solid #87847F;
width:180px
}
a.footer{
color:#474747;
padding:2px;
}
.calendar table{
width:100%;
}
.calendar th,
.calendar td{
text-align:center;
font-size:10px;
padding: 0.1em 0.25em 0.1em 0.3em;
}
.calendar tbody td,
.calendar .invalid{
color:silver;
}
.calendar .valid{
color:blue;
font-weight:bold;
cursor:pointer;
}
.calendar .valid.hover{
background:#FFFF77;
font-weight:bold;
}
.calendar caption a,
.calendar .next{
color:blue;
font-weight:bold;
padding:2px;
cursor:pointer;
}
.calendar caption a,
.calendar .prev{
color:blue;
font-weight:bold;
padding:2px;
}
.calendar .active,
.calendar .hilite,
.calendar .inactive{
color:white;
background-color:#BE3916;
font-weight:bold;
}
.calendar .active,
.calendar .inactive{
background-color:red;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 B

+64
View File
@@ -0,0 +1,64 @@
body {
padding-top: 60px;
}
#bottom-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
}
#pagination_bar {
color: #999999 !important;
}
.simplepagination ul {
display: inline-block;
}
.simplepagination li {
display: inline;
}
.simplepagination .disabled a,
.simplepagination .disabled a:hover {
background-color: transparent;
cursor: default;
}
.sidebar-nav {
padding: 9px 0;
}
.form-horizontal .param-label {
float: left;
padding-top: 5px;
text-align: left;
width: 200px;
}
.form-horizontal .param-controls {
margin-left: 210px;
}
.form-horizontal .control-group {
margin-bottom: 8px;
}
.spaced select,
.spaced input[type="text"] {
margin-bottom: 8px;
}
.padded5 {
padding: 5px;
}
.buttons_list .bset {
display: none;
}
.buttons_list .active {
display: block;
}
+5 -5
View File
@@ -68,7 +68,7 @@ div#footer {
#menubar {
margin: 5px;
display: table;
/*display: table;*/
width: 735px;
margin-top: 35px;
}
@@ -83,7 +83,7 @@ div#footer {
font-weight: bold;
}
#menubar a, #menubar a:visited {
/*#menubar a, #menubar a:visited {
color: black;
font-weight: bold;
}
@@ -91,7 +91,7 @@ div#footer {
#menubar label {
color: black;
font-weight: bold;
}
}*/
#page {
width: 100%;
@@ -167,7 +167,7 @@ div#footer {
width: 100%;
}
.menubar a, .menubar a:visited {
/*.menubar a, .menubar a:visited {
text-decoration: none;
}
@@ -201,7 +201,7 @@ div#footer {
.menubar .title {
color: white;
}
}*/
.menubardropdown ul {
background: white;
+10 -84
View File
@@ -1,93 +1,19 @@
html, body {
font-family: arial, helvetica, verdana, tahoma, sans-serif;
font-size: small;
background: #153F65;
margin: 0;
padding: 0;
}
#loginbox {
margin: 100px auto 10px auto;
padding: 0 0 15px 0;
font-size: 1em;
width: 630px;
}
#logo {
float: left;
text-align: center;
width: 300px;
margin-top: 10px;
border-right: 1px solid #ccc;
#logo {
margin-top: 60px;
}
#logo img {
height: 90px;
height: 100px;
}
#test {
float: right;
width: 300px;
input[type="text"],
input[type="password"] {
width: 315px;
padding: 7px;
}
.roundedbox {
margin: 10px auto;
padding: 10px;
width: 610px;
background: white;
font-size: 1.1em;
border: 5px solid #333;
border-radius: 10px;
.form-actions {
padding-right: 0px;
padding-left: 0px;
}
.roundedbox h1 {
padding: 0;
margin: 0;
font-size: 1.2em;
text-align: center;
}
.roundedbox h2 {
margin: 30px 10px 0 10px;
font-size: small;
}
.roundedbox h3 {
font-size: small;
text-align: center;
}
.roundedbox a, a:visited {
font-weight: bold;
color: black;
text-decoration: none;
}
.spacer {
clear: both;
}
/* Mootools tooltips */
.tip {
color: #fff;
width: 139px;
z-index: 13000;
border: 1px solid #cccccc;
}
.tip-title {
font-weight: bold;
font-size: 11px;
margin: 0;
color: #9FD4FF;
padding: 8px 8px 4px;
background: #eee;
}
.tip-text {
font-size: 11px;
padding: 4px 8px 8px;
background: #eee;
color: black;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

-31
View File
@@ -1,31 +0,0 @@
/**
* Autocompleter.Local
*
* http://digitarald.de/project/autocompleter/
*
* @version 1.1.2
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
Autocompleter.Local = new Class({
Extends: Autocompleter,
options: {
minLength: 0,
delay: 200
},
initialize: function(element, tokens, options) {
this.parent(element, options);
this.tokens = tokens;
},
query: function() {
this.update(this.filter());
}
});
-109
View File
@@ -1,109 +0,0 @@
/**
* Autocompleter.Request
*
* http://digitarald.de/project/autocompleter/
*
* @version 1.1.2
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
Autocompleter.Request = new Class({
Extends: Autocompleter,
options: {/*
indicator: null,
indicatorClass: null,
onRequest: $empty,
onComplete: $empty,*/
postData: {},
ajaxOptions: {},
postVar: 'value'
},
query: function(){
var data = $unlink(this.options.postData) || {};
data[this.options.postVar] = this.queryValue;
var indicator = $(this.options.indicator);
if (indicator) indicator.setStyle('display', '');
var cls = this.options.indicatorClass;
if (cls) this.element.addClass(cls);
this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
this.request.send({'data': data});
},
/**
* queryResponse - abstract
*
* Inherated classes have to extend this function and use this.parent()
*/
queryResponse: function() {
var indicator = $(this.options.indicator);
if (indicator) indicator.setStyle('display', 'none');
var cls = this.options.indicatorClass;
if (cls) this.element.removeClass(cls);
return this.fireEvent('onComplete', [this.element, this.request]);
}
});
Autocompleter.Request.JSON = new Class({
Extends: Autocompleter.Request,
initialize: function(el, url, options) {
this.parent(el, options);
this.request = new Request.JSON($merge({
'url': url,
'link': 'cancel'
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
},
queryResponse: function(response) {
this.parent();
this.update(response);
}
});
Autocompleter.Request.HTML = new Class({
Extends: Autocompleter.Request,
initialize: function(el, url, options) {
this.parent(el, options);
this.request = new Request.HTML($merge({
'url': url,
'link': 'cancel',
'update': this.choices
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
},
queryResponse: function(tree, elements) {
this.parent();
if (!elements || !elements.length) {
this.hideChoices();
} else {
this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function(choice) {
var value = choice.innerHTML;
choice.inputValue = value;
this.addChoiceEvents(choice.set('html', this.markQueryValue(value)));
}, this);
this.showChoices();
}
}
});
/* compatibility */
Autocompleter.Ajax = {
Base: Autocompleter.Request,
Json: Autocompleter.Request.JSON,
Xhtml: Autocompleter.Request.HTML
};
-442
View File
@@ -1,442 +0,0 @@
/**
* Autocompleter
*
* http://digitarald.de/project/autocompleter/
*
* @version 1.1.2
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var Autocompleter = new Class({
Implements: [Options, Events],
options: {/*
onOver: $empty,
onSelect: $empty,
onSelection: $empty,
onShow: $empty,
onHide: $empty,
onBlur: $empty,
onFocus: $empty,*/
minLength: 1,
markQuery: true,
width: 'inherit',
maxChoices: 10,
injectChoice: null,
customChoices: null,
emptyChoices: null,
visibleChoices: true,
className: 'autocompleter-choices',
zIndex: 42,
delay: 400,
observerOptions: {},
fxOptions: {},
autoSubmit: false,
overflow: false,
overflowMargin: 25,
selectFirst: false,
filter: null,
filterCase: false,
filterSubset: false,
forceSelect: false,
selectMode: true,
choicesMatch: null,
multiple: false,
separator: ', ',
separatorSplit: /\s*[,;]\s*/,
autoTrim: false,
allowDupes: false,
cache: true,
relative: false
},
initialize: function(element, options) {
this.element = $(element);
this.setOptions(options);
this.build();
this.observer = new Observer(this.element, this.prefetch.bind(this), $merge({
'delay': this.options.delay
}, this.options.observerOptions));
this.queryValue = null;
if (this.options.filter) this.filter = this.options.filter.bind(this);
var mode = this.options.selectMode;
this.typeAhead = (mode == 'type-ahead');
this.selectMode = (mode === true) ? 'selection' : mode;
this.cached = [];
},
/**
* build - Initialize DOM
*
* Builds the html structure for choices and appends the events to the element.
* Override this function to modify the html generation.
*/
build: function() {
if ($(this.options.customChoices)) {
this.choices = this.options.customChoices;
} else {
this.choices = new Element('ul', {
'class': this.options.className,
'styles': {
'zIndex': this.options.zIndex
}
}).inject(document.body);
this.relative = false;
if (this.options.relative) {
this.choices.inject(this.element, 'after');
this.relative = this.element.getOffsetParent();
}
this.fix = new OverlayFix(this.choices);
}
if (!this.options.separator.test(this.options.separatorSplit)) {
this.options.separatorSplit = this.options.separator;
}
this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, $merge({
'property': 'opacity',
'link': 'cancel',
'duration': 200
}, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0);
this.element.setProperty('autocomplete', 'off')
.addEvent((Browser.Engine.trident || Browser.Engine.webkit) ? 'keydown' : 'keypress', this.onCommand.bind(this))
.addEvent('click', this.onCommand.bind(this, [false]))
.addEvent('focus', this.toggleFocus.create({bind: this, arguments: true, delay: 100}))
.addEvent('blur', this.toggleFocus.create({bind: this, arguments: false, delay: 100}));
},
destroy: function() {
if (this.fix) this.fix.destroy();
this.choices = this.selected = this.choices.destroy();
},
toggleFocus: function(state) {
this.focussed = state;
if (!state) this.hideChoices(true);
this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]);
},
onCommand: function(e) {
if (!e && this.focussed) return this.prefetch();
if (e && e.key && !e.shift) {
switch (e.key) {
case 'enter':
if (this.element.value != this.opted) return true;
if (this.selected && this.visible) {
this.choiceSelect(this.selected);
return !!(this.options.autoSubmit);
}
break;
case 'up': case 'down':
if (!this.prefetch() && this.queryValue !== null) {
var up = (e.key == 'up');
this.choiceOver((this.selected || this.choices)[
(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
](this.options.choicesMatch), true);
}
return false;
case 'esc': case 'tab':
this.hideChoices(true);
break;
}
}
return true;
},
setSelection: function(finish) {
var input = this.selected.inputValue, value = input;
var start = this.queryValue.length, end = input.length;
if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
if (this.options.multiple) {
var split = this.options.separatorSplit;
value = this.element.value;
start += this.queryIndex;
end += this.queryIndex;
var old = value.substr(this.queryIndex).split(split, 1)[0];
value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
if (finish) {
var tokens = value.split(this.options.separatorSplit).filter(function(entry) {
return this.test(entry);
}, /[^\s,]+/);
if (!this.options.allowDupes) tokens = [].combine(tokens);
var sep = this.options.separator;
value = tokens.join(sep) + sep;
end = value.length;
}
}
this.observer.setValue(value);
this.opted = value;
if (finish || this.selectMode == 'pick') start = end;
this.element.selectRange(start, end);
this.fireEvent('onSelection', [this.element, this.selected, value, input]);
},
showChoices: function() {
var match = this.options.choicesMatch, first = this.choices.getFirst(match);
this.selected = this.selectedValue = null;
if (this.fix) {
var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto';
this.choices.setStyles({
'left': pos.left,
'top': pos.bottom,
'width': (width === true || width == 'inherit') ? pos.width : width
});
}
if (!first) return;
if (!this.visible) {
this.visible = true;
this.choices.setStyle('display', '');
if (this.fx) this.fx.start(1);
this.fireEvent('onShow', [this.element, this.choices]);
}
if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead);
var items = this.choices.getChildren(match), max = this.options.maxChoices;
var styles = {'overflowY': 'hidden', 'height': ''};
this.overflown = false;
if (items.length > max) {
var item = items[max - 1];
styles.overflowY = 'scroll';
styles.height = item.getCoordinates(this.choices).bottom;
this.overflown = true;
};
this.choices.setStyles(styles);
this.fix.show();
if (this.options.visibleChoices) {
var scroll = document.getScroll(),
size = document.getSize(),
coords = this.choices.getCoordinates();
if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x;
if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y;
window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top));
}
},
hideChoices: function(clear) {
if (clear) {
var value = this.element.value;
if (this.options.forceSelect) value = this.opted;
if (this.options.autoTrim) {
value = value.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator);
}
this.observer.setValue(value);
}
if (!this.visible) return;
this.visible = false;
if (this.selected) this.selected.removeClass('autocompleter-selected');
this.observer.clear();
var hide = function(){
this.choices.setStyle('display', 'none');
this.fix.hide();
}.bind(this);
if (this.fx) this.fx.start(0).chain(hide);
else hide();
this.fireEvent('onHide', [this.element, this.choices]);
},
prefetch: function() {
var value = this.element.value, query = value;
if (this.options.multiple) {
var split = this.options.separatorSplit;
var values = value.split(split);
var index = this.element.getSelectedRange().start;
var toIndex = value.substr(0, index).split(split);
var last = toIndex.length - 1;
index -= toIndex[last].length;
query = values[last];
}
if (query.length < this.options.minLength) {
this.hideChoices();
} else {
if (query === this.queryValue || (this.visible && query == this.selectedValue)) {
if (this.visible) return false;
this.showChoices();
} else {
this.queryValue = query;
this.queryIndex = index;
if (!this.fetchCached()) this.query();
}
}
return true;
},
fetchCached: function() {
return false;
if (!this.options.cache
|| !this.cached
|| !this.cached.length
|| this.cached.length >= this.options.maxChoices
|| this.queryValue) return false;
this.update(this.filter(this.cached));
return true;
},
update: function(tokens) {
this.choices.empty();
this.cached = tokens;
var type = tokens && $type(tokens);
if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
(this.options.emptyChoices || this.hideChoices).call(this);
} else {
if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
tokens.each(this.options.injectChoice || function(token){
var choice = new Element('li', {'html': this.markQueryValue(token)});
choice.inputValue = token;
this.addChoiceEvents(choice).inject(this.choices);
}, this);
this.showChoices();
}
},
choiceOver: function(choice, selection) {
if (!choice || choice == this.selected) return;
if (this.selected) this.selected.removeClass('autocompleter-selected');
this.selected = choice.addClass('autocompleter-selected');
this.fireEvent('onSelect', [this.element, this.selected, selection]);
if (!this.selectMode) this.opted = this.element.value;
if (!selection) return;
this.selectedValue = this.selected.inputValue;
if (this.overflown) {
var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
}
if (this.selectMode) this.setSelection();
},
choiceSelect: function(choice) {
if (choice) this.choiceOver(choice);
this.setSelection(true);
this.queryValue = false;
this.hideChoices();
},
filter: function(tokens) {
return (tokens || this.tokens).filter(function(token) {
return this.test(token);
}, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i'));
},
/**
* markQueryValue
*
* Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
* Call this i.e. from your custom parseChoices, same for addChoiceEvents
*
* @param {String} Text
* @return {String} Text
*/
markQueryValue: function(str) {
return (!this.options.markQuery || !this.queryValue) ? str
: str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '<span class="autocompleter-queried">$1</span>');
},
/**
* addChoiceEvents
*
* Appends the needed event handlers for a choice-entry to the given element.
*
* @param {Element} Choice entry
* @return {Element} Choice entry
*/
addChoiceEvents: function(el) {
return el.addEvents({
'mouseover': this.choiceOver.bind(this, [el]),
'click': this.choiceSelect.bind(this, [el])
});
}
});
var OverlayFix = new Class({
initialize: function(el) {
if (Browser.Engine.trident) {
this.element = $(el);
this.relative = this.element.getOffsetParent();
this.fix = new Element('iframe', {
'frameborder': '0',
'scrolling': 'no',
'src': 'javascript:false;',
'styles': {
'position': 'absolute',
'border': 'none',
'display': 'none',
'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
}
}).inject(this.element, 'after');
}
},
show: function() {
if (this.fix) {
var coords = this.element.getCoordinates(this.relative);
delete coords.right;
delete coords.bottom;
this.fix.setStyles($extend(coords, {
'display': '',
'zIndex': (this.element.getStyle('zIndex') || 1) - 1
}));
}
return this;
},
hide: function() {
if (this.fix) this.fix.setStyle('display', 'none');
return this;
},
destroy: function() {
if (this.fix) this.fix = this.fix.destroy();
}
});
Element.implement({
getSelectedRange: function() {
if (!Browser.Engine.trident) return {start: this.selectionStart, end: this.selectionEnd};
var pos = {start: 0, end: 0};
var range = this.getDocument().selection.createRange();
if (!range || range.parentElement() != this) return pos;
var dup = range.duplicate();
if (this.type == 'text') {
pos.start = 0 - dup.moveStart('character', -100000);
pos.end = pos.start + range.text.length;
} else {
var value = this.value;
var offset = value.length - value.match(/[\n\r]*$/)[0].length;
dup.moveToElementText(this);
dup.setEndPoint('StartToEnd', range);
pos.end = offset - dup.text.length;
dup.setEndPoint('StartToStart', range);
pos.start = offset - dup.text.length;
}
return pos;
},
selectRange: function(start, end) {
if (Browser.Engine.trident) {
var diff = this.value.substr(start, end - start).replace(/\r/g, '').length;
start = this.value.substr(0, start).replace(/\r/g, '').length;
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', start + diff);
range.moveStart('character', start);
range.select();
} else {
this.focus();
this.setSelectionRange(start, end);
}
return this;
}
});
/* compatibility */
Autocompleter.Base = Autocompleter;
-69
View File
@@ -1,69 +0,0 @@
/**
* Observer - Observe formelements for changes
*
* - Additional code from clientside.cnet.com
*
* @version 1.1
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var Observer = new Class({
Implements: [Options, Events],
options: {
periodical: false,
delay: 1000
},
initialize: function(el, onFired, options){
this.element = $(el) || $$(el);
this.addEvent('onFired', onFired);
this.setOptions(options);
this.bound = this.changed.bind(this);
this.resume();
},
changed: function() {
var value = this.element.get('value');
if ($equals(this.value, value)) return;
this.clear();
this.value = value;
this.timeout = this.onFired.delay(this.options.delay, this);
},
setValue: function(value) {
this.value = value;
this.element.set('value', value);
return this.clear();
},
onFired: function() {
this.fireEvent('onFired', [this.value, this.element]);
},
clear: function() {
$clear(this.timeout || null);
return this;
},
pause: function(){
if (this.timer) $clear(this.timer);
else this.element.removeEvent('keyup', this.bound);
return this.clear();
},
resume: function(){
this.value = this.element.get('value');
if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this);
else this.element.addEvent('keyup', this.bound);
return this;
}
});
var $equals = function(obj1, obj2) {
return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2));
};
-19
View File
@@ -1,19 +0,0 @@
/*
---
description: ProgressBar
authors:
- David Walsh (http://davidwalsh.name)
license:
- MIT-style license
requires:
core/1.2.1: '*'
more/1.2.1: 'Fx.*'
provides:
- ProgressBar
...
*/
var ProgressBar=new Class({Implements:[Events,Options],options:{container:document.body,boxID:"progress-bar-box-id",percentageID:"progress-bar-percentage-id",displayID:"progress-bar-display-id",startPercentage:0,displayText:false,speed:10,step:1,allowMore:false,onComplete:$empty,onChange:$empty},initialize:function(a){this.setOptions(a);this.options.container=document.id(this.options.container);this.createElements();},createElements:function(){var b=new Element("div",{id:this.options.boxID});var a=new Element("div",{id:this.options.percentageID,style:"width:0px;"});a.inject(b);b.inject(this.options.container);if(this.options.displayText){var c=new Element("div",{id:this.options.displayID});c.inject(this.options.container);}this.set(this.options.startPercentage);},calculate:function(a){return(document.id(this.options.boxID).getStyle("width").replace("px","")*(a/100)).toInt();},animate:function(b){var c=false;var a=this;if(!a.options.allowMore&&b>100){b=100;}a.to=b.toInt();document.id(a.options.percentageID).set("morph",{duration:this.options.speed,link:"cancel",onComplete:function(){a.fireEvent("change",[a.to]);if(b>=100){a.fireEvent("complete",[a.to]);}}}).morph({width:a.calculate(b)});if(a.options.displayText){document.id(a.options.displayID).set("text",a.to+"%");}},set:function(a){this.animate(a);},step:function(){this.set(this.to+this.options.step);}});
-443
View File
@@ -1,443 +0,0 @@
/**
* SqueezeBox - Expandable Lightbox
*
* Allows to open various content as modal,
* centered and animated box.
*
* Dependencies: MooTools 1.3.1
*
* Inspired by
* ... Lokesh Dhakar - The original Lightbox v2
*
* @version 1.3 rc1
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var SqueezeBox = {
presets: {
onOpen: function(){},
onClose: function(){},
onUpdate: function(){},
onResize: function(){},
onMove: function(){},
onShow: function(){},
onHide: function(){},
size: {x: 600, y: 450},
sizeLoading: {x: 200, y: 150},
marginInner: {x: 20, y: 20},
marginImage: {x: 50, y: 75},
handler: false,
target: null,
closable: true,
closeBtn: true,
zIndex: 65555,
overlayOpacity: 0.7,
classWindow: '',
classOverlay: '',
overlayFx: {},
resizeFx: {},
contentFx: {},
parse: false, // 'rel'
parseSecure: false,
shadow: true,
document: null,
ajaxOptions: {}
},
initialize: function(presets) {
if (this.options) return this;
this.presets = Object.merge(this.presets, presets);
this.doc = this.presets.document || document;
this.options = {};
this.setOptions(this.presets).build();
this.bound = {
window: this.reposition.pass(null,this),
scroll: this.checkTarget.bind(this),
close: this.close.bind(this),
key: this.onKey.bind(this)
};
this.isOpen = this.isLoading = false;
return this;
},
build: function() {
this.overlay = new Element('div', {
id: 'sbox-overlay',
styles: {display: 'none', zIndex: this.options.zIndex}
});
this.win = new Element('div', {
id: 'sbox-window',
styles: {display: 'none', zIndex: this.options.zIndex + 2}
});
if (this.options.shadow) {
if (Browser.safari || Browser.chrome) {
this.win.setStyle('-webkit-box-shadow', '0 0 10px rgba(0, 0, 0, 0.7)');
} else if (!Browser.ie) {
var shadow = new Element('div', {'class': 'sbox-bg-wrap'}).inject(this.win);
var relay = function(e) {
this.overlay.fireEvent('click', [e]);
}.bind(this);
['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'].each(function(dir) {
new Element('div', {'class': 'sbox-bg sbox-bg-' + dir}).inject(shadow).addEvent('click', relay);
});
}
}
this.content = new Element('div', {id: 'sbox-content'}).inject(this.win);
if (this.options.closeBtn) {
this.closeBtn = new Element('a', {id: 'sbox-btn-close', href: '#'}).inject(this.win);
}
this.fx = {
overlay: new Fx.Tween(this.overlay, Object.merge({
property: 'opacity',
onStart: Events.prototype.clearChain,
duration: 250,
link: 'cancel'
}, this.options.overlayFx)).set(0),
win: new Fx.Morph(this.win, Object.merge({
onStart: Events.prototype.clearChain,
unit: 'px',
duration: 750,
transition: Fx.Transitions.Quint.easeOut,
link: 'cancel',
unit: 'px'
}, this.options.resizeFx)),
content: new Fx.Tween(this.content, Object.merge({
property: 'opacity',
duration: 250,
link: 'cancel'
}, this.options.contentFx)).set(0)
};
$(this.doc.body).adopt(this.overlay, this.win);
},
assign: function(to, options) {
return ($(to) || $$(to)).addEvent('click', function() {
return !SqueezeBox.fromElement(this, options);
});
},
open: function(subject, options) {
this.initialize();
if (this.element != null) this.trash();
this.element = $(subject) || false;
this.setOptions(Object.merge(this.presets, options || {}));
if (this.element && this.options.parse) {
var obj = this.element.getProperty(this.options.parse);
if (obj && (obj = JSON.decode(obj, this.options.parseSecure))) this.setOptions(obj);
}
this.url = ((this.element) ? (this.element.get('href')) : subject) || this.options.url || '';
this.assignOptions();
var handler = handler || this.options.handler;
if (handler) return this.setContent(handler, this.parsers[handler].call(this, true));
var ret = false;
return this.parsers.some(function(parser, key) {
var content = parser.call(this);
if (content) {
ret = this.setContent(key, content);
return true;
}
return false;
}, this);
},
fromElement: function(from, options) {
return this.open(from, options);
},
assignOptions: function() {
this.overlay.set('class', this.options.classOverlay);
this.win.set('class', this.options.classWindow);
if (Browser.ie) this.win.addClass('sbox-window-ie6');
if (!this.options.closeBtn) {
this.closeBtn.dispose();
} else {
this.closeBtn.inject(this.win);
}
},
close: function(e) {
var stoppable = (typeOf(e) == 'event');
if (stoppable) e.stop();
if (!this.isOpen || (stoppable && !Function.from(this.options.closable).call(this, e))) return this;
this.fx.overlay.start(0).chain(this.toggleOverlay.bind(this));
this.win.setStyle('display', 'none');
this.fireEvent('onClose', [this.content]);
this.trash();
this.toggleListeners(false);
this.isOpen = false;
return this;
},
trash: function() {
this.element = this.asset = null;
this.content.empty();
this.options = {};
this.removeEvents().setOptions(this.presets).callChain();
},
onError: function() {
this.asset = null;
this.setContent('string', this.options.errorMsg || 'An error occurred');
},
setContent: function(handler, content) {
if (!this.handlers[handler]) return false;
this.content.className = 'sbox-content-' + handler;
this.applyTimer = this.applyContent.delay(this.fx.overlay.options.duration, this, this.handlers[handler].call(this, content));
if (this.overlay.retrieve('opacity')) return this;
this.toggleOverlay(true);
this.fx.overlay.start(this.options.overlayOpacity);
return this.reposition();
},
applyContent: function(content, size) {
if (!this.isOpen && !this.applyTimer) return;
this.applyTimer = clearTimeout(this.applyTimer);
this.hideContent();
if (!content) {
this.toggleLoading(true);
} else {
if (this.isLoading) this.toggleLoading(false);
this.fireEvent('onUpdate', [this.content], 20);
}
if (content) {
if (['string', 'array'].contains(typeOf(content))) this.content.set('html', content);
else if ((!this.content.contains(content)) && content != this.content) this.content.adopt(content);
}
this.callChain();
if (!this.isOpen) {
this.toggleListeners(true);
this.resize(size, true);
this.isOpen = true;
this.fireEvent('onOpen', [this.content]);
} else {
this.resize(size);
}
},
resize: function(size, instantly) {
this.showTimer = clearTimeout(this.showTimer || null);
var box = this.doc.getSize(), scroll = this.doc.getScroll();
this.size = Object.merge((this.isLoading) ? this.options.sizeLoading : this.options.size, size);
var to = {
width: this.size.x,
height: this.size.y,
left: (scroll.x + (box.x - this.size.x - this.options.marginInner.x) / 2).toInt(),
top: (scroll.y + (box.y - this.size.y - this.options.marginInner.y) / 2).toInt()
};
this.hideContent();
if (!instantly) {
this.fx.win.start(to).chain(this.showContent.bind(this));
} else {
this.win.setStyles(to).setStyle('display', '');
this.showTimer = this.showContent.delay(50, this);
}
return this.reposition();
},
toggleListeners: function(state) {
var fn = (state) ? 'addEvent' : 'removeEvent';
if (this.options.closeBtn) {
this.closeBtn[fn]('click', this.bound.close);
}
this.overlay[fn]('click', this.bound.close);
this.doc[fn]('keydown', this.bound.key)[fn]('mousewheel', this.bound.scroll);
this.doc.getWindow()[fn]('resize', this.bound.window)[fn]('scroll', this.bound.window);
},
toggleLoading: function(state) {
this.isLoading = state;
this.win[(state) ? 'addClass' : 'removeClass']('sbox-loading');
if (state) this.fireEvent('onLoading', [this.win]);
},
toggleOverlay: function(state) {
var full = this.doc.getSize().x;
this.overlay.setStyle('display', (state) ? '' : 'none');
this.doc.body[(state) ? 'addClass' : 'removeClass']('body-overlayed');
if (state) {
this.scrollOffset = this.doc.getWindow().getSize().x - full;
this.doc.body.setStyle('margin-right', this.scrollOffset);
} else {
this.doc.body.setStyle('margin-right', '');
}
},
showContent: function() {
if (this.content.get('opacity')) this.fireEvent('onShow', [this.win]);
this.fx.content.start(1);
},
hideContent: function() {
if (!this.content.get('opacity')) this.fireEvent('onHide', [this.win]);
this.fx.content.cancel().set(0);
},
onKey: function(e) {
switch (e.key) {
case 'esc': this.close(e);
case 'up': case 'down': return false;
}
},
checkTarget: function(e) {
return (this.content.contains(e.target) && e.target != this.content);
},
reposition: function() {
var size = this.doc.getSize(), scroll = this.doc.getScroll(), ssize = this.doc.getScrollSize();
this.overlay.setStyles({
width: ssize.x + 'px',
height: ssize.y + 'px'
});
this.win.setStyles({
left: (scroll.x + (size.x - this.win.offsetWidth) / 2 - this.scrollOffset).toInt() + 'px',
top: (scroll.y + (size.y - this.win.offsetHeight) / 2).toInt() + 'px'
});
return this.fireEvent('onMove', [this.overlay, this.win]);
},
removeEvents: function(type) {
if (!this.$events) return this;
if (!type) this.$events = null;
else if (this.$events[type]) this.$events[type] = null;
return this;
},
extend: function(properties) {
return Object.append(this, properties);
},
handlers: new Hash(),
parsers: new Hash()
};
SqueezeBox.extend(new Events(function(){})).extend(new Options(function(){})).extend(new Chain(function(){}));
SqueezeBox.parsers.extend({
image: function(preset) {
return (preset || (/\.(?:jpg|png|gif)$/i).test(this.url)) ? this.url : false;
},
clone: function(preset) {
if ($(this.options.target)) return $(this.options.target);
if (this.element && !this.element.parentNode) return this.element;
var bits = this.url.match(/#([\w-]+)$/);
return (bits) ? $(bits[1]) : (preset ? this.element : false);
},
ajax: function(preset) {
return (preset || (this.url && !(/^(?:javascript|#)/i).test(this.url))) ? this.url : false;
},
iframe: function(preset) {
return (preset || this.url) ? this.url : false;
},
string: function(preset) {
return true;
}
});
SqueezeBox.handlers.extend({
image: function(url) {
var size, tmp = new Image();
this.asset = null;
tmp.onload = tmp.onabort = tmp.onerror = (function() {
tmp.onload = tmp.onabort = tmp.onerror = null;
if (!tmp.width) {
this.onError.delay(10, this);
return;
}
var box = this.doc.getSize();
box.x -= this.options.marginImage.x;
box.y -= this.options.marginImage.y;
size = {x: tmp.width, y: tmp.height};
for (var i = 2; i--;) {
if (size.x > box.x) {
size.y *= box.x / size.x;
size.x = box.x;
} else if (size.y > box.y) {
size.x *= box.y / size.y;
size.y = box.y;
}
}
size.x = size.x.toInt();
size.y = size.y.toInt();
this.asset = $(tmp);
tmp = null;
this.asset.width = size.x;
this.asset.height = size.y;
this.applyContent(this.asset, size);
}).bind(this);
tmp.src = url;
if (tmp && tmp.onload && tmp.complete) tmp.onload();
return (this.asset) ? [this.asset, size] : null;
},
clone: function(el) {
if (el) return el.clone();
return this.onError();
},
adopt: function(el) {
if (el) return el;
return this.onError();
},
ajax: function(url) {
var options = this.options.ajaxOptions || {};
this.asset = new Request.HTML(Object.merge({
method: 'get',
evalScripts: false
}, this.options.ajaxOptions)).addEvents({
onSuccess: function(resp) {
this.applyContent(resp);
if (options.evalScripts !== null && !options.evalScripts) Browser.exec(this.asset.response.javascript);
this.fireEvent('onAjax', [resp, this.asset]);
this.asset = null;
}.bind(this),
onFailure: this.onError.bind(this)
});
this.asset.send.delay(10, this.asset, [{url: url}]);
},
iframe: function(url) {
this.asset = new Element('iframe', Object.merge({
src: url,
frameBorder: 0,
width: this.options.size.x,
height: this.options.size.y
}, this.options.iframeOptions));
if (this.options.iframePreload) {
this.asset.addEvent('load', function() {
this.applyContent(this.asset.setStyle('display', ''));
}.bind(this));
this.asset.setStyle('display', 'none').inject(this.content);
return false;
}
return this.asset;
},
string: function(str) {
return str;
}
});
SqueezeBox.handlers.url = SqueezeBox.handlers.ajax;
SqueezeBox.parsers.url = SqueezeBox.parsers.ajax;
SqueezeBox.parsers.adopt = SqueezeBox.parsers.clone;
+67
View File
@@ -0,0 +1,67 @@
function domainform_cb() {
$('input:text:visible:first').focus();
$("#id_aliases").dynamic_input();
$(".submit").one('click', function(e) {
simple_ajax_form_post(e, domainform_cb);
});
}
function accountform_init() {
$("#id_aliases").dynamic_input();
$("#id_email").autocompleter({
from_character: "@",
choices: get_domains_list
});
$("#id_domains")
.autocompleter({
choices: get_domains_list
})
.dynamic_input();
}
function newaccount_cb() {
$('input:text:visible:first').focus();
accountform_init();
$("#wizard").cwizard();
}
function editaccount_cb() {
accountform_init();
$('#submit').click(function(e) {
simple_ajax_form_post(e, editaccount_cb);
});
}
function dlistform_cb() {
$("#id_email").autocompleter({
from_character: "@",
choices: get_domains_list
});
$("#id_recipients").dynamic_input();
$(".submit").one('click', function(e) {
simple_ajax_form_post(e, dlistform_cb);
});
}
function importform_cb() {
$(".submit").one('click', function(e) {
if ($("#id_sourcefile").attr("value") == "") {
e.preventDefault();
return;
}
$("#import_status").css("display", "block");
$("form").submit();
});
}
function importdone(status, msg) {
$("#import_status").css("display", "none");
if (status == "ok") {
$("#modalbox").modal('hide');
window.location.reload();
} else {
$("#import_result").html("");
$(".modal-header").notify({top_position: 10});
$(".modal-header").notify('error', msg);
}
}
+166
View File
@@ -0,0 +1,166 @@
(function($) {
var Autocompleter = function(element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.autocompleter.defaults, options);
this.choices = {
value: null
};
if (typeof this.options.choices === "function") {
this.options.choices(this.choices);
} else {
this.choices.value = this.options.choices();
}
this.$menu =
$('<ul class="dropdown-menu autocompleter" data-toggle="dropdown" />');
$("body").append(this.$menu);
this.$menu.on("click", $.proxy(this.select_entry, this));
this.$element.attr("autocomplete", "off");
this.$element.keydown($.proxy(this.keydown, this));
this.$element.keyup($.proxy(this.keyup, this));
this.$element.blur($.proxy(this.hide_menu, this));
};
Autocompleter.prototype = {
constructor: Autocompleter,
check_user_input: function() {
var value = this.$element.attr("value");
var start = -1;
var pattern = null;
if (this.options.from_character) {
start = value.indexOf(this.options.from_character);
if (start == -1) {
return;
}
pattern = value.substr(start + 1);
} else {
pattern = value;
}
var exp = new RegExp("^" + pattern);
this.$menu.empty();
$.each(this.choices.value, $.proxy(function(index, value) {
if (exp.test(value)) {
this.$menu.append($('<li><a href="#" name="' + value
+ '">' + value + '</a></li>'));
}
}, this));
var coords = this.$element.offset();
this.$menu.css({
position: "absolute",
top: coords.top + this.$element.outerHeight(),
left: coords.left,
width: this.$element.outerWidth()
});
if (this.$menu.children().length) {
this.$menu.show();
} else {
this.$menu.hide();
}
},
hide_menu: function() {
setTimeout($.proxy(function() { this.$menu.hide(); }, this), 150);
},
select_entry: function(evt) {
if (evt != undefined) {
evt.preventDefault();
}
var $link = this.$menu.find('.active > a');
var curvalue = this.$element.attr("value");
this.$element.attr("value", curvalue.substr(
0, curvalue.indexOf(this.options.from_character) + 1
) + $link.attr("name"));
this.hide_menu();
},
activate_next: function() {
var active = this.$menu.find('.active').removeClass('active')
, next = active.next();
if (!next.length) {
next = $(this.$menu.find('li').first());
}
next.addClass('active');
},
activate_prev: function() {
var active = this.$menu.find('.active').removeClass('active')
, prev = active.prev();
if (!prev.length) {
prev = this.$menu.find('li').last();
}
prev.addClass('active');
},
keydown: function(evt) {
evt.stopPropagation();
switch (evt.keyCode) {
case 13:
case 27:
evt.preventDefault();
break;
case 38:
evt.preventDefault();
this.activate_prev();
break;
case 40:
evt.preventDefault();
this.activate_next();
break;
};
},
keyup: function(evt) {
evt.stopPropagation();
evt.preventDefault();
switch (evt.keyCode) {
case 40:
case 38:
break;
case 13:
this.select_entry();
break;
case 27:
this.hide_menu();
break;
default:
this.check_user_input();
};
}
};
$.fn.autocompleter = function(option) {
return this.each(function() {
var $this = $(this),
data = $this.data('autocompleter'),
options = typeof option === "object" && option;
if (!data) {
$this.data('autocompleter', new Autocompleter(this, options));
}
if (typeof option === "string") {
data[option]();
}
});
};
$.fn.autocompleter.defaults = {};
})(jQuery);
+1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+48 -26
View File
@@ -1,14 +1,17 @@
window.addEvent('domready', function(){
parse_menubar('topmenubar');
parse_menubar('menubar');
$(document).ready(function() {
$(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
$(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
infobox = new InfoBox({
//parse_menubar('#topmenubar');
//parse_menubar('#menubar');
/*infobox = new InfoBox({
parent : $("menubar"),
message : "Loading"
});
});*/
/* Specific javascript code for the demo... not the best place */
$$("a[name=sendspam], a[name=sendvirus]").addEvent("click", function(evt) {
/*$$("a[name=sendspam], a[name=sendvirus]").addEvent("click", function(evt) {
evt.stop();
new Request.JSON({
url: this.get("href"),
@@ -21,7 +24,7 @@ window.addEvent('domready', function(){
}
}
}).get();
});
});*/
});
var media_url = "";
@@ -65,8 +68,29 @@ function enable_link(link, callback) {
}
function parse_menubar(id) {
if ($(id)) {
$(id).getElements('li.dropdown').each(function(elem){
var $menubar = $(id);
if ($menubar == undefined) {
return;
}
$menubar.find('.dropdown-toggle').dropdown();
$menubar.find('a[data-toggle="modal"]').click(function(e) {
console.log(this);
e.preventDefault();
var href = $(this).attr('href');
if (href.indexOf('#') == 0) {
$(href).modal('open');
} else {
$.get(href, function(data) {
$('<div class="modal" >' + data + '</div>').modal();
}).success(function() {
$('input:text:visible:first').focus();
});
}
});
/*.each(function(elem){
var list = elem.getElement('ul.links');
var myFx = new Fx.Slide(list, {
duration: 200
@@ -76,7 +100,6 @@ function parse_menubar(id) {
myFx.wrapper.setStyles({
position : "absolute",
/*top: 30,*/
left : coords['left']
});
myFx.hide();
@@ -91,11 +114,11 @@ function parse_menubar(id) {
myFx.slideOut();
}
});
});
SqueezeBox.assign($(id).getElements('a[class=boxed]'), {
});*/
/*SqueezeBox.assign($(id).getElements('a[class=boxed]'), {
parse: 'rel'
});
}
});*/
};
get_iframe_body = function(id) {
@@ -220,17 +243,16 @@ gethref = function(obj) {
return url;
};
saveparams = function(id, message) {
$$("input[name=update]").addEvent("click", function(evt) {
evt.stop();
$(id).set("send", {
onSuccess: function(response) {
var decode = JSON.decode(response);
if (decode.status == "ok") {
infobox.info(message);
infobox.hide(1);
}
/*function saveparams(id, message) {
$("#update").click(function(evt) {
evt.preventDefault();
var $form = $("form");
$.post($form.attr("action"), $form.serialize(), function(data) {
if (data.status == "ok") {
$("body").notify("success", message, 2000);
}
}).send();
});
});
};
};*/
-91
View File
@@ -1,91 +0,0 @@
var Confirmation = new Class({
Implements: [Options, Events],
options: {
checkboxes: []
},
build_checkboxes: function() {
var result = "";
var cbhash = new Hash(this.options.checkboxes);
cbhash.each(function(value, key, hash) {
result += "<input type='checkbox' name='" + key + "' value='' />";
result += "<label>" + value + "</label>";
});
return result;
},
initialize: function(url, urlparams, question, options) {
this.setOptions(options);
Confirmation.url = url;
Confirmation.urlparams = urlparams;
var content = new Element("div", {id: "confirmbox"});
var icondiv = new Element("div", {
id: "dlg-iconbox",
html: "<img src='/static/pics/dialog-warning.png' alt='Warning' />"
}).inject(content);
this.textdiv = new Element("div", {
id: "dlg-textbox",
html: "<b>" + question + "</b>"
+ "<p>" + this.build_checkboxes() + "</p>"
}).inject(content);
var buttonsdiv = new Element("div", {
id: "dlg-buttons"
}).inject(content);
new Element("input", {type: "button", name: "ok", id: "ok", value: "Ok"})
.addEvent("click", this.ok_handler)
.inject(buttonsdiv);
new Element("input", {type: "button", name: "cancel", value: "Cancel"})
.addEvent("click", this.cancel_handler)
.inject(buttonsdiv);
new Element("input", {type: "hidden", name: "result",
id: "result", value: "cancel"})
.inject(content);
SqueezeBox.open(content, {
size: {x: 350, y: 140},
handler: "adopt",
onClose: this.close_handler.bind(content)
});
},
close_handler: function(content) {
var result = this.getElement("input[name=result]");
if (result.get("value") != "ok") {
return;
}
var params = Confirmation.urlparams;
$$("input[type=checkbox]:checked").each(function(item) {
if (params != "") {
params += "&";
}
params += item.get("name") + "=true";
});
new Request.JSON.mdb({
method: "get",
url: Confirmation.url,
onSuccess: function(res) {
if (res.status == "ok") {
window.location.reload();
} else {
infobox.error(res.respmsg);
infobox.hide(2);
}
}
}).send(params);
},
ok_handler: function(evt) {
$("result").value = "ok";
parent.SqueezeBox.close();
},
cancel_handler: function(evt) {
parent.SqueezeBox.close();
}
});
+79
View File
@@ -0,0 +1,79 @@
(function($) {
var Cwizard = function(element, options) {
this.$element = $(element);
this.$element.carousel("pause");
this.setcallbacks();
};
Cwizard.prototype = {
constructor: Cwizard,
setcallbacks: function() {
$(".next").one("click", $.proxy(this.next, this));
$(".prev").one("click", $.proxy(this.prev, this));
$(".submit").one("click", $.proxy(this.submit, this));
},
post: function(last) {
var $form = $('form');
var data = $form.serialize() + "&stepid=" + $(".item.active").attr("id");
$.post($form.attr("action"), data, $.proxy(function(resp) {
if (resp.status == "ok") {
if (!last) {
this.$element.carousel('next');
} else {
$("#modalbox").modal('hide').remove();
window.location.reload();
}
return;
}
if (resp.content) {
$(".modal").html(resp.content);
}
if (resp.respmsg) {
$(".modal-body").prepend(build_error_alert(resp.respmsg));
}
this.setcallbacks();
}, this));
},
update_buttons: function() {
$('.bset.active').removeClass("active");
$("#" + $(".item.active").attr("id") + "_buttons").addClass("active");
},
next: function(evt) {
evt.preventDefault();
this.$element.on('slid', this.update_buttons);
this.post(false);
},
prev: function(evt) {
evt.preventDefault();
this.$element.on('slid', update_buttons);
this.$element.carousel('prev');
},
submit: function(evt) {
evt.preventDefault();
this.post(true);
}
};
$.fn.cwizard = function(method) {
return this.each(function() {
var $this = $(this),
data = $this.data('cwizard'),
options = typeof method === "object" && method;
if (!data) {
$this.data('cwizard', new Cwizard(this, options));
}
if (typeof method === "string") {
data[method]();
}
});
};
})(jQuery);
+40 -27
View File
@@ -1,27 +1,7 @@
var Domains = new Class({
initialize: function(rooturl, deloptions) {
this.rooturl = rooturl;
if (deloptions != undefined) {
this.deloptions = deloptions;
} else {
this.deloptions = new Array();
}
if ($("subcontent") != undefined) {
SqueezeBox.assign($("subcontent").getElements('a[class=boxed]'), {
parse: 'rel'
});
}
setDivHeight("content", 20, 0);
this.objtable = new HtmlTable($("objects_table"), {
selectable: true
});
(function($) {
var objtable = null;
$$("a[name=new]").addEvent("click", this.new_clickcb.bind(this));
$$("a[name=remove]").addEvent("click", this.remove_clickcb.bind(this));
},
new_clickcb: function(evt) {
function new_clickcb(evt) {
var type = $("objects").get("name");
var sizes = $("objects").get("rel").split(" ");
@@ -30,9 +10,9 @@ var Domains = new Class({
size: {x: parseInt(sizes[0]), y: parseInt(sizes[1])},
handler: 'iframe'
});
},
};
remove_clickcb: function(evt) {
function remove_clickcb(evt) {
evt.stop();
if (this.objtable._selectedRows.length == 0) {
return;
@@ -62,5 +42,38 @@ var Domains = new Class({
checkboxes: this.deloptions
}
);
}
});
};
var methods = {
init: function(rooturl, deloptions) {
this.rooturl = rooturl;
if (deloptions != undefined) {
this.deloptions = deloptions;
} else {
this.deloptions = new Array();
}
if ($("subcontent") != undefined) {
SqueezeBox.assign($("subcontent").getElements('a[class=boxed]'), {
parse: 'rel'
});
}
setDivHeight("content", 20, 0);
this.objtable = new HtmlTable($("objects_table"), {
selectable: true
});
$$("a[name=new]").addEvent("click", new_clickcb);
$$("a[name=remove]").addEvent("click", remove_clickcb);
}
};
$.fn.Domains = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error(gettext('Unknown method: ') + method);
}
};
})(jQuery);
+106
View File
@@ -0,0 +1,106 @@
(function($) {
var DynamicInput = function(element, options) {
console.log(element);
this.$element = $(element);
this.options = $.extend({}, $.fn.dynamic_input.defaults, options);
this.nextid = 1;
this.baseid = this.$element.attr("id");
this.basename = this.$element.attr("name").split("_")[0];
this.$element.keyup($.proxy(this.checknotempty, this));
for (var cpt = 1; true; cpt++) {
var $input = $("#" + this.baseid + "_" + cpt);
if (!$input.length) {
break;
}
$input.after(this.addrmlink($input));
$input.focusout(this.checkempty);
this.nextid++;
}
};
DynamicInput.prototype = {
constructor: DynamicInput,
addrmlink: function(input) {
var $rmlink = $('<a href="#"'
+ 'id="' + input.attr("id") + '_rmbtn' + '"'
+ '"><i class="icon-remove"></i></a>');
$rmlink.click($.proxy(this.removeinput, $rmlink));
return $rmlink;
},
addinput: function() {
var id = this.baseid + '_' + this.nextid;
var name = this.basename + '_' + this.nextid;
var $ninput = $('<input type="text"'
+ 'id="' + id + '" '
+ 'name="' + name + '"'
+ '/>');
var $rmlink = this.addrmlink($ninput);
$ninput.focusout(this.checkempty);
$ninput.attr("value", this.$element.attr("value"));
this.$element.attr("value", this.options.emptylabel);
this.$element.after($ninput, $rmlink);
this.nextid++;
},
removeinput: function(evt, force) {
evt.preventDefault();
var id = "#" + this.attr("id").replace("_rmbtn", "");
var $input = $(id);
if ($input.attr("value") == "" && (force == undefined || !force)) {
return;
}
$input.remove();
this.remove();
},
checknotempty: function(evt) {
if (evt.keyCode != 13) {
return;
}
if (this.$element.attr("value") == "") {
return;
}
this.addinput();
},
checkempty: function(evt) {
var $input = $(evt.target);
if ($input.attr("value") == "") {
$("#" + $input.attr("id") + "_rmbtn").trigger("click", true);
}
}
};
$.fn.dynamic_input = function(method) {
return this.each(function() {
var $this = $(this),
data = $this.data('dynamic_input'),
options = typeof method === "object" && method;
if (!data) {
$this.data('dynamic_input', new DynamicInput(this, options));
}
if (typeof method === "string") {
data[method]();
}
});
};
/*
* Allow an external access to the constructor (for inheritance)
*/
$.fn.dynamic_input.Constructor = DynamicInput;
$.fn.dynamic_input.defaults = {
emptylabel: ""
};
})(jQuery);
-94
View File
@@ -1,94 +0,0 @@
var DynamicTextInput = new Class({
Implements: [Options],
options: {
parentContainer: null,
containerLevel: 1
},
initialize: function(targets, options) {
if (!$defined(targets) || !targets.length) {
return;
}
this.fields_cnt = 0;
for (var cpt = 0; cpt < targets.length; cpt++) {
var target = targets[cpt];
var btn;
if (cpt == 0) {
btn = new Element("img", {
src: parent.static_url("pics/add.png")
});
btn.addEvent("click", this.newelement.bind(this));
} else {
var btnid = "btn_" + cpt;
btn = new Element("img", {
src: parent.static_url("pics/remove.png"),
id: btnid
});
btn.addEvent("click", this.removeelement.bind(this));
}
btn.setStyles({
"float": "right",
"margin-top": "2px"
});
btn.inject(target, "after");
this.fields_cnt++;
}
this.nextid = targets.length;
this.target = targets[0];
this.setOptions(options);
},
createfield: function() {
var div = new Element("div").addClass("row");
var label = new Element("label").inject(div);
var ninput = new Element("input", {
type: "text",
id: this.target.get("id") + "_" + this.nextid,
name: this.target.get("name"),
value: this.target.get("value")
}).inject(div);
return [div, ninput];
},
newelement: function(event) {
if (this.target.get("value") == "") {
return;
}
var field = this.createfield();
var delbtn = new Element("img", {
id: "delbtn_" + this.nextid,
src: parent.static_url("pics/remove.png")
});
this.nextid += 1;
delbtn.setStyles({
"float" : "right",
"margin-top": "2px"
});
if (!this.options.parentContainer) {
var container = this.target;
for (var i = 0; i < this.options.containerLevel; i++) {
container = container.getParent()
}
field[0].inject(container, "after");
} else {
field[0].inject(this.options.parentContainer);
}
delbtn.inject(field[1], "after");
delbtn.addEvent("click", this.removeelement.bind(this));
this.target.set("value", "");
this.fields_cnt++;
},
removeelement: function(event) {
var id = (event.target.get("id").split("_"))[1];
var input = $("id_" + this.target.get("name") + "_" + id);
input.destroy();
event.target.destroy();
this.fields_cnt--;
}
});
-126
View File
@@ -1,126 +0,0 @@
var Form = new Class({
Implements: [Options],
options: {
resptarget: null
},
callbacks: {
error: {},
success: {},
extra_data: {}
},
initialize: function(options) {
this.setOptions(options);
$(document.body)
.removeEvents("submit")
.addEvent("submit", this.submit.bind(this));
this.init_help_messages();
},
init_help_messages: function() {
$$("input[type!=submit]", "select").addEvents({
focus: function(evt) {
var helpdiv = $(evt.target.name + "_helptext");
if (helpdiv) {
var coords = evt.target.getCoordinates();
helpdiv.setPosition({x: 10, y: coords['top'] + coords['height'] + 5});
helpdiv.setStyle("display", "block");
}
},
blur: function(evt) {
var helpdiv = $(evt.target.name + "_helptext");
if (helpdiv) {
helpdiv.setStyle("display", "none");
}
}
});
},
register_callback: function(category, name, callback) {
if (this.callbacks[category] == undefined) {
return false;
}
this.callbacks[category][name] = callback;
return true;
},
register_error_callback: function(name, callback) {
return this.register_callback("error", name, callback);
},
register_success_callback: function(name, callback) {
return this.register_callback("success", name, callback);
},
register_extra_data_callback: function(name, callback) {
return this.register_callback("extra_data", name, callback);
},
submit: function(event) {
var form = event.target;
var myid = form.get("id");
var data = form.toQueryString();
event.stop();
if (this.callbacks["extra_data"][myid] != undefined) {
if (data != "") {
data += "&";
}
data += this.callbacks["extra_data"][myid]();
}
new Request.JSON({
url: form.get("action"),
method: form.get("method"),
data: data,
onSuccess: function(response) {
if (response.status == "ko") {
if (response.norefresh != undefined && response.norefresh == true) {
$$("div[class=error]").set("html", response.respmsg);
} else {
var target = (this.options.resptarget)
? $(this.options.resptarget) : $(document.body);
target.set("html", response.content);
this.init_help_messages();
/*$(document.body).addEvent("submit", ajax_submit);*/
if (this.callbacks["error"][myid] != undefined) {
this.callbacks["error"][myid]();
}
}
return;
}
if ($defined(response.respmsg)) {
if ($defined(parent.current_anchor)) {
parent.current_anchor.loading_message = response.respmsg;
parent.current_anchor.loading_color = "green";
} else {
parent.infobox.info(response.respmsg);
parent.infobox.hide(1);
}
}
if ($defined(response.ajaxnav)) {
if ($defined(response.url)) {
parent.current_anchor.baseurl(response.url, 1);
}
parent.current_anchor.update(1);
} else if ($defined(response.url)) {
parent.location.href = response.url;
}
if (this.callbacks["success"][myid] != undefined) {
this.callbacks["success"][myid](response);
}
parent.SqueezeBox.close();
}.bind(this),
onFailure: function(xhr) {
parent.document.getElement('iframe')
.setStyles({width: 800, height: 600});
$(document.body).set("html", xhr.responseText);
}
}).send();
}
});
@@ -1,32 +1,31 @@
/*
* Class that implements a simple anchor based navigation system for
* AJAX applications.
*/
var AnchorNavigation = new Class({
Implements: [Options],
var History = function(options) {
this.options = $.extend({}, this.defaults, options);
this.callbacks = {};
this.params = {};
this.base = '';
this.serialized = null;
this.updatenext = true;
this.reset_loading_infos();
if (this.options.defcallback) {
this.register_callback("default", this.options.defcallback);
this.check_id =
setInterval($.proxy(this.check, this), this.options.checkinterval);
}
};
options: {
History.prototype = {
constructor: History,
defaults: {
checkinterval: 300,
defloadingtext: gettext("Loading..."),
defloadingcolor: "gray",
deflocation: null,
defcallback: null
},
initialize: function(deflocation, options) {
this.setOptions(options);
this.deflocation = deflocation;
this.callbacks = {};
this.params = $H();
this.base = '';
this.serialized = null;
this.updatenext = true;
this.reset_loading_infos();
if (this.options.defcallback) {
this.register_callback("default", this.options.defcallback);
this.ca_id =
this.check_anchor.bind(this).periodical(this.options.checkinterval);
}
paramslength: function() {
return Object.keys(this.params).length;
},
reset_loading_infos: function() {
@@ -36,7 +35,7 @@ var AnchorNavigation = new Class({
reset: function() {
this.base = null;
this.params.empty();
this.params = {};
return this;
},
@@ -47,13 +46,13 @@ var AnchorNavigation = new Class({
if (splits.length == 0) {
return this;
}
if (!$defined(reset)) {
if (reset === undefined) {
reset = false;
}
if (reset) {
this.reset();
}
this.base = (splits[0] == "") ? this.deflocation : splits[0];
this.base = (splits[0] == "") ? this.options.deflocation : splits[0];
var re = new RegExp("/$");
if (!this.base.match(re)) {
@@ -78,21 +77,21 @@ var AnchorNavigation = new Class({
serialize: function() {
var res = this.base;
if (this.params.getLength() != 0) {
res += "?" + this.params.toQueryString();
if (this.paramslength() != 0) {
res += "?" + $.param(this.params);
}
return res;
},
update: function(force, noupdate) {
window.fireEvent("pageRefresh");
$(window).trigger("pageRefresh");
location.hash = this.serialize();
if (!$defined(noupdate)) {
if (noupdate === undefined) {
noupdate = false;
}
if (!noupdate) {
if ($defined(force)) {
if (force) {
this.force = force;
}
} else {
@@ -116,11 +115,11 @@ var AnchorNavigation = new Class({
setparamfromstring: function(str) {
var def = str.split('=');
this.params.set(def[0], def[1]);
this.params[def[0]] = def[1];
},
setparam: function(name, value) {
this.params.set(name, value);
this.params[name] = value;
return this;
},
@@ -137,7 +136,7 @@ var AnchorNavigation = new Class({
},
baseurl: function(value, noreset) {
if (!$defined(noreset) || noreset == 0) {
if (noreset === undefined || noreset == 0) {
this.reset();
}
this.base = value;
@@ -175,51 +174,41 @@ var AnchorNavigation = new Class({
set_default_callback: function(callback) {
this.register_callback("default", callback);
if (!$defined(this.ca_id)) {
if (this.ca_id === undefined) {
this.ca_id =
this.check_anchor.bind(this).periodical(this.options.checkinterval);
setInterval($.proxy(this.check, this), this.options.checkinterval);
}
},
check_anchor: function() {
if (this.serialized == location.hash
&& !$defined(this.force)) {
check: function() {
if (this.serialized == location.hash && this.force === undefined) {
return;
}
delete(this.force);
this.from_string(location.hash);
if (!this.serialized) {
location.hash = this.deflocation;
location.hash = this.options.deflocation;
return;
}
if (!this.updatenext) {
this.updatenext = true;
return;
}
var query = this.serialized.substring(1);
infobox.show(this.loading_message, {
profile: this.loading_color,
spinner: true
});
new Request.JSON({
$.ajax({
url: query,
noCache : true,
onComplete: function() {
ajax_login_redirect();
},
onSuccess: function(resp) {
var callback = ($defined(resp.callback)) ? resp.callback : "default";
cache: false,
complete: $.proxy(function(XMLHttpRequest, textStatus) {
var resp;
try {
resp = $.parseJSON(XMLHttpRequest.responseText);
} catch (e) {
resp = { status: 'ko', respmsg: gettext('Internal Error') };
}
var callback = (resp.callback != undefined) ? resp.callback : "default";
this.callbacks[callback](resp);
infobox.info(gettext("Done"));
infobox.hide(1);
this.reset_loading_infos();
}.bind(this),
onFailure: function(xhr) {
$(document.body).set("html", xhr.responseText);
$(document.body).setStyle("overflow", "auto");
}
}).get();
}, this)
});
}
});
};
-123
View File
@@ -1,123 +0,0 @@
var InfoBox = new Class({
Implements: [Options, Events],
options: {
parent : null,
message : "This is my info box!",
width : 200
},
profiles: {
gray : {"background" : "#EEEEEE", "border" : "#CCCCCC"},
green : {"background" : "#DAF8DA", "border" : "#166D14"},
red : {"background" : "#F9D2D2", "border" : "#FF2A00"},
yellow : {"background" : "#FDE6B5", "border" : "#FF7F00"}
},
initialize: function(options) {
this.setOptions(options);
var boxleft = $(document.body).getSize().x / 2 - this.options.width / 2;
this.box = new Element("div", {"id" : "infobox"});
this.box.setStyles({
"font-size" : "1em",
"font-weight" : "bold",
"text-align" : "left",
"padding" : "10px",
"position" : "absolute",
"display" : "none"
});
this.calcsize();
this.setProfile("gray");
this.spinner = new Element("img", {
"src" : "/static/css/spinner.gif"
});
this.spinner.setStyle("float", "left");
this.spinner.inject(this.box);
this.label = new Element("label").set("html", this.options.message);
this.label.setStyles({
"white-space": "pre-line"
/*"margin-left" : "10px"*/
});
this.label.inject(this.box);
this.box.inject($(document.body));
},
calcsize: function(width) {
var w = ($defined(width) ? width : this.options.width);
var boxleft = $(document.body).getSize().x / 2 - w / 2;
this.box.setStyles({
width: w + "px",
left: boxleft + "px",
top: "0px"
});
},
setMessage: function(text) {
this.label.set("html", text);
},
setProfile: function(color) {
this.box.setStyles({
"background" : this.profiles[color].background,
"border" : "2px solid " + this.profiles[color].border
});
},
info: function(message) {
this.show(message, {
profile: "green"
});
},
error: function(message) {
this.show(message, {
profile: "red"
});
},
warning: function(message) {
this.show(message, {
profile: "yellow"
});
},
show: function(message, arguments) {
if ($defined(this.start)) {
if ($time() - this.start > this.delay) {
$clear(this.showtimer);
delete(this.start);
delete(this.delay);
} else {
this.showtimer = this.show.delay(100, this, [message, arguments]);
return;
}
}
if ($defined(message)) {
this.setMessage(message);
}
if ($defined(arguments.profile)) {
this.setProfile(arguments.profile);
}
if ($defined(arguments.delay)) {
this.start = $time();
this.delay = arguments.delay * 1000;
}
if ($defined(arguments.spinner) && arguments.spinner) {
this.spinner.setStyle("display", "block");
} else {
this.spinner.setStyle("display", "none");
}
this.box.setStyle("display", "block");
},
hide: function(timer) {
this.timer = this.hide_cb.periodical(timer * 1000, this);
},
hide_cb: function() {
$clear(this.timer);
this.box.setStyle("display", "none");
}
});
+4
View File
File diff suppressed because one or more lines are too long
-314
View File
@@ -1,314 +0,0 @@
// MooTools: the javascript framework.
// Load this file's selection again by visiting: http://mootools.net/more/0d7eff673be62f7563fb40582690b0f5
// Or build this file again with packager using: packager build More/String.QueryString More/URI More/Hash More/Form.Request More/Fx.Accordion More/Fx.Slide More/Drag.Move More/HtmlTable.Select More/Tips
/*
---
copyrights:
- [MooTools](http://mootools.net)
licenses:
- [MIT License](http://mootools.net/license.txt)
...
*/
MooTools.More={version:"1.3.1.1",build:"0292a3af1eea242b817fecf9daa127417d10d4ce"};String.implement({parseQueryString:function(d,a){if(d==null){d=true;
}if(a==null){a=true;}var c=this.split(/[&;]/),b={};if(!c.length){return b;}c.each(function(i){var e=i.indexOf("=")+1,g=e?i.substr(e):"",f=e?i.substr(0,e-1).match(/([^\]\[]+|(\B)(?=\]))/g):[i],h=b;
if(!f){return;}if(a){g=decodeURIComponent(g);}f.each(function(k,j){if(d){k=decodeURIComponent(k);}var l=h[k];if(j<f.length-1){h=h[k]=l||{};}else{if(typeOf(l)=="array"){l.push(g);
}else{h[k]=l!=null?[l,g]:g;}}});});return b;},cleanQueryString:function(a){return this.split("&").filter(function(e){var b=e.indexOf("="),c=b<0?"":e.substr(0,b),d=e.substr(b+1);
return a?a.call(null,c,d):(d||d===0);}).join("&");}});(function(){var b=function(){return this.get("value");};var a=this.URI=new Class({Implements:Options,options:{},regex:/^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)?(\.\.?$|(?:[^?#\/]*\/)*)([^?#]*)(?:\?([^#]*))?(?:#(.*))?/,parts:["scheme","user","password","host","port","directory","file","query","fragment"],schemes:{http:80,https:443,ftp:21,rtsp:554,mms:1755,file:0},initialize:function(d,c){this.setOptions(c);
var e=this.options.base||a.base;if(!d){d=e;}if(d&&d.parsed){this.parsed=Object.clone(d.parsed);}else{this.set("value",d.href||d.toString(),e?new a(e):false);
}},parse:function(e,d){var c=e.match(this.regex);if(!c){return false;}c.shift();return this.merge(c.associate(this.parts),d);},merge:function(d,c){if((!d||!d.scheme)&&(!c||!c.scheme)){return false;
}if(c){this.parts.every(function(e){if(d[e]){return false;}d[e]=c[e]||"";return true;});}d.port=d.port||this.schemes[d.scheme.toLowerCase()];d.directory=d.directory?this.parseDirectory(d.directory,c?c.directory:""):"/";
return d;},parseDirectory:function(d,e){d=(d.substr(0,1)=="/"?"":(e||"/"))+d;if(!d.test(a.regs.directoryDot)){return d;}var c=[];d.replace(a.regs.endSlash,"").split("/").each(function(f){if(f==".."&&c.length>0){c.pop();
}else{if(f!="."){c.push(f);}}});return c.join("/")+"/";},combine:function(c){return c.value||c.scheme+"://"+(c.user?c.user+(c.password?":"+c.password:"")+"@":"")+(c.host||"")+(c.port&&c.port!=this.schemes[c.scheme]?":"+c.port:"")+(c.directory||"/")+(c.file||"")+(c.query?"?"+c.query:"")+(c.fragment?"#"+c.fragment:"");
},set:function(d,f,e){if(d=="value"){var c=f.match(a.regs.scheme);if(c){c=c[1];}if(c&&this.schemes[c.toLowerCase()]==null){this.parsed={scheme:c,value:f};
}else{this.parsed=this.parse(f,(e||this).parsed)||(c?{scheme:c,value:f}:{value:f});}}else{if(d=="data"){this.setData(f);}else{this.parsed[d]=f;}}return this;
},get:function(c,d){switch(c){case"value":return this.combine(this.parsed,d?d.parsed:false);case"data":return this.getData();}return this.parsed[c]||"";
},go:function(){document.location.href=this.toString();},toURI:function(){return this;},getData:function(e,d){var c=this.get(d||"query");if(!(c||c===0)){return e?null:{};
}var f=c.parseQueryString();return e?f[e]:f;},setData:function(c,f,d){if(typeof c=="string"){var e=this.getData();e[arguments[0]]=arguments[1];c=e;}else{if(f){c=Object.merge(this.getData(),c);
}}return this.set(d||"query",Object.toQueryString(c));},clearData:function(c){return this.set(c||"query","");},toString:b,valueOf:b});a.regs={endSlash:/\/$/,scheme:/^(\w+):/,directoryDot:/\.\/|\.$/};
a.base=new a(Array.from(document.getElements("base[href]",true)).getLast(),{base:document.location});String.implement({toURI:function(c){return new a(this,c);
}});}).call(this);(function(){if(this.Hash){return;}var a=this.Hash=new Type("Hash",function(b){if(typeOf(b)=="hash"){b=Object.clone(b.getClean());}for(var c in b){this[c]=b[c];
}return this;});this.$H=function(b){return new a(b);};a.implement({forEach:function(b,c){Object.forEach(this,b,c);},getClean:function(){var c={};for(var b in this){if(this.hasOwnProperty(b)){c[b]=this[b];
}}return c;},getLength:function(){var c=0;for(var b in this){if(this.hasOwnProperty(b)){c++;}}return c;}});a.alias("each","forEach");a.implement({has:Object.prototype.hasOwnProperty,keyOf:function(b){return Object.keyOf(this,b);
},hasValue:function(b){return Object.contains(this,b);},extend:function(b){a.each(b||{},function(d,c){a.set(this,c,d);},this);return this;},combine:function(b){a.each(b||{},function(d,c){a.include(this,c,d);
},this);return this;},erase:function(b){if(this.hasOwnProperty(b)){delete this[b];}return this;},get:function(b){return(this.hasOwnProperty(b))?this[b]:null;
},set:function(b,c){if(!this[b]||this.hasOwnProperty(b)){this[b]=c;}return this;},empty:function(){a.each(this,function(c,b){delete this[b];},this);return this;
},include:function(b,c){if(this[b]==undefined){this[b]=c;}return this;},map:function(b,c){return new a(Object.map(this,b,c));},filter:function(b,c){return new a(Object.filter(this,b,c));
},every:function(b,c){return Object.every(this,b,c);},some:function(b,c){return Object.some(this,b,c);},getKeys:function(){return Object.keys(this);},getValues:function(){return Object.values(this);
},toQueryString:function(b){return Object.toQueryString(this,b);}});a.alias({indexOf:"keyOf",contains:"hasValue"});}).call(this);Class.Mutators.Binds=function(a){if(!this.prototype.initialize){this.implement("initialize",function(){});
}return a;};Class.Mutators.initialize=function(a){return function(){Array.from(this.Binds).each(function(b){var c=this[b];if(c){this[b]=c.bind(this);}},this);
return a.apply(this,arguments);};};Class.Occlude=new Class({occlude:function(c,b){b=document.id(b||this.element);var a=b.retrieve(c||this.property);if(a&&!this.occluded){return(this.occluded=a);
}this.occluded=false;b.store(c||this.property,this);return this.occluded;}});Class.refactor=function(b,a){Object.each(a,function(e,d){var c=b.prototype[d];
if(c&&c.$origin){c=c.$origin;}b.implement(d,(typeof e=="function")?function(){var f=this.previous;this.previous=c||function(){};var g=e.apply(this,arguments);
this.previous=f;return g;}:e);});return b;};(function(){var b=function(e,d){var f=[];Object.each(d,function(g){Object.each(g,function(h){e.each(function(i){f.push(i+"-"+h+(i=="border"?"-width":""));
});});});return f;};var c=function(f,e){var d=0;Object.each(e,function(h,g){if(g.test(f)){d=d+h.toInt();}});return d;};var a=function(d){return !!(!d||d.offsetHeight||d.offsetWidth);
};Element.implement({measure:function(h){if(a(this)){return h.call(this);}var g=this.getParent(),e=[];while(!a(g)&&g!=document.body){e.push(g.expose());
g=g.getParent();}var f=this.expose(),d=h.call(this);f();e.each(function(i){i();});return d;},expose:function(){if(this.getStyle("display")!="none"){return function(){};
}var d=this.style.cssText;this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=d;}.bind(this);
},getDimensions:function(d){d=Object.merge({computeSize:false},d);var i={x:0,y:0};var h=function(j,e){return(e.computeSize)?j.getComputedSize(e):j.getSize();
};var f=this.getParent("body");if(f&&this.getStyle("display")=="none"){i=this.measure(function(){return h(this,d);});}else{if(f){try{i=h(this,d);}catch(g){}}}return Object.append(i,(i.x||i.x===0)?{width:i.x,height:i.y}:{x:i.width,y:i.height});
},getComputedSize:function(d){if(d&&d.plains){d.planes=d.plains;}d=Object.merge({styles:["padding","border"],planes:{height:["top","bottom"],width:["left","right"]},mode:"both"},d);
var g={},e={width:0,height:0},f;if(d.mode=="vertical"){delete e.width;delete d.planes.width;}else{if(d.mode=="horizontal"){delete e.height;delete d.planes.height;
}}b(d.styles,d.planes).each(function(h){g[h]=this.getStyle(h).toInt();},this);Object.each(d.planes,function(i,h){var k=h.capitalize(),j=this.getStyle(h);
if(j=="auto"&&!f){f=this.getDimensions();}j=g[h]=(j=="auto")?f[h]:j.toInt();e["total"+k]=j;i.each(function(m){var l=c(m,g);e["computed"+m.capitalize()]=l;
e["total"+k]+=l;});},this);return Object.append(e,g);}});}).call(this);(function(){var a=Element.prototype.position;Element.implement({position:function(g){if(g&&(g.x!=null||g.y!=null)){return a?a.apply(this,arguments):this;
}Object.each(g||{},function(u,t){if(u==null){delete g[t];}});g=Object.merge({relativeTo:document.body,position:{x:"center",y:"center"},offset:{x:0,y:0}},g);
var r={x:0,y:0},e=false;var c=this.measure(function(){return document.id(this.getOffsetParent());});if(c&&c!=this.getDocument().body){r=c.measure(function(){return this.getPosition();
});e=c!=document.id(g.relativeTo);g.offset.x=g.offset.x-r.x;g.offset.y=g.offset.y-r.y;}var s=function(t){if(typeOf(t)!="string"){return t;}t=t.toLowerCase();
var u={};if(t.test("left")){u.x="left";}else{if(t.test("right")){u.x="right";}else{u.x="center";}}if(t.test("upper")||t.test("top")){u.y="top";}else{if(t.test("bottom")){u.y="bottom";
}else{u.y="center";}}return u;};g.edge=s(g.edge);g.position=s(g.position);if(!g.edge){if(g.position.x=="center"&&g.position.y=="center"){g.edge={x:"center",y:"center"};
}else{g.edge={x:"left",y:"top"};}}this.setStyle("position","absolute");var f=document.id(g.relativeTo)||document.body,d=f==document.body?window.getScroll():f.getPosition(),l=d.y,h=d.x;
var n=this.getDimensions({computeSize:true,styles:["padding","border","margin"]});var j={},o=g.offset.y,q=g.offset.x,k=window.getSize();switch(g.position.x){case"left":j.x=h+q;
break;case"right":j.x=h+q+f.offsetWidth;break;default:j.x=h+((f==document.body?k.x:f.offsetWidth)/2)+q;break;}switch(g.position.y){case"top":j.y=l+o;break;
case"bottom":j.y=l+o+f.offsetHeight;break;default:j.y=l+((f==document.body?k.y:f.offsetHeight)/2)+o;break;}if(g.edge){var b={};switch(g.edge.x){case"left":b.x=0;
break;case"right":b.x=-n.x-n.computedRight-n.computedLeft;break;default:b.x=-(n.totalWidth/2);break;}switch(g.edge.y){case"top":b.y=0;break;case"bottom":b.y=-n.y-n.computedTop-n.computedBottom;
break;default:b.y=-(n.totalHeight/2);break;}j.x+=b.x;j.y+=b.y;}j={left:((j.x>=0||e||g.allowNegative)?j.x:0).toInt(),top:((j.y>=0||e||g.allowNegative)?j.y:0).toInt()};
var i={left:"x",top:"y"};["minimum","maximum"].each(function(t){["left","top"].each(function(u){var v=g[t]?g[t][i[u]]:null;if(v!=null&&((t=="minimum")?j[u]<v:j[u]>v)){j[u]=v;
}});});if(f.getStyle("position")=="fixed"||g.relFixedPosition){var m=window.getScroll();j.top+=m.y;j.left+=m.x;}if(g.ignoreScroll){var p=f.getScroll();
j.top-=p.y;j.left-=p.x;}if(g.ignoreMargins){j.left+=(g.edge.x=="right"?n["margin-right"]:g.edge.x=="center"?-n["margin-left"]+((n["margin-right"]+n["margin-left"])/2):-n["margin-left"]);
j.top+=(g.edge.y=="bottom"?n["margin-bottom"]:g.edge.y=="center"?-n["margin-top"]+((n["margin-bottom"]+n["margin-top"])/2):-n["margin-top"]);}j.left=Math.ceil(j.left);
j.top=Math.ceil(j.top);if(g.returnPos){return j;}else{this.setStyles(j);}return this;}});}).call(this);var IframeShim=new Class({Implements:[Options,Events,Class.Occlude],options:{className:"iframeShim",src:'javascript:false;document.write("");',display:false,zIndex:null,margin:0,offset:{x:0,y:0},browsers:(Browser.ie6||(Browser.firefox&&Browser.version<3&&Browser.Platform.mac))},property:"IframeShim",initialize:function(b,a){this.element=document.id(b);
if(this.occlude()){return this.occluded;}this.setOptions(a);this.makeShim();return this;},makeShim:function(){if(this.options.browsers){var c=this.element.getStyle("zIndex").toInt();
if(!c){c=1;var b=this.element.getStyle("position");if(b=="static"||!b){this.element.setStyle("position","relative");}this.element.setStyle("zIndex",c);
}c=((this.options.zIndex!=null||this.options.zIndex===0)&&c>this.options.zIndex)?this.options.zIndex:c-1;if(c<0){c=1;}this.shim=new Element("iframe",{src:this.options.src,scrolling:"no",frameborder:0,styles:{zIndex:c,position:"absolute",border:"none",filter:"progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)"},"class":this.options.className}).store("IframeShim",this);
var a=(function(){this.shim.inject(this.element,"after");this[this.options.display?"show":"hide"]();this.fireEvent("inject");}).bind(this);if(!IframeShim.ready){window.addEvent("load",a);
}else{a();}}else{this.position=this.hide=this.show=this.dispose=Function.from(this);}},position:function(){if(!IframeShim.ready||!this.shim){return this;
}var a=this.element.measure(function(){return this.getSize();});if(this.options.margin!=undefined){a.x=a.x-(this.options.margin*2);a.y=a.y-(this.options.margin*2);
this.options.offset.x+=this.options.margin;this.options.offset.y+=this.options.margin;}this.shim.set({width:a.x,height:a.y}).position({relativeTo:this.element,offset:this.options.offset});
return this;},hide:function(){if(this.shim){this.shim.setStyle("display","none");}return this;},show:function(){if(this.shim){this.shim.setStyle("display","block");
}return this.position();},dispose:function(){if(this.shim){this.shim.dispose();}return this;},destroy:function(){if(this.shim){this.shim.destroy();}return this;
}});window.addEvent("load",function(){IframeShim.ready=true;});var Mask=new Class({Implements:[Options,Events],Binds:["position"],options:{style:{},"class":"mask",maskMargins:false,useIframeShim:true,iframeShimOptions:{}},initialize:function(b,a){this.target=document.id(b)||document.id(document.body);
this.target.store("mask",this);this.setOptions(a);this.render();this.inject();},render:function(){this.element=new Element("div",{"class":this.options["class"],id:this.options.id||"mask-"+String.uniqueID(),styles:Object.merge({},this.options.style,{display:"none"}),events:{click:function(a){this.fireEvent("click",a);
if(this.options.hideOnClick){this.hide();}}.bind(this)}});this.hidden=true;},toElement:function(){return this.element;},inject:function(b,a){a=a||(this.options.inject?this.options.inject.where:"")||this.target==document.body?"inside":"after";
b=b||(this.options.inject&&this.options.inject.target)||this.target;this.element.inject(b,a);if(this.options.useIframeShim){this.shim=new IframeShim(this.element,this.options.iframeShimOptions);
this.addEvents({show:this.shim.show.bind(this.shim),hide:this.shim.hide.bind(this.shim),destroy:this.shim.destroy.bind(this.shim)});}},position:function(){this.resize(this.options.width,this.options.height);
this.element.position({relativeTo:this.target,position:"topLeft",ignoreMargins:!this.options.maskMargins,ignoreScroll:this.target==document.body});return this;
},resize:function(a,e){var b={styles:["padding","border"]};if(this.options.maskMargins){b.styles.push("margin");}var d=this.target.getComputedSize(b);if(this.target==document.body){this.element.setStyles({width:0,height:0});
var c=window.getScrollSize();if(d.totalHeight<c.y){d.totalHeight=c.y;}if(d.totalWidth<c.x){d.totalWidth=c.x;}}this.element.setStyles({width:Array.pick([a,d.totalWidth,d.x]),height:Array.pick([e,d.totalHeight,d.y])});
return this;},show:function(){if(!this.hidden){return this;}window.addEvent("resize",this.position);this.position();this.showMask.apply(this,arguments);
return this;},showMask:function(){this.element.setStyle("display","block");this.hidden=false;this.fireEvent("show");},hide:function(){if(this.hidden){return this;
}window.removeEvent("resize",this.position);this.hideMask.apply(this,arguments);if(this.options.destroyOnHide){return this.destroy();}return this;},hideMask:function(){this.element.setStyle("display","none");
this.hidden=true;this.fireEvent("hide");},toggle:function(){this[this.hidden?"show":"hide"]();},destroy:function(){this.hide();this.element.destroy();this.fireEvent("destroy");
this.target.eliminate("mask");}});Element.Properties.mask={set:function(b){var a=this.retrieve("mask");if(a){a.destroy();}return this.eliminate("mask").store("mask:options",b);
},get:function(){var a=this.retrieve("mask");if(!a){a=new Mask(this,this.retrieve("mask:options"));this.store("mask",a);}return a;}};Element.implement({mask:function(a){if(a){this.set("mask",a);
}this.get("mask").show();return this;},unmask:function(){this.get("mask").hide();return this;}});var Spinner=new Class({Extends:Mask,Implements:Chain,options:{"class":"spinner",containerPosition:{},content:{"class":"spinner-content"},messageContainer:{"class":"spinner-msg"},img:{"class":"spinner-img"},fxOptions:{link:"chain"}},initialize:function(c,a){this.target=document.id(c)||document.id(document.body);
this.target.store("spinner",this);this.setOptions(a);this.render();this.inject();var b=function(){this.active=false;}.bind(this);this.addEvents({hide:b,show:b});
},render:function(){this.parent();this.element.set("id",this.options.id||"spinner-"+String.uniqueID());this.content=document.id(this.options.content)||new Element("div",this.options.content);
this.content.inject(this.element);if(this.options.message){this.msg=document.id(this.options.message)||new Element("p",this.options.messageContainer).appendText(this.options.message);
this.msg.inject(this.content);}if(this.options.img){this.img=document.id(this.options.img)||new Element("div",this.options.img);this.img.inject(this.content);
}this.element.set("tween",this.options.fxOptions);},show:function(a){if(this.active){return this.chain(this.show.bind(this));}if(!this.hidden){this.callChain.delay(20,this);
return this;}this.active=true;return this.parent(a);},showMask:function(a){var b=function(){this.content.position(Object.merge({relativeTo:this.element},this.options.containerPosition));
}.bind(this);if(a){this.parent();b();}else{if(!this.options.style.opacity){this.options.style.opacity=this.element.getStyle("opacity").toFloat();}this.element.setStyles({display:"block",opacity:0}).tween("opacity",this.options.style.opacity);
b();this.hidden=false;this.fireEvent("show");this.callChain();}},hide:function(a){if(this.active){return this.chain(this.hide.bind(this));}if(this.hidden){this.callChain.delay(20,this);
return this;}this.active=true;return this.parent(a);},hideMask:function(a){if(a){return this.parent();}this.element.tween("opacity",0).get("tween").chain(function(){this.element.setStyle("display","none");
this.hidden=true;this.fireEvent("hide");this.callChain();}.bind(this));},destroy:function(){this.content.destroy();this.parent();this.target.eliminate("spinner");
}});Request=Class.refactor(Request,{options:{useSpinner:false,spinnerOptions:{},spinnerTarget:false},initialize:function(a){this._send=this.send;this.send=function(b){var c=this.getSpinner();
if(c){c.chain(this._send.pass(b,this)).show();}else{this._send(b);}return this;};this.previous(a);},getSpinner:function(){if(!this.spinner){var b=document.id(this.options.spinnerTarget)||document.id(this.options.update);
if(this.options.useSpinner&&b){b.set("spinner",this.options.spinnerOptions);var a=this.spinner=b.get("spinner");["complete","exception","cancel"].each(function(c){this.addEvent(c,a.hide.bind(a));
},this);}}return this.spinner;}});Element.Properties.spinner={set:function(a){var b=this.retrieve("spinner");if(b){b.destroy();}return this.eliminate("spinner").store("spinner:options",a);
},get:function(){var a=this.retrieve("spinner");if(!a){a=new Spinner(this,this.retrieve("spinner:options"));this.store("spinner",a);}return a;}};Element.implement({spin:function(a){if(a){this.set("spinner",a);
}this.get("spinner").show();return this;},unspin:function(){this.get("spinner").hide();return this;}});Events.Pseudos=function(g,c,e){var b="monitorEvents:";
var a=function(h){return{store:h.store?function(i,j){h.store(b+i,j);}:function(i,j){(h.$monitorEvents||(h.$monitorEvents={}))[i]=j;},retrieve:h.retrieve?function(i,j){return h.retrieve(b+i,j);
}:function(i,j){if(!h.$monitorEvents){return j;}return h.$monitorEvents[i]||j;}};};var f=function(j){if(j.indexOf(":")==-1||!g){return null;}var i=Slick.parse(j).expressions[0][0],m=i.pseudos,h=m.length,k=[];
while(h--){if(g[m[h].key]){k.push({event:i.tag,value:m[h].value,pseudo:m[h].key,original:j});}}return k.length?k:null;};var d=function(h){return Object.merge.apply(this,h.map(function(i){return g[i.pseudo].options||{};
}));};return{addEvent:function(m,p,j){var n=f(m);if(!n){return c.call(this,m,p,j);}var k=a(this),s=k.retrieve(m,[]),h=n[0].event,t=d(n),o=p,i=t[h]||{},l=Array.slice(arguments,2),r=this,q;
if(i.args){l.append(Array.from(i.args));}if(i.base){h=i.base;}if(i.onAdd){i.onAdd(this);}n.each(function(u){var v=o;o=function(){(i.listener||g[u.pseudo].listener).call(r,u,v,arguments,q,t);
};});q=o.bind(this);s.include({event:p,monitor:q});k.store(m,s);c.apply(this,[m,p].concat(l));return c.apply(this,[h,q].concat(l));},removeEvent:function(l,n){var m=f(l);
if(!m){return e.call(this,l,n);}var j=a(this),o=j.retrieve(l);if(!o){return this;}var h=m[0].event,p=d(m),i=p[h]||{},k=Array.slice(arguments,2);if(i.args){k.append(Array.from(i.args));
}if(i.base){h=i.base;}if(i.onRemove){i.onRemove(this);}e.apply(this,[l,n].concat(k));o.each(function(q,r){if(!n||q.event==n){e.apply(this,[h,q.monitor].concat(k));
}delete o[r];},this);j.store(l,o);return this;}};};(function(){var b={once:{listener:function(e,f,d,c){f.apply(this,d);this.removeEvent(e.event,c).removeEvent(e.original,f);
}},throttle:{listener:function(d,e,c){if(!e._throttled){e.apply(this,c);e._throttled=setTimeout(function(){e._throttled=false;},d.value||250);}}},pause:{listener:function(d,e,c){clearTimeout(e._pause);
e._pause=e.delay(d.value||250,this,c);}}};Events.definePseudo=function(c,d){b[c]=Type.isFunction(d)?{listener:d}:d;return this;};Events.lookupPseudo=function(c){return b[c];
};var a=Events.prototype;Events.implement(Events.Pseudos(b,a.addEvent,a.removeEvent));["Request","Fx"].each(function(c){if(this[c]){this[c].implement(Events.prototype);
}});}).call(this);(function(){var d={},c=["once","throttle","pause"],b=c.length;while(b--){d[c[b]]=Events.lookupPseudo(c[b]);}Event.definePseudo=function(e,f){d[e]=Type.isFunction(f)?{listener:f}:f;
return this;};var a=Element.prototype;[Element,Window,Document].invoke("implement",Events.Pseudos(d,a.addEvent,a.removeEvent));}).call(this);(function(){var b=!(window.attachEvent&&!window.addEventListener),e=Element.NativeEvents;
e.focusin=2;e.focusout=2;var c=function(g,j,h){var i=Element.Events[g.event],k;if(i){k=i.condition;}return Slick.match(j,g.value)&&(!k||k.call(j,h));};
var f=function(g){var h="$delegation:";return{base:"focusin",onRemove:function(i){i.retrieve(h+"forms",[]).each(function(j){j.retrieve(h+"listeners",[]).each(function(k){j.removeEvent(g,k);
});j.eliminate(h+g+"listeners").eliminate(h+g+"originalFn");});},listener:function(q,r,p,s,t){var j=p[0],i=this.retrieve(h+"forms",[]),o=j.target,l=(o.get("tag")=="form")?o:j.target.getParent("form"),n=l.retrieve(h+"originalFn",[]),k=l.retrieve(h+"listeners",[]);
i.include(l);this.store(h+"forms",i);if(!n.contains(r)){var m=function(u){if(c(q,this,u)){r.call(this,u);}};l.addEvent(g,m);n.push(r);k.push(m);l.store(h+g+"originalFn",n).store(h+g+"listeners",k);
}}};};var a=function(g){return{base:"focusin",listener:function(j,k,h){var i={blur:function(){this.removeEvents(i);}};i[g]=function(l){if(c(j,this,l)){k.call(this,l);
}};h[0].target.addEvents(i);}};};var d={mouseenter:{base:"mouseover"},mouseleave:{base:"mouseout"},focus:{base:"focus"+(b?"":"in"),args:[true]},blur:{base:b?"blur":"focusout",args:[true]}};
if(!b){Object.append(d,{submit:f("submit"),reset:f("reset"),change:a("change"),select:a("select")});}Event.definePseudo("relay",{listener:function(j,k,i,g,h){var l=i[0];
for(var n=l.target;n&&n!=this;n=n.parentNode){var m=document.id(n);if(c(j,m,l)){if(m){k.call(m,l,m);}return;}}},options:d});}).call(this);if(!window.Form){window.Form={};
}(function(){Form.Request=new Class({Binds:["onSubmit","onFormValidate"],Implements:[Options,Events,Class.Occlude],options:{requestOptions:{evalScripts:true,useSpinner:true,emulation:false,link:"ignore"},sendButtonClicked:true,extraData:{},resetForm:true},property:"form.request",initialize:function(b,c,a){this.element=document.id(b);
if(this.occlude()){return this.occluded;}this.update=document.id(c);this.setOptions(a);this.makeRequest();if(this.options.resetForm){this.request.addEvent("success",function(){Function.attempt(function(){this.element.reset();
}.bind(this));if(window.OverText){OverText.update();}}.bind(this));}this.attach();},toElement:function(){return this.element;},makeRequest:function(){this.request=new Request.HTML(Object.merge({update:this.update,emulation:false,spinnerTarget:this.element,method:this.element.get("method")||"post"},this.options.requestOptions)).addEvents({success:function(b,d,c,a){["complete","success"].each(function(e){this.fireEvent(e,[this.update,b,d,c,a]);
},this);}.bind(this),failure:function(){this.fireEvent("complete",arguments).fireEvent("failure",arguments);}.bind(this),exception:function(){this.fireEvent("failure",arguments);
}.bind(this)});},attach:function(a){if(a==null){a=true;}var c=a?"addEvent":"removeEvent";this.element[c]("click:relay(button, input[type=submit])",this.saveClickedButton.bind(this));
var b=this.element.retrieve("validator");if(b){b[c]("onFormValidate",this.onFormValidate);}else{this.element[c]("submit",this.onSubmit);}},detach:function(){this.attach(false);
return this;},enable:function(){this.attach();return this;},disable:function(){this.detach();return this;},onFormValidate:function(c,b,a){if(!a){return;
}var d=this.element.retrieve("validator");if(c||(d&&!d.options.stopOnFailure)){a.stop();this.send();}},onSubmit:function(a){var b=this.element.retrieve("validator");
if(b){this.element.removeEvent("submit",this.onSubmit);b.addEvent("onFormValidate",this.onFormValidate);this.element.validate();return;}if(a){a.stop();
}this.send();},saveClickedButton:function(a,b){if(!this.options.sendButtonClicked||!b.get("name")){return;}this.options.extraData[b.get("name")]=b.get("value")||true;
this.clickedCleaner=function(){delete this.options.extraData[b.get("name")];this.clickedCleaner=function(){};}.bind(this);},clickedCleaner:function(){},send:function(){var b=this.element.toQueryString().trim(),a=Object.toQueryString(this.options.extraData);
if(b){b+="&"+a;}else{b=a;}this.fireEvent("send",[this.element,b.parseQueryString()]);this.request.send({data:b,url:this.options.requestOptions.url||this.element.get("action")});
this.clickedCleaner();return this;}});Element.Properties.formRequest={set:function(){var a=Array.link(arguments,{options:Type.isObject,update:Type.isElement,updateId:Type.isString}),c=a.update||a.updateId,b=this.retrieve("form.request");
if(c){if(b){b.update=document.id(c);}this.store("form.request:update",c);}if(a.options){if(b){b.setOptions(a.options);}this.store("form.request:options",a.options);
}return this;},get:function(){var a=Array.link(arguments,{options:Type.isObject,update:Type.isElement,updateId:Type.isString}),b=a.update||a.updateId;if(a.options||b||!this.retrieve("form.request")){if(a.options||!this.retrieve("form.request:options")){this.set("form.request",a.options);
}if(b){this.set("form.request",b);}this.store("form.request",new Form.Request(this,this.retrieve("form.request:update"),this.retrieve("form.request:options")));
}return this.retrieve("form.request");}};Element.implement({formUpdate:function(b,a){this.get("formRequest",b,a).send();return this;}});}).call(this);Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b);
this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c;
},set:function(b){for(var c in b){if(!this.elements[c]){continue;}var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);}}return this;
},start:function(c){if(!this.check(c)){return this;}var h={},j={};for(var d in c){if(!this.elements[d]){continue;}var f=c[d],a=h[d]={},g=j[d]={};for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);
a[b]=e.from;g[b]=e.to;}}return this.parent(h,j);}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{fixedHeight:false,fixedWidth:false,display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,resetHeight:true},initialize:function(){var g=function(h){return h!=null;
};var f=Array.link(arguments,{container:Type.isElement,options:Type.isObject,togglers:g,elements:g});this.parent(f.elements,f.options);var b=this.options,e=this.togglers=$$(f.togglers);
this.previous=-1;this.internalChain=new Chain();if(b.alwaysHide){this.options.link="chain";}if(b.show||this.options.show===0){b.display=false;this.previous=b.show;
}if(b.start){b.display=false;b.show=false;}var d=this.effects={};if(b.opacity){d.opacity="fullOpacity";}if(b.width){d.width=b.fixedWidth?"fullWidth":"offsetWidth";
}if(b.height){d.height=b.fixedHeight?"fullHeight":"scrollHeight";}for(var c=0,a=e.length;c<a;c++){this.addSection(e[c],this.elements[c]);}this.elements.each(function(j,h){if(b.show===h){this.fireEvent("active",[e[h],j]);
}else{for(var k in d){j.setStyle(k,0);}}},this);if(b.display||b.display===0||b.initialDisplayFx===false){this.display(b.display,b.initialDisplayFx);}if(b.fixedHeight!==false){b.resetHeight=false;
}this.addEvent("complete",this.internalChain.callChain.bind(this.internalChain));},addSection:function(g,d){g=document.id(g);d=document.id(d);this.togglers.include(g);
this.elements.include(d);var f=this.togglers,c=this.options,h=f.contains(g),a=f.indexOf(g),b=this.display.pass(a,this);g.store("accordion:display",b).addEvent(c.trigger,b);
if(c.height){d.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(c.width){d.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
}d.fullOpacity=1;if(c.fixedWidth){d.fullWidth=c.fixedWidth;}if(c.fixedHeight){d.fullHeight=c.fixedHeight;}d.setStyle("overflow","hidden");if(!h){for(var e in this.effects){d.setStyle(e,0);
}}return this;},removeSection:function(f,b){var e=this.togglers,a=e.indexOf(f),c=this.elements[a];var d=function(){e.erase(f);this.elements.erase(c);this.detach(f);
}.bind(this);if(this.now==a||b!=null){this.display(b!=null?b:(a-1>=0?a-1:0)).chain(d);}else{d();}return this;},detach:function(b){var a=function(c){c.removeEvent(this.options.trigger,c.retrieve("accordion:display"));
}.bind(this);if(!b){this.togglers.each(a);}else{a(b);}return this;},display:function(b,c){if(!this.check(b,c)){return this;}var h={},g=this.elements,a=this.options,f=this.effects;
if(c==null){c=true;}if(typeOf(b)=="element"){b=g.indexOf(b);}if(b==this.previous&&!a.alwaysHide){return this;}if(a.resetHeight){var e=g[this.previous];
if(e&&!this.selfHidden){for(var d in f){e.setStyle(d,e[f[d]]);}}}if((this.timer&&a.link=="chain")||(b===this.previous&&!a.alwaysHide)){return this;}this.previous=b;
this.selfHidden=false;g.each(function(l,k){h[k]={};var j;if(k!=b){j=true;}else{if(a.alwaysHide&&((l.offsetHeight>0&&a.height)||l.offsetWidth>0&&a.width)){j=true;
this.selfHidden=true;}}this.fireEvent(j?"background":"active",[this.togglers[k],l]);for(var m in f){h[k][m]=j?0:l[f[m]];}if(!c&&!j&&a.resetHeight){h[k].height="auto";
}},this);this.internalChain.clearChain();this.internalChain.chain(function(){if(a.resetHeight&&!this.selfHidden){var i=g[b];if(i){i.setStyle("height","auto");
}}}.bind(this));return c?this.start(h):this.set(h);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);
var a=Array.link(arguments,{container:Type.isElement});this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);
var a=this.togglers.length;if(a&&(!d||e)){e=e!=null?e:a-1;c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);
b.inject(this.container);}}return this.parent.apply(this,arguments);}});Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical",wrapper:false,hideOverflow:true,resetHeight:false},initialize:function(b,a){b=this.element=this.subject=document.id(b);
this.parent(a);a=this.options;var d=b.retrieve("wrapper"),c=b.getStyles("margin","position","overflow");if(a.hideOverflow){c=Object.append(c,{overflow:"hidden"});
}if(a.wrapper){d=document.id(a.wrapper).setStyles(c);}if(!d){d=new Element("div",{styles:c}).wraps(b);}b.store("wrapper",d).setStyle("margin",0);if(b.getStyle("overflow")=="visible"){b.setStyle("overflow","hidden");
}this.now=[];this.open=true;this.wrapper=d;this.addEvent("complete",function(){this.open=(d["offset"+this.layout.capitalize()]!=0);if(this.open&&a.resetHeight){d.setStyle("height","");
}},true);},vertical:function(){this.margin="margin-top";this.layout="height";this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";
this.layout="width";this.offset=this.element.offsetWidth;},set:function(a){this.element.setStyle(this.margin,a[0]);this.wrapper.setStyle(this.layout,a[1]);
return this;},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(b,e){if(!this.check(b,e)){return this;
}this[e||this.options.mode]();var d=this.element.getStyle(this.margin).toInt(),c=this.wrapper.getStyle(this.layout).toInt(),a=[[d,c],[0,this.offset]],g=[[d,c],[-this.offset,0]],f;
switch(b){case"in":f=a;break;case"out":f=g;break;case"toggle":f=(c==0)?a:g;}return this.parent(f[0],f[1]);},slideIn:function(a){return this.start("in",a);
},slideOut:function(a){return this.start("out",a);},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0]);},show:function(a){this[a||this.options.mode]();
this.open=true;return this.set([0,this.offset]);},toggle:function(a){return this.start("toggle",a);}});Element.Properties.slide={set:function(a){this.get("slide").cancel().setOptions(a);
return this;},get:function(){var a=this.retrieve("slide");if(!a){a=new Fx.Slide(this,{link:"cancel"});this.store("slide",a);}return a;}};Element.implement({slide:function(d,e){d=d||"toggle";
var b=this.get("slide"),a;switch(d){case"hide":b.hide(e);break;case"show":b.show(e);break;case"toggle":var c=this.retrieve("slide:flag",b.open);b[c?"slideOut":"slideIn"](e);
this.store("slide:flag",!c);a=true;break;default:b.start(d,e);}if(!a){this.eliminate("slide:flag");}return this;}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Type.isObject,element:function(c){return c!=null;
}});this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=typeOf(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.ie)?"selectstart":"mousedown";if(Browser.ie&&!Drag.ondragstartFixed){document.ondragstart=Function.from(false);
Drag.ondragstartFixed=true;}this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:Function.from(false)};
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
return this;},start:function(a){var k=this.options;if(a.rightClick){return;}if(k.preventDefault){a.preventDefault();}if(k.stopPropagation){a.stopPropagation();
}this.mouse.start=a.page;this.fireEvent("beforeStart",this.element);var c=k.limit;this.limit={x:[],y:[]};var j=this.element.getStyles("left","right","top","bottom");
this._invert={x:k.modifiers.x=="left"&&j.left=="auto"&&!isNaN(j.right.toInt())&&(k.modifiers.x="right"),y:k.modifiers.y=="top"&&j.top=="auto"&&!isNaN(j.bottom.toInt())&&(k.modifiers.y="bottom")};
var e,g;for(e in k.modifiers){if(!k.modifiers[e]){continue;}var b=this.element.getStyle(k.modifiers[e]);if(b&&!b.match(/px$/)){if(!g){g=this.element.getCoordinates(this.element.getOffsetParent());
}b=g[k.modifiers[e]];}if(k.style){this.value.now[e]=(b||0).toInt();}else{this.value.now[e]=this.element[k.modifiers[e]];}if(k.invert){this.value.now[e]*=-1;
}if(this._invert[e]){this.value.now[e]*=-1;}this.mouse.pos[e]=a.page[e]-this.value.now[e];if(c&&c[e]){var d=2;while(d--){var f=c[e][d];if(f||f===0){this.limit[e][d]=(typeof f=="function")?f():f;
}}}}if(typeOf(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}var h={mousemove:this.bound.check,mouseup:this.bound.cancel};
h[this.selection]=this.bound.eventStop;this.document.addEvents(h);},check:function(a){if(this.options.preventDefault){a.preventDefault();}var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));
if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);
}},drag:function(b){var a=this.options;if(a.preventDefault){b.preventDefault();}this.mouse.now=b.page;for(var c in a.modifiers){if(!a.modifiers[c]){continue;
}this.value.now[c]=this.mouse.now[c]-this.mouse.pos[c];if(a.invert){this.value.now[c]*=-1;}if(this._invert[c]){this.value.now[c]*=-1;}if(a.limit&&this.limit[c]){if((this.limit[c][1]||this.limit[c][1]===0)&&(this.value.now[c]>this.limit[c][1])){this.value.now[c]=this.limit[c][1];
}else{if((this.limit[c][0]||this.limit[c][0]===0)&&(this.value.now[c]<this.limit[c][0])){this.value.now[c]=this.limit[c][0];}}}if(a.grid[c]){this.value.now[c]-=((this.value.now[c]-(this.limit[c][0]||0))%a.grid[c]);
}if(a.style){this.element.setStyle(a.modifiers[c],this.value.now[c]+a.unit);}else{this.element[a.modifiers[c]]=this.value.now[c];}}this.fireEvent("drag",[this.element,b]);
},cancel:function(a){this.document.removeEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});if(a){this.document.removeEvent(this.selection,this.bound.eventStop);
this.fireEvent("cancel",this.element);}},stop:function(b){var a={mousemove:this.bound.drag,mouseup:this.bound.stop};a[this.selection]=this.bound.eventStop;
this.document.removeEvents(a);if(b){this.fireEvent("complete",[this.element,b]);}}});Element.implement({makeResizable:function(a){var b=new Drag(this,Object.merge({modifiers:{x:"width",y:"height"}},a));
this.store("resizer",b);return b.addEvent("drag",function(){this.fireEvent("resize",b);}.bind(this));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false,precalculate:false,includeMargins:true,checkDroppables:true},initialize:function(b,a){this.parent(b,a);
b=this.element;this.droppables=$$(this.options.droppables);this.container=document.id(this.options.container);if(this.container&&typeOf(this.container)!="element"){this.container=document.id(this.container.getDocument().body);
}if(this.options.style){if(this.options.modifiers.x=="left"&&this.options.modifiers.y=="top"){var e,c=b.getOffsetParent();var d=b.getStyles("left","top");
if(c&&(d.left=="auto"||d.top=="auto")){b.setPosition(b.getPosition(c));}}if(b.getStyle("position")=="static"){b.setStyle("position","absolute");}}this.addEvent("start",this.checkDroppables,true);
this.overed=null;},start:function(a){if(this.container){this.options.limit=this.calculateLimit();}if(this.options.precalculate){this.positions=this.droppables.map(function(b){return b.getCoordinates();
});}this.parent(a);},calculateLimit:function(){var j=this.element,e=this.container,d=document.id(j.getOffsetParent())||document.body,h=e.getCoordinates(d),c={},b={},k={},g={},m={};
["top","right","bottom","left"].each(function(q){c[q]=j.getStyle("margin-"+q).toInt();b[q]=j.getStyle("border-"+q).toInt();k[q]=e.getStyle("margin-"+q).toInt();
g[q]=e.getStyle("border-"+q).toInt();m[q]=d.getStyle("padding-"+q).toInt();},this);var f=j.offsetWidth+c.left+c.right,p=j.offsetHeight+c.top+c.bottom,i=0,l=0,o=h.right-g.right-f,a=h.bottom-g.bottom-p;
if(this.options.includeMargins){i+=c.left;l+=c.top;}else{o+=c.right;a+=c.bottom;}if(j.getStyle("position")=="relative"){var n=j.getCoordinates(d);n.left-=j.getStyle("left").toInt();
n.top-=j.getStyle("top").toInt();i-=n.left;l-=n.top;if(e.getStyle("position")!="relative"){i+=g.left;l+=g.top;}o+=c.left-n.left;a+=c.top-n.top;if(e!=d){i+=k.left+m.left;
l+=((Browser.ie6||Browser.ie7)?0:k.top)+m.top;}}else{i-=c.left;l-=c.top;if(e!=d){i+=h.left+g.left;l+=h.top+g.top;}}return{x:[i,o],y:[l,a]};},getDroppableCoordinates:function(c){var b=c.getCoordinates();
if(c.getStyle("position")=="fixed"){var a=window.getScroll();b.left+=a.x;b.right+=a.x;b.top+=a.y;b.bottom+=a.y;}return b;},checkDroppables:function(){var a=this.droppables.filter(function(d,c){d=this.positions?this.positions[c]:this.getDroppableCoordinates(d);
var b=this.mouse.now;return(b.x>d.left&&b.x<d.right&&b.y<d.bottom&&b.y>d.top);},this).getLast();if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);
}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a);if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();
}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]);this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);
this.store("dragger",b);return b;}});(function(){var a="$moo:keys-pressed",b="$moo:keys-keyup";Event.definePseudo("keys",function(d,e,c){var g=c[0],f=[],h=this.retrieve(a,[]);
f.append(d.value.replace("++",function(){f.push("+");return"";}).split("+"));h.include(g.key);if(f.every(function(j){return h.contains(j);})){e.apply(this,c);
}this.store(a,h);if(!this.retrieve(b)){var i=function(j){(function(){h=this.retrieve(a,[]).erase(j.key);this.store(a,h);}).delay(0,this);};this.store(b,i).addEvent("keyup",i);
}});Object.append(Event.Keys,{shift:16,control:17,alt:18,capslock:20,pageup:33,pagedown:34,end:35,home:36,numlock:144,scrolllock:145,";":186,"=":187,",":188,"-":Browser.firefox?109:189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222,"+":107});
}).call(this);(function(){var a=this.Keyboard=new Class({Extends:Events,Implements:[Options],options:{defaultEventType:"keydown",active:false,manager:null,events:{},nonParsedEvents:["activate","deactivate","onactivate","ondeactivate","changed","onchanged"]},initialize:function(f){if(f&&f.manager){this._manager=f.manager;
delete f.manager;}this.setOptions(f);this._setup();},addEvent:function(h,g,f){return this.parent(a.parse(h,this.options.defaultEventType,this.options.nonParsedEvents),g,f);
},removeEvent:function(g,f){return this.parent(a.parse(g,this.options.defaultEventType,this.options.nonParsedEvents),f);},toggleActive:function(){return this[this.isActive()?"deactivate":"activate"]();
},activate:function(f){if(f){if(f.isActive()){return this;}if(this._activeKB&&f!=this._activeKB){this.previous=this._activeKB;this.previous.fireEvent("deactivate");
}this._activeKB=f.fireEvent("activate");a.manager.fireEvent("changed");}else{if(this._manager){this._manager.activate(this);}}return this;},isActive:function(){return this._manager?(this._manager._activeKB==this):(a.manager==this);
},deactivate:function(f){if(f){if(f===this._activeKB){this._activeKB=null;f.fireEvent("deactivate");a.manager.fireEvent("changed");}}else{if(this._manager){this._manager.deactivate(this);
}}return this;},relinquish:function(){if(this.isActive()&&this._manager&&this._manager.previous){this._manager.activate(this._manager.previous);}else{this.deactivate();
}return this;},manage:function(f){if(f._manager){f._manager.drop(f);}this._instances.push(f);f._manager=this;if(!this._activeKB){this.activate(f);}return this;
},drop:function(f){f.relinquish();this._instances.erase(f);if(this._activeKB==f){if(this.previous&&this._instances.contains(this.previous)){this.activate(this.previous);
}else{this._activeKB=this._instances[0];}}return this;},trace:function(){a.trace(this);},each:function(f){a.each(this,f);},_instances:[],_disable:function(f){if(this._activeKB==f){this._activeKB=null;
}},_setup:function(){this.addEvents(this.options.events);if(a.manager&&!this._manager){a.manager.manage(this);}if(this.options.active){this.activate();
}else{this.relinquish();}},_handle:function(h,g){if(h.preventKeyboardPropagation){return;}var f=!!this._manager;if(f&&this._activeKB){this._activeKB._handle(h,g);
if(h.preventKeyboardPropagation){return;}}this.fireEvent(g,h);if(!f&&this._activeKB){this._activeKB._handle(h,g);}}});var b={};var c=["shift","control","alt","meta"];
var e=/^(?:shift|control|ctrl|alt|meta)$/;a.parse=function(h,g,k){if(k&&k.contains(h.toLowerCase())){return h;}h=h.toLowerCase().replace(/^(keyup|keydown):/,function(m,l){g=l;
return"";});if(!b[h]){var f,j={};h.split("+").each(function(l){if(e.test(l)){j[l]=true;}else{f=l;}});j.control=j.control||j.ctrl;var i=[];c.each(function(l){if(j[l]){i.push(l);
}});if(f){i.push(f);}b[h]=i.join("+");}return g+":keys("+b[h]+")";};a.each=function(f,g){var h=f||a.manager;while(h){g.run(h);h=h._activeKB;}};a.stop=function(f){f.preventKeyboardPropagation=true;
};a.manager=new a({active:true});a.trace=function(f){f=f||a.manager;var g=window.console&&console.log;if(g){console.log("the following items have focus: ");
}a.each(f,function(h){if(g){console.log(document.id(h.widget)||h.wiget||h);}});};var d=function(g){var f=[];c.each(function(h){if(g[h]){f.push(h);}});if(!e.test(g.key)){f.push(g.key);
}a.manager._handle(g,g.type+":keys("+f.join("+")+")");};document.addEvents({keyup:d,keydown:d});}).call(this);Keyboard.prototype.options.nonParsedEvents.combine(["rebound","onrebound"]);
Keyboard.implement({addShortcut:function(b,a){this._shortcuts=this._shortcuts||[];this._shortcutIndex=this._shortcutIndex||{};a.getKeyboard=Function.from(this);
a.name=b;this._shortcutIndex[b]=a;this._shortcuts.push(a);if(a.keys){this.addEvent(a.keys,a.handler);}return this;},addShortcuts:function(b){for(var a in b){this.addShortcut(a,b[a]);
}return this;},removeShortcut:function(b){var a=this.getShortcut(b);if(a&&a.keys){this.removeEvent(a.keys,a.handler);delete this._shortcutIndex[b];this._shortcuts.erase(a);
}return this;},removeShortcuts:function(a){a.each(this.removeShortcut,this);return this;},getShortcuts:function(){return this._shortcuts||[];},getShortcut:function(a){return(this._shortcutIndex||{})[a];
}});Keyboard.rebind=function(b,a){Array.from(a).each(function(c){c.getKeyboard().removeEvent(c.keys,c.handler);c.getKeyboard().addEvent(b,c.handler);c.keys=b;
c.getKeyboard().fireEvent("rebound");});};Keyboard.getActiveShortcuts=function(b){var a=[],c=[];Keyboard.each(b,[].push.bind(a));a.each(function(d){c.extend(d.getShortcuts());
});return c;};Keyboard.getShortcut=function(c,b,d){d=d||{};var a=d.many?[]:null,e=d.many?function(g){var f=g.getShortcut(c);if(f){a.push(f);}}:function(f){if(!a){a=f.getShortcut(c);
}};Keyboard.each(b,e);return a;};Keyboard.getShortcuts=function(b,a){return Keyboard.getShortcut(b,a,{many:true});};var HtmlTable=new Class({Implements:[Options,Events,Class.Occlude],options:{properties:{cellpadding:0,cellspacing:0,border:0},rows:[],headers:[],footers:[]},property:"HtmlTable",initialize:function(){var a=Array.link(arguments,{options:Type.isObject,table:Type.isElement,id:Type.isString});
this.setOptions(a.options);if(!a.table&&a.id){a.table=document.id(a.id);}this.element=a.table||new Element("table",this.options.properties);if(this.occlude()){return this.occluded;
}this.build();},build:function(){this.element.store("HtmlTable",this);this.body=document.id(this.element.tBodies[0])||new Element("tbody").inject(this.element);
$$(this.body.rows);if(this.options.headers.length){this.setHeaders(this.options.headers);}else{this.thead=document.id(this.element.tHead);}if(this.thead){this.head=this.getHead();
}if(this.options.footers.length){this.setFooters(this.options.footers);}this.tfoot=document.id(this.element.tFoot);if(this.tfoot){this.foot=document.id(this.tfoot.rows[0]);
}this.options.rows.each(function(a){this.push(a);},this);},toElement:function(){return this.element;},empty:function(){this.body.empty();return this;},set:function(e,a){var d=(e=="headers")?"tHead":"tFoot",b=d.toLowerCase();
this[b]=(document.id(this.element[d])||new Element(b).inject(this.element,"top")).empty();var c=this.push(a,{},this[b],e=="headers"?"th":"td");if(e=="headers"){this.head=this.getHead();
}else{this.foot=this.getHead();}return c;},getHead:function(){var a=this.thead.rows;return a.length>1?$$(a):a.length?document.id(a[0]):false;},setHeaders:function(a){this.set("headers",a);
return this;},setFooters:function(a){this.set("footers",a);return this;},push:function(f,c,e,a,b){if(typeOf(f)=="element"&&f.get("tag")=="tr"){f.inject(e||this.body,b);
return{tr:f,tds:f.getChildren("td")};}var d=f.map(function(i){var j=new Element(a||"td",i?i.properties:{}),h=(i?i.content:"")||i,g=typeOf(h);if(["element","array","collection","elements"].contains(g)){j.adopt(h);
}else{j.set("html",h);}return j;});return{tr:new Element("tr",c).inject(e||this.body,b).adopt(d),tds:d};}});["adopt","inject","wraps","grab","replaces","dispose"].each(function(a){HtmlTable.implement(a,function(){this.element[a].apply(this.element,arguments);
return this;});});Element.implement({isDisplayed:function(){return this.getStyle("display")!="none";},isVisible:function(){var a=this.offsetWidth,b=this.offsetHeight;
return(a==0&&b==0)?false:(a>0&&b>0)?true:this.style.display!="none";},toggle:function(){return this[this.isDisplayed()?"hide":"show"]();},hide:function(){var b;
try{b=this.getStyle("display");}catch(a){}if(b=="none"){return this;}return this.store("element:_originalDisplay",b||"").setStyle("display","none");},show:function(a){if(!a&&this.isDisplayed()){return this;
}a=a||this.retrieve("element:_originalDisplay")||"block";return this.setStyle("display",(a=="none")?"block":a);},swapClass:function(a,b){return this.removeClass(a).addClass(b);
}});Document.implement({clearSelection:function(){if(window.getSelection){var a=window.getSelection();if(a&&a.removeAllRanges){a.removeAllRanges();}}else{if(document.selection&&document.selection.empty){try{document.selection.empty();
}catch(b){}}}}});HtmlTable=Class.refactor(HtmlTable,{options:{useKeyboard:true,classRowSelected:"table-tr-selected",classRowHovered:"table-tr-hovered",classSelectable:"table-selectable",shiftForMultiSelect:true,allowMultiSelect:true,selectable:false},initialize:function(){this.previous.apply(this,arguments);
if(this.occluded){return this.occluded;}this._selectedRows=new Elements();this._bound={mouseleave:this._mouseleave.bind(this),clickRow:this._clickRow.bind(this)};
if(this.options.selectable){this.enableSelect();}},empty:function(){this.selectNone();return this.previous();},enableSelect:function(){this._selectEnabled=true;
this._attachSelects();this.element.addClass(this.options.classSelectable);return this;},disableSelect:function(){this._selectEnabled=false;this._attachSelects(false);
this.element.removeClass(this.options.classSelectable);return this;},push:function(){var a=this.previous.apply(this,arguments);this._updateSelects();return a;
},isSelected:function(a){return this._selectedRows.contains(a);},toggleRow:function(a){return this[(this.isSelected(a)?"de":"")+"selectRow"](a);},selectRow:function(b,a){if(this.isSelected(b)||(!a&&!this.body.getChildren().contains(b))){return;
}if(!this.options.allowMultiSelect){this.selectNone();}if(!this.isSelected(b)){this._selectedRows.push(b);b.addClass(this.options.classRowSelected);this.fireEvent("rowFocus",[b,this._selectedRows]);
}this._focused=b;document.clearSelection();return this;},deselectRow:function(b,a){if(!this.isSelected(b)||(!a&&!this.body.getChildren().contains(b))){return;
}this._selectedRows=new Elements(Array.from(this._selectedRows).erase(b));b.removeClass(this.options.classRowSelected);this.fireEvent("rowUnfocus",[b,this._selectedRows]);
return this;},selectAll:function(a){if(!a&&!this.options.allowMultiSelect){return;}this.selectRange(0,this.body.rows.length,a);return this;},selectNone:function(){return this.selectAll(true);
},selectRange:function(b,a,f){if(!this.options.allowMultiSelect&&!f){return;}var g=f?"deselectRow":"selectRow",e=Array.clone(this.body.rows);if(typeOf(b)=="element"){b=e.indexOf(b);
}if(typeOf(a)=="element"){a=e.indexOf(a);}a=a<e.length-1?a:e.length-1;if(a<b){var d=b;b=a;a=d;}for(var c=b;c<=a;c++){this[g](e[c],true);}return this;},deselectRange:function(b,a){this.selectRange(b,a,true);
},getSelected:function(){return this._selectedRows;},_enterRow:function(a){if(this._hovered){this._hovered=this._leaveRow(this._hovered);}this._hovered=a.addClass(this.options.classRowHovered);
},_leaveRow:function(a){a.removeClass(this.options.classRowHovered);},_updateSelects:function(){Array.each(this.body.rows,function(a){var b=a.retrieve("binders");
if(!b&&!this._selectEnabled){return;}if(!b){b={mouseenter:this._enterRow.pass([a],this),mouseleave:this._leaveRow.pass([a],this)};a.store("binders",b);
}if(this._selectEnabled){a.addEvents(b);}else{a.removeEvents(b);}},this);},_shiftFocus:function(b,a){if(!this._focused){return this.selectRow(this.body.rows[0],a);
}var c=this._getRowByOffset(b);if(c===null||this._focused==this.body.rows[c]){return this;}this.toggleRow(this.body.rows[c],a);},_clickRow:function(a,b){var c=(a.shift||a.meta||a.control)&&this.options.shiftForMultiSelect;
if(!c&&!(a.rightClick&&this.isSelected(b)&&this.options.allowMultiSelect)){this.selectNone();}if(a.rightClick){this.selectRow(b);}else{this.toggleRow(b);
}if(a.shift){this.selectRange(this._rangeStart||this.body.rows[0],b,this._rangeStart?!this.isSelected(b):true);this._focused=b;}this._rangeStart=b;},_getRowByOffset:function(c){if(!this._focused){return 0;
}var b=Array.clone(this.body.rows),a=b.indexOf(this._focused)+c;if(a<0){a=null;}if(a>=b.length){a=null;}return a;},_attachSelects:function(d){d=d!=null?d:true;
var g=d?"addEvents":"removeEvents";this.element[g]({mouseleave:this._bound.mouseleave});this.body[g]({"click:relay(tr)":this._bound.clickRow,"contextmenu:relay(tr)":this._bound.clickRow});
if(this.options.useKeyboard||this.keyboard){if(!this.keyboard){var f,e;var c=function(i){var h=function(j){clearTimeout(f);j.preventDefault();var k=this.body.rows[this._getRowByOffset(i)];
if(j.shift&&k&&this.isSelected(k)){this.deselectRow(this._focused);this._focused=k;}else{if(k&&(!this.options.allowMultiSelect||!j.shift)){this.selectNone();
}this._shiftFocus(i,j);}if(e){f=h.delay(100,this,j);}else{f=(function(){e=true;h(j);}).delay(400);}}.bind(this);return h;}.bind(this);var b=function(){clearTimeout(f);
e=false;};this.keyboard=new Keyboard({events:{"keydown:shift+up":c(-1),"keydown:shift+down":c(1),"keyup:shift+up":b,"keyup:shift+down":b,"keyup:up":b,"keyup:down":b},active:true});
var a="";if(this.options.allowMultiSelect&&this.options.shiftForMultiSelect&&this.options.useKeyboard){a=" (Shift multi-selects).";}this.keyboard.addShortcuts({"Select Previous Row":{keys:"up",shortcut:"up arrow",handler:c(-1),description:"Select the previous row in the table."+a},"Select Next Row":{keys:"down",shortcut:"down arrow",handler:c(1),description:"Select the next row in the table."+a}});
}this.keyboard[d?"activate":"deactivate"]();}this._updateSelects();},_mouseleave:function(){if(this._hovered){this._leaveRow(this._hovered);}}});(function(){var a=function(c,b){return(c)?(typeOf(c)=="function"?c(b):b.get(c)):"";
};this.Tips=new Class({Implements:[Events,Options],options:{onShow:function(){this.tip.setStyle("display","block");},onHide:function(){this.tip.setStyle("display","none");
},title:"title",text:function(b){return b.get("rel")||b.get("href");},showDelay:100,hideDelay:100,className:"tip-wrap",offset:{x:16,y:16},windowPadding:{x:0,y:0},fixed:false},initialize:function(){var b=Array.link(arguments,{options:Type.isObject,elements:function(c){return c!=null;
}});this.setOptions(b.options);if(b.elements){this.attach(b.elements);}this.container=new Element("div",{"class":"tip"});},toElement:function(){if(this.tip){return this.tip;
}this.tip=new Element("div",{"class":this.options.className,styles:{position:"absolute",top:0,left:0}}).adopt(new Element("div",{"class":"tip-top"}),this.container,new Element("div",{"class":"tip-bottom"}));
return this.tip;},attach:function(b){$$(b).each(function(d){var f=a(this.options.title,d),e=a(this.options.text,d);d.set("title","").store("tip:native",f).retrieve("tip:title",f);
d.retrieve("tip:text",e);this.fireEvent("attach",[d]);var c=["enter","leave"];if(!this.options.fixed){c.push("move");}c.each(function(h){var g=d.retrieve("tip:"+h);
if(!g){g=function(i){this["element"+h.capitalize()].apply(this,[i,d]);}.bind(this);}d.store("tip:"+h,g).addEvent("mouse"+h,g);},this);},this);return this;
},detach:function(b){$$(b).each(function(d){["enter","leave","move"].each(function(e){d.removeEvent("mouse"+e,d.retrieve("tip:"+e)).eliminate("tip:"+e);
});this.fireEvent("detach",[d]);if(this.options.title=="title"){var c=d.retrieve("tip:native");if(c){d.set("title",c);}}},this);return this;},elementEnter:function(c,b){clearTimeout(this.timer);
this.timer=(function(){this.container.empty();["title","text"].each(function(e){var d=b.retrieve("tip:"+e);var f=this["_"+e+"Element"]=new Element("div",{"class":"tip-"+e}).inject(this.container);
if(d){this.fill(f,d);}},this);this.show(b);this.position((this.options.fixed)?{page:b.getPosition()}:c);}).delay(this.options.showDelay,this);},elementLeave:function(c,b){clearTimeout(this.timer);
this.timer=this.hide.delay(this.options.hideDelay,this,b);this.fireForParent(c,b);},setTitle:function(b){if(this._titleElement){this._titleElement.empty();
this.fill(this._titleElement,b);}return this;},setText:function(b){if(this._textElement){this._textElement.empty();this.fill(this._textElement,b);}return this;
},fireForParent:function(c,b){b=b.getParent();if(!b||b==document.body){return;}if(b.retrieve("tip:enter")){b.fireEvent("mouseenter",c);}else{this.fireForParent(c,b);
}},elementMove:function(c,b){this.position(c);},position:function(f){if(!this.tip){document.id(this);}var c=window.getSize(),b=window.getScroll(),g={x:this.tip.offsetWidth,y:this.tip.offsetHeight},d={x:"left",y:"top"},e={y:false,x2:false,y2:false,x:false},h={};
for(var i in d){h[d[i]]=f.page[i]+this.options.offset[i];if(h[d[i]]<0){e[i]=true;}if((h[d[i]]+g[i]-b[i])>c[i]-this.options.windowPadding[i]){h[d[i]]=f.page[i]-this.options.offset[i]-g[i];
e[i+"2"]=true;}}this.fireEvent("bound",e);this.tip.setStyles(h);},fill:function(b,c){if(typeof c=="string"){b.set("html",c);}else{b.adopt(c);}},show:function(b){if(!this.tip){document.id(this);
}if(!this.tip.getParent()){this.tip.inject(document.body);}this.fireEvent("show",[this.tip,b]);},hide:function(b){if(!this.tip){document.id(this);}this.fireEvent("hide",[this.tip,b]);
}});}).call(this);
-485
View File
@@ -1,485 +0,0 @@
/*
---
MooTools: the javascript framework
web build:
- http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7
packager build:
- packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff
copyrights:
- [MooTools](http://mootools.net)
licenses:
- [MIT License](http://mootools.net/license.txt)
...
*/
(function(){this.MooTools={version:"1.3.1",build:"af48c8d589f43f32212f9bb8ff68a127e6a3ba6c"};var e=this.typeOf=function(i){if(i==null){return"null";}if(i.$family){return i.$family();
}if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments";
}if("item" in i){return"collection";}}}return typeof i;};var u=this.instanceOf=function(w,i){if(w==null){return false;}var v=w.$constructor||w.constructor;
while(v){if(v===i){return true;}v=v.parent;}return w instanceof i;};var f=this.Function;var r=true;for(var q in {toString:1}){r=null;}if(r){r=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];
}f.prototype.overloadSetter=function(v){var i=this;return function(x,w){if(x==null){return this;}if(v||typeof x!="string"){for(var y in x){i.call(this,y,x[y]);
}if(r){for(var z=r.length;z--;){y=r[z];if(x.hasOwnProperty(y)){i.call(this,y,x[y]);}}}}else{i.call(this,x,w);}return this;};};f.prototype.overloadGetter=function(v){var i=this;
return function(x){var y,w;if(v||typeof x!="string"){y=x;}else{if(arguments.length>1){y=arguments;}}if(y){w={};for(var z=0;z<y.length;z++){w[y[z]]=i.call(this,y[z]);
}}else{w=i.call(this,x);}return w;};};f.prototype.extend=function(i,v){this[i]=v;}.overloadSetter();f.prototype.implement=function(i,v){this.prototype[i]=v;
}.overloadSetter();var o=Array.prototype.slice;f.from=function(i){return(e(i)=="function")?i:function(){return i;};};Array.from=function(i){if(i==null){return[];
}return(k.isEnumerable(i)&&typeof i!="string")?(e(i)=="array")?i:o.call(i):[i];};Number.from=function(v){var i=parseFloat(v);return isFinite(i)?i:null;
};String.from=function(i){return i+"";};f.implement({hide:function(){this.$hidden=true;return this;},protect:function(){this.$protected=true;return this;
}});var k=this.Type=function(x,w){if(x){var v=x.toLowerCase();var i=function(y){return(e(y)==v);};k["is"+x]=i;if(w!=null){w.prototype.$family=(function(){return v;
}).hide();w.type=i;}}if(w==null){return null;}w.extend(this);w.$constructor=k;w.prototype.$constructor=w;return w;};var p=Object.prototype.toString;k.isEnumerable=function(i){return(i!=null&&typeof i.length=="number"&&p.call(i)!="[object Function]");
};var b={};var d=function(i){var v=e(i.prototype);return b[v]||(b[v]=[]);};var h=function(w,A){if(A&&A.$hidden){return;}var v=d(this);for(var x=0;x<v.length;
x++){var z=v[x];if(e(z)=="type"){h.call(z,w,A);}else{z.call(this,w,A);}}var y=this.prototype[w];if(y==null||!y.$protected){this.prototype[w]=A;}if(this[w]==null&&e(A)=="function"){t.call(this,w,function(i){return A.apply(i,o.call(arguments,1));
});}};var t=function(i,w){if(w&&w.$hidden){return;}var v=this[i];if(v==null||!v.$protected){this[i]=w;}};k.implement({implement:h.overloadSetter(),extend:t.overloadSetter(),alias:function(i,v){h.call(this,i,this.prototype[v]);
}.overloadSetter(),mirror:function(i){d(this).push(i);return this;}});new k("Type",k);var c=function(v,z,x){var w=(z!=Object),D=z.prototype;if(w){z=new k(v,z);
}for(var A=0,y=x.length;A<y;A++){var E=x[A],C=z[E],B=D[E];if(C){C.protect();}if(w&&B){delete D[E];D[E]=B.protect();}}if(w){z.implement(D);}return c;};c("String",String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","quote","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase"])("Array",Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"])("Number",Number,["toExponential","toFixed","toLocaleString","toPrecision"])("Function",f,["apply","call","bind"])("RegExp",RegExp,["exec","test"])("Object",Object,["create","defineProperty","defineProperties","keys","getPrototypeOf","getOwnPropertyDescriptor","getOwnPropertyNames","preventExtensions","isExtensible","seal","isSealed","freeze","isFrozen"])("Date",Date,["now"]);
Object.extend=t.overloadSetter();Date.extend("now",function(){return +(new Date);});new k("Boolean",Boolean);Number.prototype.$family=function(){return isFinite(this)?"number":"null";
}.hide();Number.extend("random",function(v,i){return Math.floor(Math.random()*(i-v+1)+v);});var l=Object.prototype.hasOwnProperty;Object.extend("forEach",function(i,w,x){for(var v in i){if(l.call(i,v)){w.call(x,i[v],v,i);
}}});Object.each=Object.forEach;Array.implement({forEach:function(x,y){for(var w=0,v=this.length;w<v;w++){if(w in this){x.call(y,this[w],w,this);}}},each:function(i,v){Array.forEach(this,i,v);
return this;}});var s=function(i){switch(e(i)){case"array":return i.clone();case"object":return Object.clone(i);default:return i;}};Array.implement("clone",function(){var v=this.length,w=new Array(v);
while(v--){w[v]=s(this[v]);}return w;});var a=function(v,i,w){switch(e(w)){case"object":if(e(v[i])=="object"){Object.merge(v[i],w);}else{v[i]=Object.clone(w);
}break;case"array":v[i]=w.clone();break;default:v[i]=w;}return v;};Object.extend({merge:function(C,y,x){if(e(y)=="string"){return a(C,y,x);}for(var B=1,w=arguments.length;
B<w;B++){var z=arguments[B];for(var A in z){a(C,A,z[A]);}}return C;},clone:function(i){var w={};for(var v in i){w[v]=s(i[v]);}return w;},append:function(z){for(var y=1,w=arguments.length;
y<w;y++){var v=arguments[y]||{};for(var x in v){z[x]=v[x];}}return z;}});["Object","WhiteSpace","TextNode","Collection","Arguments"].each(function(i){new k(i);
});var j=Date.now();String.extend("uniqueID",function(){return(j++).toString(36);});var g=this.Hash=new k("Hash",function(i){if(e(i)=="hash"){i=Object.clone(i.getClean());
}for(var v in i){this[v]=i[v];}return this;});g.implement({forEach:function(i,v){Object.forEach(this,i,v);},getClean:function(){var v={};for(var i in this){if(this.hasOwnProperty(i)){v[i]=this[i];
}}return v;},getLength:function(){var v=0;for(var i in this){if(this.hasOwnProperty(i)){v++;}}return v;}});g.alias("each","forEach");Object.type=k.isObject;
var n=this.Native=function(i){return new k(i.name,i.initialize);};n.type=k.type;n.implement=function(x,v){for(var w=0;w<x.length;w++){x[w].implement(v);
}return n;};var m=Array.type;Array.type=function(i){return u(i,Array)||m(i);};this.$A=function(i){return Array.from(i).slice();};this.$arguments=function(v){return function(){return arguments[v];
};};this.$chk=function(i){return !!(i||i===0);};this.$clear=function(i){clearTimeout(i);clearInterval(i);return null;};this.$defined=function(i){return(i!=null);
};this.$each=function(w,v,x){var i=e(w);((i=="arguments"||i=="collection"||i=="array"||i=="elements")?Array:Object).each(w,v,x);};this.$empty=function(){};
this.$extend=function(v,i){return Object.append(v,i);};this.$H=function(i){return new g(i);};this.$merge=function(){var i=Array.slice(arguments);i.unshift({});
return Object.merge.apply(null,i);};this.$lambda=f.from;this.$mixin=Object.merge;this.$random=Number.random;this.$splat=Array.from;this.$time=Date.now;
this.$type=function(i){var v=e(i);if(v=="elements"){return"array";}return(v=="null")?false:v;};this.$unlink=function(i){switch(e(i)){case"object":return Object.clone(i);
case"array":return Array.clone(i);case"hash":return new g(i);default:return i;}};}).call(this);Array.implement({invoke:function(a){var b=Array.slice(arguments,1);
return this.map(function(c){return c[a].apply(c,b);});},every:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&!c.call(d,this[b],b,this)){return false;
}}return true;},filter:function(d,e){var c=[];for(var b=0,a=this.length;b<a;b++){if((b in this)&&d.call(e,this[b],b,this)){c.push(this[b]);}}return c;},clean:function(){return this.filter(function(a){return a!=null;
});},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b;}}return -1;},map:function(d,e){var c=[];
for(var b=0,a=this.length;b<a;b++){if(b in this){c[b]=d.call(e,this[b],b,this);}}return c;},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&c.call(d,this[b],b,this)){return true;
}}return false;},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];}return d;},link:function(c){var a={};
for(var e=0,b=this.length;e<b;e++){for(var d in c){if(c[d](this[e])){a[d]=this[e];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;
},append:function(a){this.push.apply(this,a);return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[Number.random(0,this.length-1)]:null;
},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;
},erase:function(b){for(var a=this.length;a--;){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];
for(var b=0,a=this.length;b<a;b++){var c=typeOf(this[b]);if(c=="null"){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments"||instanceOf(this[b],Array))?Array.flatten(this[b]):this[b]);
}return d;},pick:function(){for(var b=0,a=this.length;b<a;b++){if(this[b]!=null){return this[b];}}return null;},hexToRgb:function(b){if(this.length!=3){return null;
}var a=this.map(function(c){if(c.length==1){c+=c;}return c.toInt(16);});return(b)?a:"rgb("+a+")";},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";
}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});Array.alias("extend","append");
var $pick=function(){return Array.from(arguments).pick();};String.implement({test:function(a,b){return((typeOf(a)=="regexp")?a:new RegExp(""+a,b)).test(this);
},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);
}return(a[c]!=null)?a[c]:"";});}});Number.implement({limit:function(b,a){return Math.min(a,Math.max(b,this));},round:function(a){a=Math.pow(10,a||0).toFixed(a<0?-a:0);
return Math.round(this*a)/a;},times:function(b,c){for(var a=0;a<this;a++){b.call(c,a,this);}},toFloat:function(){return parseFloat(this);},toInt:function(a){return parseInt(this,a||10);
}});Number.alias("each","times");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat(Array.from(arguments)));
};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);Function.extend({attempt:function(){for(var b=0,a=arguments.length;
b<a;b++){try{return arguments[b]();}catch(c){}}return null;}});Function.implement({attempt:function(a,c){try{return this.apply(c,Array.from(a));}catch(b){}return null;
},bind:function(c){var a=this,b=(arguments.length>1)?Array.slice(arguments,1):null;return function(){if(!b&&!arguments.length){return a.call(c);}if(b&&arguments.length){return a.apply(c,b.concat(Array.from(arguments)));
}return a.apply(c,b||arguments);};},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b);
},periodical:function(c,b,a){return setInterval(this.pass((a==null?[]:a),b),c);}});delete Function.prototype.bind;Function.implement({create:function(b){var a=this;
b=b||{};return function(d){var c=b.arguments;c=(c!=null)?Array.from(c):Array.slice(arguments,(b.event)?1:0);if(b.event){c=[d||window.event].extend(c);}var e=function(){return a.apply(b.bind||null,c);
};if(b.delay){return setTimeout(e,b.delay);}if(b.periodical){return setInterval(e,b.periodical);}if(b.attempt){return Function.attempt(e);}return e();};
},bind:function(c,b){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},bindWithEvent:function(c,b){var a=this;
if(b!=null){b=Array.from(b);}return function(d){return a.apply(c,(b==null)?arguments:[d].concat(b));};},run:function(a,b){return this.apply(b,Array.from(a));
}});var $try=Function.attempt;(function(){var a=Object.prototype.hasOwnProperty;Object.extend({subset:function(d,g){var f={};for(var e=0,b=g.length;e<b;
e++){var c=g[e];f[c]=d[c];}return f;},map:function(b,e,f){var d={};for(var c in b){if(a.call(b,c)){d[c]=e.call(f,b[c],c,b);}}return d;},filter:function(b,d,e){var c={};
Object.each(b,function(g,f){if(d.call(e,g,f,b)){c[f]=g;}});return c;},every:function(b,d,e){for(var c in b){if(a.call(b,c)&&!d.call(e,b[c],c)){return false;
}}return true;},some:function(b,d,e){for(var c in b){if(a.call(b,c)&&d.call(e,b[c],c)){return true;}}return false;},keys:function(b){var d=[];for(var c in b){if(a.call(b,c)){d.push(c);
}}return d;},values:function(c){var b=[];for(var d in c){if(a.call(c,d)){b.push(c[d]);}}return b;},getLength:function(b){return Object.keys(b).length;},keyOf:function(b,d){for(var c in b){if(a.call(b,c)&&b[c]===d){return c;
}}return null;},contains:function(b,c){return Object.keyOf(b,c)!=null;},toQueryString:function(b,c){var d=[];Object.each(b,function(h,g){if(c){g=c+"["+g+"]";
}var f;switch(typeOf(h)){case"object":f=Object.toQueryString(h,g);break;case"array":var e={};h.each(function(k,j){e[j]=k;});f=Object.toQueryString(e,g);
break;default:f=g+"="+encodeURIComponent(h);}if(h!=null){d.push(f);}});return d.join("&");}});})();Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(a){return Object.keyOf(this,a);
},hasValue:function(a){return Object.contains(this,a);},extend:function(a){Hash.each(a||{},function(c,b){Hash.set(this,b,c);},this);return this;},combine:function(a){Hash.each(a||{},function(c,b){Hash.include(this,b,c);
},this);return this;},erase:function(a){if(this.hasOwnProperty(a)){delete this[a];}return this;},get:function(a){return(this.hasOwnProperty(a))?this[a]:null;
},set:function(a,b){if(!this[a]||this.hasOwnProperty(a)){this[a]=b;}return this;},empty:function(){Hash.each(this,function(b,a){delete this[a];},this);
return this;},include:function(a,b){if(this[a]==null){this[a]=b;}return this;},map:function(a,b){return new Hash(Object.map(this,a,b));},filter:function(a,b){return new Hash(Object.filter(this,a,b));
},every:function(a,b){return Object.every(this,a,b);},some:function(a,b){return Object.some(this,a,b);},getKeys:function(){return Object.keys(this);},getValues:function(){return Object.values(this);
},toQueryString:function(a){return Object.toQueryString(this,a);}});Hash.extend=Object.append;Hash.alias({indexOf:"keyOf",contains:"hasValue"});(function(){var l=this.document;
var j=l.window=this;var b=1;this.$uid=(j.ActiveXObject)?function(e){return(e.uid||(e.uid=[b++]))[0];}:function(e){return e.uid||(e.uid=b++);};$uid(j);$uid(l);
var a=navigator.userAgent.toLowerCase(),c=navigator.platform.toLowerCase(),k=a.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],g=k[1]=="ie"&&l.documentMode;
var p=this.Browser={extend:Function.prototype.extend,name:(k[1]=="version")?k[3]:k[1],version:g||parseFloat((k[1]=="opera"&&k[4])?k[4]:k[2]),Platform:{name:a.match(/ip(?:ad|od|hone)/)?"ios":(a.match(/(?:webos|android)/)||c.match(/mac|win|linux/)||["other"])[0]},Features:{xpath:!!(l.evaluate),air:!!(j.runtime),query:!!(l.querySelector),json:!!(j.JSON)},Plugins:{}};
p[p.name]=true;p[p.name+parseInt(p.version,10)]=true;p.Platform[p.Platform.name]=true;p.Request=(function(){var r=function(){return new XMLHttpRequest();
};var q=function(){return new ActiveXObject("MSXML2.XMLHTTP");};var e=function(){return new ActiveXObject("Microsoft.XMLHTTP");};return Function.attempt(function(){r();
return r;},function(){q();return q;},function(){e();return e;});})();p.Features.xhr=!!(p.Request);var i=(Function.attempt(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);p.Plugins.Flash={version:Number(i[0]||"0."+i[1])||0,build:Number(i[2])||0};
p.exec=function(q){if(!q){return q;}if(j.execScript){j.execScript(q);}else{var e=l.createElement("script");e.setAttribute("type","text/javascript");e.text=q;
l.head.appendChild(e);l.head.removeChild(e);}return q;};String.implement("stripScripts",function(q){var e="";var r=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(s,t){e+=t+"\n";
return"";});if(q===true){p.exec(e);}else{if(typeOf(q)=="function"){q(e,r);}}return r;});p.extend({Document:this.Document,Window:this.Window,Element:this.Element,Event:this.Event});
this.Window=this.$constructor=new Type("Window",function(){});this.$family=Function.from("window").hide();Window.mirror(function(e,q){j[e]=q;});this.Document=l.$constructor=new Type("Document",function(){});
l.$family=Function.from("document").hide();Document.mirror(function(e,q){l[e]=q;});l.html=l.documentElement;l.head=l.getElementsByTagName("head")[0];if(l.execCommand){try{l.execCommand("BackgroundImageCache",false,true);
}catch(h){}}if(this.attachEvent&&!this.addEventListener){var d=function(){this.detachEvent("onunload",d);l.head=l.html=l.window=null;};this.attachEvent("onunload",d);
}var n=Array.from;try{n(l.html.childNodes);}catch(h){Array.from=function(q){if(typeof q!="string"&&Type.isEnumerable(q)&&typeOf(q)!="array"){var e=q.length,r=new Array(e);
while(e--){r[e]=q[e];}return r;}return n(q);};var m=Array.prototype,o=m.slice;["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice"].each(function(e){var q=m[e];
Array[e]=function(r){return q.apply(Array.from(r),o.call(arguments,1));};});}if(p.Platform.ios){p.Platform.ipod=true;}p.Engine={};var f=function(q,e){p.Engine.name=q;
p.Engine[q+e]=true;p.Engine.version=e;};if(p.ie){p.Engine.trident=true;switch(p.version){case 6:f("trident",4);break;case 7:f("trident",5);break;case 8:f("trident",6);
}}if(p.firefox){p.Engine.gecko=true;if(p.version>=3){f("gecko",19);}else{f("gecko",18);}}if(p.safari||p.chrome){p.Engine.webkit=true;switch(p.version){case 2:f("webkit",419);
break;case 3:f("webkit",420);break;case 4:f("webkit",525);}}if(p.opera){p.Engine.presto=true;if(p.version>=9.6){f("presto",960);}else{if(p.version>=9.5){f("presto",950);
}else{f("presto",925);}}}if(p.name=="unknown"){switch((a.match(/(?:webkit|khtml|gecko)/)||[])[0]){case"webkit":case"khtml":p.Engine.webkit=true;break;case"gecko":p.Engine.gecko=true;
}}this.$exec=p.exec;}).call(this);var Event=new Type("Event",function(a,i){if(!i){i=window;}var o=i.document;a=a||i.event;if(a.$extended){return a;}this.$extended=true;
var n=a.type,k=a.target||a.srcElement,m={},c={},q=null,h,l,b,p;while(k&&k.nodeType==3){k=k.parentNode;}if(n.indexOf("key")!=-1){b=a.which||a.keyCode;p=Object.keyOf(Event.Keys,b);
if(n=="keydown"){var d=b-111;if(d>0&&d<13){p="f"+d;}}if(!p){p=String.fromCharCode(b).toLowerCase();}}else{if((/click|mouse|menu/i).test(n)){o=(!o.compatMode||o.compatMode=="CSS1Compat")?o.html:o.body;
m={x:(a.pageX!=null)?a.pageX:a.clientX+o.scrollLeft,y:(a.pageY!=null)?a.pageY:a.clientY+o.scrollTop};c={x:(a.pageX!=null)?a.pageX-i.pageXOffset:a.clientX,y:(a.pageY!=null)?a.pageY-i.pageYOffset:a.clientY};
if((/DOMMouseScroll|mousewheel/).test(n)){l=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3;}h=(a.which==3)||(a.button==2);if((/over|out/).test(n)){q=a.relatedTarget||a[(n=="mouseover"?"from":"to")+"Element"];
var j=function(){while(q&&q.nodeType==3){q=q.parentNode;}return true;};var g=(Browser.firefox2)?j.attempt():j();q=(g)?q:null;}}else{if((/gesture|touch/i).test(n)){this.rotation=a.rotation;
this.scale=a.scale;this.targetTouches=a.targetTouches;this.changedTouches=a.changedTouches;var f=this.touches=a.touches;if(f&&f[0]){var e=f[0];m={x:e.pageX,y:e.pageY};
c={x:e.clientX,y:e.clientY};}}}}return Object.append(this,{event:a,type:n,page:m,client:c,rightClick:h,wheel:l,relatedTarget:document.id(q),target:document.id(k),code:b,key:p,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey});
});Event.Keys={enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46};Event.Keys=new Hash(Event.Keys);Event.implement({stop:function(){return this.stopPropagation().preventDefault();
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
}else{this.event.returnValue=false;}return this;}});(function(){var a=this.Class=new Type("Class",function(h){if(instanceOf(h,Function)){h={initialize:h};
}var g=function(){e(this);if(g.$prototyping){return this;}this.$caller=null;var i=(this.initialize)?this.initialize.apply(this,arguments):this;this.$caller=this.caller=null;
return i;}.extend(this).implement(h);g.$constructor=a;g.prototype.$constructor=g;g.prototype.parent=c;return g;});var c=function(){if(!this.$caller){throw new Error('The method "parent" cannot be called.');
}var g=this.$caller.$name,h=this.$caller.$owner.parent,i=(h)?h.prototype[g]:null;if(!i){throw new Error('The method "'+g+'" has no parent.');}return i.apply(this,arguments);
};var e=function(g){for(var h in g){var j=g[h];switch(typeOf(j)){case"object":var i=function(){};i.prototype=j;g[h]=e(new i);break;case"array":g[h]=j.clone();
break;}}return g;};var b=function(g,h,j){if(j.$origin){j=j.$origin;}var i=function(){if(j.$protected&&this.$caller==null){throw new Error('The method "'+h+'" cannot be called.');
}var l=this.caller,m=this.$caller;this.caller=m;this.$caller=i;var k=j.apply(this,arguments);this.$caller=m;this.caller=l;return k;}.extend({$owner:g,$origin:j,$name:h});
return i;};var f=function(h,i,g){if(a.Mutators.hasOwnProperty(h)){i=a.Mutators[h].call(this,i);if(i==null){return this;}}if(typeOf(i)=="function"){if(i.$hidden){return this;
}this.prototype[h]=(g)?i:b(this,h,i);}else{Object.merge(this.prototype,h,i);}return this;};var d=function(g){g.$prototyping=true;var h=new g;delete g.$prototyping;
return h;};a.implement("implement",f.overloadSetter());a.Mutators={Extends:function(g){this.parent=g;this.prototype=d(g);},Implements:function(g){Array.from(g).each(function(j){var h=new j;
for(var i in h){f.call(this,i,h[i],true);}},this);}};}).call(this);(function(){this.Chain=new Class({$chain:[],chain:function(){this.$chain.append(Array.flatten(arguments));
return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){this.$chain.empty();
return this;}});var a=function(b){return b.replace(/^on([A-Z])/,function(c,d){return d.toLowerCase();});};this.Events=new Class({$events:{},addEvent:function(d,c,b){d=a(d);
if(c==$empty){return this;}this.$events[d]=(this.$events[d]||[]).include(c);if(b){c.internal=true;}return this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
}return this;},fireEvent:function(e,c,b){e=a(e);var d=this.$events[e];if(!d){return this;}c=Array.from(c);d.each(function(f){if(b){f.delay(b,this,c);}else{f.apply(this,c);
}},this);return this;},removeEvent:function(e,d){e=a(e);var c=this.$events[e];if(c&&!d.internal){var b=c.indexOf(d);if(b!=-1){delete c[b];}}return this;
},removeEvents:function(d){var e;if(typeOf(d)=="object"){for(e in d){this.removeEvent(e,d[e]);}return this;}if(d){d=a(d);}for(e in this.$events){if(d&&d!=e){continue;
}var c=this.$events[e];for(var b=c.length;b--;){if(b in c){this.removeEvent(e,c[b]);}}}return this;}});this.Options=new Class({setOptions:function(){var b=this.options=Object.merge.apply(null,[{},this.options].append(arguments));
if(this.addEvent){for(var c in b){if(typeOf(b[c])!="function"||!(/^on[A-Z]/).test(c)){continue;}this.addEvent(c,b[c]);delete b[c];}}return this;}});}).call(this);
(function(){var k,n,l,g,a={},c={},m=/\\/g;var e=function(q,p){if(q==null){return null;}if(q.Slick===true){return q;}q=(""+q).replace(/^\s+|\s+$/g,"");g=!!p;
var o=(g)?c:a;if(o[q]){return o[q];}k={Slick:true,expressions:[],raw:q,reverse:function(){return e(this.raw,true);}};n=-1;while(q!=(q=q.replace(j,b))){}k.length=k.expressions.length;
return o[k.raw]=(g)?h(k):k;};var i=function(o){if(o==="!"){return" ";}else{if(o===" "){return"!";}else{if((/^!/).test(o)){return o.replace(/^!/,"");}else{return"!"+o;
}}}};var h=function(u){var r=u.expressions;for(var p=0;p<r.length;p++){var t=r[p];var q={parts:[],tag:"*",combinator:i(t[0].combinator)};for(var o=0;o<t.length;
o++){var s=t[o];if(!s.reverseCombinator){s.reverseCombinator=" ";}s.combinator=s.reverseCombinator;delete s.reverseCombinator;}t.reverse().push(q);}return u;
};var f=function(o){return o.replace(/[-[\]{}()*+?.\\^$|,#\s]/g,function(p){return"\\"+p;});};var j=new RegExp("^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)".replace(/<combinator>/,"["+f(">+~`!@$%^&={}\\;</")+"]").replace(/<unicode>/g,"(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])").replace(/<unicode1>/g,"(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])"));
function b(x,s,D,z,r,C,q,B,A,y,u,F,G,v,p,w){if(s||n===-1){k.expressions[++n]=[];l=-1;if(s){return"";}}if(D||z||l===-1){D=D||" ";var t=k.expressions[n];
if(g&&t[l]){t[l].reverseCombinator=i(D);}t[++l]={combinator:D,tag:"*"};}var o=k.expressions[n][l];if(r){o.tag=r.replace(m,"");}else{if(C){o.id=C.replace(m,"");
}else{if(q){q=q.replace(m,"");if(!o.classList){o.classList=[];}if(!o.classes){o.classes=[];}o.classList.push(q);o.classes.push({value:q,regexp:new RegExp("(^|\\s)"+f(q)+"(\\s|$)")});
}else{if(G){w=w||p;w=w?w.replace(m,""):null;if(!o.pseudos){o.pseudos=[];}o.pseudos.push({key:G.replace(m,""),value:w,type:F.length==1?"class":"element"});
}else{if(B){B=B.replace(m,"");u=(u||"").replace(m,"");var E,H;switch(A){case"^=":H=new RegExp("^"+f(u));break;case"$=":H=new RegExp(f(u)+"$");break;case"~=":H=new RegExp("(^|\\s)"+f(u)+"(\\s|$)");
break;case"|=":H=new RegExp("^"+f(u)+"(-|$)");break;case"=":E=function(I){return u==I;};break;case"*=":E=function(I){return I&&I.indexOf(u)>-1;};break;
case"!=":E=function(I){return u!=I;};break;default:E=function(I){return !!I;};}if(u==""&&(/^[*$^]=$/).test(A)){E=function(){return false;};}if(!E){E=function(I){return I&&H.test(I);
};}if(!o.attributes){o.attributes=[];}o.attributes.push({key:B,operator:A,value:u,test:E});}}}}}return"";}var d=(this.Slick||{});d.parse=function(o){return e(o);
};d.escapeRegExp=f;if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);(function(){var j={},l={},b=Object.prototype.toString;
j.isNativeCode=function(c){return(/\{\s*\[native code\]\s*\}/).test(""+c);};j.isXML=function(c){return(!!c.xmlVersion)||(!!c.xml)||(b.call(c)=="[object XMLDocument]")||(c.nodeType==9&&c.documentElement.nodeName!="HTML");
};j.setDocument=function(w){var t=w.nodeType;if(t==9){}else{if(t){w=w.ownerDocument;}else{if(w.navigator){w=w.document;}else{return;}}}if(this.document===w){return;
}this.document=w;var y=w.documentElement,u=this.getUIDXML(y),o=l[u],A;if(o){for(A in o){this[A]=o[A];}return;}o=l[u]={};o.root=y;o.isXMLDocument=this.isXML(w);
o.brokenStarGEBTN=o.starSelectsClosedQSA=o.idGetsName=o.brokenMixedCaseQSA=o.brokenGEBCN=o.brokenCheckedQSA=o.brokenEmptyAttributeQSA=o.isHTMLDocument=o.nativeMatchesSelector=false;
var m,n,x,q,r;var s,c="slick_uniqueid";var z=w.createElement("div");var p=w.body||w.getElementsByTagName("body")[0]||y;p.appendChild(z);try{z.innerHTML='<a id="'+c+'"></a>';
o.isHTMLDocument=!!w.getElementById(c);}catch(v){}if(o.isHTMLDocument){z.style.display="none";z.appendChild(w.createComment(""));n=(z.getElementsByTagName("*").length>1);
try{z.innerHTML="foo</foo>";s=z.getElementsByTagName("*");m=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");}catch(v){}o.brokenStarGEBTN=n||m;try{z.innerHTML='<a name="'+c+'"></a><b id="'+c+'"></b>';
o.idGetsName=w.getElementById(c)===z.firstChild;}catch(v){}if(z.getElementsByClassName){try{z.innerHTML='<a class="f"></a><a class="b"></a>';z.getElementsByClassName("b").length;
z.firstChild.className="b";q=(z.getElementsByClassName("b").length!=2);}catch(v){}try{z.innerHTML='<a class="a"></a><a class="f b a"></a>';x=(z.getElementsByClassName("a").length!=2);
}catch(v){}o.brokenGEBCN=q||x;}if(z.querySelectorAll){try{z.innerHTML="foo</foo>";s=z.querySelectorAll("*");o.starSelectsClosedQSA=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");
}catch(v){}try{z.innerHTML='<a class="MiX"></a>';o.brokenMixedCaseQSA=!z.querySelectorAll(".MiX").length;}catch(v){}try{z.innerHTML='<select><option selected="selected">a</option></select>';
o.brokenCheckedQSA=(z.querySelectorAll(":checked").length==0);}catch(v){}try{z.innerHTML='<a class=""></a>';o.brokenEmptyAttributeQSA=(z.querySelectorAll('[class*=""]').length!=0);
}catch(v){}}try{z.innerHTML='<form action="s"><input id="action"/></form>';r=(z.firstChild.getAttribute("action")!="s");}catch(v){}o.nativeMatchesSelector=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector;
if(o.nativeMatchesSelector){try{o.nativeMatchesSelector.call(y,":slick");o.nativeMatchesSelector=null;}catch(v){}}}try{y.slick_expando=1;delete y.slick_expando;
o.getUID=this.getUIDHTML;}catch(v){o.getUID=this.getUIDXML;}p.removeChild(z);z=s=p=null;o.getAttribute=(o.isHTMLDocument&&r)?function(D,B){var E=this.attributeGetters[B];
if(E){return E.call(D);}var C=D.getAttributeNode(B);return(C)?C.nodeValue:null;}:function(C,B){var D=this.attributeGetters[B];return(D)?D.call(C):C.getAttribute(B);
};o.hasAttribute=(y&&this.isNativeCode(y.hasAttribute))?function(C,B){return C.hasAttribute(B);}:function(C,B){C=C.getAttributeNode(B);return !!(C&&(C.specified||C.nodeValue));
};o.contains=(y&&this.isNativeCode(y.contains))?function(B,C){return B.contains(C);}:(y&&y.compareDocumentPosition)?function(B,C){return B===C||!!(B.compareDocumentPosition(C)&16);
}:function(B,C){if(C){do{if(C===B){return true;}}while((C=C.parentNode));}return false;};o.documentSorter=(y.compareDocumentPosition)?function(C,B){if(!C.compareDocumentPosition||!B.compareDocumentPosition){return 0;
}return C.compareDocumentPosition(B)&4?-1:C===B?0:1;}:("sourceIndex" in y)?function(C,B){if(!C.sourceIndex||!B.sourceIndex){return 0;}return C.sourceIndex-B.sourceIndex;
}:(w.createRange)?function(E,C){if(!E.ownerDocument||!C.ownerDocument){return 0;}var D=E.ownerDocument.createRange(),B=C.ownerDocument.createRange();D.setStart(E,0);
D.setEnd(E,0);B.setStart(C,0);B.setEnd(C,0);return D.compareBoundaryPoints(Range.START_TO_END,B);}:null;y=null;for(A in o){this[A]=o[A];}};var e=/^([#.]?)((?:[\w-]+|\*))$/,g=/\[.+[*$^]=(?:""|'')?\]/,f={};
j.search=function(q,D,O,v){var B=this.found=(v)?null:(O||[]);if(!q){return B;}else{if(q.navigator){q=q.document;}else{if(!q.nodeType){return B;}}}var z,N,s=this.uniques={},y=!!(O&&O.length),c=(q.nodeType==9);
if(this.document!==(c?q:q.ownerDocument)){this.setDocument(q);}if(y){for(N=B.length;N--;){s[this.getUID(B[N])]=true;}}if(typeof D=="string"){var C=D.match(e);
simpleSelectors:if(C){var K=C[1],V=C[2],I,G;if(!K){if(V=="*"&&this.brokenStarGEBTN){break simpleSelectors;}G=q.getElementsByTagName(V);if(v){return G[0]||null;
}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{if(K=="#"){if(!this.isHTMLDocument||!c){break simpleSelectors;}I=q.getElementById(V);
if(!I){return B;}if(this.idGetsName&&I.getAttributeNode("id").nodeValue!=V){break simpleSelectors;}if(v){return I||null;}if(!(y&&s[this.getUID(I)])){B.push(I);
}}else{if(K=="."){if(!this.isHTMLDocument||((!q.getElementsByClassName||this.brokenGEBCN)&&q.querySelectorAll)){break simpleSelectors;}if(q.getElementsByClassName&&!this.brokenGEBCN){G=q.getElementsByClassName(V);
if(v){return G[0]||null;}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{var u=new RegExp("(^|\\s)"+d.escapeRegExp(V)+"(\\s|$)");G=q.getElementsByTagName("*");
for(N=0;I=G[N++];){className=I.className;if(!(className&&u.test(className))){continue;}if(v){return I;}if(!(y&&s[this.getUID(I)])){B.push(I);}}}}}}if(y){this.sort(B);
}return(v)?null:B;}querySelector:if(q.querySelectorAll){if(!this.isHTMLDocument||this.brokenMixedCaseQSA||f[D]||(this.brokenCheckedQSA&&D.indexOf(":checked")>-1)||(this.brokenEmptyAttributeQSA&&g.test(D))||d.disableQSA){break querySelector;
}var A=D;if(!c){var M=q.getAttribute("id"),p="slickid__";q.setAttribute("id",p);A="#"+p+" "+A;}try{if(v){return q.querySelector(A)||null;}else{G=q.querySelectorAll(A);
}}catch(P){f[D]=1;break querySelector;}finally{if(!c){if(M){q.setAttribute("id",M);}else{q.removeAttribute("id");}}}if(this.starSelectsClosedQSA){for(N=0;
I=G[N++];){if(I.nodeName>"@"&&!(y&&s[this.getUID(I)])){B.push(I);}}}else{for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}if(y){this.sort(B);
}return B;}z=this.Slick.parse(D);if(!z.length){return B;}}else{if(D==null){return B;}else{if(D.Slick){z=D;}else{if(this.contains(q.documentElement||q,D)){(B)?B.push(D):B=D;
return B;}else{return B;}}}}this.posNTH={};this.posNTHLast={};this.posNTHType={};this.posNTHTypeLast={};this.push=(!y&&(v||(z.length==1&&z.expressions[0].length==1)))?this.pushArray:this.pushUID;
if(B==null){B=[];}var L,H,F;var J,U,E,T,Q,x,t;var w,r,o,R,S=z.expressions;search:for(N=0;(r=S[N]);N++){for(L=0;(o=r[L]);L++){J="combinator:"+o.combinator;
if(!this[J]){continue search;}U=(this.isXMLDocument)?o.tag:o.tag.toUpperCase();E=o.id;T=o.classList;Q=o.classes;x=o.attributes;t=o.pseudos;R=(L===(r.length-1));
this.bitUniques={};if(R){this.uniques=s;this.found=B;}else{this.uniques={};this.found=[];}if(L===0){this[J](q,U,E,Q,x,t,T);if(v&&R&&B.length){break search;
}}else{if(v&&R){for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);if(B.length){break search;}}}else{for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);
}}}w=this.found;}}if(y||(z.expressions.length>1)){this.sort(B);}return(v)?(B[0]||null):B;};j.uidx=1;j.uidk="slick-uniqueid";j.getUIDXML=function(m){var c=m.getAttribute(this.uidk);
if(!c){c=this.uidx++;m.setAttribute(this.uidk,c);}return c;};j.getUIDHTML=function(c){return c.uniqueNumber||(c.uniqueNumber=this.uidx++);};j.sort=function(c){if(!this.documentSorter){return c;
}c.sort(this.documentSorter);return c;};j.cacheNTH={};j.matchNTH=/^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;j.parseNTHArgument=function(p){var n=p.match(this.matchNTH);
if(!n){return false;}var o=n[2]||false;var m=n[1]||1;if(m=="-"){m=-1;}var c=+n[3]||0;n=(o=="n")?{a:m,b:c}:(o=="odd")?{a:2,b:1}:(o=="even")?{a:2,b:0}:{a:0,b:m};
return(this.cacheNTH[p]=n);};j.createNTHPseudo=function(o,m,c,n){return function(r,p){var t=this.getUID(r);if(!this[c][t]){var z=r.parentNode;if(!z){return false;
}var q=z[o],s=1;if(n){var y=r.nodeName;do{if(q.nodeName!=y){continue;}this[c][this.getUID(q)]=s++;}while((q=q[m]));}else{do{if(q.nodeType!=1){continue;
}this[c][this.getUID(q)]=s++;}while((q=q[m]));}}p=p||"n";var u=this.cacheNTH[p]||this.parseNTHArgument(p);if(!u){return false;}var x=u.a,w=u.b,v=this[c][t];
if(x==0){return w==v;}if(x>0){if(v<w){return false;}}else{if(w<v){return false;}}return((v-w)%x)==0;};};j.pushArray=function(o,c,q,n,m,p){if(this.matchSelector(o,c,q,n,m,p)){this.found.push(o);
}};j.pushUID=function(p,c,r,o,m,q){var n=this.getUID(p);if(!this.uniques[n]&&this.matchSelector(p,c,r,o,m,q)){this.uniques[n]=true;this.found.push(p);}};
j.matchNode=function(m,n){if(this.isHTMLDocument&&this.nativeMatchesSelector){try{return this.nativeMatchesSelector.call(m,n.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g,'[$1="$2"]'));
}catch(u){}}var t=this.Slick.parse(n);if(!t){return true;}var r=t.expressions,p,s=0,q;for(q=0;(currentExpression=r[q]);q++){if(currentExpression.length==1){var o=currentExpression[0];
if(this.matchSelector(m,(this.isXMLDocument)?o.tag:o.tag.toUpperCase(),o.id,o.classes,o.attributes,o.pseudos)){return true;}s++;}}if(s==t.length){return false;
}var c=this.search(this.document,t),v;for(q=0;v=c[q++];){if(v===m){return true;}}return false;};j.matchPseudo=function(p,c,o){var m="pseudo:"+c;if(this[m]){return this[m](p,o);
}var n=this.getAttribute(p,c);return(o)?o==n:!!n;};j.matchSelector=function(n,u,c,o,p,r){if(u){var s=(this.isXMLDocument)?n.nodeName:n.nodeName.toUpperCase();
if(u=="*"){if(s<"@"){return false;}}else{if(s!=u){return false;}}}if(c&&n.getAttribute("id")!=c){return false;}var q,m,t;if(o){for(q=o.length;q--;){t=n.getAttribute("class")||n.className;
if(!(t&&o[q].regexp.test(t))){return false;}}}if(p){for(q=p.length;q--;){m=p[q];if(m.operator?!m.test(this.getAttribute(n,m.key)):!this.hasAttribute(n,m.key)){return false;
}}}if(r){for(q=r.length;q--;){m=r[q];if(!this.matchPseudo(n,m.key,m.value)){return false;}}}return true;};var i={" ":function(p,v,m,q,r,t,o){var s,u,n;
if(this.isHTMLDocument){getById:if(m){u=this.document.getElementById(m);if((!u&&p.all)||(this.idGetsName&&u&&u.getAttributeNode("id").nodeValue!=m)){n=p.all[m];
if(!n){return;}if(!n[0]){n=[n];}for(s=0;u=n[s++];){var c=u.getAttributeNode("id");if(c&&c.nodeValue==m){this.push(u,v,null,q,r,t);break;}}return;}if(!u){if(this.contains(this.root,p)){return;
}else{break getById;}}else{if(this.document!==p&&!this.contains(p,u)){return;}}this.push(u,v,null,q,r,t);return;}getByClass:if(q&&p.getElementsByClassName&&!this.brokenGEBCN){n=p.getElementsByClassName(o.join(" "));
if(!(n&&n.length)){break getByClass;}for(s=0;u=n[s++];){this.push(u,v,m,null,r,t);}return;}}getByTag:{n=p.getElementsByTagName(v);if(!(n&&n.length)){break getByTag;
}if(!this.brokenStarGEBTN){v=null;}for(s=0;u=n[s++];){this.push(u,v,m,q,r,t);}}},">":function(o,c,q,n,m,p){if((o=o.firstChild)){do{if(o.nodeType==1){this.push(o,c,q,n,m,p);
}}while((o=o.nextSibling));}},"+":function(o,c,q,n,m,p){while((o=o.nextSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);break;}}},"^":function(o,c,q,n,m,p){o=o.firstChild;
if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:+"](o,c,q,n,m,p);}}},"~":function(p,c,r,o,m,q){while((p=p.nextSibling)){if(p.nodeType!=1){continue;
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}},"++":function(o,c,q,n,m,p){this["combinator:+"](o,c,q,n,m,p);
this["combinator:!+"](o,c,q,n,m,p);},"~~":function(o,c,q,n,m,p){this["combinator:~"](o,c,q,n,m,p);this["combinator:!~"](o,c,q,n,m,p);},"!":function(o,c,q,n,m,p){while((o=o.parentNode)){if(o!==this.document){this.push(o,c,q,n,m,p);
}}},"!>":function(o,c,q,n,m,p){o=o.parentNode;if(o!==this.document){this.push(o,c,q,n,m,p);}},"!+":function(o,c,q,n,m,p){while((o=o.previousSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);
break;}}},"!^":function(o,c,q,n,m,p){o=o.lastChild;if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:!+"](o,c,q,n,m,p);}}},"!~":function(p,c,r,o,m,q){while((p=p.previousSibling)){if(p.nodeType!=1){continue;
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}}};for(var h in i){j["combinator:"+h]=i[h];}var k={empty:function(c){var m=c.firstChild;
return !(m&&m.nodeType==1)&&!(c.innerText||c.textContent||"").length;},not:function(c,m){return !this.matchNode(c,m);},contains:function(c,m){return(c.innerText||c.textContent||"").indexOf(m)>-1;
},"first-child":function(c){while((c=c.previousSibling)){if(c.nodeType==1){return false;}}return true;},"last-child":function(c){while((c=c.nextSibling)){if(c.nodeType==1){return false;
}}return true;},"only-child":function(n){var m=n;while((m=m.previousSibling)){if(m.nodeType==1){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeType==1){return false;
}}return true;},"nth-child":j.createNTHPseudo("firstChild","nextSibling","posNTH"),"nth-last-child":j.createNTHPseudo("lastChild","previousSibling","posNTHLast"),"nth-of-type":j.createNTHPseudo("firstChild","nextSibling","posNTHType",true),"nth-last-of-type":j.createNTHPseudo("lastChild","previousSibling","posNTHTypeLast",true),index:function(m,c){return this["pseudo:nth-child"](m,""+c+1);
},even:function(c){return this["pseudo:nth-child"](c,"2n");},odd:function(c){return this["pseudo:nth-child"](c,"2n+1");},"first-of-type":function(c){var m=c.nodeName;
while((c=c.previousSibling)){if(c.nodeName==m){return false;}}return true;},"last-of-type":function(c){var m=c.nodeName;while((c=c.nextSibling)){if(c.nodeName==m){return false;
}}return true;},"only-of-type":function(n){var m=n,o=n.nodeName;while((m=m.previousSibling)){if(m.nodeName==o){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeName==o){return false;
}}return true;},enabled:function(c){return !c.disabled;},disabled:function(c){return c.disabled;},checked:function(c){return c.checked||c.selected;},focus:function(c){return this.isHTMLDocument&&this.document.activeElement===c&&(c.href||c.type||this.hasAttribute(c,"tabindex"));
},root:function(c){return(c===this.root);},selected:function(c){return c.selected;}};for(var a in k){j["pseudo:"+a]=k[a];}j.attributeGetters={"class":function(){return this.getAttribute("class")||this.className;
},"for":function(){return("htmlFor" in this)?this.htmlFor:this.getAttribute("for");},href:function(){return("href" in this)?this.getAttribute("href",2):this.getAttribute("href");
},style:function(){return(this.style)?this.style.cssText:this.getAttribute("style");},tabindex:function(){var c=this.getAttributeNode("tabindex");return(c&&c.specified)?c.nodeValue:null;
},type:function(){return this.getAttribute("type");}};var d=j.Slick=(this.Slick||{});d.version="1.1.5";d.search=function(m,n,c){return j.search(m,n,c);
};d.find=function(c,m){return j.search(c,m,null,true);};d.contains=function(c,m){j.setDocument(c);return j.contains(c,m);};d.getAttribute=function(m,c){return j.getAttribute(m,c);
};d.match=function(m,c){if(!(m&&c)){return false;}if(!c||c===m){return true;}j.setDocument(m);return j.matchNode(m,c);};d.defineAttributeGetter=function(c,m){j.attributeGetters[c]=m;
return this;};d.lookupAttributeGetter=function(c){return j.attributeGetters[c];};d.definePseudo=function(c,m){j["pseudo:"+c]=function(o,n){return m.call(o,n);
};return this;};d.lookupPseudo=function(c){var m=j["pseudo:"+c];if(m){return function(n){return m.call(this,n);};}return null;};d.override=function(m,c){j.override(m,c);
return this;};d.isXML=j.isXML;d.uidOf=function(c){return j.getUIDHTML(c);};if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);
var Element=function(b,g){var h=Element.Constructors[b];if(h){return h(g);}if(typeof b!="string"){return document.id(b).set(g);}if(!g){g={};}if(!(/^[\w-]+$/).test(b)){var e=Slick.parse(b).expressions[0][0];
b=(e.tag=="*")?"div":e.tag;if(e.id&&g.id==null){g.id=e.id;}var d=e.attributes;if(d){for(var f=0,c=d.length;f<c;f++){var a=d[f];if(a.value!=null&&a.operator=="="&&g[a.key]==null){g[a.key]=a.value;
}}}if(e.classList&&g["class"]==null){g["class"]=e.classList.join(" ");}}return document.newElement(b,g);};if(Browser.Element){Element.prototype=Browser.Element.prototype;
}new Type("Element",Element).mirror(function(a){if(Array.prototype[a]){return;}var b={};b[a]=function(){var h=[],e=arguments,j=true;for(var g=0,d=this.length;
g<d;g++){var f=this[g],c=h[g]=f[a].apply(f,e);j=(j&&typeOf(c)=="element");}return(j)?new Elements(h):h;};Elements.implement(b);});if(!Browser.Element){Element.parent=Object;
Element.Prototype={"$family":Function.from("element").hide()};Element.mirror(function(a,b){Element.Prototype[a]=b;});}Element.Constructors={};Element.Constructors=new Hash;
var IFrame=new Type("IFrame",function(){var e=Array.link(arguments,{properties:Type.isObject,iframe:function(f){return(f!=null);}});var c=e.properties||{},b;
if(e.iframe){b=document.id(e.iframe);}var d=c.onload||function(){};delete c.onload;c.id=c.name=[c.id,c.name,b?(b.id||b.name):"IFrame_"+String.uniqueID()].pick();
b=new Element(b||"iframe",c);var a=function(){d.call(b.contentWindow);};if(window.frames[c.id]){a();}else{b.addListener("load",a);}return b;});var Elements=this.Elements=function(a){if(a&&a.length){var e={},d;
for(var c=0;d=a[c++];){var b=Slick.uidOf(d);if(!e[b]){e[b]=true;this.push(d);}}}};Elements.prototype={length:0};Elements.parent=Array;new Type("Elements",Elements).implement({filter:function(a,b){if(!a){return this;
}return new Elements(Array.filter(this,(typeOf(a)=="string")?function(c){return c.match(a);}:a,b));}.protect(),push:function(){var d=this.length;for(var b=0,a=arguments.length;
b<a;b++){var c=document.id(arguments[b]);if(c){this[d++]=c;}}return(this.length=d);}.protect(),unshift:function(){var b=[];for(var c=0,a=arguments.length;
c<a;c++){var d=document.id(arguments[c]);if(d){b.push(d);}}return Array.prototype.unshift.apply(this,b);}.protect(),concat:function(){var b=new Elements(this);
for(var c=0,a=arguments.length;c<a;c++){var d=arguments[c];if(Type.isEnumerable(d)){b.append(d);}else{b.push(d);}}return b;}.protect(),append:function(c){for(var b=0,a=c.length;
b<a;b++){this.push(c[b]);}return this;}.protect(),empty:function(){while(this.length){delete this[--this.length];}return this;}.protect()});Elements.alias("extend","append");
(function(){var g=Array.prototype.splice,b={"0":0,"1":1,length:2};g.call(b,1,1);if(b[1]==1){Elements.implement("splice",function(){var e=this.length;g.apply(this,arguments);
while(e>=this.length){delete this[e--];}return this;}.protect());}Elements.implement(Array.prototype);Array.mirror(Elements);var f;try{var a=document.createElement("<input name=x>");
f=(a.name=="x");}catch(c){}var d=function(e){return(""+e).replace(/&/g,"&amp;").replace(/"/g,"&quot;");};Document.implement({newElement:function(e,h){if(h&&h.checked!=null){h.defaultChecked=h.checked;
}if(f&&h){e="<"+e;if(h.name){e+=' name="'+d(h.name)+'"';}if(h.type){e+=' type="'+d(h.type)+'"';}e+=">";delete h.name;delete h.type;}return this.id(this.createElement(e)).set(h);
}});})();Document.implement({newTextNode:function(a){return this.createTextNode(a);},getDocument:function(){return this;},getWindow:function(){return this.window;
},id:(function(){var a={string:function(d,c,b){d=Slick.find(b,"#"+d.replace(/(\W)/g,"\\$1"));return(d)?a.element(d,c):null;},element:function(b,c){$uid(b);
if(!c&&!b.$family&&!(/^(?:object|embed)$/i).test(b.tagName)){Object.append(b,Element.Prototype);}return b;},object:function(c,d,b){if(c.toElement){return a.element(c.toElement(b),d);
}return null;}};a.textnode=a.whitespace=a.window=a.document=function(b){return b;};return function(c,e,d){if(c&&c.$family&&c.uid){return c;}var b=typeOf(c);
return(a[b])?a[b](c,e,d||document):null;};})()});if(window.$==null){Window.implement("$",function(a,b){return document.id(a,b,this.document);});}Window.implement({getDocument:function(){return this.document;
},getWindow:function(){return this;}});[Document,Element].invoke("implement",{getElements:function(a){return Slick.search(this,a,new Elements);},getElement:function(a){return document.id(Slick.find(this,a));
}});(function(b,d,a){this.Selectors={};var e=this.Selectors.Pseudo=new Hash();var c=function(){for(var f in e){if(e.hasOwnProperty(f)){Slick.definePseudo(f,e[f]);
delete e[f];}}};Slick.search=function(g,h,f){c();return b.call(this,g,h,f);};Slick.find=function(f,g){c();return d.call(this,f,g);};Slick.match=function(g,f){c();
return a.call(this,g,f);};})(Slick.search,Slick.find,Slick.match);if(window.$$==null){Window.implement("$$",function(a){var f=new Elements;if(arguments.length==1&&typeof a=="string"){return Slick.search(this.document,a,f);
}var c=Array.flatten(arguments);for(var d=0,b=c.length;d<b;d++){var e=c[d];switch(typeOf(e)){case"element":f.push(e);break;case"string":Slick.search(this.document,e,f);
}}return f;});}if(window.$$==null){Window.implement("$$",function(a){if(arguments.length==1){if(typeof a=="string"){return Slick.search(this.document,a,new Elements);
}else{if(Type.isEnumerable(a)){return new Elements(a);}}}return new Elements(arguments);});}(function(){var k={},i={};var n={input:"checked",option:"selected",textarea:"value"};
var e=function(p){return(i[p]||(i[p]={}));};var j=function(q){var p=q.uid;if(q.removeEvents){q.removeEvents();}if(q.clearAttributes){q.clearAttributes();
}if(p!=null){delete k[p];delete i[p];}return q;};var o=["defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];
var d=["compact","nowrap","ismap","declare","noshade","checked","disabled","readOnly","multiple","selected","noresize","defer","defaultChecked"];var g={html:"innerHTML","class":"className","for":"htmlFor",text:(function(){var p=document.createElement("div");
return(p.textContent==null)?"innerText":"textContent";})()};var m=["type"];var h=["value","defaultValue"];var l=/^(?:href|src|usemap)$/i;d=d.associate(d);
o=o.associate(o.map(String.toLowerCase));m=m.associate(m);Object.append(g,h.associate(h));var c={before:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p);
}},after:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p.nextSibling);}},bottom:function(q,p){p.appendChild(q);},top:function(q,p){p.insertBefore(q,p.firstChild);
}};c.inside=c.bottom;Object.each(c,function(q,r){r=r.capitalize();var p={};p["inject"+r]=function(s){q(this,document.id(s,true));return this;};p["grab"+r]=function(s){q(document.id(s,true),this);
return this;};Element.implement(p);});var b=function(s,r){if(!s){return r;}s=Object.clone(Slick.parse(s));var q=s.expressions;for(var p=q.length;p--;){q[p][0].combinator=r;
}return s;};Element.implement({set:function(r,q){var p=Element.Properties[r];(p&&p.set)?p.set.call(this,q):this.setProperty(r,q);}.overloadSetter(),get:function(q){var p=Element.Properties[q];
return(p&&p.get)?p.get.apply(this):this.getProperty(q);}.overloadGetter(),erase:function(q){var p=Element.Properties[q];(p&&p.erase)?p.erase.apply(this):this.removeProperty(q);
return this;},setProperty:function(q,r){q=o[q]||q;if(r==null){return this.removeProperty(q);}var p=g[q];(p)?this[p]=r:(d[q])?this[q]=!!r:this.setAttribute(q,""+r);
return this;},setProperties:function(p){for(var q in p){this.setProperty(q,p[q]);}return this;},getProperty:function(q){q=o[q]||q;var p=g[q]||m[q];return(p)?this[p]:(d[q])?!!this[q]:(l.test(q)?this.getAttribute(q,2):(p=this.getAttributeNode(q))?p.nodeValue:null)||null;
},getProperties:function(){var p=Array.from(arguments);return p.map(this.getProperty,this).associate(p);},removeProperty:function(q){q=o[q]||q;var p=g[q];
(p)?this[p]="":(d[q])?this[q]=false:this.removeAttribute(q);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;
},hasClass:function(p){return this.className.clean().contains(p," ");},addClass:function(p){if(!this.hasClass(p)){this.className=(this.className+" "+p).clean();
}return this;},removeClass:function(p){this.className=this.className.replace(new RegExp("(^|\\s)"+p+"(?:\\s|$)"),"$1");return this;},toggleClass:function(p,q){if(q==null){q=!this.hasClass(p);
}return(q)?this.addClass(p):this.removeClass(p);},adopt:function(){var s=this,p,u=Array.flatten(arguments),t=u.length;if(t>1){s=p=document.createDocumentFragment();
}for(var r=0;r<t;r++){var q=document.id(u[r],true);if(q){s.appendChild(q);}}if(p){this.appendChild(p);}return this;},appendText:function(q,p){return this.grab(this.getDocument().newTextNode(q),p);
},grab:function(q,p){c[p||"bottom"](document.id(q,true),this);return this;},inject:function(q,p){c[p||"bottom"](this,document.id(q,true));return this;},replaces:function(p){p=document.id(p,true);
p.parentNode.replaceChild(this,p);return this;},wraps:function(q,p){q=document.id(q,true);return this.replaces(q).grab(q,p);},getPrevious:function(p){return document.id(Slick.find(this,b(p,"!~")));
},getAllPrevious:function(p){return Slick.search(this,b(p,"!~"),new Elements);},getNext:function(p){return document.id(Slick.find(this,b(p,"~")));},getAllNext:function(p){return Slick.search(this,b(p,"~"),new Elements);
},getFirst:function(p){return document.id(Slick.search(this,b(p,">"))[0]);},getLast:function(p){return document.id(Slick.search(this,b(p,">")).getLast());
},getParent:function(p){return document.id(Slick.find(this,b(p,"!")));},getParents:function(p){return Slick.search(this,b(p,"!"),new Elements);},getSiblings:function(p){return Slick.search(this,b(p,"~~"),new Elements);
},getChildren:function(p){return Slick.search(this,b(p,">"),new Elements);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;
},getElementById:function(p){return document.id(Slick.find(this,"#"+(""+p).replace(/(\W)/g,"\\$1")));},getSelected:function(){this.selectedIndex;return new Elements(Array.from(this.options).filter(function(p){return p.selected;
}));},toQueryString:function(){var p=[];this.getElements("input, select, textarea").each(function(r){var q=r.type;if(!r.name||r.disabled||q=="submit"||q=="reset"||q=="file"||q=="image"){return;
}var s=(r.get("tag")=="select")?r.getSelected().map(function(t){return document.id(t).get("value");}):((q=="radio"||q=="checkbox")&&!r.checked)?null:r.get("value");
Array.from(s).each(function(t){if(typeof t!="undefined"){p.push(encodeURIComponent(r.name)+"="+encodeURIComponent(t));}});});return p.join("&");},destroy:function(){var p=j(this).getElementsByTagName("*");
Array.each(p,j);Element.dispose(this);return null;},empty:function(){Array.from(this.childNodes).each(Element.dispose);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
},match:function(p){return !p||Slick.match(this,p);}});var a=function(t,s,q){if(!q){t.setAttributeNode(document.createAttribute("id"));}if(t.clearAttributes){t.clearAttributes();
t.mergeAttributes(s);t.removeAttribute("uid");if(t.options){var u=t.options,p=s.options;for(var r=u.length;r--;){u[r].selected=p[r].selected;}}}var v=n[s.tagName.toLowerCase()];
if(v&&s[v]){t[v]=s[v];}};Element.implement("clone",function(r,p){r=r!==false;var w=this.cloneNode(r),q;if(r){var s=w.getElementsByTagName("*"),u=this.getElementsByTagName("*");
for(q=s.length;q--;){a(s[q],u[q],p);}}a(w,this,p);if(Browser.ie){var t=w.getElementsByTagName("object"),v=this.getElementsByTagName("object");for(q=t.length;
q--;){t[q].outerHTML=v[q].outerHTML;}}return document.id(w);});var f={contains:function(p){return Slick.contains(this,p);}};if(!document.contains){Document.implement(f);
}if(!document.createElement("div").contains){Element.implement(f);}Element.implement("hasChild",function(p){return this!==p&&this.contains(p);});[Element,Window,Document].invoke("implement",{addListener:function(s,r){if(s=="unload"){var p=r,q=this;
r=function(){q.removeListener("unload",r);p();};}else{k[$uid(this)]=this;}if(this.addEventListener){this.addEventListener(s,r,!!arguments[2]);}else{this.attachEvent("on"+s,r);
}return this;},removeListener:function(q,p){if(this.removeEventListener){this.removeEventListener(q,p,!!arguments[2]);}else{this.detachEvent("on"+q,p);
}return this;},retrieve:function(q,p){var s=e($uid(this)),r=s[q];if(p!=null&&r==null){r=s[q]=p;}return r!=null?r:null;},store:function(q,p){var r=e($uid(this));
r[q]=p;return this;},eliminate:function(p){var q=e($uid(this));delete q[p];return this;}});if(window.attachEvent&&!window.addEventListener){window.addListener("unload",function(){Object.each(k,j);
if(window.CollectGarbage){CollectGarbage();}});}})();Element.Properties={};Element.Properties=new Hash;Element.Properties.style={set:function(a){this.style.cssText=a;
},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();
}};(function(a){if(a!=null){Element.Properties.maxlength=Element.Properties.maxLength={get:function(){var b=this.getAttribute("maxLength");return b==a?null:b;
}};}})(document.createElement("input").getAttribute("maxLength"));Element.Properties.html=(function(){var c=Function.attempt(function(){var e=document.createElement("table");
e.innerHTML="<tr><td></td></tr>";});var d=document.createElement("div");var a={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};
a.thead=a.tfoot=a.tbody;var b={set:function(){var f=Array.flatten(arguments).join("");var g=(!c&&a[this.get("tag")]);if(g){var h=d;h.innerHTML=g[1]+f+g[2];
for(var e=g[0];e--;){h=h.firstChild;}this.empty().adopt(h.childNodes);}else{this.innerHTML=f;}}};b.erase=b.set;return b;})();(function(){var c=document.html;
Element.Properties.styles={set:function(f){this.setStyles(f);}};var e=(c.style.opacity!=null);var d=/alpha\(opacity=([\d.]+)\)/i;var b=function(g,f){if(!g.currentStyle||!g.currentStyle.hasLayout){g.style.zoom=1;
}if(e){g.style.opacity=f;}else{f=(f==1)?"":"alpha(opacity="+f*100+")";var h=g.style.filter||g.getComputedStyle("filter")||"";g.style.filter=d.test(h)?h.replace(d,f):h+f;
}};Element.Properties.opacity={set:function(g){var f=this.style.visibility;if(g==0&&f!="hidden"){this.style.visibility="hidden";}else{if(g!=0&&f!="visible"){this.style.visibility="visible";
}}b(this,g);},get:(e)?function(){var f=this.style.opacity||this.getComputedStyle("opacity");return(f=="")?1:f;}:function(){var f,g=(this.style.filter||this.getComputedStyle("filter"));
if(g){f=g.match(d);}return(f==null||g==null)?1:(f[1]/100);}};var a=(c.style.cssFloat==null)?"styleFloat":"cssFloat";Element.implement({getComputedStyle:function(h){if(this.currentStyle){return this.currentStyle[h.camelCase()];
}var g=Element.getDocument(this).defaultView,f=g?g.getComputedStyle(this,null):null;return(f)?f.getPropertyValue((h==a)?"float":h.hyphenate()):null;},setOpacity:function(f){b(this,f);
return this;},getOpacity:function(){return this.get("opacity");},setStyle:function(g,f){switch(g){case"opacity":return this.set("opacity",parseFloat(f));
case"float":g=a;}g=g.camelCase();if(typeOf(f)!="string"){var h=(Element.Styles[g]||"@").split(" ");f=Array.from(f).map(function(k,j){if(!h[j]){return"";
}return(typeOf(k)=="number")?h[j].replace("@",Math.round(k)):k;}).join(" ");}else{if(f==String(Number(f))){f=Math.round(f);}}this.style[g]=f;return this;
},getStyle:function(l){switch(l){case"opacity":return this.get("opacity");case"float":l=a;}l=l.camelCase();var f=this.style[l];if(!f||l=="zIndex"){f=[];
for(var k in Element.ShortStyles){if(l!=k){continue;}for(var j in Element.ShortStyles[k]){f.push(this.getStyle(j));}return f.join(" ");}f=this.getComputedStyle(l);
}if(f){f=String(f);var h=f.match(/rgba?\([\d\s,]+\)/);if(h){f=f.replace(h[0],h[0].rgbToHex());}}if(Browser.opera||(Browser.ie&&isNaN(parseFloat(f)))){if((/^(height|width)$/).test(l)){var g=(l=="width")?["left","right"]:["top","bottom"],i=0;
g.each(function(m){i+=this.getStyle("border-"+m+"-width").toInt()+this.getStyle("padding-"+m).toInt();},this);return this["offset"+l.capitalize()]-i+"px";
}if(Browser.opera&&String(f).indexOf("px")!=-1){return f;}if((/^border(.+)Width|margin|padding/).test(l)){return"0px";}}return f;},setStyles:function(g){for(var f in g){this.setStyle(f,g[f]);
}return this;},getStyles:function(){var f={};Array.flatten(arguments).each(function(g){f[g]=this.getStyle(g);},this);return f;}});Element.Styles={left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"};
Element.Styles=new Hash(Element.Styles);Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(l){var k=Element.ShortStyles;
var g=Element.Styles;["margin","padding"].each(function(m){var n=m+l;k[m][n]=g[n]="@px";});var j="border"+l;k.border[j]=g[j]="@px @ rgb(@, @, @)";var i=j+"Width",f=j+"Style",h=j+"Color";
k[j]={};k.borderWidth[i]=k[j][i]=g[i]="@px";k.borderStyle[f]=k[j][f]=g[f]="@";k.borderColor[h]=k[j][h]=g[h]="rgb(@, @, @)";});}).call(this);(function(){Element.Properties.events={set:function(b){this.addEvents(b);
}};[Element,Window,Document].invoke("implement",{addEvent:function(f,h){var i=this.retrieve("events",{});if(!i[f]){i[f]={keys:[],values:[]};}if(i[f].keys.contains(h)){return this;
}i[f].keys.push(h);var g=f,b=Element.Events[f],d=h,j=this;if(b){if(b.onAdd){b.onAdd.call(this,h);}if(b.condition){d=function(k){if(b.condition.call(this,k)){return h.call(this,k);
}return true;};}g=b.base||g;}var e=function(){return h.call(j);};var c=Element.NativeEvents[g];if(c){if(c==2){e=function(k){k=new Event(k,j.getWindow());
if(d.call(j,k)===false){k.stop();}};}this.addListener(g,e,arguments[2]);}i[f].values.push(e);return this;},removeEvent:function(e,d){var c=this.retrieve("events");
if(!c||!c[e]){return this;}var h=c[e];var b=h.keys.indexOf(d);if(b==-1){return this;}var g=h.values[b];delete h.keys[b];delete h.values[b];var f=Element.Events[e];
if(f){if(f.onRemove){f.onRemove.call(this,d);}e=f.base||e;}return(Element.NativeEvents[e])?this.removeListener(e,g,arguments[2]):this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
}return this;},removeEvents:function(b){var d;if(typeOf(b)=="object"){for(d in b){this.removeEvent(d,b[d]);}return this;}var c=this.retrieve("events");
if(!c){return this;}if(!b){for(d in c){this.removeEvents(d);}this.eliminate("events");}else{if(c[b]){c[b].keys.each(function(e){this.removeEvent(b,e);},this);
delete c[b];}}return this;},fireEvent:function(e,c,b){var d=this.retrieve("events");if(!d||!d[e]){return this;}c=Array.from(c);d[e].keys.each(function(f){if(b){f.delay(b,this,c);
}else{f.apply(this,c);}},this);return this;},cloneEvents:function(e,d){e=document.id(e);var c=e.retrieve("events");if(!c){return this;}if(!d){for(var b in c){this.cloneEvents(e,b);
}}else{if(c[d]){c[d].keys.each(function(f){this.addEvent(d,f);},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,orientationchange:2,touchstart:2,touchmove:2,touchend:2,touchcancel:2,gesturestart:2,gesturechange:2,gestureend:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:2,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
var a=function(b){var c=b.relatedTarget;if(c==null){return true;}if(!c){return false;}return(c!=this&&c.prefix!="xul"&&typeOf(this)!="document"&&!this.contains(c));
};Element.Events={mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.firefox)?"DOMMouseScroll":"mousewheel"}};
Element.Events=new Hash(Element.Events);}).call(this);(function(){var h=document.createElement("div"),e=document.createElement("div");h.style.height="0";
h.appendChild(e);var d=(e.offsetParent===h);h=e=null;var l=function(m){return k(m,"position")!="static"||a(m);};var i=function(m){return l(m)||(/^(?:table|td|th)$/i).test(m.tagName);
};Element.implement({scrollTo:function(m,n){if(a(this)){this.getWindow().scrollTo(m,n);}else{this.scrollLeft=m;this.scrollTop=n;}return this;},getSize:function(){if(a(this)){return this.getWindow().getSize();
}return{x:this.offsetWidth,y:this.offsetHeight};},getScrollSize:function(){if(a(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};
},getScroll:function(){if(a(this)){return this.getWindow().getScroll();}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var n=this.parentNode,m={x:0,y:0};
while(n&&!a(n)){m.x+=n.scrollLeft;m.y+=n.scrollTop;n=n.parentNode;}return m;},getOffsetParent:d?function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
}var n=(k(m,"position")=="static")?i:l;while((m=m.parentNode)){if(n(m)){return m;}}return null;}:function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
}try{return m.offsetParent;}catch(n){}return null;},getOffsets:function(){if(this.getBoundingClientRect&&!Browser.Platform.ios){var r=this.getBoundingClientRect(),o=document.id(this.getDocument().documentElement),q=o.getScroll(),t=this.getScrolls(),s=(k(this,"position")=="fixed");
return{x:r.left.toInt()+t.x+((s)?0:q.x)-o.clientLeft,y:r.top.toInt()+t.y+((s)?0:q.y)-o.clientTop};}var n=this,m={x:0,y:0};if(a(this)){return m;}while(n&&!a(n)){m.x+=n.offsetLeft;
m.y+=n.offsetTop;if(Browser.firefox){if(!c(n)){m.x+=b(n);m.y+=g(n);}var p=n.parentNode;if(p&&k(p,"overflow")!="visible"){m.x+=b(p);m.y+=g(p);}}else{if(n!=this&&Browser.safari){m.x+=b(n);
m.y+=g(n);}}n=n.offsetParent;}if(Browser.firefox&&!c(this)){m.x-=b(this);m.y-=g(this);}return m;},getPosition:function(p){if(a(this)){return{x:0,y:0};}var q=this.getOffsets(),n=this.getScrolls();
var m={x:q.x-n.x,y:q.y-n.y};if(p&&(p=document.id(p))){var o=p.getPosition();return{x:m.x-o.x-b(p),y:m.y-o.y-g(p)};}return m;},getCoordinates:function(o){if(a(this)){return this.getWindow().getCoordinates();
}var m=this.getPosition(o),n=this.getSize();var p={left:m.x,top:m.y,width:n.x,height:n.y};p.right=p.left+p.width;p.bottom=p.top+p.height;return p;},computePosition:function(m){return{left:m.x-j(this,"margin-left"),top:m.y-j(this,"margin-top")};
},setPosition:function(m){return this.setStyles(this.computePosition(m));}});[Document,Window].invoke("implement",{getSize:function(){var m=f(this);return{x:m.clientWidth,y:m.clientHeight};
},getScroll:function(){var n=this.getWindow(),m=f(this);return{x:n.pageXOffset||m.scrollLeft,y:n.pageYOffset||m.scrollTop};},getScrollSize:function(){var o=f(this),n=this.getSize(),m=this.getDocument().body;
return{x:Math.max(o.scrollWidth,m.scrollWidth,n.x),y:Math.max(o.scrollHeight,m.scrollHeight,n.y)};},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var m=this.getSize();
return{top:0,left:0,bottom:m.y,right:m.x,height:m.y,width:m.x};}});var k=Element.getComputedStyle;function j(m,n){return k(m,n).toInt()||0;}function c(m){return k(m,"-moz-box-sizing")=="border-box";
}function g(m){return j(m,"border-top-width");}function b(m){return j(m,"border-left-width");}function a(m){return(/^(?:body|html)$/i).test(m.tagName);
}function f(m){var n=m.getDocument();return(!n.compatMode||n.compatMode=="CSS1Compat")?n.html:n.body;}}).call(this);Element.alias({position:"setPosition"});
[Window,Document,Element].invoke("implement",{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});(function(){var f=this.Fx=new Class({Implements:[Chain,Events,Options],options:{fps:60,unit:false,duration:500,frames:null,frameSkip:true,link:"ignore"},initialize:function(g){this.subject=this.subject||this;
this.setOptions(g);},getTransition:function(){return function(g){return -(Math.cos(Math.PI*g)-1)/2;};},step:function(g){if(this.options.frameSkip){var h=(this.time!=null)?(g-this.time):0,i=h/this.frameInterval;
this.time=g;this.frame+=i;}else{this.frame++;}if(this.frame<this.frames){var j=this.transition(this.frame/this.frames);this.set(this.compute(this.from,this.to,j));
}else{this.frame=this.frames;this.set(this.compute(this.from,this.to,1));this.stop();}},set:function(g){return g;},compute:function(i,h,g){return f.compute(i,h,g);
},check:function(){if(!this.isRunning()){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));
return false;}return false;},start:function(k,j){if(!this.check(k,j)){return this;}this.from=k;this.to=j;this.frame=(this.options.frameSkip)?0:-1;this.time=null;
this.transition=this.getTransition();var i=this.options.frames,h=this.options.fps,g=this.options.duration;this.duration=f.Durations[g]||g.toInt();this.frameInterval=1000/h;
this.frames=i||Math.round(this.duration/this.frameInterval);this.fireEvent("start",this.subject);b.call(this,h);return this;},stop:function(){if(this.isRunning()){this.time=null;
d.call(this,this.options.fps);if(this.frames==this.frame){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
}}else{this.fireEvent("stop",this.subject);}}return this;},cancel:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);this.frame=this.frames;
this.fireEvent("cancel",this.subject).clearChain();}return this;},pause:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);}return this;
},resume:function(){if((this.frame<this.frames)&&!this.isRunning()){b.call(this,this.options.fps);}return this;},isRunning:function(){var g=e[this.options.fps];
return g&&g.contains(this);}});f.compute=function(i,h,g){return(h-i)*g+i;};f.Durations={"short":250,normal:500,"long":1000};var e={},c={};var a=function(){var h=Date.now();
for(var j=this.length;j--;){var g=this[j];if(g){g.step(h);}}};var b=function(h){var g=e[h]||(e[h]=[]);g.push(this);if(!c[h]){c[h]=a.periodical(Math.round(1000/h),g);
}};var d=function(h){var g=e[h];if(g){g.erase(this);if(!g.length&&c[h]){delete e[h];c[h]=clearInterval(c[h]);}}};}).call(this);Fx.CSS=new Class({Extends:Fx,prepare:function(c,d,b){b=Array.from(b);
if(b[1]==null){b[1]=b[0];b[0]=c.getStyle(d);}var a=b.map(this.parse);return{from:a[0],to:a[1]};},parse:function(a){a=Function.from(a)();a=(typeof a=="string")?a.split(" "):Array.from(a);
return a.map(function(c){c=String(c);var b=false;Object.each(Fx.CSS.Parsers,function(f,e){if(b){return;}var d=f.parse(c);if(d||d===0){b={value:d,parser:f};
}});b=b||{value:c,parser:Fx.CSS.Parsers.String};return b;});},compute:function(d,c,b){var a=[];(Math.min(d.length,c.length)).times(function(e){a.push({value:d[e].parser.compute(d[e].value,c[e].value,b),parser:d[e].parser});
});a.$family=Function.from("fx:css:value");return a;},serve:function(c,b){if(typeOf(c)!="fx:css:value"){c=this.parse(c);}var a=[];c.each(function(d){a=a.concat(d.parser.serve(d.value,b));
});return a;},render:function(a,d,c,b){a.setStyle(d,this.serve(c,b));},search:function(a){if(Fx.CSS.Cache[a]){return Fx.CSS.Cache[a];}var c={},b=new RegExp("^"+a.escapeRegExp()+"$");
Array.each(document.styleSheets,function(f,e){var d=f.href;if(d&&d.contains("://")&&!d.contains(document.domain)){return;}var g=f.rules||f.cssRules;Array.each(g,function(k,h){if(!k.style){return;
}var j=(k.selectorText)?k.selectorText.replace(/^\w+/,function(i){return i.toLowerCase();}):null;if(!j||!b.test(j)){return;}Object.each(Element.Styles,function(l,i){if(!k.style[i]||Element.ShortStyles[i]){return;
}l=String(k.style[i]);c[i]=((/^rgb/).test(l))?l.rgbToHex():l;});});});return Fx.CSS.Cache[a]=c;}});Fx.CSS.Cache={};Fx.CSS.Parsers={Color:{parse:function(a){if(a.match(/^#[0-9a-f]{3,6}$/i)){return a.hexToRgb(true);
}return((a=a.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[a[1],a[2],a[3]]:false;},compute:function(c,b,a){return c.map(function(e,d){return Math.round(Fx.compute(c[d],b[d],a));
});},serve:function(a){return a.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(b,a){return(a)?b+a:b;}},String:{parse:Function.from(false),compute:function(b,a){return a;
},serve:function(a){return a;}}};Fx.CSS.Parsers=new Hash(Fx.CSS.Parsers);Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);
this.parent(a);},set:function(b,a){if(arguments.length==1){a=b;b=this.property||this.options.property;}this.render(this.element,b,a,this.options.unit);
return this;},start:function(c,e,d){if(!this.check(c,e,d)){return this;}var b=Array.flatten(arguments);this.property=this.options.property||b.shift();var a=this.prepare(this.element,this.property,b);
return this.parent(a.from,a.to);}});Element.Properties.tween={set:function(a){this.get("tween").cancel().setOptions(a);return this;},get:function(){var a=this.retrieve("tween");
if(!a){a=new Fx.Tween(this,{link:"cancel"});this.store("tween",a);}return a;}};Element.implement({tween:function(a,c,b){this.get("tween").start(arguments);
return this;},fade:function(c){var e=this.get("tween"),d="opacity",a;c=[c,"toggle"].pick();switch(c){case"in":e.start(d,1);break;case"out":e.start(d,0);
break;case"show":e.set(d,1);break;case"hide":e.set(d,0);break;case"toggle":var b=this.retrieve("fade:flag",this.get("opacity")==1);e.start(d,(b)?0:1);this.store("fade:flag",!b);
a=true;break;default:e.start(d,arguments);}if(!a){this.eliminate("fade:flag");}return this;},highlight:function(c,a){if(!a){a=this.retrieve("highlight:original",this.getStyle("background-color"));
a=(a=="transparent")?"#fff":a;}var b=this.get("tween");b.start("background-color",c||"#ffff88",a).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
b.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);
},set:function(a){if(typeof a=="string"){a=this.search(a);}for(var b in a){this.render(this.element,b,a[b],this.options.unit);}return this;},compute:function(e,d,c){var a={};
for(var b in e){a[b]=this.parent(e[b],d[b],c);}return a;},start:function(b){if(!this.check(b)){return this;}if(typeof b=="string"){b=this.search(b);}var e={},d={};
for(var c in b){var a=this.prepare(this.element,c,b[c]);e[c]=a.from;d[c]=a.to;}return this.parent(e,d);}});Element.Properties.morph={set:function(a){this.get("morph").cancel().setOptions(a);
return this;},get:function(){var a=this.retrieve("morph");if(!a){a=new Fx.Morph(this,{link:"cancel"});this.store("morph",a);}return a;}};Element.implement({morph:function(a){this.get("morph").start(a);
return this;}});Fx.implement({getTransition:function(){var a=this.options.transition||Fx.Transitions.Sine.easeInOut;if(typeof a=="string"){var b=a.split(":");
a=Fx.Transitions;a=a[b[0]]||a[b[0].capitalize()];if(b[1]){a=a["ease"+b[1].capitalize()+(b[2]?b[2].capitalize():"")];}}return a;}});Fx.Transition=function(c,b){b=Array.from(b);
var a=function(d){return c(d,b);};return Object.append(a,{easeIn:a,easeOut:function(d){return 1-c(1-d,b);},easeInOut:function(d){return(d<=0.5?c(2*d,b):(2-c(2*(1-d),b)))/2;
}});};Fx.Transitions={linear:function(a){return a;}};Fx.Transitions=new Hash(Fx.Transitions);Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);
}};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a&&a[0]||6);},Expo:function(a){return Math.pow(2,8*(a-1));},Circ:function(a){return 1-Math.sin(Math.acos(a));
},Sine:function(a){return 1-Math.cos(a*Math.PI/2);},Back:function(b,a){a=a&&a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a);},Bounce:function(f){var e;for(var d=0,c=1;
1;d+=c,c/=2){if(f>=(7-4*d)/11){e=c*c-Math.pow((11-6*d-11*f)/4,2);break;}}return e;},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a&&a[0]||1)/3);
}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,a+2);});});(function(){var d=function(){},a=("onprogress" in new Browser.Request);
var c=this.Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false,timeout:0,noCache:false},initialize:function(e){this.xhr=new Browser.Request();
this.setOptions(e);this.headers=this.options.headers;},onStateChange:function(){var e=this.xhr;if(e.readyState!=4||!this.running){return;}this.running=false;
this.status=0;Function.attempt(function(){var f=e.status;this.status=(f==1223)?204:f;}.bind(this));e.onreadystatechange=d;if(a){e.onprogress=e.onloadstart=d;
}clearTimeout(this.timer);this.response={text:this.xhr.responseText||"",xml:this.xhr.responseXML};if(this.options.isSuccess.call(this,this.status)){this.success(this.response.text,this.response.xml);
}else{this.failure();}},isSuccess:function(){var e=this.status;return(e>=200&&e<300);},isRunning:function(){return !!this.running;},processScripts:function(e){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return Browser.exec(e);
}return e.stripScripts(this.options.evalScripts);},success:function(f,e){this.onSuccess(this.processScripts(f),e);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},loadstart:function(e){this.fireEvent("loadstart",[e,this.xhr]);
},progress:function(e){this.fireEvent("progress",[e,this.xhr]);},timeout:function(){this.fireEvent("timeout",this.xhr);},setHeader:function(e,f){this.headers[e]=f;
return this;},getHeader:function(e){return Function.attempt(function(){return this.xhr.getResponseHeader(e);}.bind(this));},check:function(){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));return false;}return false;},send:function(o){if(!this.check(o)){return this;
}this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.running=true;var l=typeOf(o);if(l=="string"||l=="element"){o={data:o};}var h=this.options;
o=Object.append({data:h.data,url:h.url,method:h.method},o);var j=o.data,f=String(o.url),e=o.method.toLowerCase();switch(typeOf(j)){case"element":j=document.id(j).toQueryString();
break;case"object":case"hash":j=Object.toQueryString(j);}if(this.options.format){var m="format="+this.options.format;j=(j)?m+"&"+j:m;}if(this.options.emulation&&!["get","post"].contains(e)){var k="_method="+e;
j=(j)?k+"&"+j:k;e="post";}if(this.options.urlEncoded&&["post","put"].contains(e)){var g=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers["Content-type"]="application/x-www-form-urlencoded"+g;
}if(!f){f=document.location.pathname;}var i=f.lastIndexOf("/");if(i>-1&&(i=f.indexOf("#"))>-1){f=f.substr(0,i);}if(this.options.noCache){f+=(f.contains("?")?"&":"?")+String.uniqueID();
}if(j&&e=="get"){f+=(f.contains("?")?"&":"?")+j;j=null;}var n=this.xhr;if(a){n.onloadstart=this.loadstart.bind(this);n.onprogress=this.progress.bind(this);
}n.open(e.toUpperCase(),f,this.options.async,this.options.user,this.options.password);if(this.options.user&&"withCredentials" in n){n.withCredentials=true;
}n.onreadystatechange=this.onStateChange.bind(this);Object.each(this.headers,function(q,p){try{n.setRequestHeader(p,q);}catch(r){this.fireEvent("exception",[p,q]);
}},this);this.fireEvent("request");n.send(j);if(!this.options.async){this.onStateChange();}if(this.options.timeout){this.timer=this.timeout.delay(this.options.timeout,this);
}return this;},cancel:function(){if(!this.running){return this;}this.running=false;var e=this.xhr;e.abort();clearTimeout(this.timer);e.onreadystatechange=d;
if(a){e.onprogress=e.onloadstart=d;}this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});var b={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(e){b[e]=function(g){var f={method:e};
if(g!=null){f.data=g;}return this.send(f);};});c.implement(b);Element.Properties.send={set:function(e){var f=this.get("send").cancel();f.setOptions(e);
return this;},get:function(){var e=this.retrieve("send");if(!e){e=new c({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")});
this.store("send",e);}return e;}};Element.implement({send:function(e){var f=this.get("send");f.send({data:this,url:e||f.options.url});return this;}});})();
Request.HTML=new Class({Extends:Request,options:{update:false,append:false,evalScripts:true,filter:false,headers:{Accept:"text/html, application/xml, text/xml, */*"}},success:function(e){var d=this.options,b=this.response;
b.html=e.stripScripts(function(f){b.javascript=f;});var c=b.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);if(c){b.html=c[1];}var a=new Element("div").set("html",b.html);
b.tree=a.childNodes;b.elements=a.getElements("*");if(d.filter){b.tree=b.elements.filter(d.filter);}if(d.update){document.id(d.update).empty().set("html",b.html);
}else{if(d.append){document.id(d.append).adopt(a.getChildren());}}if(d.evalScripts){Browser.exec(b.javascript);}this.onSuccess(b.tree,b.elements,b.html,b.javascript);
}});Element.Properties.load={set:function(a){var b=this.get("load").cancel();b.setOptions(a);return this;},get:function(){var a=this.retrieve("load");if(!a){a=new Request.HTML({data:this,link:"cancel",update:this,method:"get"});
this.store("load",a);}return a;}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Type.isObject,url:Type.isString}));
return this;}});if(typeof JSON=="undefined"){this.JSON={};}JSON=new Hash({stringify:JSON.stringify,parse:JSON.parse});(function(){var special={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
var escape=function(chr){return special[chr]||"\\u"+("0000"+chr.charCodeAt(0).toString(16)).slice(-4);};JSON.validate=function(string){string=string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"");
return(/^[\],:{}\s]*$/).test(string);};JSON.encode=JSON.stringify?function(obj){return JSON.stringify(obj);}:function(obj){if(obj&&obj.toJSON){obj=obj.toJSON();
}switch(typeOf(obj)){case"string":return'"'+obj.replace(/[\x00-\x1f\\"]/g,escape)+'"';case"array":return"["+obj.map(JSON.encode).clean()+"]";case"object":case"hash":var string=[];
Object.each(obj,function(value,key){var json=JSON.encode(value);if(json){string.push(JSON.encode(key)+":"+json);}});return"{"+string+"}";case"number":case"boolean":return""+obj;
case"null":return"null";}return null;};JSON.decode=function(string,secure){if(!string||typeOf(string)!="string"){return null;}if(secure||JSON.secure){if(JSON.parse){return JSON.parse(string);
}if(!JSON.validate(string)){throw new Error("JSON could not decode the input; security is enabled and the value is not secure.");}}return eval("("+string+")");
};}).call(this);Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(a){this.parent(a);Object.append(this.headers,{Accept:"application/json","X-Request":"JSON"});
},success:function(c){var b;try{b=this.response.json=JSON.decode(c,this.options.secure);}catch(a){this.fireEvent("error",[c,a]);return;}if(b==null){this.onFailure();
}else{this.onSuccess(b,c);}}});var Cookie=new Class({Implements:Options,options:{path:"/",domain:false,duration:false,secure:false,document:document,encode:true},initialize:function(b,a){this.key=b;
this.setOptions(a);},write:function(b){if(this.options.encode){b=encodeURIComponent(b);}if(this.options.domain){b+="; domain="+this.options.domain;}if(this.options.path){b+="; path="+this.options.path;
}if(this.options.duration){var a=new Date();a.setTime(a.getTime()+this.options.duration*24*60*60*1000);b+="; expires="+a.toGMTString();}if(this.options.secure){b+="; secure";
}this.options.document.cookie=this.key+"="+b;return this;},read:function(){var a=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(a)?decodeURIComponent(a[1]):null;},dispose:function(){new Cookie(this.key,Object.merge({},this.options,{duration:-1})).write("");return this;}});
Cookie.write=function(b,c,a){return new Cookie(b,a).write(c);};Cookie.read=function(a){return new Cookie(a).read();};Cookie.dispose=function(b,a){return new Cookie(b,a).dispose();
};(function(j,l){var m,g,f=[],c,b,n=true;try{n=j.frameElement!=null;}catch(i){}var h=function(){clearTimeout(b);if(m){return;}Browser.loaded=m=true;l.removeListener("DOMContentLoaded",h).removeListener("readystatechange",a);
l.fireEvent("domready");j.fireEvent("domready");};var a=function(){for(var e=f.length;e--;){if(f[e]()){h();return true;}}return false;};var k=function(){clearTimeout(b);
if(!a()){b=setTimeout(k,10);}};l.addListener("DOMContentLoaded",h);var d=l.createElement("div");if(d.doScroll&&!n){f.push(function(){try{d.doScroll();return true;
}catch(o){}return false;});c=true;}if(l.readyState){f.push(function(){var e=l.readyState;return(e=="loaded"||e=="complete");});}if("onreadystatechange" in l){l.addListener("readystatechange",a);
}else{c=true;}if(c){k();}Element.Events.domready={onAdd:function(e){if(m){e.call(this);}}};Element.Events.load={base:"load",onAdd:function(e){if(g&&this==j){e.call(this);
}},condition:function(){if(this==j){h();delete Element.Events.load;}return true;}};j.addEvent("load",function(){g=true;});})(window,document);(function(){var Swiff=this.Swiff=new Class({Implements:Options,options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"window",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(path,options){this.instance="Swiff_"+String.uniqueID();this.setOptions(options);options=this.options;var id=this.id=options.id||this.instance;
var container=document.id(options.container);Swiff.CallBacks[this.instance]={};var params=options.params,vars=options.vars,callBacks=options.callBacks;
var properties=Object.append({height:options.height,width:options.width},options.properties);var self=this;for(var callBack in callBacks){Swiff.CallBacks[this.instance][callBack]=(function(option){return function(){return option.apply(self.object,arguments);
};})(callBacks[callBack]);vars[callBack]="Swiff.CallBacks."+this.instance+"."+callBack;}params.flashVars=Object.toQueryString(vars);if(Browser.ie){properties.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
params.movie=path;}else{properties.type="application/x-shockwave-flash";}properties.data=path;var build='<object id="'+id+'"';for(var property in properties){build+=" "+property+'="'+properties[property]+'"';
}build+=">";for(var param in params){if(params[param]){build+='<param name="'+param+'" value="'+params[param]+'" />';}}build+="</object>";this.object=((container)?container.empty():new Element("div")).set("html",build).firstChild;
},replaces:function(element){element=document.id(element,true);element.parentNode.replaceChild(this.toElement(),element);return this;},inject:function(element){document.id(element,true).appendChild(this.toElement());
return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].append(arguments));}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};}).call(this);
+102
View File
@@ -0,0 +1,102 @@
(function($) {
var Notify = function(element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.notify.defaults, options);
};
Notify.prototype = {
constructor: Notify,
build_box: function(bid) {
if (bid == undefined) {
bid = "notifybox";
}
var div = $("<div class='alert' />", {
id: bid,
click: $.proxy(this.destroy_box, this)
});
return div;
},
destroy_box: function(evt) {
evt.preventDefault();
this.$element.hide().remove();
},
set_position: function(box) {
box.css({
position: "absolute",
top: this.options.top_position,
left: "50%",
marginLeft: '-' + (box.outerWidth() / 2) + 'px'
});
},
set_message: function(box, value) {
var content = '<a class="close" data-dismiss="alert">×</a>' + value;
box.html(content);
},
show: function(klass, message, timer) {
var nbox = this.build_box();
if (klass != "normal") {
nbox.addClass("alert-" + klass);
}
this.set_message(nbox, message);
this.set_position(nbox);
this.$element.append(nbox);
if (timer != undefined) {
window.setTimeout(function() {
$('.alert').alert('close');
}, timer);
}
return this;
},
success: function(message, timer) {
return this.show.apply(this, ["success", message, timer]);
},
info: function(message, timer) {
return this.show.apply(this, ["info", message, timer]);
},
error: function(message, timer) {
return this.show.apply(this, ["error", message, timer]);
},
warning: function(message, timer) {
return this.show.apply(this, ["warning", message, timer]);
},
hide: function() {
}
};
$.fn.notify = function(method) {
var args = arguments;
return this.each(function() {
var $this = $(this),
data = $this.data('notify'),
options = typeof method === "object" && method;
if (!data) {
$this.data('notify', new Notify(this, options));
data = $this.data('notify');
}
if (typeof method === "string") {
data[method].apply(data, Array.prototype.slice.call(args, 1));
}
});
};
$.fn.notify.defaults = {
top_position: 50
};
})(jQuery);
-67
View File
@@ -1,67 +0,0 @@
window.addEvent('domready', function() {
var tip = new Tips($$(".Tips"));
var current_role = "";
var current_sizes = "";
var accordion = new Accordion('h3.atStart', 'div.atStart', {
opacity: true,
onActive: function(toggler, element){
toggler.setStyle('color', '#ff3300');
current_role = element.get("id");
current_sizes = element.get("rel");
},
onBackground: function(toggler, element) {
toggler.setStyle('color', '#222');
}
}, $('accordion'));
SqueezeBox.assign($("content").getElements('a[class=boxed]'), {
parse: 'rel'
});
$$("a[name=addperm]").addEvent("click", function(evt) {
evt.stop();
var sizes = current_sizes.split(" ");
var addperm_url = evt.target.get("href") + "?role=" + current_role;
SqueezeBox.open(addperm_url, {
size: {x: parseInt(sizes[0]), y: parseInt(sizes[1])},
handler: 'iframe'
});
});
$$("a[name=delperms]").addEvent("click", function(evt) {
evt.stop();
var selection = $(current_role).getElements("input[id=selection]:checked");
if (selection.length == 0) {
return;
}
if (!confirm(gettext("Remove this selection?"))) {
return;
}
var sr_selection = "";
selection.each(function(item) {
if (sr_selection != "") {
sr_selection += ",";
}
sr_selection += item.get("value");
});
new Request.JSON({
url : evt.target.get("href"),
onSuccess: function(response) {
if (response.status == "ok") {
$(current_role).set("html", response.content);
infobox.info(response.message);
} else {
infobox.error(response.message);
}
infobox.hide(2);
}
}).send({
method: "get",
data: "role=" + current_role + "&selection=" + sr_selection
});
});
});
-15
View File
@@ -1,15 +0,0 @@
window.addEvent('domready', function() {
var tip = new Tips($$(".Tips"));
var accordion = new Accordion('h3.atStart', 'div.atStart', {
opacity: true,
onActive: function(toggler, element){
toggler.setStyle('color', '#ff3300');
},
onBackground: function(toggler, element){
toggler.setStyle('color', '#222');
}
}, $('accordion'));
saveparams("uparams_form", gettext("Preferences saved"));
});
-15
View File
@@ -1,15 +0,0 @@
window.addEvent('domready', function() {
var tip = new Tips($$(".Tips"));
var accordion = new Accordion('h3.atStart', 'div.atStart', {
opacity: true,
onActive: function(toggler, element){
toggler.setStyle('color', '#ff3300');
},
onBackground: function(toggler, element){
toggler.setStyle('color', '#222');
}
}, $('accordion'));
saveparams("params_form", gettext("Parameters saved"));
});
+118 -11
View File
@@ -2,6 +2,43 @@
* Collection of functions that are accessible to every page.
*/
function modalbox(e, css) {
e.preventDefault();
var href = $(this).attr('href');
var modalcb = $(this).attr('modalcb');
if (href.indexOf('#') == 0) {
$(href).modal('open');
return;
}
$.get(href, function(data) {
if (typeof data === "object") {
if (data.status == "ko" && data.respmsg) {
$("body").notify("error", data.respmsg);
}
return;
}
var $div = $('<div id="modalbox" class="modal fade" >' + data + '</div>')
.modal()
.one('shown', function() {
if (modalcb != undefined) {
eval(modalcb + '()');
}
})
.on('hidden', function() {
$("#modalbox").remove();
});
if (css != undefined) {
$div.css(css);
}
});
}
function modalbox_autowidth(e) {
modalbox.apply(this, [e, {width: 'auto'}]);
}
/*
* Simple function that redirect ajax requests to the login page if
* the status code received with a response is equal to 278.
@@ -16,20 +53,90 @@ function ajax_login_redirect() {
this.xhr.getResponseHeader("Location").replace(/\?.*$/, params);
}
/*
* Simple shorcut do create a bootstrap alert box (error mode)
*/
function build_error_alert(msg) {
return $('<div class="alert alert-error"> \
<a class="close" data-dismiss="alert" href="#">&times;</a>' + msg + "</div>");
}
/*
* '.keys()' method support for old browsers :p
*/
if (!Object.keys) {
Object.keys = function (obj) {
var keys = [],
k;
for (k in obj) {
if (Object.prototype.hasOwnProperty.call(obj, k)) {
keys.push(k);
}
}
return keys;
};
}
/*
* Simple function that sends a form using an 'ajax' post request.
*
* The function is intended to be used in a modal environment.
*/
function simple_ajax_form_post(e, options) {
e.preventDefault();
var $form = $("form");
var defaults = {reload_on_success: true, reload_mode: 'full'};
var opts = $.extend({}, defaults, options);
var args = $form.serialize();
if (options.extradata != undefined) {
args += "&" + options.extradata;
}
$.post($form.attr("action"), args, function(data) {
if (data.status == "ok") {
if (opts.success_cb != undefined) {
opts.success_cb(data);
}
$("#modalbox").modal('hide');
if (opts.reload_on_success) {
if (opts.reload_mode == 'full') {
window.location.reload();
} else {
history.update(true);
}
}
if (data.respmsg) {
$("body").notify('success', data.respmsg, 2000);
}
} else {
if (data.content != "") {
$('.modal').html(data.content);
}
if (data.respmsg) {
$('.modal-body').prepend(build_error_alert(data.respmsg));
}
if (opts.error_cb != undefined) {
opts.error_cb();
}
}
});
}
/*
* Simple wrapper around Request.JSON. We just ensure that
* redirections are correctly catched. (on session timeout for
* example)
*/
Request.JSON.mdb = new Class({
Extends: Request.JSON,
// Request.JSON.mdb = new Class({
// Extends: Request.JSON,
options: {
format: "json",
onComplete: ajax_login_redirect,
onFailure: function(xhr) {
$(document.body).setStyle("overflow", "auto");
$(document.body).set("html", xhr.responseText);
}
}
});
// options: {
// format: "json",
// onComplete: ajax_login_redirect,
// onFailure: function(xhr) {
// $(document.body).setStyle("overflow", "auto");
// $(document.body).set("html", xhr.responseText);
// }
// }
// });
-59
View File
@@ -1,59 +0,0 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/Autocompleter.css" />
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/Observer.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/Autocompleter.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/Autocompleter.Request.js"></script>
<script type="text/javascript">
window.addEvent("domready", function() {
var form = new Form({resptarget: "formcontainer"});
$("createfrom").addEvent("change", function(evt) {
var url = "";
var styles = null;
var from = this.get("value");
evt.stop();
if (from == "create") {
url = "{% url admin.views.create_domain_admin %}";
styles = {height: 380};
} else {
url = "{% url admin.views.domain_admin_promotion %}";
styles = {height: 200};
}
var size = {y: styles.height};
new Request.JSON.mdb({
url: url,
onSuccess: function(response) {
$("formcontainer").set("html", response.content);
form.init_help_messages();
if (from == "promote") {
new Autocompleter.Request.JSON("id_name",
"{% url admin.views.search_account %}", {
postVar: "search",
minLength: 3,
onComplete: ajax_login_redirect
});
}
$(parent.document).getElement('iframe').setStyles(styles);
parent.SqueezeBox.resize(size);
}
}).get();
});
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
{% if error %}<div class="error">{{ error }}</div>{% endif %}
<div class="center">
<select id="createfrom">
<option value="none">{% trans "Choose" %}</option>
<option value="create">{% trans "Create a new account" %}</option>
<option value="promote">{% trans "Promote an existing account" %}</option>
</select>
</div>
<div id="formcontainer"></div>
{% endblock %}
-25
View File
@@ -1,25 +0,0 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEvent("domready", function() {
var form = new Form();
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
{% if error %}<div class="error">{{ error }}</div>{% endif %}
{% if not addurl %}
{% url admin.views.add_permission as addurl %}
{% endif %}
<form action="{{ addurl }}" method="POST" id="permform" name="permform">
<input type="hidden" name="role" id="role" value="{{ role }}" />
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{{ submit_label }}" />
</div>
</form>
{% endblock %}
-22
View File
@@ -1,22 +0,0 @@
{% extends "layout_simple.html" %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEvent("domready", function() {
var form = new Form();
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
<div class="error">{% if error %}{{ error }}{% endif %}</div>
<form action="{{ action }}" enctype="{{ enctype }}"
method="POST" id="{{ formid }}" name="{{ formid }}">
{% include "common/genericform.html" %}
{% block extrafields %}{% endblock %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{{ submit_label }}" />
</div>
</form>
{% endblock %}
-9
View File
@@ -1,9 +0,0 @@
{% load i18n %}
<form action="{% url admin.views.create_domain_admin %}" method="POST"
id="permform" name="permform">
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{% trans 'Create' %}" />
</div>
</form>
+7
View File
@@ -0,0 +1,7 @@
{% extends "common/generic_modal_form.html" %}
{% load libextras %}
{% block formbody %}
{% render_field form.email %}
{% render_fields_group form "recipients" %}
{% render_field form.enabled %}
{% endblock %}
@@ -1,10 +0,0 @@
{% load i18n %}
<form action="{% url admin.views.domain_admin_promotion %}" method="POST"
id="permform" name="permform">
<input type="hidden" name="role" id="role" value="{{ role }}" />
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{% trans 'Promote' %}" />
</div>
</form>
+8
View File
@@ -0,0 +1,8 @@
{% extends "common/generic_modal_form.html" %}
{% load libextras %}
{% block formbody %}
{% render_field form.name %}
{% render_field form.quota %}
{% render_fields_group form "aliases" %}
{% render_field form.enabled %}
{% endblock %}
+11 -5
View File
@@ -1,11 +1,17 @@
{% extends "admin/listing.html" %}
{% load i18n admin_extras libextras %}
{% block html_head %}
{{ block.super }}
<script type="text/javascript">
window.addEvent('domready', function() {
{% url admin.views.mailboxes as view_url %}
bindRows("{{ view_url }}", "{{ current_page }}");
{{ block.super }}
<script type="text/javascript">
$(document).ready(function() {
$("a[name=deldomain]").confirm({
question: gettext("Delete this domain?"),
checkboxes: {keepdir: gettext("Do not delete domain directory")}
});
{% url admin.views.mailboxes as view_url %}
//bindRows("{{ view_url }}", "{{ current_page }}");
});
</script>
{% endblock %}
{% block leftcol %}<div class="well sidebar-nav">{% domains_menu "domains" user %}</div>{% endblock %}
-23
View File
@@ -1,23 +0,0 @@
{% extends "nlayout.html" %}
{% load i18n admin_extras libextras %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/confirmation.js" type="text/javascript"></script>
<script src="{{ MEDIA_URL }}js/domains.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEvent("domready", function() {
new Domains("{% url index %}"{% if deloptions %}, { {% join deloptions %} } {% endif %});
});
</script>
{% endblock %}
{% block middletitle %}
{% block pagetitle %}{% endblock %}{% if domain and domain != "global" %} ({% trans "for" %} {{ domain.name }}){% endif %}
{% endblock %}
{% block menu %}{% domains_menu selection user domid %}{% endblock %}
{% block content %}
{% if messages %}
{% display_messages messages %}
{% endif %}
<div id="subcontent">
{% block subcontent %}{% endblock %}
</div>
{% endblock %}
+1 -7
View File
@@ -1,13 +1,7 @@
{% extends "admin/settings_header.html" %}
{% block menu %}
{% load admin_extras %}
{% settings_menu "extensions" user %}
{% endblock %}
{% block setcontent %}
{% load i18n %}
{% block apparea %}
<form method="POST" action="{% url admin.views.saveextensions %}">
{{ extensions|safe }}
<br />
<input type="submit" name="apply" value="{% trans "Apply" %}" />
</form>
{% endblock %}
+4
View File
@@ -0,0 +1,4 @@
{% extends "twocols.html" %}
{% block html_head %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/admin.js"></script>
{% endblock %}
+34
View File
@@ -0,0 +1,34 @@
{% extends "admin/listing.html" %}
{% load admin_extras libextras %}
{% block html_head %}
{{ block.super }}
<script type="text/javascript" src="{{ MEDIA_URL }}js/creation_wizard.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/autocompleter.js"></script>
<script type="text/javascript">
function get_domains_list(container) {
$.getJSON("{% url modoboa.admin.views.domains_list %}", function(data) {
container.value = data;
});
}
function get_account_list(container) {
$.getJSON("{% url modoboa.admin.views.accounts_list %}", function(data) {
container.value = data;
});
}
$(document).ready(function() {
$("a[name=delaccount]").confirm({
question: gettext("Delete this account?"),
checkboxes: {keepdir: gettext("Do not delete mailbox directory")}
});
$("a[name=deldlist]").confirm({
question: gettext("Delete this list?")
});
$("#pagination_bar").find(".disabled").click(function(e) {
e.preventDefault();
});
});
</script>
{% endblock %}
{% block leftcol %}<div class="well sidebar-nav">{% identities_menu user %}</div>{% endblock %}

Some files were not shown because too many files have changed in this diff Show More