diff --git a/.gitignore b/.gitignore index 184684c84..dffc08ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.pyc .idea venv +/.venv/ diff --git a/0001-fix-some-issue-on-self-signed-cert.patch b/0001-fix-some-issue-on-self-signed-cert.patch deleted file mode 100644 index 3f379b3da..000000000 --- a/0001-fix-some-issue-on-self-signed-cert.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 348f6dbaa4b3e7141c9d32e1c44e3ea1ba2d9984 Mon Sep 17 00:00:00 2001 -From: qtwrk -Date: Tue, 10 Mar 2020 17:23:30 +0100 -Subject: [PATCH] fix some issue on self-signed cert - ---- - cyberpanel.sh | 4 ++-- - cyberpanel_upgrade.sh | 55 +++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 55 insertions(+), 4 deletions(-) - -diff --git a/cyberpanel.sh b/cyberpanel.sh -index d4ce5caf..d657d3e3 100644 ---- a/cyberpanel.sh -+++ b/cyberpanel.sh -@@ -1123,7 +1123,7 @@ dnQualifier = CyberPanel - [server_exts] - extendedKeyUsage = 1.3.6.1.5.5.7.3.1 - EOF --openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:3072 -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem -+openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem - - if [[ $VERSION == "OLS" ]] ; then - key_path="/usr/local/lsws/admin/conf/webadmin.key" -@@ -1133,7 +1133,7 @@ else - cert_path="/usr/local/lsws/admin/conf/cert/admin.crt" - fi - --openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:3072 -keyout $key_path -out $cert_path -+openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout $key_path -out $cert_path - rm -f /root/cyberpanel/cert_conf - } - -diff --git a/cyberpanel_upgrade.sh b/cyberpanel_upgrade.sh -index db0c76bd..41004b66 100644 ---- a/cyberpanel_upgrade.sh -+++ b/cyberpanel_upgrade.sh -@@ -26,6 +26,44 @@ if [[ $SERVER_COUNTRY == "CN" ]] ; then - GIT_CONTENT_URL="gitee.com/qtwrk/cyberpanel/raw" - fi - -+regenerate_cert() { -+cat << EOF > /usr/local/CyberCP/cert_conf -+[req] -+prompt=no -+distinguished_name=cyberpanel -+[cyberpanel] -+commonName = www.example.com -+countryName = CP -+localityName = CyberPanel -+organizationName = CyberPanel -+organizationalUnitName = CyberPanel -+stateOrProvinceName = CP -+emailAddress = mail@example.com -+name = CyberPanel -+surname = CyberPanel -+givenName = CyberPanel -+initials = CP -+dnQualifier = CyberPanel -+[server_exts] -+extendedKeyUsage = 1.3.6.1.5.5.7.3.1 -+EOF -+if [[ $1 == "8090" ]] ; then -+openssl req -x509 -config /usr/local/CyberCP/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem -+fi -+ -+if [[ $1 == "7080" ]] ; then -+ if [[ -f /usr/local/lsws/admin/conf/webadmin.key ]] ; then -+ key_path="/usr/local/lsws/admin/conf/webadmin.key" -+ cert_path="/usr/local/lsws/admin/conf/webadmin.crt" -+ else -+ key_path="/usr/local/lsws/admin/conf/cert/admin.key" -+ cert_path="/usr/local/lsws/admin/conf/cert/admin.crt" -+ fi -+openssl req -x509 -config /usr/local/CyberCP/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout $key_path -out $cert_path -+fi -+rm -f /usr/local/CyberCP/cert_conf -+ -+} - - input_branch() { - echo -e "\nPress Enter key to continue with latest version or Enter specific version such as: \e[31m1.9.4\e[39m , \e[31m1.9.5\e[39m ...etc" -@@ -233,6 +271,19 @@ fi - - install_utility - -+output=$(timeout 3 openssl s_client -connect 127.0.0.1:8090 2>/dev/null) -+echo $output | grep -q "mail@example.com" -+if [[ $? == "0" ]] ; then -+# it is using default installer generated cert -+regenerate_cert 8090 -+fi -+output=$(timeout 3 openssl s_client -connect 127.0.0.1:7080 2>/dev/null) -+echo $output | grep -q "mail@example.com" -+if [[ $? == "0" ]] ; then -+regenerate_cert 7080 -+fi -+ -+ - if [[ $SERVER_OS == "CentOS7" ]] ; then - - sed -i 's|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|g' /usr/local/lsws/{lsphp72,lsphp73}/etc/php.ini -@@ -245,14 +296,14 @@ yum list installed lsphp74-devel - fi - - if [[ $SERVER_OS == "Ubuntu" ]] ; then -- dpkg -l lsphp74-dev -+ dpkg -l lsphp74-dev > /dev/null 2>&1 - if [[ $? != "0" ]] ; then - apt install -y lsphp74-dev - fi - fi - - if [[ ! -f /usr/local/lsws/lsphp74/lib64/php/modules/zip.so ]] && [[ $SERVER_OS == "CentOS7" ]] ; then -- yum list installed libzip-devel -+ yum list installed libzip-devel > /dev/null 2>&1 - if [[ $? == "0" ]] ; then - yum remove -y libzip-devel - fi --- -2.17.1 - diff --git a/CLManager/CLManagerMain.py b/CLManager/CLManagerMain.py index 2a02fd91c..a2809033f 100644 --- a/CLManager/CLManagerMain.py +++ b/CLManager/CLManagerMain.py @@ -10,7 +10,7 @@ from django.shortcuts import HttpResponse from math import ceil from websiteFunctions.models import Websites from CLManager.models import CLPackages - +from plogical.httpProc import httpProc class CLManagerMain(multi.Thread): @@ -27,29 +27,14 @@ class CLManagerMain(multi.Thread): self.submitCageFSInstall() elif self.function == 'enableOrDisable': self.enableOrDisable() - except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [ContainerManager.run]') def renderC(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if currentACL['admin'] == 1: - pass - else: - return ACLManager.loadError() - - ipFile = "/etc/cyberpanel/machineIP" - f = open(ipFile) - ipData = f.read() - ipAddress = ipData.split('\n', 1)[0] - data = {} data['CL'] = 0 data['activatedPath'] = 0 - data['ipAddress'] = ipAddress CLPath = '/etc/sysconfig/cloudlinux' activatedPath = '/home/cyberpanel/cloudlinux' @@ -60,11 +45,14 @@ class CLManagerMain(multi.Thread): data['activatedPath'] = 1 if data['CL'] == 0: - return render(self.request, 'CLManager/notAvailable.html', data) + proc = httpProc(self.request, 'CLManager/notAvailable.html', data, 'admin') + return proc.render() elif data['activatedPath'] == 0: - return render(self.request, 'CLManager/notAvailable.html', data) + proc = httpProc(self.request, 'CLManager/notAvailable.html', data, 'admin') + return proc.render() else: - return render(self.request, 'CLManager/cloudLinux.html', data) + proc = httpProc(self.request, 'CLManager/cloudLinux.html', data, 'admin') + return proc.render() def submitCageFSInstall(self): try: diff --git a/CLManager/CageFS.py b/CLManager/CageFS.py index 17713a6b8..ee4991d6b 100644 --- a/CLManager/CageFS.py +++ b/CLManager/CageFS.py @@ -243,10 +243,6 @@ def main(): elif args["function"] == "submitinstallImunifyAV": CageFS.submitinstallImunifyAV() - - - - if __name__ == "__main__": main() diff --git a/CLManager/urls.py b/CLManager/urls.py index d298e391a..0f2aff59c 100644 --- a/CLManager/urls.py +++ b/CLManager/urls.py @@ -2,17 +2,18 @@ from django.conf.urls import url from . import views urlpatterns = [ + url(r'^CreatePackage$', views.CreatePackage, name='CreatePackageCL'), + url(r'^listPackages$', views.listPackages, name='listPackagesCL'), + url(r'^monitorUsage$', views.monitorUsage, name='monitorUsage'), url(r'^CageFS$', views.CageFS, name='CageFS'), url(r'^submitCageFSInstall$', views.submitCageFSInstall, name='submitCageFSInstall'), - url(r'^submitWebsiteListing$', views.getFurtherAccounts, name='submitWebsiteListing'), - url(r'^enableOrDisable$', views.enableOrDisable, name='enableOrDisable'), - url(r'^CreatePackage$', views.CreatePackage, name='CreatePackageCL'), - url(r'^submitCreatePackage$', views.submitCreatePackage, name='submitCreatePackageCL'), - url(r'^listPackages$', views.listPackages, name='listPackagesCL'), - url(r'^fetchPackages$', views.fetchPackages, name='fetchPackagesCL'), - url(r'^deleteCLPackage$', views.deleteCLPackage, name='deleteCLPackage'), - url(r'^saveSettings$', views.saveSettings, name='saveSettings'), - url(r'^monitorUsage$', views.monitorUsage, name='monitorUsage'), - url(r'^manage/(?P(.*))$', views.websiteContainerLimit, name='websiteContainerLimitCL'), - url(r'^getUsageData$', views.getUsageData, name='getUsageData'), + + # url(r'^submitWebsiteListing$', views.getFurtherAccounts, name='submitWebsiteListing'), + # url(r'^enableOrDisable$', views.enableOrDisable, name='enableOrDisable'), + # url(r'^submitCreatePackage$', views.submitCreatePackage, name='submitCreatePackageCL'), + # url(r'^fetchPackages$', views.fetchPackages, name='fetchPackagesCL'), + # url(r'^deleteCLPackage$', views.deleteCLPackage, name='deleteCLPackage'), + # url(r'^saveSettings$', views.saveSettings, name='saveSettings'), + # url(r'^manage/(?P(.*))$', views.websiteContainerLimit, name='websiteContainerLimitCL'), + # url(r'^getUsageData$', views.getUsageData, name='getUsageData'), ] \ No newline at end of file diff --git a/CLScript/CLMain.py b/CLScript/CLMain.py index c6f730ba4..0d09cec9b 100644 --- a/CLScript/CLMain.py +++ b/CLScript/CLMain.py @@ -4,8 +4,8 @@ class CLMain(): def __init__(self): self.path = '/usr/local/CyberCP/version.txt' #versionInfo = json.loads(open(self.path, 'r').read()) - self.version = '2.0' - self.build = '3' + self.version = '2.1' + self.build = '1' ipFile = "/etc/cyberpanel/machineIP" f = open(ipFile) diff --git a/CLScript/CloudLinuxResellers.py b/CLScript/CloudLinuxResellers.py index 0f93d04a6..c64509b33 100755 --- a/CLScript/CloudLinuxResellers.py +++ b/CLScript/CloudLinuxResellers.py @@ -14,7 +14,6 @@ import argparse import json from CLScript.CLMain import CLMain - class CloudLinuxResellers(CLMain): def __init__(self, id, name): @@ -23,17 +22,26 @@ class CloudLinuxResellers(CLMain): self.name = name def listAll(self, owner=None): + import pwd users = [] acl = ACL.objects.get(name='reseller') + from plogical.vhost import vhost for items in Administrator.objects.filter(acl=acl): if self.name != None: if self.name != items.userName: continue + + try: + uid = pwd.getpwnam(items.userName).pw_uid + except: + vhost.addUser(items.userName, '/home/%s' % (items.userName)) + uid = pwd.getpwnam(items.userName).pw_uid + user = {'name': items.userName, "locale_code": "EN_us", "email": items.email, - "id": None + "id": uid } users.append(user) diff --git a/CLScript/CloudLinuxUsers.py b/CLScript/CloudLinuxUsers.py index bdc984655..a26d2e9e5 100755 --- a/CLScript/CloudLinuxUsers.py +++ b/CLScript/CloudLinuxUsers.py @@ -81,7 +81,7 @@ class CloudLinuxUsers(CLMain): for webs in websites: try: itemPackage = webs.package - package = {'name': itemPackage.packageName, 'owner': webs.externalApp} + package = {'name': itemPackage.packageName, 'owner': webs.admin.userName} user = {} @@ -92,7 +92,12 @@ class CloudLinuxUsers(CLMain): user['username'] = webs.externalApp if self.ow: - user['owner'] = webs.externalApp + if webs.admin.owner == 1: + user['owner'] = webs.admin.userName + else: + from loginSystem.models import Administrator + oAdmin = Administrator.objects.get(pk=webs.admin.owner) + user['owner'] = oAdmin.userName if self.domain: user['domain'] = webs.domain @@ -133,7 +138,11 @@ class CloudLinuxUsers(CLMain): if self.owner == None: websites = Websites.objects.all() else: - websites = Websites.objects.filter(externalApp=self.owner) + from loginSystem.models import Administrator + from plogical.acl import ACLManager + oAdmin = Administrator.objects.get(userName=self.owner) + currentACL = ACLManager.loadedACL(oAdmin.pk) + websites = ACLManager.findWebsiteObjects(currentACL, oAdmin.pk) if self.username != None: websites = websites.filter(externalApp=self.username) diff --git a/CLScript/UserInfo.py b/CLScript/UserInfo.py index 472b614f3..55b266be9 100755 --- a/CLScript/UserInfo.py +++ b/CLScript/UserInfo.py @@ -2,10 +2,15 @@ import getpass def main(): + import pwd if getpass.getuser() == 'root': userType = "admin" else: - userType = "user" + try: + uid = pwd.getpwnam(getpass.getuser()).pw_uid + userType = 'reseller' + except: + userType = 'user' data = """{ "userName": "%s", diff --git a/CPScripts/fixperms.sh b/CPScripts/fixperms.sh index 37c2f5da2..e1ceefdac 100644 --- a/CPScripts/fixperms.sh +++ b/CPScripts/fixperms.sh @@ -194,7 +194,7 @@ fixperms_cyberpanel () { echo "Fixing public_html...." tput sgr0 #Fix perms of public_html itself - chown "$verbose" "$account":"$account" "$HOMEDIR"/public_html + chown "$verbose" "$account":nobody "$HOMEDIR"/public_html chmod "$verbose" 755 "$HOMEDIR"/public_html tput bold diff --git a/CPScripts/mailscannerinstaller.sh b/CPScripts/mailscannerinstaller.sh index da9a2490d..6e324a22b 100644 --- a/CPScripts/mailscannerinstaller.sh +++ b/CPScripts/mailscannerinstaller.sh @@ -2,22 +2,21 @@ #systemctl stop firewalld check_return() { -#check previous command result , 0 = ok , non-0 = something wrong. -if [[ $? -eq "0" ]] ; then - : -else - echo -e "\ncommand failed, exiting..." - exit -fi + #check previous command result , 0 = ok , non-0 = something wrong. + if [[ $? -eq "0" ]]; then + : + else + echo -e "\ncommand failed, exiting..." + exit + fi } -echo 'backup configs'; -cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); -cp /etc/postfix/master.cf /etc/postfix/master.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); -cp /etc/postfix/main.cf /etc/postfix/main.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); +echo 'backup configs' +cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf-bak_$(date '+%Y-%m-%d_%H_%M:%S') +cp /etc/postfix/master.cf /etc/postfix/master.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S') +cp /etc/postfix/main.cf /etc/postfix/main.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S') cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext-bak_$(date '+%Y-%m-%d_%H_%M:%S') - ZONE=$(firewall-cmd --get-default-zone) firewall-cmd --zone=$ZONE --add-port=4190/tcp --permanent systemctl stop firewalld @@ -27,167 +26,131 @@ csf -x MAILSCANNER=/etc/MailScanner -if [ -d $MAILSCANNER ];then - -echo "MailScanner found. If you wish to reinstall then remove the package and revert" -echo "Postfix back to its original config at /etc/postfix/main.cf and remove" -echo "/etc/MailScanner and /usr/share/MailScanner directories" -exit +if [ -d $MAILSCANNER ]; then + echo "MailScanner found. If you wish to reinstall then remove the package and revert" + echo "Postfix back to its original config at /etc/postfix/main.cf and remove" + echo "/etc/MailScanner and /usr/share/MailScanner directories" + exit fi -if [ -f /etc/os-release ];then -OS=$(head -1 /etc/os-release) -UBUNTUVERSION=$(sed '6q;d' /etc/os-release) -CENTOSVERSION=$(sed '5q;d' /etc/os-release) -CLNVERSION=$(sed '3q;d' /etc/os-release) -fi - -if [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Net::Patricia' - -freshclam -v -DIR=/etc/mail/spamassassin - -if [ -d "$DIR" ]; then -sa-update - -else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit -fi - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -dnf --enablerepo=powertools install -y perl-IO-stringy -dnf --enablerepo=PowerTools install -y perl-IO-stringy -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav clamav-update "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/8/x86_64/unrar-5.4.0-1.el8.x86_64.rpm - -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus - -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Sys::Hostname::Long' -perl -MCPAN -e 'install Sys::SigAction' - - - -freshclam -v +### Check SpamAssasin before moving forward DIR=/etc/mail/spamassassin -if [ -d "$DIR" ]; then -sa-update - +if [ -d "$DIR" ]; then + sa-update else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit + echo "Please install spamassassin through the CyberPanel interface before proceeding" + exit fi -elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Net::Patricia' - -freshclam -v -DIR=/etc/mail/spamassassin - -if [ -d "$DIR" ]; then -sa-update - -else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit +if [ -f /etc/os-release ]; then + OS=$(head -1 /etc/os-release) + UBUNTUVERSION=$(sed '6q;d' /etc/os-release) + CENTOSVERSION=$(sed '5q;d' /etc/os-release) + CLNVERSION=$(sed '3q;d' /etc/os-release) fi -elif [ "$OS" = "NAME=\"Ubuntu\"" ];then +if [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ]; then - apt-get install -y libmysqlclient-dev + setenforce 0 + yum install -y perl yum-utils perl-CPAN + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - apt-get install -y cpanminus gcc perl bzip2 zip make patch automake rpm libarchive-zip-perl libfilesys-df-perl libole-storage-lite-perl libsys-hostname-long-perl libsys-sigaction-perl libregexp-common-net-cidr-perl libmime-tools-perl libdbd-sqlite3-perl binutils build-essential libfilesys-df-perl zlib1g unzip mlocate clamav libdbd-mysql-perl unrar libclamav-dev libclamav-client-perl libclamunrar9 + rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Net::Patricia' -cpanm Encoding::FixLatin -cpanm Digest::SHA1 -cpanm Geo::IP -cpanm Razor2::Client::Agent -cpanm Net::Patricia -cpanm Net::CIDR + freshclam -v -sudo systemctl stop clamav-freshclam.service +elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ]; then -freshclam + setenforce 0 + yum install -y perl yum-utils perl-CPAN + dnf --enablerepo=powertools install -y perl-IO-stringy + dnf --enablerepo=PowerTools install -y perl-IO-stringy + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav clamav-update "perl(DBD::mysql)" -sudo systemctl start clamav-freshclam.service + rpm -Uvh https://forensics.cert.org/centos/cert/8/x86_64/unrar-5.4.0-1.el8.x86_64.rpm -DIR=/etc/spamassassin -if [ -d "$DIR" ]; then + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus -apt-get -y install razor pyzor libencode-detect-perl libgeo-ip-perl libnet-patricia-perl -sa-update -else -echo "Please install spamassassin through the CyberPanel interface before proceeding" -exit -fi + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Sys::Hostname::Long' + perl -MCPAN -e 'install Sys::SigAction' + + freshclam -v + +elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ]; then + + setenforce 0 + yum install -y perl yum-utils perl-CPAN + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" + + rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Net::Patricia' + + freshclam -v + +elif [ "$OS" = "NAME=\"Ubuntu\"" ]; then + + apt-get install -y libmysqlclient-dev + + apt-get install -y cpanminus gcc perl bzip2 zip make patch automake rpm libarchive-zip-perl libfilesys-df-perl libole-storage-lite-perl libsys-hostname-long-perl libsys-sigaction-perl libregexp-common-net-cidr-perl libmime-tools-perl libdbd-sqlite3-perl binutils build-essential libfilesys-df-perl zlib1g unzip mlocate clamav libdbd-mysql-perl unrar libclamav-dev libclamav-client-perl libclamunrar9 + + cpanm Encoding::FixLatin + cpanm Digest::SHA1 + cpanm Geo::IP + cpanm Razor2::Client::Agent + cpanm Net::Patricia + cpanm Net::CIDR + + sudo systemctl stop clamav-freshclam.service + + freshclam + + sudo systemctl start clamav-freshclam.service fi -echo "header_checks = regexp:/etc/postfix/header_checks" >> /etc/postfix/main.cf -echo "/^Received:/ HOLD" >> /etc/postfix/header_checks +echo "header_checks = regexp:/etc/postfix/header_checks" >>/etc/postfix/main.cf +echo "/^Received:/ HOLD" >>/etc/postfix/header_checks systemctl restart postfix -if [ "$OS" = "NAME=\"Ubuntu\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.noarch.deb -dpkg -i *.noarch.deb +if [ "$OS" = "NAME=\"Ubuntu\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.noarch.deb + dpkg -i *.noarch.deb -mkdir /var/run/MailScanner -mkdir /var/lock/subsys -mkdir /var/lock/subsys/MailScanner -chown -R postfix:postfix /var/run/MailScanner -chown -R postfix:postfix /var/lock/subsys/MailScanner -chown -R postfix:postfix /var/spool/MailScanner + mkdir /var/run/MailScanner + mkdir /var/lock/subsys + mkdir /var/lock/subsys/MailScanner + chown -R postfix:postfix /var/run/MailScanner + chown -R postfix:postfix /var/lock/subsys/MailScanner + chown -R postfix:postfix /var/spool/MailScanner -elif [ "$OS" = "NAME=\"CentOS Linux\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm -rpm -Uvh *.rhel.noarch.rpm +elif [ "$OS" = "NAME=\"CentOS Linux\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm + rpm -Uvh *.rhel.noarch.rpm -elif [ "$OS" = "NAME=\"CloudLinux\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm -rpm -Uvh *.rhel.noarch.rpm +elif [ "$OS" = "NAME=\"CloudLinux\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm + rpm -Uvh *.rhel.noarch.rpm fi mkdir /var/spool/MailScanner/spamassassin @@ -234,8 +197,15 @@ PASSWORD=$(cat /etc/cyberpanel/mysqlPassword) USER=root DATABASE=mailscanner ADMINPASS=$(cat /etc/cyberpanel/adminPass) -mysql -u${USER} -p${PASSWORD} < "/usr/local/CyberCP/public/mailwatch/create.sql" -mysql -u${USER} -p${PASSWORD} -e "use mailscanner"; + +### Fix a bug in MailWatch SQL File + +sed -i 's/char(512)/char(255)/g' /usr/local/CyberCP/public/mailwatch/create.sql + +## + +mysql -u${USER} -p${PASSWORD} <"/usr/local/CyberCP/public/mailwatch/create.sql" +mysql -u${USER} -p${PASSWORD} -e "use mailscanner" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "GRANT ALL ON mailscanner.* TO root@localhost IDENTIFIED BY '${PASSWORD}';" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "FLUSH PRIVILEGES;" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "INSERT INTO mailscanner.users SET username = 'admin', password = MD5('${ADMINPASS}'), fullname = 'admin', type = 'A';" @@ -247,11 +217,11 @@ sed -i "s/^define('DB_PASS',.*/define('DB_PASS','${PASSWORD}');/" /usr/local/Cyb sed -i "s/^define('MAILWATCH_HOME',.*/define(\'MAILWATCH_HOME\', \'\/usr\/local\/CyberCP\/public\/mailwatch\/mailscanner');/" /usr/local/CyberCP/public/mailwatch/mailscanner/conf.php MSDEFAULT=/etc/MailScanner/defaults -if [ -f "$MSDEFAULT" ];then -sed -i 's/^run_mailscanner=.*/run_mailscanner=1/' /etc/MailScanner/defaults -elif [ ! -f "$MSDEFAULT" ];then -touch /etc/MailScanner/defaults -echo "run_mailscanner=1" >> /etc/MailScanner/defaults +if [ -f "$MSDEFAULT" ]; then + sed -i 's/^run_mailscanner=.*/run_mailscanner=1/' /etc/MailScanner/defaults +elif [ ! -f "$MSDEFAULT" ]; then + touch /etc/MailScanner/defaults + echo "run_mailscanner=1" >>/etc/MailScanner/defaults fi cp /usr/local/CyberCP/public/mailwatch/MailScanner_perl_scripts/MailWatchConf.pm /usr/share/MailScanner/perl/custom/ @@ -268,125 +238,121 @@ systemctl restart mailscanner IPADDRESS=$(cat /etc/cyberpanel/machineIP) +### Furhter onwards is sieve configurations -echo 'Setting up spamassassin and sieve to deliver spam to Junk folder by default' -#echo "If you wish mailscanner/spamassassin to send spam email to a spam folder please follow the tutorial on the Cyberpanel Website" -echo 'Fix protocols' -sed -i 's/^protocols =.*/protocols = imap pop3 lmtp sieve/g' /etc/dovecot/dovecot.conf - - -sed -i "s|^user_query.*|user_query = SELECT '5000' as uid, '5000' as gid, '/home/vmail/%d/%n' as home,mail FROM e_users WHERE email='%u';|g" /etc/dovecot/dovecot-sql.conf.ext - -if [ "$OS" = "NAME=\"Ubuntu\"" ];then -if [ "$UBUNTUVERSION" = "VERSION_ID=\"18.04\"" ];then - apt-get install -y dovecot-managesieved dovecot-sieve dovecot-lmtpd net-tools pflogsumm -elif [ "$UBUNTUVERSION" = "VERSION_ID=\"20.04\"" ];then - apt-get install -y libmysqlclient-dev - sed -e '/deb/ s/^#*/#/' -i /etc/apt/sources.list.d/dovecot.list - apt install -y dovecot-lmtpd dovecot-managesieved dovecot-sieve net-tools pflogsumm -fi - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ];then - - yum install -y nano net-tools dovecot-pigeonhole postfix-perl-scripts - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ];then - - rpm -Uvh http://mirror.ghettoforge.org/distributions/gf/el/8/gf/x86_64/gf-release-8-11.gf.el8.noarch.rpm - dnf --enablerepo=gf-plus upgrade -y dovecot23* - dnf --enablerepo=gf-plus install -y dovecot23-pigeonhole - dnf install -y net-tools postfix-perl-scripts - -elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ];then - - yum install -y nano net-tools dovecot-pigeonhole postfix-perl-scripts -fi - - -# Create Sieve files -mkdir -p /etc/dovecot/sieve/global -touch /var/log/{dovecot-lda-errors.log,dovecot-lda.log} -touch /var/log/{dovecot-sieve-errors.log,dovecot-sieve.log} -touch /var/log/{dovecot-lmtp-errors.log,dovecot-lmtp.log} -touch /etc/dovecot/sieve/default.sieve -chown vmail: -R /etc/dovecot/sieve -chown vmail:mail /var/log/dovecot-* - -echo 'Create Sieve Default spam to Junk rule' -cat >> /etc/dovecot/sieve/default.sieve <> /etc/dovecot/dovecot.conf <>/etc/dovecot/sieve/default.sieve <>/etc/dovecot/dovecot.conf < /dev/null) diff --git a/CyberCP/secMiddleware.py b/CyberCP/secMiddleware.py index 8f0271330..46f683235 100755 --- a/CyberCP/secMiddleware.py +++ b/CyberCP/secMiddleware.py @@ -1,7 +1,7 @@ # coding=utf-8 from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging import json -from django.shortcuts import HttpResponse +from django.shortcuts import HttpResponse, render import re from loginSystem.models import Administrator @@ -10,6 +10,12 @@ class secMiddleware: HIGH = 0 LOW = 1 + def get_client_ip(request): + ip = request.META.get('HTTP_CF_CONNECTING_IP') + if ip is None: + ip = request.META.get('REMOTE_ADDR') + return ip + def __init__(self, get_response): self.get_response = get_response @@ -17,7 +23,7 @@ class secMiddleware: try: uID = request.session['userID'] admin = Administrator.objects.get(pk=uID) - ipAddr = request.META.get('REMOTE_ADDR') + ipAddr = get_client_ip(request) if ipAddr.find('.') > -1: if request.session['ipAddr'] == ipAddr or admin.securityLevel == secMiddleware.LOW: @@ -25,20 +31,19 @@ class secMiddleware: else: del request.session['userID'] del request.session['ipAddr'] - logging.writeToFile(request.META.get('REMOTE_ADDR')) + logging.writeToFile(get_client_ip(request)) final_dic = {'error_message': "Session reuse detected, IPAddress logged.", "errorMessage": "Session reuse detected, IPAddress logged."} final_json = json.dumps(final_dic) return HttpResponse(final_json) else: - ipAddr = request.META.get('REMOTE_ADDR').split(':')[:3] - + ipAddr = get_client_ip(request).split(':')[:3] if request.session['ipAddr'] == ipAddr or admin.securityLevel == secMiddleware.LOW: pass else: del request.session['userID'] del request.session['ipAddr'] - logging.writeToFile(request.META.get('REMOTE_ADDR')) + logging.writeToFile(get_client_ip(request)) final_dic = {'error_message': "Session reuse detected, IPAddress logged.", "errorMessage": "Session reuse detected, IPAddress logged."} final_json = json.dumps(final_dic) @@ -67,7 +72,7 @@ class secMiddleware: final_json = json.dumps(final_dic) return HttpResponse(final_json) - if request.build_absolute_uri().find('webhook') > -1 or request.build_absolute_uri().find('saveSpamAssassinConfigurations') > -1 or request.build_absolute_uri().find('docker') > -1 or request.build_absolute_uri().find('cloudAPI') > -1 or request.build_absolute_uri().find('filemanager') > -1 or request.build_absolute_uri().find('verifyLogin') > -1 or request.build_absolute_uri().find('submitUserCreation') > -1: + if request.build_absolute_uri().find('api/verifyConn') > -1 or request.build_absolute_uri().find('webhook') > -1 or request.build_absolute_uri().find('saveSpamAssassinConfigurations') > -1 or request.build_absolute_uri().find('docker') > -1 or request.build_absolute_uri().find('cloudAPI') > -1 or request.build_absolute_uri().find('filemanager') > -1 or request.build_absolute_uri().find('verifyLogin') > -1 or request.build_absolute_uri().find('submitUserCreation') > -1: continue if key == 'recordContentAAAA' or key == 'backupDestinations' or key == 'ports' \ or key == 'imageByPass' or key == 'passwordByPass' or key == 'cronCommand' \ @@ -96,18 +101,25 @@ class secMiddleware: logging.writeToFile(str(msg)) response = self.get_response(request) return response - + # else: + # try: + # if request.path.find('cloudAPI/') > -1 or request.path.find('api/') > -1: + # pass + # else: + # uID = request.session['userID'] + # except: + # return render(request, 'loginSystem/login.html', {}) response = self.get_response(request) response['X-XSS-Protection'] = "1; mode=block" - #response['Strict-Transport-Security'] = "max-age=31536000; includeSubDomains; preload" response['X-Frame-Options'] = "sameorigin" response['Content-Security-Policy'] = "script-src 'self' https://www.jsdelivr.com" response['Content-Security-Policy'] = "connect-src *;" response['Content-Security-Policy'] = "font-src 'self' 'unsafe-inline' https://www.jsdelivr.com https://fonts.googleapis.com" response['Content-Security-Policy'] = "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://www.jsdelivr.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://cdn.jsdelivr.net" + #response['Content-Security-Policy'] = "default-src 'self' cyberpanel.cloud *.cyberpanel.cloud" response['X-Content-Type-Options'] = "nosniff" response['Referrer-Policy'] = "same-origin" - return response \ No newline at end of file + return response diff --git a/CyberCP/settings.py b/CyberCP/settings.py index 64905d503..12eb81229 100755 --- a/CyberCP/settings.py +++ b/CyberCP/settings.py @@ -114,7 +114,7 @@ DATABASES = { 'USER': 'cyberpanel', 'PASSWORD': 'Bz9gF7Hr7X4RtD', 'HOST': 'localhost', - 'PORT':'' + 'PORT': '' }, 'rootdb': { 'ENGINE': 'django.db.backends.mysql', diff --git a/IncBackups/IncBackupPath.py b/IncBackups/IncBackupPath.py new file mode 100644 index 000000000..10cc418b1 --- /dev/null +++ b/IncBackups/IncBackupPath.py @@ -0,0 +1,7 @@ +from enum import Enum + + +class IncBackupPath(Enum): + SFTP = "/home/cyberpanel/sftp" + AWS = "/home/cyberpanel/aws" + # WASABI = "/home/cyberpanel/wasabi" diff --git a/IncBackups/IncBackupProvider.py b/IncBackups/IncBackupProvider.py new file mode 100644 index 000000000..9645be3d5 --- /dev/null +++ b/IncBackups/IncBackupProvider.py @@ -0,0 +1,8 @@ +from enum import Enum, auto + + +class IncBackupProvider(Enum): + LOCAL = auto() + SFTP = auto() + AWS = auto() + # WASABI = auto() diff --git a/IncBackups/IncBackups.py b/IncBackups/IncBackups.py index fbb5807e4..cbabdd047 100644 --- a/IncBackups/IncBackups.py +++ b/IncBackups/IncBackups.py @@ -219,9 +219,16 @@ class IncJobs(multi.Thread): try: logging.statusWriter(self.statusPath, 'Backing up data..', 1) + backupPath = '/home/%s' % (self.website.domain) + # Define our excludes file for use with restic + backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) + resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) + if self.backupDestinations == 'local': - backupPath = '/home/%s' % (self.website.domain) command = 'restic -r %s backup %s --password-file %s --exclude %s' % (self.repoPath, backupPath, self.passwordFile, self.repoPath) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2] newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (backupPath), snapshotid=snapShotid, destination=self.backupDestinations) @@ -230,8 +237,10 @@ class IncJobs(multi.Thread): elif self.backupDestinations[:4] == 'sftp': remotePath = '/home/backup/%s' % (self.website.domain) - backupPath = '/home/%s' % (self.website.domain) command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2] newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (remotePath), snapshotid=snapShotid, destination=self.backupDestinations) @@ -312,13 +321,23 @@ class IncJobs(multi.Thread): try: logging.statusWriter(self.statusPath, 'Will first initiate backup repo..', 1) + # Define our excludes file for use with restic + backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) + resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) + if self.backupDestinations == 'local': command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD ProcessUtilities.executioner(command, self.website.externalApp) elif self.backupDestinations[:4] == 'sftp': remotePath = '/home/backup/%s' % (self.website.domain) command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (self.backupDestinations, remotePath, self.passwordFile) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD ProcessUtilities.executioner(command) logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1) diff --git a/IncBackups/IncBackupsControl.py b/IncBackups/IncBackupsControl.py index c8e17ef83..d7adc34dc 100644 --- a/IncBackups/IncBackupsControl.py +++ b/IncBackups/IncBackupsControl.py @@ -1,8 +1,10 @@ #!/usr/local/CyberCP/bin/python import os import os.path +import shlex +import subprocess import sys - +import requests sys.path.append('/usr/local/CyberCP') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") @@ -83,9 +85,7 @@ class IncJobs(multi.Thread): result = self.getRemoteBackups() activator = 0 - json_data = "[" - checker = 0 - + json_data = [] if result[0].find('unable to open config file') == -1: for items in reversed(result): @@ -98,20 +98,11 @@ class IncJobs(multi.Thread): if activator: entry = items.split(' ') - - dic = {'id': entry[0], - 'date': "%s %s" % (entry[2], entry[3]), - 'host': entry[5], - 'path': entry[-1] - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' + json_data.append({'id': entry[0], + 'date': "%s %s" % (entry[2], entry[3]), + 'host': entry[5], + 'path': entry[-1] + }) final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data}) return HttpResponse(final_json) @@ -144,14 +135,23 @@ class IncJobs(multi.Thread): secret = open(path, 'r').read() return key, secret - def awsFunction(self, fType, backupPath=None, snapshotID=None, bType=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def awsFunction(self, fType, backupPath=None, snapshotID=None, bType=None, delete=None): try: if fType == 'backup': key, secret = self.getAWSData() - command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s backup %s --password-file %s' % ( - key, secret, self.website.domain, backupPath, self.passwordFile) + # Define our excludes file for use with restic + backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) + resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s backup %s --password-file %s --exclude /home/%s/backup --exclude /home/%s/incbackup' % ( + key, secret, self.website.domain, backupPath, self.passwordFile, self.website.domain, self.website.domain) + + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD result = ProcessUtilities.outputExecutioner(command) if result.find('saved') == -1: @@ -186,6 +186,27 @@ class IncJobs(multi.Thread): if result.find('restoring') == -1: logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) return 0 + elif delete: + + self.backupDestinations = self.jobid.destination + + key, secret = self.getAWSData() + + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s forget %s --password-file %s' % ( + key, secret, self.website, snapshotID, self.passwordFile) + + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s prune --password-file %s' % ( + key, secret, self.website, self.passwordFile) + + ProcessUtilities.outputExecutioner(command) else: self.backupDestinations = self.jobid.destination @@ -207,10 +228,20 @@ class IncJobs(multi.Thread): logging.statusWriter(self.statusPath, "%s [88][5009]" % (str(msg)), 1) return 0 - def localFunction(self, backupPath, type, restore=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def localFunction(self, backupPath, type, restore=None, delete=None): + if restore == None: - command = 'restic -r %s backup %s --password-file %s --exclude %s' % ( - self.repoPath, backupPath, self.passwordFile, self.repoPath) + # Define our excludes file for use with restic + backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) + resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) + + command = 'restic -r %s backup %s --password-file %s --exclude %s --exclude /home/%s/backup' % ( + self.repoPath, backupPath, self.passwordFile, self.repoPath, self.website.domain) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD result = ProcessUtilities.outputExecutioner(command) if result.find('saved') == -1: @@ -228,6 +259,23 @@ class IncJobs(multi.Thread): newSnapshot = JobSnapshots(job=self.jobid, type='%s:%s' % (type, backupPath), snapshotid=snapShotid, destination=self.backupDestinations) newSnapshot.save() + return 1 + elif delete: + + repoLocation = '/home/%s/incbackup' % (self.website) + + command = 'restic -r %s forget %s --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile) + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'restic -r %s prune --password-file %s' % (repoLocation, self.passwordFile) + ProcessUtilities.outputExecutioner(command) + return 1 else: repoLocation = '/home/%s/incbackup' % (self.website) @@ -242,11 +290,19 @@ class IncJobs(multi.Thread): return 1 - def sftpFunction(self, backupPath, type, restore=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def sftpFunction(self, backupPath, type, restore=None, delete=None): if restore == None: + # Define our excludes file for use with restic + backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) + resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) remotePath = '/home/backup/%s' % (self.website.domain) - command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % ( - self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath) + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s --exclude /home/%s/backup' % ( + self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath, self.website.domain) + # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. + if os.path.isfile(backupExcludesFile): + command = command + resticBackupExcludeCMD result = ProcessUtilities.outputExecutioner(command) if result.find('saved') == -1: @@ -265,6 +321,20 @@ class IncJobs(multi.Thread): destination=self.backupDestinations) newSnapshot.save() return 1 + elif delete: + repoLocation = '/home/backup/%s' % (self.website) + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s forget %s --password-file %s' % ( + self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile) + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s prune --password-file %s' % (self.jobid.destination, repoLocation, self.passwordFile) + ProcessUtilities.outputExecutioner(command) else: if self.reconstruct == 'remote': repoLocation = '/home/backup/%s' % (self.website) @@ -426,6 +496,7 @@ class IncJobs(multi.Thread): def restorePoint(self): try: + self.statusPath = self.extraArgs['tempPath'] self.website = self.extraArgs['website'] jobid = self.extraArgs['jobid'] @@ -515,177 +586,29 @@ class IncJobs(multi.Thread): def prepareBackupMeta(self): try: - ######### Generating meta - - ## XML Generation - - metaFileXML = Element('metaFile') - - child = SubElement(metaFileXML, 'masterDomain') - child.text = self.website.domain - - child = SubElement(metaFileXML, 'phpSelection') - child.text = self.website.phpSelection - - child = SubElement(metaFileXML, 'externalApp') - child.text = self.website.externalApp - - childDomains = self.website.childdomains_set.all() - - databases = self.website.databases_set.all() - - ## Child domains XML - - childDomainsXML = Element('ChildDomains') - - for items in childDomains: - childDomainXML = Element('domain') - - child = SubElement(childDomainXML, 'domain') - child.text = items.domain - child = SubElement(childDomainXML, 'phpSelection') - child.text = items.phpSelection - child = SubElement(childDomainXML, 'path') - child.text = items.path - - childDomainsXML.append(childDomainXML) - - metaFileXML.append(childDomainsXML) - - ## Databases XML - - databasesXML = Element('Databases') - - for items in databases: - try: - dbuser = DBUsers.objects.get(user=items.dbUser) - userToTry = items.dbUser - except: - dbusers = DBUsers.objects.all().filter(user=items.dbUser) - for it in dbusers: - dbuser = it - break - - userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbName) - - if userToTry == 0 or userToTry == 1: - continue - - try: - dbuser = DBUsers.objects.get(user=userToTry) - except: - dbusers = DBUsers.objects.all().filter(user=userToTry) - for it in dbusers: - dbuser = it - break + ## Use the meta function from backup utils for future improvements. - databaseXML = Element('database') + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile('Creating meta for %s. [IncBackupsControl.py]' % (self.website.domain)) - child = SubElement(databaseXML, 'dbName') - child.text = items.dbName - child = SubElement(databaseXML, 'dbUser') - child.text = userToTry - child = SubElement(databaseXML, 'password') - child.text = dbuser.password - - databasesXML.append(databaseXML) - - metaFileXML.append(databasesXML) - - ## Get Aliases - - aliasesXML = Element('Aliases') - - aliases = backupUtilities.getAliases(self.website.domain) - - for items in aliases: - child = SubElement(aliasesXML, 'alias') - child.text = items - - metaFileXML.append(aliasesXML) - - ## Finish Alias - - ## DNS Records XML - - try: - - dnsRecordsXML = Element("dnsrecords") - dnsRecords = DNS.getDNSRecords(self.website.domain) - - for items in dnsRecords: - dnsRecordXML = Element('dnsrecord') - - child = SubElement(dnsRecordXML, 'type') - child.text = items.type - child = SubElement(dnsRecordXML, 'name') - child.text = items.name - child = SubElement(dnsRecordXML, 'content') - child.text = items.content - child = SubElement(dnsRecordXML, 'priority') - child.text = str(items.prio) - - dnsRecordsXML.append(dnsRecordXML) - - metaFileXML.append(dnsRecordsXML) - - except BaseException as msg: - logging.statusWriter(self.statusPath, '%s. [158:prepMeta]' % (str(msg)), 1) - - ## Email accounts XML - - try: - emailRecordsXML = Element('emails') - eDomain = eDomains.objects.get(domain=self.website.domain) - emailAccounts = eDomain.eusers_set.all() - - for items in emailAccounts: - emailRecordXML = Element('emailAccount') - - child = SubElement(emailRecordXML, 'email') - child.text = items.email - child = SubElement(emailRecordXML, 'password') - child.text = items.password - - emailRecordsXML.append(emailRecordXML) - - metaFileXML.append(emailRecordsXML) - except BaseException as msg: - pass - #logging.statusWriter(self.statusPath, '%s. [warning:179:prepMeta]' % (str(msg)), 1) - - ## Email meta generated! - - def prettify(elem): - """Return a pretty-printed XML string for the Element. - """ - rough_string = ElementTree.tostring(elem, 'utf-8') - reparsed = minidom.parseString(rough_string) - return reparsed.toprettyxml(indent=" ") - - ## /home/example.com/backup/backup-example-06-50-03-Thu-Feb-2018/meta.xml -- metaPath - - metaPath = '/home/cyberpanel/%s' % (str(randint(1000, 9999))) - - xmlpretty = prettify(metaFileXML).encode('ascii', 'ignore') - metaFile = open(metaPath, 'w') - metaFile.write(xmlpretty.decode('utf-8')) - metaFile.close() - os.chmod(metaPath, 0o640) + from plogical.backupUtilities import backupUtilities + status, message, metaPath = backupUtilities.prepareBackupMeta(self.website.domain, None, None, None, 0) ## meta generated - logging.statusWriter(self.statusPath, 'Meta data is ready..', 1) - - metaPathNew = '/home/%s/meta.xml' % (self.website.domain) - command = 'mv %s %s' % (metaPath, metaPathNew) - ProcessUtilities.executioner(command) - - return 1 + if status == 1: + logging.statusWriter(self.statusPath, 'Meta data is ready..', 1) + metaPathNew = '/home/%s/meta.xml' % (self.website.domain) + command = 'mv %s %s' % (metaPath, metaPathNew) + ProcessUtilities.executioner(command) + return 1 + else: + logging.statusWriter(self.statusPath, "%s [544][5009]" % (message), 1) + return 0 except BaseException as msg: - logging.statusWriter(self.statusPath, "%s [207][5009]" % (str(msg)), 1) + logging.statusWriter(self.statusPath, "%s [548][5009]" % (str(msg)), 1) return 0 def backupData(self): @@ -717,6 +640,7 @@ class IncJobs(multi.Thread): databases = self.website.databases_set.all() for items in databases: + if mysqlUtilities.mysqlUtilities.createDatabaseBackup(items.dbName, '/home/cyberpanel') == 0: return 0 @@ -749,6 +673,7 @@ class IncJobs(multi.Thread): backupPath = '/home/vmail/%s' % (self.website.domain) if os.path.exists(backupPath): + if self.backupDestinations == 'local': if self.localFunction(backupPath, 'email') == 0: return 0 @@ -796,6 +721,10 @@ class IncJobs(multi.Thread): if self.backupDestinations == 'local': command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) @@ -804,6 +733,10 @@ class IncJobs(multi.Thread): command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % ( self.backupDestinations, remotePath, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) else: @@ -811,9 +744,12 @@ class IncJobs(multi.Thread): command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s init --password-file %s' % ( key, secret, self.website.domain, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) - return 1 logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1) @@ -840,6 +776,7 @@ Subject: %s mailUtilities.SendEmail(sender, TO, message) def createBackup(self): + self.statusPath = self.extraArgs['tempPath'] website = self.extraArgs['website'] self.backupDestinations = self.extraArgs['backupDestinations'] @@ -850,10 +787,34 @@ Subject: %s ### Checking if restic is installed before moving on command = 'restic' + if ProcessUtilities.outputExecutioner(command).find('restic is a backup program which') == -1: - logging.statusWriter(self.statusPath, 'It seems restic is not installed, for incremental backups to work ' - 'restic must be installed. You can manually install restic using this ' - 'guide -> http://go.cyberpanel.net/restic. [5009]', 1) + try: + + CentOSPath = '/etc/redhat-release' + + if os.path.exists(CentOSPath): + command = 'yum install -y yum-plugin-copr' + ProcessUtilities.executioner(command) + command = 'yum copr enable -y copart/restic' + ProcessUtilities.executioner(command) + command = 'yum install -y restic' + ProcessUtilities.executioner(command) + + else: + command = 'apt-get update -y' + ProcessUtilities.executioner(command) + + command = 'apt-get install restic -y' + ProcessUtilities.executioner(command) + + except: + logging.statusWriter(self.statusPath, + 'It seems restic is not installed, for incremental backups to work ' + 'restic must be installed. You can manually install restic using this ' + 'guide -> https://go.cyberpanel.net/restic. [5009]', 1) + pass + return 0 ## Restic check completed. @@ -882,6 +843,8 @@ Subject: %s if self.initiateRepo() == 0: return 0 + + if self.prepareBackupMeta() == 0: return 0 @@ -911,3 +874,38 @@ Subject: %s 'Failed to delete meta file: %s. [IncJobs.createBackup.591]' % str(msg), 1) logging.statusWriter(self.statusPath, 'Completed', 1) + + ### Delete Snapshot + + def DeleteSnapShot(self, inc_job): + try: + + self.statusPath = logging.fileName + + job_snapshots = inc_job.jobsnapshots_set.all() + + ### Fetch the website name from JobSnapshot object and set these variable as they are needed in called functions below + + self.website = job_snapshots[0].job.website.domain + self.passwordFile = '/home/%s/%s' % (self.website, self.website) + + for job_snapshot in job_snapshots: + + ## Functions above use the self.jobid varilable to extract information about this snapshot, so this below variable needs to be set + + self.jobid = job_snapshot + + if self.jobid.destination == 'local': + self.localFunction('none', 'none', 0, 1) + elif self.jobid.destination[:4] == 'sftp': + self.sftpFunction('none', 'none', 0, 1) + else: + self.awsFunction('restore', '', self.jobid.snapshotid, None, 1) + + return 1 + + except BaseException as msg: + logging.statusWriter(self.statusPath, "%s [903:DeleteSnapShot][5009]" % (str(msg)), 1) + return 0 + + diff --git a/IncBackups/models.py b/IncBackups/models.py index f75aafaaf..9e87e6aec 100644 --- a/IncBackups/models.py +++ b/IncBackups/models.py @@ -1,13 +1,13 @@ - - from django.db import models from websiteFunctions.models import Websites from datetime import datetime + class IncJob(models.Model): website = models.ForeignKey(Websites, on_delete=models.CASCADE) date = models.DateTimeField(default=datetime.now, blank=True) + class JobSnapshots(models.Model): job = models.ForeignKey(IncJob, on_delete=models.CASCADE) type = models.CharField(max_length=300) @@ -21,10 +21,9 @@ class BackupJob(models.Model): websiteData = models.IntegerField() websiteDatabases = models.IntegerField() websiteDataEmails = models.IntegerField() + retention = models.IntegerField(default=0) # 0 being unlimited retention class JobSites(models.Model): job = models.ForeignKey(BackupJob, on_delete=models.CASCADE) website = models.CharField(max_length=300) - - diff --git a/IncBackups/static/IncBackups/IncBackups.js b/IncBackups/static/IncBackups/IncBackups.js index 32b01ef70..79b13571e 100644 --- a/IncBackups/static/IncBackups/IncBackups.js +++ b/IncBackups/static/IncBackups/IncBackups.js @@ -101,7 +101,7 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) { function ListInitialDatas(response) { if (response.data.status === 1) { - $scope.records = JSON.parse(response.data.data); + $scope.records = response.data.data; } else { new PNotify({ title: 'Error!', @@ -240,7 +240,7 @@ app.controller('createIncrementalBackups', function ($scope, $http, $timeout) { function ListInitialDatas(response) { $scope.cyberpanelLoading = true; if (response.data.status === 1) { - $scope.jobs = JSON.parse(response.data.data); + $scope.jobs = response.data.data; } else { new PNotify({ title: 'Operation Failed!', @@ -358,7 +358,7 @@ app.controller('incrementalDestinations', function ($scope, $http) { function ListInitialDatas(response) { $scope.cyberpanelLoading = true; if (response.data.status === 1) { - $scope.records = JSON.parse(response.data.data); + $scope.records = response.data.data; } else { new PNotify({ title: 'Operation Failed!', @@ -599,6 +599,7 @@ app.controller('scheduleBackupInc', function ($scope, $http) { var data = { backupDestinations: $scope.backupDest, backupFreq: $scope.backupFreq, + backupRetention: $scope.backupRetention, websiteData: $scope.websiteData, websiteEmails: $scope.websiteEmails, websiteDatabases: $scope.websiteDatabases, @@ -621,7 +622,7 @@ app.controller('scheduleBackupInc', function ($scope, $http) { if (response.data.status === 1) { new PNotify({ title: 'Success!', - text: 'Destination successfully removed.', + text: 'Operation successful.', type: 'success' }); } else { @@ -668,12 +669,11 @@ app.controller('scheduleBackupInc', function ($scope, $http) { function ListInitialDatas(response) { $scope.cyberpanelLoading = true; if (response.data.status === 1) { - $scope.records = JSON.parse(response.data.data); - var parsed = JSON.parse(response.data.data); - - for (var j = 0; j < parsed.length; j++) { - websitesToBeBackedTemp.push(parsed[j].website); - } + let data = response.data.data; + $scope.records = data; + data.forEach(item => { + websitesToBeBackedTemp.push(item.website) + }) } else { new PNotify({ title: 'Operation Failed!', @@ -766,7 +766,7 @@ app.controller('scheduleBackupInc', function ($scope, $http) { function ListInitialDatas(response) { $scope.cyberpanelLoading = true; if (response.data.status === 1) { - $scope.websites = JSON.parse(response.data.data); + $scope.websites = response.data.data; if(response.data.websiteData === 1){ $scope.websiteData = true; @@ -1074,7 +1074,7 @@ app.controller('restoreRemoteBackupsInc', function ($scope, $http, $timeout) { function ListInitialDatas(response) { $scope.cyberpanelLoading = true; if (response.data.status === 1) { - $scope.records = JSON.parse(response.data.data); + $scope.records = response.data.data; } else { new PNotify({ title: 'Error!', diff --git a/IncBackups/templates/IncBackups/backupSchedule.html b/IncBackups/templates/IncBackups/backupSchedule.html index 7724ca483..54827c781 100755 --- a/IncBackups/templates/IncBackups/backupSchedule.html +++ b/IncBackups/templates/IncBackups/backupSchedule.html @@ -10,7 +10,7 @@
-

{% trans "Schedule Back up" %} - {% trans "Schedule Back up" %} - {% trans "Remote Backups" %}

@@ -50,6 +50,18 @@
+
+ +
+
+ +
+
+
+ +
diff --git a/IncBackups/templates/IncBackups/restoreRemoteBackups.html b/IncBackups/templates/IncBackups/restoreRemoteBackups.html index b9e6b9228..7c2b38caa 100755 --- a/IncBackups/templates/IncBackups/restoreRemoteBackups.html +++ b/IncBackups/templates/IncBackups/restoreRemoteBackups.html @@ -55,7 +55,7 @@
- +
diff --git a/IncBackups/urls.py b/IncBackups/urls.py index 2cb3e7928..a8862cf04 100644 --- a/IncBackups/urls.py +++ b/IncBackups/urls.py @@ -2,24 +2,24 @@ from django.conf.urls import url from . import views urlpatterns = [ - url(r'^createBackup$', views.createBackup, name='createBackupInc'), - url(r'^restoreRemoteBackups$', views.restoreRemoteBackups, name='restoreRemoteBackupsInc'), - url(r'^backupDestinations$', views.backupDestinations, name='backupDestinationsInc'), - url(r'^addDestination$', views.addDestination, name='addDestinationInc'), - url(r'^populateCurrentRecords$', views.populateCurrentRecords, name='populateCurrentRecordsInc'), - url(r'^removeDestination$', views.removeDestination, name='removeDestinationInc'), - url(r'^fetchCurrentBackups$', views.fetchCurrentBackups, name='fetchCurrentBackupsInc'), - url(r'^submitBackupCreation$', views.submitBackupCreation, name='submitBackupCreationInc'), - url(r'^getBackupStatus$', views.getBackupStatus, name='getBackupStatusInc'), - url(r'^deleteBackup$', views.deleteBackup, name='deleteBackupInc'), - url(r'^fetchRestorePoints$', views.fetchRestorePoints, name='fetchRestorePointsInc'), - url(r'^restorePoint$', views.restorePoint, name='restorePointInc'), - url(r'^scheduleBackups$', views.scheduleBackups, name='scheduleBackupsInc'), - url(r'^submitBackupSchedule$', views.submitBackupSchedule, name='submitBackupScheduleInc'), - url(r'^scheduleDelete$', views.scheduleDelete, name='scheduleDeleteInc'), - url(r'^getCurrentBackupSchedules$', views.getCurrentBackupSchedules, name='getCurrentBackupSchedulesInc'), - url(r'^fetchSites$', views.fetchSites, name='fetchSites'), - url(r'^saveChanges$', views.saveChanges, name='saveChanges'), - url(r'^removeSite$', views.removeSite, name='removeSite'), - url(r'^addWebsite$', views.addWebsite, name='addWebsite'), + url(r'^createBackup$', views.create_backup, name='createBackupInc'), + url(r'^restoreRemoteBackups$', views.restore_remote_backups, name='restoreRemoteBackupsInc'), + url(r'^backupDestinations$', views.backup_destinations, name='backupDestinationsInc'), + url(r'^addDestination$', views.add_destination, name='addDestinationInc'), + url(r'^populateCurrentRecords$', views.populate_current_records, name='populateCurrentRecordsInc'), + url(r'^removeDestination$', views.remove_destination, name='removeDestinationInc'), + url(r'^fetchCurrentBackups$', views.fetch_current_backups, name='fetchCurrentBackupsInc'), + url(r'^submitBackupCreation$', views.submit_backup_creation, name='submitBackupCreationInc'), + url(r'^getBackupStatus$', views.get_backup_status, name='getBackupStatusInc'), + url(r'^deleteBackup$', views.delete_backup, name='deleteBackupInc'), + url(r'^fetchRestorePoints$', views.fetch_restore_points, name='fetchRestorePointsInc'), + url(r'^restorePoint$', views.restore_point, name='restorePointInc'), + url(r'^scheduleBackups$', views.schedule_backups, name='scheduleBackupsInc'), + url(r'^submitBackupSchedule$', views.submit_backup_schedule, name='submitBackupScheduleInc'), + url(r'^scheduleDelete$', views.schedule_delete, name='scheduleDeleteInc'), + url(r'^getCurrentBackupSchedules$', views.get_current_backup_schedules, name='getCurrentBackupSchedulesInc'), + url(r'^fetchSites$', views.fetch_sites, name='fetchSites'), + url(r'^saveChanges$', views.save_changes, name='saveChanges'), + url(r'^removeSite$', views.remove_site, name='removeSite'), + url(r'^addWebsite$', views.add_website, name='addWebsite'), ] \ No newline at end of file diff --git a/IncBackups/views.py b/IncBackups/views.py index fe229f0c9..bca22263d 100644 --- a/IncBackups/views.py +++ b/IncBackups/views.py @@ -1,425 +1,341 @@ -# -*- coding: utf-8 -*- - -from django.shortcuts import render -from plogical.acl import ACLManager -from django.shortcuts import HttpResponse, redirect -from plogical.processUtilities import ProcessUtilities -from plogical.virtualHostUtilities import virtualHostUtilities import json import os -from loginSystem.models import Administrator -from websiteFunctions.models import Websites -from .models import IncJob, BackupJob, JobSites -from .IncBackupsControl import IncJobs -from random import randint -import time -from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging -from loginSystem.views import loadLoginPage import stat -# Create your views here. +import time +from pathlib import Path +from random import randint + +from django.shortcuts import HttpResponse, redirect +from loginSystem.models import Administrator +from loginSystem.views import loadLoginPage +from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging +from plogical.acl import ACLManager +from plogical.httpProc import httpProc +from plogical.processUtilities import ProcessUtilities as pu +from plogical.virtualHostUtilities import virtualHostUtilities as vhu +from websiteFunctions.models import Websites +from .IncBackupProvider import IncBackupProvider +from .IncBackupPath import IncBackupPath +from .IncBackupsControl import IncJobs +from .models import IncJob, BackupJob, JobSites -def defRenderer(request, templateName, args): - return render(request, templateName, args) +def def_renderer(request, templateName, args, context=None): + proc = httpProc(request, templateName, + args, context) + return proc.render() -def createBackup(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0: - return ACLManager.loadError() - - websitesName = ACLManager.findAllSites(currentACL, userID) - - destinations = [] +def _get_destinations(local: bool = False): + destinations = [] + if local: destinations.append('local') + path = Path(IncBackupPath.SFTP.value) + if path.exists(): + for item in path.iterdir(): + destinations.append('sftp:%s' % item.name) - path = '/home/cyberpanel/sftp' + path = Path(IncBackupPath.AWS.value) + if path.exists(): + for item in path.iterdir(): + destinations.append('s3:s3.amazonaws.com/%s' % item.name) + return destinations - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('sftp:%s' % (items)) - path = '/home/cyberpanel/aws' - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('s3:s3.amazonaws.com/%s' % (items)) +def _get_user_acl(request): + user_id = request.session['userID'] + current_acl = ACLManager.loadedACL(user_id) + return user_id, current_acl - return defRenderer(request, 'IncBackups/createBackup.html', {'websiteList': websitesName, 'destinations': destinations}) - except BaseException as msg: - logging.writeToFile(str(msg)) - return redirect(loadLoginPage) -def backupDestinations(request): +def create_backup(request): + try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'createBackup') == 0: return ACLManager.loadError() - return defRenderer(request, 'IncBackups/incrementalDestinations.html', {}) + websites = ACLManager.findAllSites(current_acl, user_id) + + destinations = _get_destinations(local=True) + + return def_renderer(request, 'IncBackups/createBackup.html', + {'websiteList': websites, 'destinations': destinations}, 'createBackup') except BaseException as msg: logging.writeToFile(str(msg)) return redirect(loadLoginPage) -def addDestination(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0: +def backup_destinations(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'addDeleteDestinations') == 0: + return ACLManager.loadError() + + return def_renderer(request, 'IncBackups/incrementalDestinations.html', {}, 'addDeleteDestinations') + except BaseException as msg: + logging.writeToFile(str(msg)) + return redirect(loadLoginPage) + + +def add_destination(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'addDeleteDestinations') == 0: return ACLManager.loadErrorJson('destStatus', 0) data = json.loads(request.body) - if data['type'] == 'SFTP': + if data['type'].lower() == IncBackupProvider.SFTP.name.lower(): + path = Path(IncBackupPath.SFTP.value) + path.mkdir(exist_ok=True) - ipAddress = data['IPAddress'] + ip_address = data['IPAddress'] password = data['password'] - ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress) + address_file = path / ip_address + port = data.get('backupSSHPort', '22') - try: - port = data['backupSSHPort'] - except: - port = "22" - - if os.path.exists(ipFile): + if address_file.exists(): final_dic = {'status': 0, 'error_message': 'This destination already exists.'} final_json = json.dumps(final_dic) return HttpResponse(final_json) + python_path = Path('/usr/local/CyberCP/bin/python') + backup_utils = Path(vhu.cyberPanel) / "plogical/backupUtilities.py" - try: - os.mkdir('/home/cyberpanel/sftp') - except: - pass + exec_args = "submitDestinationCreation --ipAddress %s --password %s --port %s --user %s" % \ + (ip_address, password, port, 'root') + exec_cmd = "%s %s %s" % (python_path, backup_utils, exec_args) - execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py" - execPath = execPath + " submitDestinationCreation --ipAddress " + ipAddress + " --password " \ - + password + " --port " + port + ' --user %s' % ('root') + if Path(pu.debugPath).exists(): + logging.writeToFile(exec_cmd) - if os.path.exists(ProcessUtilities.debugPath): - logging.writeToFile(execPath) + output = pu.outputExecutioner(exec_cmd) - output = ProcessUtilities.outputExecutioner(execPath) - - if os.path.exists(ProcessUtilities.debugPath): + if Path(pu.debugPath).exists(): logging.writeToFile(output) if output.find('1,') > -1: - - content = '%s\n%s' % (ipAddress, port) - writeToFile = open(ipFile, 'w') - writeToFile.write(content) - writeToFile.close() + content = '%s\n%s' % (ip_address, port) + with open(address_file, 'w') as outfile: + outfile.write(content) command = 'cat /root/.ssh/config' - currentConfig = ProcessUtilities.outputExecutioner(command) + current_config = pu.outputExecutioner(command) - tmpFile = '/home/cyberpanel/sshconfig' + tmp_file = '/home/cyberpanel/sshconfig' + with open(tmp_file, 'w') as outfile: + if current_config.find('cat') == -1: + outfile.write(current_config) - writeToFile = open(tmpFile, 'w') - if currentConfig.find('cat') == -1: - writeToFile.write(currentConfig) + content = "Host %s\n" \ + " IdentityFile ~/.ssh/cyberpanel\n" \ + " Port %s\n" % (ip_address, port) + if current_config.find(ip_address) == -1: + outfile.write(content) - content = """Host %s - IdentityFile ~/.ssh/cyberpanel - Port %s -""" % (ipAddress, port) - if currentConfig.find(ipAddress) == -1: - writeToFile.write(content) - writeToFile.close() - - - command = 'mv %s /root/.ssh/config' % (tmpFile) - ProcessUtilities.executioner(command) + command = 'mv %s /root/.ssh/config' % tmp_file + pu.executioner(command) command = 'chown root:root /root/.ssh/config' - ProcessUtilities.executioner(command) + pu.executioner(command) final_dic = {'status': 1, 'error_message': 'None'} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - else: final_dic = {'status': 0, 'error_message': output} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - else: - aws = '/home/cyberpanel/aws' + final_json = json.dumps(final_dic) + return HttpResponse(final_json) - try: - os.mkdir(aws) - except: - pass + if data['type'].lower() == IncBackupProvider.AWS.name.lower(): + path = Path(IncBackupPath.AWS.value) + path.mkdir(exist_ok=True) - AWS_ACCESS_KEY_ID = data['AWS_ACCESS_KEY_ID'] - AWS_SECRET_ACCESS_KEY = data['AWS_SECRET_ACCESS_KEY'] + access_key = data['AWS_ACCESS_KEY_ID'] + secret_key = data['AWS_SECRET_ACCESS_KEY'] - awsFile = '/home/cyberpanel/aws/%s' % (AWS_ACCESS_KEY_ID) + aws_file = path / access_key - writeToFile = open(awsFile, 'w') - writeToFile.write(AWS_SECRET_ACCESS_KEY) - writeToFile.close() + with open(aws_file, 'w') as outfile: + outfile.write(secret_key) - os.chmod(awsFile, stat.S_IRUSR | stat.S_IWUSR) + aws_file.chmod(stat.S_IRUSR | stat.S_IWUSR) final_dic = {'status': 1} final_json = json.dumps(final_dic) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def populateCurrentRecords(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0: +def populate_current_records(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'addDeleteDestinations') == 0: return ACLManager.loadErrorJson('fetchStatus', 0) data = json.loads(request.body) - if data['type'] == 'SFTP': + json_data = [] + if data['type'].lower() == IncBackupProvider.SFTP.name.lower(): + path = Path(IncBackupPath.SFTP.value) - path = '/home/cyberpanel/sftp' - - if os.path.exists(path): - - json_data = "[" - checker = 0 - - for items in os.listdir(path): - fullPath = '/home/cyberpanel/sftp/%s' % (items) - - data = open(fullPath, 'r').readlines() - dic = { - 'ip': data[0].strip('\n'), - 'port': data[1], - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - else: - final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''}) - return HttpResponse(final_json) - else: - path = '/home/cyberpanel/aws' - - if os.path.exists(path): - - json_data = "[" - checker = 0 - - for items in os.listdir(path): - dic = { - 'AWS_ACCESS_KEY_ID': items - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) + if path.exists(): + for item in path.iterdir(): + with open(item, 'r') as infile: + _file = infile.readlines() + json_data.append({ + 'ip': _file[0].strip('\n'), + 'port': _file[1], + }) + else: + final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''}) + return HttpResponse(final_json) + + if data['type'].lower() == IncBackupProvider.AWS.name.lower(): + path = Path(IncBackupPath.AWS.value) + + if path.exists(): + for item in path.iterdir(): + json_data.append({'AWS_ACCESS_KEY_ID': item.name}) else: final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''}) return HttpResponse(final_json) - json_data = json_data + ']' final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data}) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def removeDestination(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0: +def remove_destination(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'addDeleteDestinations') == 0: return ACLManager.loadErrorJson('destStatus', 0) data = json.loads(request.body) - ipAddress = data['IPAddress'] + if 'IPAddress' in data: + file_name = data['IPAddress'] - if data['type'] == 'SFTP': - ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress) - else: - ipFile = '/home/cyberpanel/aws/%s' % (ipAddress) + if data['type'].lower() == IncBackupProvider.SFTP.name.lower(): + dest_file = Path(IncBackupPath.SFTP.value) / file_name + dest_file.unlink() - - os.remove(ipFile) + if data['type'].lower() == IncBackupProvider.AWS.name.lower(): + dest_file = Path(IncBackupPath.AWS.value) / file_name + dest_file.unlink() final_dic = {'status': 1, 'error_message': 'None'} final_json = json.dumps(final_dic) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'destStatus': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def fetchCurrentBackups(request): + +def fetch_current_backups(request): try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) data = json.loads(request.body) - backupDomain = data['websiteToBeBacked'] + backup_domain = data['websiteToBeBacked'] - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('fetchStatus', 0) - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() + if 'backupDestinations' in data: + backup_destinations = data['backupDestinations'] + extra_args = {'website': backup_domain, 'backupDestinations': backup_destinations} - try: - backupDestinations = data['backupDestinations'] - - extraArgs = {} - extraArgs['website'] = backupDomain - extraArgs['backupDestinations'] = backupDestinations - try: - extraArgs['password'] = data['password'] - except: + if 'password' in data: + extra_args['password'] = data['password'] + else: final_json = json.dumps({'status': 0, 'error_message': "Please supply the password."}) return HttpResponse(final_json) - startJob = IncJobs('Dummpy', extraArgs) - return startJob.fetchCurrentBackups() - - except: - - website = Websites.objects.get(domain=backupDomain) - + start_job = IncJobs('Dummy', extra_args) + return start_job.fetchCurrentBackups() + else: + website = Websites.objects.get(domain=backup_domain) backups = website.incjob_set.all() - - json_data = "[" - checker = 0 - - for items in reversed(backups): - - includes = "" - - jobs = items.jobsnapshots_set.all() - + json_data = [] + for backup in reversed(backups): + snapshots = [] + jobs = backup.jobsnapshots_set.all() for job in jobs: - includes = '%s,%s:%s' % (includes, job.type, job.snapshotid) - - dic = {'id': items.id, - 'date': str(items.date), - 'includes': includes - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' + snapshots.append({'type': job.type, 'snapshotid': job.snapshotid, 'destination': job.destination}) + json_data.append({'id': backup.id, + 'date': str(backup.date), + 'snapshots': snapshots + }) final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data}) return HttpResponse(final_json) - - except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def submitBackupCreation(request): + +def submit_backup_creation(request): try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) data = json.loads(request.body) - backupDomain = data['websiteToBeBacked'] - backupDestinations = data['backupDestinations'] + backup_domain = data['websiteToBeBacked'] + backup_destinations = data['backupDestinations'] - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('metaStatus', 0) - tempPath = "/home/cyberpanel/" + str(randint(1000, 9999)) + temp_path = Path("/home/cyberpanel/") / str(randint(1000, 9999)) - try: - websiteData = data['websiteData'] - except: - websiteData = False + extra_args = {} + extra_args['website'] = backup_domain + extra_args['tempPath'] = str(temp_path) + extra_args['backupDestinations'] = backup_destinations + extra_args['websiteData'] = data['websiteData'] if 'websiteData' in data else False + extra_args['websiteEmails'] = data['websiteEmails'] if 'websiteEmails' in data else False + extra_args['websiteSSLs'] = data['websiteSSLs'] if 'websiteSSLs' in data else False + extra_args['websiteDatabases'] = data['websiteDatabases'] if 'websiteDatabases' in data else False - try: - websiteEmails = data['websiteEmails'] - except: - websiteEmails = False - - try: - websiteSSLs = data['websiteSSLs'] - except: - websiteSSLs = False - - - try: - websiteDatabases = data['websiteDatabases'] - except: - websiteDatabases = False - - extraArgs = {} - extraArgs['website'] = backupDomain - extraArgs['tempPath'] = tempPath - extraArgs['backupDestinations'] = backupDestinations - extraArgs['websiteData'] = websiteData - extraArgs['websiteEmails'] = websiteEmails - extraArgs['websiteSSLs'] = websiteSSLs - extraArgs['websiteDatabases'] = websiteDatabases - - startJob = IncJobs('createBackup', extraArgs) - startJob.start() + start_job = IncJobs('createBackup', extra_args) + start_job.start() time.sleep(2) - final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': tempPath}) + final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': str(temp_path)}) return HttpResponse(final_json) - except BaseException as msg: logging.writeToFile(str(msg)) final_dic = {'status': 0, 'metaStatus': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def getBackupStatus(request): + +def get_backup_status(request): try: data = json.loads(request.body) status = data['tempPath'] - backupDomain = data['websiteToBeBacked'] + backup_domain = data['websiteToBeBacked'] - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) - - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('fetchStatus', 0) @@ -437,7 +353,7 @@ def getBackupStatus(request): if os.path.exists(status): command = "cat " + status - result = ProcessUtilities.outputExecutioner(command, 'cyberpanel') + result = pu.outputExecutioner(command, 'cyberpanel') if result.find("Completed") > -1: @@ -468,77 +384,70 @@ def getBackupStatus(request): else: final_json = json.dumps({'backupStatus': 1, 'error_message': "None", "status": 1, "abort": 0}) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'backupStatus': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) logging.writeToFile(str(msg) + " [backupStatus]") return HttpResponse(final_json) -def deleteBackup(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) - data = json.loads(request.body) - backupDomain = data['websiteToBeBacked'] - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: +def delete_backup(request): + try: + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) + data = json.loads(request.body) + backup_domain = data['websiteToBeBacked'] + + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('fetchStatus', 0) - id = data['backupID'] + backup_id = data['backupID'] - IncJob.objects.get(id=id).delete() + inc_job = IncJob.objects.get(id=backup_id) + + job = IncJobs(None, None) + job.DeleteSnapShot(inc_job) + + inc_job.delete() final_dic = {'status': 1, 'error_message': 'None'} final_json = json.dumps(final_dic) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'destStatus': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def fetchRestorePoints(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) - data = json.loads(request.body) - backupDomain = data['websiteToBeBacked'] - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: +def fetch_restore_points(request): + try: + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) + data = json.loads(request.body) + backup_domain = data['websiteToBeBacked'] + + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('fetchStatus', 0) data = json.loads(request.body) - id = data['id'] + job_id = data['id'] - incJob = IncJob.objects.get(id=id) + inc_job = IncJob.objects.get(id=job_id) - backups = incJob.jobsnapshots_set.all() - - json_data = "[" - checker = 0 + backups = inc_job.jobsnapshots_set.all() + json_data = [] for items in backups: + json_data.append({'id': items.id, + 'snapshotid': items.snapshotid, + 'type': items.type, + 'destination': items.destination, + }) - dic = {'id': items.id, - 'snapshotid': items.snapshotid, - 'type': items.type, - 'destination': items.destination, - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data}) return HttpResponse(final_json) except BaseException as msg: @@ -546,350 +455,258 @@ def fetchRestorePoints(request): final_json = json.dumps(final_dic) return HttpResponse(final_json) -def restorePoint(request): +def restore_point(request): try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - admin = Administrator.objects.get(pk=userID) + user_id, current_acl = _get_user_acl(request) + admin = Administrator.objects.get(pk=user_id) data = json.loads(request.body) - backupDomain = data['websiteToBeBacked'] - jobid = data['jobid'] + backup_domain = data['websiteToBeBacked'] + job_id = data['jobid'] - if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1: + if ACLManager.checkOwnership(backup_domain, admin, current_acl) == 1: pass else: return ACLManager.loadErrorJson('metaStatus', 0) - tempPath = "/home/cyberpanel/" + str(randint(1000, 9999)) + temp_path = Path("/home/cyberpanel/") / str(randint(1000, 9999)) if data['reconstruct'] == 'remote': extraArgs = {} - extraArgs['website'] = backupDomain - extraArgs['jobid'] = jobid - extraArgs['tempPath'] = tempPath + extraArgs['website'] = backup_domain + extraArgs['jobid'] = job_id + extraArgs['tempPath'] = str(temp_path) extraArgs['reconstruct'] = data['reconstruct'] extraArgs['backupDestinations'] = data['backupDestinations'] extraArgs['password'] = data['password'] extraArgs['path'] = data['path'] else: extraArgs = {} - extraArgs['website'] = backupDomain - extraArgs['jobid'] = jobid - extraArgs['tempPath'] = tempPath + extraArgs['website'] = backup_domain + extraArgs['jobid'] = job_id + extraArgs['tempPath'] = str(temp_path) extraArgs['reconstruct'] = data['reconstruct'] - - startJob = IncJobs('restorePoint', extraArgs) - startJob.start() - + start_job = IncJobs('restorePoint', extraArgs) + start_job.start() time.sleep(2) - final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': tempPath}) + final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': str(temp_path)}) return HttpResponse(final_json) - except BaseException as msg: logging.writeToFile(str(msg)) final_dic = {'status': 0, 'metaStatus': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def scheduleBackups(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def schedule_backups(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadError() - websitesName = ACLManager.findAllSites(currentACL, userID) + websites = ACLManager.findAllSites(current_acl, user_id) - destinations = [] - destinations.append('local') + destinations = _get_destinations(local=True) - path = '/home/cyberpanel/sftp' - - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('sftp:%s' % (items)) - - path = '/home/cyberpanel/aws' - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('s3:s3.amazonaws.com/%s' % (items)) - - websitesName = ACLManager.findAllSites(currentACL, userID) - - return defRenderer(request, 'IncBackups/backupSchedule.html', {'websiteList': websitesName, 'destinations': destinations}) + return def_renderer(request, 'IncBackups/backupSchedule.html', + {'websiteList': websites, 'destinations': destinations}, 'scheduleBackups') except BaseException as msg: logging.writeToFile(str(msg)) return redirect(loadLoginPage) -def submitBackupSchedule(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def submit_backup_schedule(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) data = json.loads(request.body) - backupDest = data['backupDestinations'] - backupFreq = data['backupFreq'] - websitesToBeBacked = data['websitesToBeBacked'] + backup_dest = data['backupDestinations'] + backup_freq = data['backupFreq'] + backup_retention = data['backupRetention'] + backup_sites = data['websitesToBeBacked'] - try: - websiteData = data['websiteData'] - websiteData = 1 - except: - websiteData = False - websiteData = 0 + backup_data = 1 if 'websiteData' in data else 0 + backup_emails = 1 if 'websiteEmails' in data else 0 + backup_databases = 1 if 'websiteDatabases' in data else 0 - try: - websiteEmails = data['websiteEmails'] - websiteEmails = 1 - except: - websiteEmails = False - websiteEmails = 0 + backup_job = BackupJob(websiteData=backup_data, websiteDataEmails=backup_emails, + websiteDatabases=backup_databases, destination=backup_dest, frequency=backup_freq, + retention=backup_retention) + backup_job.save() - try: - websiteDatabases = data['websiteDatabases'] - websiteDatabases = 1 - except: - websiteDatabases = False - websiteDatabases = 0 - - newJob = BackupJob(websiteData=websiteData, websiteDataEmails=websiteEmails, websiteDatabases=websiteDatabases, destination=backupDest, frequency=backupFreq) - newJob.save() - - for items in websitesToBeBacked: - jobsite = JobSites(job=newJob, website=items) - jobsite.save() + for site in backup_sites: + backup_site_job = JobSites(job=backup_job, website=site) + backup_site_job.save() final_json = json.dumps({'status': 1, 'error_message': "None"}) return HttpResponse(final_json) - - except BaseException as msg: final_json = json.dumps({'status': 0, 'error_message': str(msg)}) return HttpResponse(final_json) -def getCurrentBackupSchedules(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def get_current_backup_schedules(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('fetchStatus', 0) records = BackupJob.objects.all() - json_data = "[" - checker = 0 - + json_data = [] for items in records: - dic = {'id': items.id, - 'destination': items.destination, - 'frequency': items.frequency, - 'numberOfSites': items.jobsites_set.all().count() - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' + json_data.append({'id': items.id, + 'destination': items.destination, + 'frequency': items.frequency, + 'retention': items.retention, + 'numberOfSites': items.jobsites_set.all().count() + }) final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data}) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def fetchSites(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def fetch_sites(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('fetchStatus', 0) data = json.loads(request.body) job = BackupJob.objects.get(pk=data['id']) - json_data = "[" - checker = 0 - - for items in job.jobsites_set.all(): - dic = {'id': items.id, - 'website': items.website, - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' + json_data = [] + for jobsite in job.jobsites_set.all(): + json_data.append({'id': jobsite.id, + 'website': jobsite.website, + }) final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data, 'websiteData': job.websiteData, 'websiteDatabases': job.websiteDatabases, 'websiteEmails': job.websiteDataEmails}) return HttpResponse(final_json) - except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)} final_json = json.dumps(final_dic) return HttpResponse(final_json) -def scheduleDelete(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def schedule_delete(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) data = json.loads(request.body) - id = data['id'] + job_id = data['id'] - backupJob = BackupJob.objects.get(id=id) - backupJob.delete() + backup_job = BackupJob.objects.get(id=job_id) + backup_job.delete() final_json = json.dumps({'status': 1, 'error_message': "None"}) return HttpResponse(final_json) - except BaseException as msg: final_json = json.dumps({'status': 0, 'error_message': str(msg)}) return HttpResponse(final_json) -def restoreRemoteBackups(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0: +def restore_remote_backups(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'createBackup') == 0: return ACLManager.loadError() - websitesName = ACLManager.findAllSites(currentACL, userID) + websites = ACLManager.findAllSites(current_acl, user_id) - destinations = [] + destinations = _get_destinations() - path = '/home/cyberpanel/sftp' - - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('sftp:%s' % (items)) - - path = '/home/cyberpanel/aws' - if os.path.exists(path): - for items in os.listdir(path): - destinations.append('s3:s3.amazonaws.com/%s' % (items)) - - return defRenderer(request, 'IncBackups/restoreRemoteBackups.html', {'websiteList': websitesName, 'destinations': destinations}) + return def_renderer(request, 'IncBackups/restoreRemoteBackups.html', + {'websiteList': websites, 'destinations': destinations}, 'createBackup') except BaseException as msg: logging.writeToFile(str(msg)) return redirect(loadLoginPage) -def saveChanges(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def save_changes(request): + try: + user_id, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) data = json.loads(request.body) - id = data['id'] - try: - websiteData = data['websiteData'] - except: - websiteData = 0 - try: - websiteDatabases = data['websiteDatabases'] - except: - websiteDatabases = 0 - try: - websiteEmails = data['websiteEmails'] - except: - websiteEmails = 0 + job_id = data['id'] - job = BackupJob.objects.get(pk=id) + backup_data = data['websiteData'] if 'websiteData' in data else 0 + backup_emails = data['websiteEmails'] if 'websiteEmails' in data else 0 + backup_databases = data['websiteDatabases'] if 'websiteDatabases' in data else 0 - job.websiteData = int(websiteData) - job.websiteDatabases = int(websiteDatabases) - job.websiteDataEmails = int(websiteEmails) + job = BackupJob.objects.get(pk=job_id) + + job.websiteData = int(backup_data) + job.websiteDatabases = int(backup_databases) + job.websiteDataEmails = int(backup_emails) job.save() final_json = json.dumps({'status': 1, 'error_message': "None"}) return HttpResponse(final_json) - - except BaseException as msg: final_json = json.dumps({'status': 0, 'error_message': str(msg)}) return HttpResponse(final_json) -def removeSite(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def remove_site(request): + try: + _, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) data = json.loads(request.body) - id = data['id'] + job_id = data['id'] website = data['website'] - - - job = BackupJob.objects.get(pk=id) - + job = BackupJob.objects.get(pk=job_id) site = JobSites.objects.get(job=job, website=website) site.delete() final_json = json.dumps({'status': 1, 'error_message': "None"}) return HttpResponse(final_json) - - except BaseException as msg: final_json = json.dumps({'status': 0, 'error_message': str(msg)}) return HttpResponse(final_json) -def addWebsite(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: +def add_website(request): + try: + _, current_acl = _get_user_acl(request) + if ACLManager.currentContextPermission(current_acl, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) data = json.loads(request.body) - id = data['id'] + job_id = data['id'] website = data['website'] - - job = BackupJob.objects.get(pk=id) + job = BackupJob.objects.get(pk=job_id) try: JobSites.objects.get(job=job, website=website) - except: + except BaseException: site = JobSites(job=job, website=website) site.save() final_json = json.dumps({'status': 1, 'error_message': "None"}) return HttpResponse(final_json) - - except BaseException as msg: final_json = json.dumps({'status': 0, 'error_message': str(msg)}) - return HttpResponse(final_json) \ No newline at end of file + return HttpResponse(final_json) diff --git a/README.md b/README.md index fa624628a..5ec273ceb 100755 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Webhosting control panel that uses OpenLiteSpeed as web server. * PHP 7.2 * PHP 7.3 * PHP 7.4 +* PHP 8.0 # Installation Instructions diff --git a/WebTerminal/CPWebSocket.py b/WebTerminal/CPWebSocket.py index 9c83e8a38..f7496c359 100644 --- a/WebTerminal/CPWebSocket.py +++ b/WebTerminal/CPWebSocket.py @@ -13,7 +13,7 @@ import json import threading as multi import time import asyncio - +from plogical.processUtilities import ProcessUtilities class SSHServer(multi.Thread): OKGREEN = '\033[92m' @@ -24,7 +24,8 @@ class SSHServer(multi.Thread): @staticmethod def findSSHPort(): try: - sshData = open('/etc/ssh/sshd_config', 'r').readlines() + + sshData = ProcessUtilities.outputExecutioner('cat /etc/ssh/sshd_config').split('\n') for items in sshData: if items.find('Port') > -1: diff --git a/WebTerminal/views.py b/WebTerminal/views.py index 145cfc3bf..282261770 100644 --- a/WebTerminal/views.py +++ b/WebTerminal/views.py @@ -7,6 +7,8 @@ from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging from loginSystem.views import loadLoginPage from random import randint import os + +from plogical.httpProc import httpProc from plogical.processUtilities import ProcessUtilities from plogical.firewallUtilities import FirewallUtilities from firewall.models import FirewallRules @@ -16,44 +18,32 @@ import plogical.randomPassword # Create your views here. def terminal(request): - try: - userID = request.session['userID'] - currentACL = ACLManager.loadedACL(userID) + password = plogical.randomPassword.generate_pass() - if currentACL['admin'] == 1: - pass - else: - return ACLManager.loadError() + verifyPath = "/home/cyberpanel/" + str(randint(100000, 999999)) + writeToFile = open(verifyPath, 'w') + writeToFile.write(password) + writeToFile.close() - password = plogical.randomPassword.generate_pass() + ## setting up ssh server + path = '/etc/systemd/system/cpssh.service' + curPath = '/usr/local/CyberCP/WebTerminal/cpssh.service' - verifyPath = "/home/cyberpanel/" + str(randint(100000, 999999)) - writeToFile = open(verifyPath, 'w') - writeToFile.write(password) - writeToFile.close() + if not os.path.exists(path): + command = 'mv %s %s' % (curPath, path) + ProcessUtilities.executioner(command) - ## setting up ssh server - path = '/etc/systemd/system/cpssh.service' - curPath = '/usr/local/CyberCP/WebTerminal/cpssh.service' + command = 'systemctl start cpssh' + ProcessUtilities.executioner(command) - if not os.path.exists(path): - command = 'mv %s %s' % (curPath, path) - ProcessUtilities.executioner(command) - - command = 'systemctl start cpssh' - ProcessUtilities.executioner(command) - - FirewallUtilities.addRule('tcp', '5678', '0.0.0.0/0') - - newFWRule = FirewallRules(name='terminal', proto='tcp', port='5678', ipAddress='0.0.0.0/0') - newFWRule.save() - - return render(request, 'WebTerminal/WebTerminal.html', {'verifyPath': verifyPath, 'password': password}) - except BaseException as msg: - logging.writeToFile(str(msg)) - return redirect(loadLoginPage) + FirewallUtilities.addRule('tcp', '5678', '0.0.0.0/0') + newFWRule = FirewallRules(name='terminal', proto='tcp', port='5678', ipAddress='0.0.0.0/0') + newFWRule.save() + proc = httpProc(request, 'WebTerminal/WebTerminal.html', + {'verifyPath': verifyPath, 'password': password}, 'admin') + return proc.render() def restart(request): try: diff --git a/backup/backupManager.py b/backup/backupManager.py index 6d0a93d50..c42b706d6 100755 --- a/backup/backupManager.py +++ b/backup/backupManager.py @@ -4,6 +4,8 @@ import os.path import sys import django +from plogical.httpProc import httpProc + sys.path.append('/usr/local/CyberCP') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") django.setup() @@ -39,43 +41,28 @@ class BackupManager: def loadBackupHome(self, request=None, userID=None, data=None): try: currentACL = ACLManager.loadedACL(userID) - return render(request, 'backup/index.html', currentACL) + proc = httpProc(request, 'backup/index.html', currentACL) + return proc.render() except BaseException as msg: return HttpResponse(str(msg)) def backupSite(self, request=None, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0: - return ACLManager.loadError() - - websitesName = ACLManager.findAllSites(currentACL, userID) - return render(request, 'backup/backup.html', {'websiteList': websitesName}) - except BaseException as msg: - return HttpResponse(str(msg)) + currentACL = ACLManager.loadedACL(userID) + websitesName = ACLManager.findAllSites(currentACL, userID) + proc = httpProc(request, 'backup/backup.html', {'websiteList': websitesName}, 'createBackup') + return proc.render() def gDrive(self, request=None, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - admin = Administrator.objects.get(pk=userID) - - if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0: - return ACLManager.loadError() - - gDriveAcctsList = [] - - gDriveAccts = admin.gdrive_set.all() - - for items in gDriveAccts: - gDriveAcctsList.append(items.name) - - websitesName = ACLManager.findAllSites(currentACL, userID) - - return render(request, 'backup/googleDrive.html', {'accounts': gDriveAcctsList, 'websites': websitesName}) - except BaseException as msg: - return HttpResponse(str(msg)) + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + gDriveAcctsList = [] + gDriveAccts = admin.gdrive_set.all() + for items in gDriveAccts: + gDriveAcctsList.append(items.name) + websitesName = ACLManager.findAllSites(currentACL, userID) + proc = httpProc(request, 'backup/googleDrive.html', {'accounts': gDriveAcctsList, 'websites': websitesName}, + 'createBackup') + return proc.render() def gDriveSetup(self, userID=None, request=None): try: @@ -356,32 +343,23 @@ class BackupManager: return HttpResponse(json_data) def restoreSite(self, request=None, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) + path = os.path.join("/home", "backup") + if not os.path.exists(path): + proc = httpProc(request, 'backup/restore.html', None, 'restoreBackup') + return proc.render() + else: + all_files = [] + ext = ".tar.gz" - if ACLManager.currentContextPermission(currentACL, 'restoreBackup') == 0: - return ACLManager.loadError() + command = 'sudo chown -R cyberpanel:cyberpanel ' + path + ACLManager.executeCall(command) - path = os.path.join("/home", "backup") - - if not os.path.exists(path): - return render(request, 'backup/restore.html') - else: - all_files = [] - ext = ".tar.gz" - - command = 'sudo chown -R cyberpanel:cyberpanel ' + path - ACLManager.executeCall(command) - - files = os.listdir(path) - for filename in files: - if filename.endswith(ext): - all_files.append(filename) - - return render(request, 'backup/restore.html', {'backups': all_files}) - - except BaseException as msg: - return HttpResponse(str(msg)) + files = os.listdir(path) + for filename in files: + if filename.endswith(ext): + all_files.append(filename) + proc = httpProc(request, 'backup/restore.html', {'backups': all_files}, 'restoreBackup') + return proc.render() def getCurrentBackups(self, userID=None, data=None): try: @@ -695,16 +673,8 @@ class BackupManager: return HttpResponse(final_json) def backupDestinations(self, request=None, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0: - return ACLManager.loadError() - - return render(request, 'backup/backupDestinations.html', {}) - - except BaseException as msg: - return HttpResponse(str(msg)) + proc = httpProc(request, 'backup/backupDestinations.html', {}, 'addDeleteDestinations') + return proc.render() def submitDestinationCreation(self, userID=None, data=None): try: @@ -726,7 +696,7 @@ class BackupManager: finalDic['port'] = "22" try: - finalDic['user'] = data['user'] + finalDic['user'] = data['userName'] except: finalDic['user'] = "root" @@ -868,31 +838,21 @@ class BackupManager: return HttpResponse(final_json) def scheduleBackup(self, request, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: - return ACLManager.loadError() - - destinations = NormalBackupDests.objects.all() - - dests = [] - - for dest in destinations: - dests.append(dest.name) - - websitesName = ACLManager.findAllSites(currentACL, userID) - - return render(request, 'backup/backupSchedule.html', {'destinations': dests, 'websites': websitesName}) - - except BaseException as msg: - return HttpResponse(str(msg)) + currentACL = ACLManager.loadedACL(userID) + destinations = NormalBackupDests.objects.all() + dests = [] + for dest in destinations: + dests.append(dest.name) + websitesName = ACLManager.findAllSites(currentACL, userID) + proc = httpProc(request, 'backup/backupSchedule.html', {'destinations': dests, 'websites': websitesName}, + 'scheduleBackups') + return proc.render() def getCurrentBackupSchedules(self, userID=None, data=None): try: currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('fetchStatus', 0) records = backupSchedules.objects.all() @@ -926,15 +886,17 @@ class BackupManager: selectedAccount = data['selectedAccount'] name = data['name'] backupFrequency = data['backupFrequency'] + backupRetention = data['backupRetention'] currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) nbd = NormalBackupDests.objects.get(name=selectedAccount) - config = {'frequency': backupFrequency} + config = {'frequency': backupFrequency, + 'retention': backupRetention} nbj = NormalBackupJobs(owner=nbd, name=name, config=json.dumps(config)) nbj.save() @@ -950,7 +912,7 @@ class BackupManager: try: currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) backupDest = data['destLoc'] @@ -1009,16 +971,8 @@ class BackupManager: return HttpResponse(final_json) def remoteBackups(self, request, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'remoteBackups') == 0: - return ACLManager.loadError() - - return render(request, 'backup/remoteBackups.html') - - except BaseException as msg: - return HttpResponse(str(msg)) + proc = httpProc(request, 'backup/remoteBackups.html', None, 'remoteBackups') + return proc.render() def submitRemoteBackups(self, userID=None, data=None): try: @@ -1371,25 +1325,12 @@ class BackupManager: return HttpResponse(json_data) def backupLogs(self, request=None, userID=None, data=None): - try: - currentACL = ACLManager.loadedACL(userID) - - if currentACL['admin'] == 1: - pass - else: - return ACLManager.loadError() - - all_files = [] - - logFiles = BackupJob.objects.all().order_by('-id') - - for logFile in logFiles: - all_files.append(logFile.logFile) - - return render(request, 'backup/backupLogs.html', {'backups': all_files}) - - except BaseException as msg: - return HttpResponse(str(msg)) + all_files = [] + logFiles = BackupJob.objects.all().order_by('-id') + for logFile in logFiles: + all_files.append(logFile.logFile) + proc = httpProc(request, 'backup/backupLogs.html', {'backups': all_files}, 'admin') + return proc.render() def fetchLogs(self, userID=None, data=None): try: @@ -1474,7 +1415,7 @@ class BackupManager: page = int(str(data['page']).strip('\n')) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) nbd = NormalBackupJobs.objects.get(name=selectedAccount) @@ -1526,6 +1467,11 @@ class BackupManager: except: frequency = 'Never' + try: + retention = config[IncScheduler.retention] + except: + retention = 'Never' + try: currentStatus = config[IncScheduler.currentStatus] except: @@ -1560,7 +1506,7 @@ class BackupManager: nbd = NormalBackupDests.objects.get(name=selectedAccount) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) allJobs = nbd.normalbackupjobs_set.all() @@ -1587,7 +1533,7 @@ class BackupManager: data = json.loads(request.body) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) selectedJob = data['selectedJob'] @@ -1648,7 +1594,7 @@ class BackupManager: nbj = NormalBackupJobs.objects.get(name=selectedJob) website = Websites.objects.get(domain=selectedWebsite) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) try: @@ -1676,14 +1622,16 @@ class BackupManager: selectedJob = data['selectedJob'] backupFrequency = data['backupFrequency'] + backupRetention = data['backupRetention'] nbj = NormalBackupJobs.objects.get(name=selectedJob) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) config = json.loads(nbj.config) config[IncScheduler.frequency] = backupFrequency + config[IncScheduler.retention] = backupRetention nbj.config = json.dumps(config) nbj.save() @@ -1710,7 +1658,7 @@ class BackupManager: nbj = NormalBackupJobs.objects.get(name=selectedJob) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) nbj.delete() @@ -1737,7 +1685,7 @@ class BackupManager: recordsToShow = int(data['recordsToShow']) page = int(str(data['page']).strip('\n')) - if ACLManager.currentContextPermission(currentACL, 'scheDuleBackups') == 0: + if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0: return ACLManager.loadErrorJson('scheduleStatus', 0) nbj = NormalBackupJobs.objects.get(name=selectedJob) diff --git a/backup/models.py b/backup/models.py index 0d4fdfc55..a9a4d1844 100755 --- a/backup/models.py +++ b/backup/models.py @@ -1,5 +1,3 @@ - - from django.db import models class DBUsers(models.Model): diff --git a/backup/static/backup/backup.js b/backup/static/backup/backup.js index 9105a96c5..92ccab6a5 100755 --- a/backup/static/backup/backup.js +++ b/backup/static/backup/backup.js @@ -6,6 +6,21 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) { + $(document).ready(function () { + $(".destinationHide").hide(); + $('#create-backup-select').select2(); + }); + + $('#create-backup-select').on('select2:select', function (e) { + var data = e.params.data; + $scope.websiteToBeBacked = data.text; + $(".destinationHide").show(); + getBackupStatus(); + populateCurrentRecords(); + $scope.destination = false; + $scope.runningBackup = true; + }); + $scope.destination = true; $scope.backupButton = true; $scope.backupLoading = true; @@ -43,7 +58,6 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) { }; - function getBackupStatus() { $scope.backupLoadingBottom = false; @@ -111,12 +125,10 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) { }; - $scope.destinationSelection = function () { $scope.backupButton = false; }; - function populateCurrentRecords() { var websiteToBeBacked = $scope.websiteToBeBacked; @@ -152,7 +164,6 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) { }; - $scope.createBackup = function () { var websiteToBeBacked = $scope.websiteToBeBacked; @@ -189,10 +200,8 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) { }; - $scope.deleteBackup = function (id) { - url = "/backup/deleteBackup"; var data = { @@ -1238,7 +1247,8 @@ app.controller('googleDrive', function ($scope, $http) { }; var data = { selectedAccount: $scope.selectedAccount, - backupFrequency: $scope.backupFrequency + backupFrequency: $scope.backupFrequency, + backupRetention: $scope.backupRetention, }; dataurl = "/backup/changeAccountFrequencygDrive"; @@ -1645,7 +1655,8 @@ app.controller('scheduleBackup', function ($scope, $http, $window) { var data = { selectedAccount: $scope.selectedAccountAdd, name: $scope.name, - backupFrequency: $scope.backupFrequency + backupFrequency: $scope.backupFrequency, + backupRetention: $scope.backupRetention, }; dataurl = "/backup/submitBackupSchedule"; @@ -1847,7 +1858,8 @@ app.controller('scheduleBackup', function ($scope, $http, $window) { }; var data = { selectedJob: $scope.selectedJob, - backupFrequency: $scope.backupFrequency + backupFrequency: $scope.backupFrequency, + backupRetention: $scope.backupRetention, }; dataurl = "/backup/changeAccountFrequencyNormal"; diff --git a/backup/templates/backup/backup.html b/backup/templates/backup/backup.html index 5d83cb414..86e35b2aa 100755 --- a/backup/templates/backup/backup.html +++ b/backup/templates/backup/backup.html @@ -22,14 +22,13 @@
-
- {% for items in websiteList %} {% endfor %} @@ -37,7 +36,7 @@
-
+
+ +
+
+
@@ -81,7 +91,7 @@

{% trans "Manage Existing Back up Schedules" %} + src="{% static 'images/loading.gif' %}" alt="cyberPanelLoading">

@@ -133,6 +143,7 @@ Last Run All Sites Frequency ({$ currently $}) + Retention ({$ currently $}) Current Status diff --git a/backup/templates/backup/index.html b/backup/templates/backup/index.html index f0cd19819..ca6869781 100755 --- a/backup/templates/backup/index.html +++ b/backup/templates/backup/index.html @@ -69,7 +69,7 @@ {% endif %} - {% if scheDuleBackups or admin %} + {% if scheduleBackups or admin %}
diff --git a/baseTemplate/static/baseTemplate/assets/finalLoginPageCSS/allCss.css b/baseTemplate/static/baseTemplate/assets/finalLoginPageCSS/allCss.css index 5c059ba8c..9b03e0ba8 100755 --- a/baseTemplate/static/baseTemplate/assets/finalLoginPageCSS/allCss.css +++ b/baseTemplate/static/baseTemplate/assets/finalLoginPageCSS/allCss.css @@ -1,55 +1,4109 @@ -pre,pre code{white-space:pre-wrap}.clear,.form-row:after,.row:after{clear:both}.btn-group-vertical>.btn:focus,.btn-group>.btn:focus,:active,:focus,:visited,a,a:active,a:focus,a:visited{outline:0}.xchart .color0 .line,.xchart .color0 circle,.xchart .color0.comp .line{stroke:#00bca4}.xchart .color0 .line .fill,.xchart .color1 .line .fill{pointer-events:none}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body,button,figure{margin:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-size:1em}q{quotes:'\201C''\201D''\2018''\2019'}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}button,input,select,textarea{font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}.collapsing,.divider,.overflow-hidden,.sr-only{overflow:hidden}table{border-spacing:0;border-collapse:collapse}@media print{blockquote,img,pre,tr{page-break-inside:avoid}*{color:#000!important;background:0 0!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:' (' attr(href)')'}abbr[title]:after{content:' (' attr(title)')'}.ir a:after,a[href^='javascript:']:after,a[href^='#']:after{content:''}blockquote,pre{border:1px solid #999}thead{display:table-header-group}img{max-width:100%!important}@page{margin:2cm .5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.jGrowl{display:none}}small{font-size:85%}a{text-decoration:none}html{font-size:62.5%;-webkit-tap-highlight-color:transparent}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.jqstooltip{box-sizing:content-box}.form-row,.row{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin-right:-10px;margin-left:-10px}.form-row:after,.form-row:before,.row:after,.row:before{display:table;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;content:' '}blockquote small,pre{line-height:1.428571429;display:block}[class*=col-]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:10px;padding-left:10px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media (min-width:768px){.boxed-layout #page-header,.boxed-layout #page-wrapper,.container{max-width:750px}.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media (min-width:992px){.boxed-layout #page-header,.boxed-layout #page-wrapper,.container{max-width:970px}.col-md-1,.col-md-10,.col-md-11,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media (min-width:1200px){.boxed-layout #page-header,.boxed-layout #page-wrapper,.container{max-width:1170px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}.row.no-gutter{margin-left:0;margin-right:0}.no-gutter>[class*=col-]{padding-left:0;padding-right:0}.pad5A{padding:5px!important}.pad5T{padding-top:5px!important}.pad5R{padding-right:5px!important}.pad5B{padding-bottom:5px!important}.pad5L{padding-left:5px!important}.pad10A{padding:10px!important}.pad10T{padding-top:10px!important}.pad10R{padding-right:10px!important}.pad10B{padding-bottom:10px!important}.pad10L{padding-left:10px!important}.pad15A{padding:15px!important}.pad15T{padding-top:15px!important}.pad15R{padding-right:15px!important}.pad15B{padding-bottom:15px!important}.pad15L{padding-left:15px!important}.pad20A{padding:20px!important}.pad20T{padding-top:20px!important}.pad20R{padding-right:20px!important}.pad20B{padding-bottom:20px!important}.pad20L{padding-left:20px!important}.pad25A{padding:25px!important}.pad25T{padding-top:25px!important}.pad25R{padding-right:25px!important}.pad25B{padding-bottom:25px!important}.pad25L{padding-left:25px!important}.pad45A{padding:45px!important}.pad45T{padding-top:45px!important}.pad45R{padding-right:45px!important}.pad45B{padding-bottom:45px!important}.pad45L{padding-left:45px!important}.pad0A{padding:0!important}.pad0T{padding-top:0!important}.pad0R{padding-right:0!important}.pad0B{padding-bottom:0!important}.pad0L{padding-left:0!important}.mrg5A{margin:5px!important}.mrg5T{margin-top:5px!important}.mrg5R{margin-right:5px!important}.mrg5B{margin-bottom:5px!important}.mrg5L{margin-left:5px!important}.mrg10A{margin:10px!important}.mrg10T{margin-top:10px!important}.mrg10R{margin-right:10px!important}.mrg10B{margin-bottom:10px!important}.mrg10L{margin-left:10px!important}.mrg15A{margin:15px!important}.mrg15T{margin-top:15px!important}.mrg15R{margin-right:15px!important}.mrg15B{margin-bottom:15px!important}.mrg15L{margin-left:15px!important}.mrg20A{margin:20px!important}.mrg20T{margin-top:20px!important}.mrg20R{margin-right:20px!important}.mrg20B{margin-bottom:20px!important}.mrg20L{margin-left:20px!important}.mrg25A{margin:25px!important}.mrg25T{margin-top:25px!important}.mrg25R{margin-right:25px!important}.mrg25B{margin-bottom:25px!important}.mrg25L{margin-left:25px!important}.mrg45A{margin:45px!important}.mrg45T{margin-top:45px!important}.mrg45R{margin-right:45px!important}.mrg45B{margin-bottom:45px!important}.mrg45L{margin-left:45px!important}.mrg0A{margin:0!important}.mrg0T{margin-top:0!important}.mrg0R{margin-right:0!important}.mrg0B{margin-bottom:0!important}.mrg0L{margin-left:0!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:500;margin:0}.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:400}.h1,h1{font-size:38px}.h2,h2{font-size:26px}.h3,h3{font-size:20px}.h4,h4{font-size:16px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}.h1 small,h1 small{font-size:24px}.h2 small,h2 small{font-size:18px}.h3 small,.h4 small,h3 small,h4 small{font-size:14px}h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:75%}blockquote{margin:0 0 20px;padding:10px 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:50;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right .small,blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right .small:before,blockquote.pull-right small:before{content:''}blockquote.pull-right .small:after,blockquote.pull-right small:after{content:'\00A0 \2014'}blockquote:after,blockquote:before{content:''}address{font-style:normal;line-height:1.428571429;margin-bottom:20px}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,'Courier New',monospace}code{font-size:90%;padding:0 4px;white-space:nowrap;color:#d05;border:1px solid #dfe8f1;border-radius:3px;background:#fafafa}pre{font-size:13px;margin:0 0 10px;padding:9.5px;word-wrap:break-word;word-break:break-all;color:#333;border:1px solid #ccc;border-radius:4px;background-color:#f5f5f5}pre code{font-size:inherit;padding:0;color:inherit;border-radius:0;background-color:transparent}.btn,.fc-button,.input-group-btn,.text-no-wrap{white-space:nowrap}p{line-height:1.6em;margin:0}.title-hero{margin:0 0 15px;padding:0;text-transform:uppercase;font-size:14px;opacity:.7}h4.title-hero{font-size:15px}.title-lead{color:#3F3F3F}.title-hero .title-lead{font-size:65%;margin:5px 0 0}.title-hero+.title-lead{margin-top:-10px}.jumbotron{font-size:21px;font-weight:200;line-height:2.1428571435;margin-bottom:30px;padding:30px;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.float-left,.pull-left{float:left!important}.float-right,.pull-right{float:right!important}.float-none{float:none!important}.font-size-10{font-size:10px!important}.font-size-11{font-size:11px!important}.font-size-12{font-size:12px!important}.font-size-13{font-size:13px!important}.font-size-14{font-size:14px!important}.font-size-15{font-size:15px!important}.font-size-16{font-size:16px!important}.font-size-17{font-size:17px!important}.font-size-18{font-size:18px!important}.font-size-20{font-size:20px!important}.font-size-23{font-size:23px!important}.font-size-26{font-size:26px!important}.font-size-28{font-size:28px!important}.font-size-35{font-size:35px!important}.font-size-50{font-size:50px!important}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-justify{text-align:justify}.text-transform-none{text-transform:none}.text-transform-upr{text-transform:uppercase}.text-transform-low{text-transform:lowercase}.text-transform-cap{text-transform:capitalize}.font-bold{font-weight:700!important}.btn,.fc-button,.font-normal{font-weight:400}.font-italic{font-style:italic}.font-none{font-style:none}.clear-none{clear:none!important}#page-wrapper:after,.btn-group:after,.btn-toolbar:after,.button-pane:after,.chat-box li:after,.clearfix:after,.comments-list li .panel-body:after,.container:after,.content-box-header:after,.example-box-wrapper:after,.files-box li:after,.form-horizontal .form-group:after,.form-input-prepend:after,.form-row:after,.info-box:after,.messages-box li:after,.nav-list li:after,.nav:after,.notifications-box li:after,.pager:after,.posts-list li:after,.tl-item:after,.tl-row:after,.todo-box li:after,.ui-datepicker-buttonpane:after,.ui-helper-clearfix:after{clear:both}.ui-front{z-index:100}.wrapper-sticky{z-index:15}.hide,.lazy,.mix,.tab-pane,[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}.tab-pane{padding:15px}.hidden,.ui-helper-hidden-accessible{display:none!important}.display-block{position:relative!important;display:block!important}.display-block .button-content{float:none}.display-block.dropdown-menu{position:static!important}.display-inline{display:inline-block}.no-border{border-color:transparent!important}.dropdown-menu.pad0A .hasDatepicker .ui-datepicker,.remove-border{border:0!important}.border-top{border-top-width:3px!important;border-top-style:solid!important}.width-100{box-sizing:border-box;width:100%}.center-margin{float:none!important;margin:0 auto}.center-block,.container{display:block;margin-right:auto;margin-left:auto}.center-vertical{position:relative;z-index:15;top:0;left:0;display:table;width:100%;height:100%}.center-vertical .center-content{display:table-cell;vertical-align:middle}.position-absolute{position:absolute}.show{display:block!important}.hidden{display:none!important;visibility:hidden!important}.invisible{visibility:hidden}.center-div{float:none!important;margin-right:auto!important;margin-left:auto!important;text-align:center!important}.btn-group>.btn-group,.btn-toolbar .btn-group,.btn-toolbar .input-group,.demo-icon{float:left}.divider,.nav-divider{ityity:.7;-moz-opacity:.7;filter:alpha(opacity: 70)}.divider{height:1px;margin:10px 0;padding:0}.divider-header{font-size:11px;padding:10px 15px;text-transform:uppercase;opacity:.2;color:#fff}.width-reset{width:auto!important}.opacity-10{opacity:.1!important;-moz-opacity:.1!important;filter:alpha(opacity: 10)!important}.info-box b,.info-box.icon-wrapper .icon-large,.opacity-30{opacity:.3!important;-moz-opacity:.3!important;filter:alpha(opacity: 30)!important}.opacity-40{opacity:.4!important;-moz-opacity:.4!important;filter:alpha(opacity: 40)!important}.info-box b,.label-description span,.opacity-60,.opacity-hover{opacity:.6!important;-moz-opacity:.6!important;filter:alpha(opacity: 60)!important}.no-shadow.transparent.btn:hover i,.opacity-80,.ui-datepicker-current.ui-priority-secondary{opacity:.8!important;-moz-opacity:.8!important;filter:alpha(opacity: 80)!important}.opacity-100,.opacity-hover:hover{opacity:1!important;-moz-opacity:1!important;filter:alpha(opacity: 100)!important}.btn-link .glyph-icon.opacity-hover{margin:0 -5px}.transparent{border-color:transparent!important;background:0 0!important;box-shadow:0 0 0 0 transparent!important}.no-shadow{box-shadow:0 0 0 transparent!important}.remove-bg{background:0 0}.nicescroll-rails{background:0 0!important}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}#loading,.login-img,.ui-widget-overlay{width:100%;height:100%}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:'';border-top:0;border-bottom:4px solid}.chosen-results,.form-wizard>ul,.nav-list ul,.nav-list-horizontal ul,.parsley-errors-list,.reset-ul,.tabs-navigation>ul,ul.messages-box,ul.notifications-box,ul.progress-box{margin:0;padding:0;list-style:none}#page-wrapper:after,#page-wrapper:before,.btn-group:after,.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.button-pane:after,.button-pane:before,.chat-box li:after,.chat-box li:before,.clearfix:after,.clearfix:before,.comments-list li .panel-body:after,.comments-list li .panel-body:before,.container:after,.container:before,.content-box-header:after,.content-box-header:before,.example-box-wrapper:after,.example-box-wrapper:before,.files-box li:after,.files-box li:before,.form-input-prepend:after,.form-input-prepend:before,.form-row:after,.form-row:before,.info-box:after,.info-box:before,.messages-box li:after,.messages-box li:before,.nav-list li:after,.nav-list li:before,.nav:after,.nav:before,.notifications-box li:after,.notifications-box li:before,.pager:after,.pager:before,.posts-list li:after,.posts-list li:before,.tl-item:after,.tl-item:before,.tl-row:after,.tl-row:before,.todo-box li:after,.todo-box li:before,.ui-datepicker-buttonpane:after,.ui-datepicker-buttonpane:before,.ui-helper-clearfix:after,.ui-helper-clearfix:before{display:table;content:''}.ui-sortable-placeholder{visibility:visible!important;border:1px dashed #efda2c!important;background:#fffce5!important}.daterangepicker td.available.in-range:hover,.daterangepicker td.in-range{background:#fffce5}.checker.disabled,.checker.disabled span,.chosen-disabled,.disabled,.radio.disabled,.radio.disabled span,.ui-rangeSlider-disabled .ui-rangeSlider-arrow,.ui-rangeSlider-disabled .ui-rangeSlider-container,.ui-rangeSlider-disabled .ui-rangeSlider-label,.ui-state-disabled,button[disabled]{cursor:not-allowed!important;opacity:.65;filter:alpha(opacity: 65)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control,input[disabled],select[disabled],textarea[disabled]{cursor:not-allowed;opacity:.65;background:#fafafa;filter:alpha(opacity: 65)}input[readonly],select[readonly],textarea[readonly]{opacity:.8;background:#fdfdfd;-moz-opacity:.8;filter:alpha(opacity: 80)}.login-img{position:fixed!important;top:0;left:0}.fixed-bg{background-repeat:no-repeat;background-attachment:fixed;background-position:center center;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}.ui-widget-overlay{position:fixed;left:0;top:0;bottom:0;right:0;text-align:center;z-index:16}.ui-widget-overlay img{position:absolute;top:50%;left:50%;margin:-26px 0 0 -26px}#loading{z-index:5555;position:fixed;left:0;top:0;background:#fff}.fade{-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.collapse{display:none}.collapse.in,.tab-pane.active{display:block}.collapsing{position:relative;height:0;-webkit-transition:height .35s ease;transition:height .35s ease}.small-padding{padding:25px 0}.medium-padding{padding:55px 0}.large-padding{padding:85px 0}.xlarge-padding{padding:115px 0}.glyph-icon{text-align:center}#page-sidebar li a.sf-with-ul:after,#page-sidebar li ul li a:before,.dataTables_paginate a i:before,.fc-icon,.glyph-icon:before,.search-choice-close:before,.ui-dialog-titlebar-close:before,.ui-icon:before{font-family:FontAwesome;font-weight:400;font-style:normal;display:inline-block;text-align:center;text-decoration:none;background:0 0;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{cursor:not-allowed;text-decoration:none;background-color:transparent;background-image:none;filter:progid: DXImageTransform.Microsoft.gradient(enabled=false)}.sr-only{position:absolute;clip:rect(0,0,0,0);width:1px;height:1px;margin:-1px;padding:0;border:0}.rm-transition{-webkit-transition:none!important;-moz-transition:none!important;-ms-transition:none!important;-o-transition:none!important}.btn,a,button,div[id^=uniform-] span{-webkit-transition:all .1s ease-in-out;-moz-transition:all .1s ease-in-out;-ms-transition:all .1s ease-in-out;-o-transition:all .1s ease-in-out}#page-header,#page-sidebar,.main-header,.top-bar{-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out}.example-box-wrapper{margin-bottom:15px;position:relative}.example-box-wrapper .ui-datepicker-inline{position:relative;width:100%}.panel-body .col-md-6 .example-box-wrapper:last-child,.panel-body .example-box-wrapper:last-child{margin-bottom:0}.example-box-wrapper .alert,.example-box-wrapper .content-box,.example-box-wrapper .dashboard-box,.example-box-wrapper .dataTables_wrapper,.example-box-wrapper .icon-box,.example-box-wrapper .image-box,.example-box-wrapper .jcrop-holder,.example-box-wrapper .jvectormap-container,.example-box-wrapper .list-group,.example-box-wrapper .loading-spinner,.example-box-wrapper .loading-stick,.example-box-wrapper .minicolors,.example-box-wrapper .nav,.example-box-wrapper .panel-layout,.example-box-wrapper .scrollable-content,.example-box-wrapper .tile-box,.example-box-wrapper .ui-accordion,.example-box-wrapper .ui-rangeSlider,.example-box-wrapper .ui-slider,.example-box-wrapper .ui-tabs,.example-box-wrapper>.btn,.example-box-wrapper>.btn-group,.example-box-wrapper>.btn-group-vertical,.example-box-wrapper>.btn-toolbar,.example-box-wrapper>.display-block.dropdown-menu,.example-box-wrapper>.dropdown,.example-box-wrapper>.dropup,.example-box-wrapper>.hasDatepicker,.example-box-wrapper>.img-humbnail,.example-box-wrapper>.minicolors,.example-box-wrapper>.pagination,.example-box-wrapper>.panel-layout,.example-box-wrapper>.progressbar,.example-box-wrapper>.thumbnail,.example-box-wrapper>form,.example-box-wrapper>h6,.example-box-wrapper>img{margin-bottom:20px}.demo-icon{font-size:22px;line-height:40px;width:40px;height:40px;margin:10px;text-align:center;color:#92A0B3;border:1px solid rgba(220,233,255,.54);border-radius:3px}.btn-block,.btn-group-justified,.btn-group-justified>.btn-group .btn,input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.demo-icon:hover{color:#59606c;border-color:#92A0B3}.font-black{color:#464646!important}.font-blue{color:#1f6dca!important}.font-blue-alt{color:#65a6ff!important}.font-azure{color:#41e5c0!important}.font-gray,.text-muted{color:#c2c2c2!important}.font-gray-dark,.text-info{color:#828282!important}.font-green,.text-success{color:#2ecc71!important}.font-orange,.text-warning{color:#fa7753!important}.font-yellow{color:#fc0!important}.font-purple{color:#984dff!important}.font-red,.has-error .help-block,.parsley-required,.text-danger{color:#ff5757!important}.font-white{color:#fff!important}.alert-info,.alert-info a{color:#6c6c6c;border-color:#c9c9c9;background:#dfe8f1}.alert-notice,.alert-notice a{color:#0f2c62;border-color:#62baf6;background:#c6e8ff}.alert-success,.alert-success a,.parsley-success{color:#1e620f;border-color:#7cd362;background:#d3ffc6}.parsley-success{background:#fff}.alert-warning,.alert-warning a,.warning{color:#624b0f;border-color:#ebc875;background:#ffeec6}.alert-danger,.alert-danger a,.danger,.parsley-error{color:#620f0f;border-color:#db6a6a;background:#ffc6c6}.bg-facebook,.bg-google,.bg-twitter{color:#fff!important}.parsley-error{background:#fff}.bg-facebook{background:#3b5998}.btn.bg-facebook:hover{background:#304b85}.bg-twitter{background:#3a92c8}.btn.bg-twitter:hover{background:#2b80b4}.bg-google{background:#dd4b39}.btn.bg-google:hover{background:#c93b2a}.badge-info,.bg-blue,.bootstrap-switch-info,.btn-info,.checkbox-info div[id^=uniform-] span.checked,.hover-blue:hover,.hover-info:hover,.label-info,.progress-bar-info,.radio-info div[id^=uniform-] span.checked{color:#fff;border-color:#308dcc;background:#3498db}.btn-info.active,.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info:active,.btn-info:focus,.btn-info:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,.label-info[href]:focus,.label-info[href]:hover,.open .dropdown-toggle.btn-info{color:#fff;border-color:#308dcc;background:#52a7e0}.badge-danger,.bg-danger,.bg-red,.bootstrap-switch-danger,.btn-danger,.checkbox-danger div[id^=uniform-] span.checked,.hover-danger:hover,.hover-red:hover,.label-danger,.progress-bar-danger,.radio-danger div[id^=uniform-] span.checked{color:#fff;border-color:#cf4436;background:#e74c3c}.btn-danger.active,.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,.label-danger[href]:focus,.label-danger[href]:hover,.open .dropdown-toggle.btn-danger{color:#fff;border-color:#cf4436;background:#eb6759}.badge-gray,.bg-gray,.btn-gray,.hover-gray:hover,.label-gray{color:#666;background:#efefef}.btn-gray.active,.btn-gray.disabled,.btn-gray.disabled.active,.btn-gray.disabled:active,.btn-gray.disabled:focus,.btn-gray.disabled:hover,.btn-gray:active,.btn-gray:focus,.btn-gray:hover,.btn-gray[disabled],.btn-gray[disabled].active,.btn-gray[disabled]:active,.btn-gray[disabled]:focus,.btn-gray[disabled]:hover,.label-gray[href]:focus,.label-gray[href]:hover,.open .dropdown-toggle.btn-gray{color:#333;background:#e7e7e7}.badge-gray-alt,.bg-gray-alt,.btn-gray-alt,.hover-gray-alt:hover,.label-gray-alt{color:#888;background:#f6f6f6}.btn-gray-alt.active,.btn-gray-alt.disabled,.btn-gray-alt.disabled.active,.btn-gray-alt.disabled:active,.btn-gray-alt.disabled:focus,.btn-gray-alt.disabled:hover,.btn-gray-alt:active,.btn-gray-alt:focus,.btn-gray-alt:hover,.btn-gray-alt[disabled],.btn-gray-alt[disabled].active,.btn-gray-alt[disabled]:active,.btn-gray-alt[disabled]:focus,.btn-gray-alt[disabled]:hover,.label-gray-alt[href]:focus,.label-gray-alt[href]:hover,.open .dropdown-toggle.btn-gray-alt{color:#444;background:#ededed}.badge-black,.bg-black,.btn-black,.hover-black:hover,.label-black{color:#ccc;border-color:#000;background:#2d2d2d}.boxed-layout.bg-black{background:#2d2d2d}.btn-black.active,.btn-black.disabled,.btn-black.disabled.active,.btn-black.disabled:active,.btn-black.disabled:focus,.btn-black.disabled:hover,.btn-black:active,.btn-black:focus,.btn-black:hover,.btn-black[disabled],.btn-black[disabled].active,.btn-black[disabled]:active,.btn-black[disabled]:focus,.btn-black[disabled]:hover,.label-black[href]:focus,.label-black[href]:hover,.open .dropdown-toggle.btn-black{color:#fdfdfd;background:#151515}.badge-black-opacity,.bg-black-opacity,.btn-black-opacity,.hover-black-opacity:hover,.label-black-opacity{color:#a9b3bb;background:#2b323d}.btn-black-opacity.active,.btn-black-opacity.disabled,.btn-black-opacity.disabled.active,.btn-black-opacity.disabled:active,.btn-black-opacity.disabled:focus,.btn-black-opacity.disabled:hover,.btn-black-opacity:active,.btn-black-opacity:focus,.btn-black-opacity:hover,.btn-black-opacity[disabled],.btn-black-opacity[disabled].active,.btn-black-opacity[disabled]:active,.btn-black-opacity[disabled]:focus,.btn-black-opacity[disabled]:hover,.label-black-opacity[href]:focus,.label-black-opacity[href]:hover,.open .dropdown-toggle.btn-black-opacity{color:#fff;background:#14171c}.badge-black-opacity-alt,.bg-black-opacity-alt,.btn-black-opacity-alt,.hover-black-opacity-alt:hover,.label-black-opacity-alt{color:#fff;background:rgba(0,0,0,.2);border-color:transparent}.btn-black-opacity-alt.active,.btn-black-opacity-alt.disabled,.btn-black-opacity-alt.disabled.active,.btn-black-opacity-alt.disabled:active,.btn-black-opacity-alt.disabled:focus,.btn-black-opacity-alt.disabled:hover,.btn-black-opacity-alt:active,.btn-black-opacity-alt:focus,.btn-black-opacity-alt:hover,.btn-black-opacity-alt[disabled],.btn-black-opacity-alt[disabled].active,.btn-black-opacity-alt[disabled]:active,.btn-black-opacity-alt[disabled]:focus,.btn-black-opacity-alt[disabled]:hover,.label-black-opacity-alt[href]:focus,.label-black-opacity-alt[href]:hover,.open .dropdown-toggle.btn-black-opacity-alt{color:#fff;background:rgba(0,0,0,.3)}.badge-success,.bg-green,.bootstrap-switch-success,.btn-success,.checkbox-success div[id^=uniform-] span.checked,.hover-green:hover,.hover-success:hover,.label-success,.progress-bar-success,.radio-success div[id^=uniform-] span.checked{color:#fff;border-color:#29b765;background:#2ecc71}.btn-success.active,.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success:active,.btn-success:focus,.btn-success:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,.label-success[href]:focus,.label-success[href]:hover,.open .dropdown-toggle.btn-success{color:#fff;border-color:#29b765;background:#58d68d}.badge-warning,.bg-orange,.bg-warning,.bootstrap-switch-warning,.btn-warning,.checkbox-warning div[id^=uniform-] span.checked,.hover-orange:hover,.hover-warning:hover,.label-warning,.progress-bar-warning,.radio-warning div[id^=uniform-] span.checked{color:#fff;border-color:#d67520;background:#e67e22}.btn-warning.active,.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,.label-warning[href]:focus,.label-warning[href]:hover,.open .dropdown-toggle.btn-warning{color:#fff;border-color:#d67520;background:#ea9143}.bg-white,.label-white,.table{background:#fff}.bg-white-opacity{background:rgba(255,255,255,.85)}.hover-white:hover{background:#fafafa}.badge-yellow,.bg-yellow,.btn-yellow,.hover-yellow:hover,.label-yellow{color:#fff;background:#fc0;border-color:#deb200}.btn-yellow.active,.btn-yellow.disabled,.btn-yellow.disabled.active,.btn-yellow.disabled:active,.btn-yellow.disabled:focus,.btn-yellow.disabled:hover,.btn-yellow:active,.btn-yellow:focus,.btn-yellow:hover,.btn-yellow[disabled],.btn-yellow[disabled].active,.btn-yellow[disabled]:active,.btn-yellow[disabled]:focus,.btn-yellow[disabled]:hover,.label-yellow[href]:focus,.label-yellow[href]:hover,.open .dropdown-toggle.btn-yellow{color:#fff;background:#e1b400;border-color:#c59e00}.badge-purple,.bg-purple,.btn-purple,.hover-purple:hover,.label-purple{color:#fff;background:#984dff;border-color:#7a3ecc}.btn-purple.active,.btn-purple.disabled,.btn-purple.disabled.active,.btn-purple.disabled:active,.btn-purple.disabled:focus,.btn-purple.disabled:hover,.btn-purple:active,.btn-purple:focus,.btn-purple:hover,.btn-purple[disabled],.btn-purple[disabled].active,.btn-purple[disabled]:active,.btn-purple[disabled]:focus,.btn-purple[disabled]:hover,.label-purple[href]:focus,.label-purple[href]:hover,.open .dropdown-toggle.btn-purple{color:#fff;background:#8134eb;border-color:#752fd6}.badge-blue-alt,.bg-blue-alt,.btn-blue-alt,.hover-blue-alt:hover,.label-blue-alt{color:#fff;background:#65a6ff;border-color:#5388d1}.btn-blue-alt.active,.btn-blue-alt.disabled,.btn-blue-alt.disabled.active,.btn-blue-alt.disabled:active,.btn-blue-alt.disabled:focus,.btn-blue-alt.disabled:hover,.btn-blue-alt:active,.btn-blue-alt:focus,.btn-blue-alt:hover,.btn-blue-alt[disabled],.btn-blue-alt[disabled].active,.btn-blue-alt[disabled]:active,.btn-blue-alt[disabled]:focus,.btn-blue-alt[disabled]:hover,.label-blue-alt[href]:focus,.label-blue-alt[href]:hover,.open .dropdown-toggle.btn-blue-alt{color:#fff;background:#478ded;border-color:#4c7ec1}.badge-azure,.bg-azure,.btn-azure,.hover-azure:hover,.label-azure{color:#fff;background:#41e5c0;border-color:#3acead}.btn-azure.active,.btn-azure.disabled,.btn-azure.disabled.active,.btn-azure.disabled:active,.btn-azure.disabled:focus,.btn-azure.disabled:hover,.btn-azure:active,.btn-azure:focus,.btn-azure:hover,.btn-azure[disabled],.btn-azure[disabled].active,.btn-azure[disabled]:active,.btn-azure[disabled]:focus,.btn-azure[disabled]:hover,.label-azure[href]:focus,.label-azure[href]:hover,.open .dropdown-toggle.btn-azure{color:#fff;background:#27d1ab;border-color:#24c19e}.border-black{border-color:#212121!important}.border-blue{border-color:#5bccf6!important}.border-blue-alt{border-color:#65a6ff!important}.border-azure{border-color:#41e5c0!important}.border-gray{border-color:#c2c2c2!important}.border-gray-dark{border-color:#828282!important}.border-green{border-color:#2ecc71!important}.border-orange{border-color:#fa7753!important}.border-yellow{border-color:#fc0!important}.border-purple{border-color:#984dff!important}.border-red{border-color:#ff5757!important}.parsley-success{border-color:#77e038!important}.parsley-error{border-color:#e03838!important}.btn,.fc-button{font-size:14px;position:relative;display:inline-block;padding:0 12px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:center;border-width:1px;border-style:solid;border-color:transparent;background-image:none;-o-user-select:none}.btn-alt,.content-box-header-alt{font-weight:700;text-transform:uppercase}.btn,.fc-button,.size-md{line-height:32px;height:34px;min-width:34px}.btn-abs{position:absolute;top:50%;right:0;margin-top:-17px}.btn.hover-round:hover{border-radius:100px}.btn-group-vertical>.btn:not(:first-child):not(:last-child),.btn-link{border-radius:0}.btn.active,.btn:active,.fc-state-active,.fc-state-down,.ui-datepicker .ui-datepicker-buttonpane button:active,.ui-datepicker .ui-datepicker-next:active,.ui-datepicker .ui-datepicker-prev:active,.ui-dialog .ui-dialog-titlebar-close:active,.ui-dialog-buttonset button:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],.disabled,.fc-state-disabled,fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;-webkit-box-shadow:none;box-shadow:none;filter:alpha(opacity=65)}.btn-link{cursor:pointer}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link:focus,.btn-link:hover{text-decoration:underline;background-color:transparent}.btn-border:hover,.pager li>a:focus,.pager li>a:hover{text-decoration:none}.btn-group-lg>.btn,.btn-lg,.size-lg{line-height:44px;min-width:56px;height:46px}.btn-lg-abs{margin-top:-23px}.btn-group-lg>.btn,.btn-lg{font-size:18px;padding:0 16px}.btn-group-sm>.btn,.btn-sm,.size-sm{line-height:28px;height:30px}.btn-sm-abs{margin-top:-15px}.btn-group-sm>.btn,.btn-sm{font-size:13px;padding:0 10px}.btn-group-xs>.btn,.btn-xs,.size-xs{line-height:20px;min-width:22px;height:22px}.btn-xs-abs{margin-top:-11px}.btn-group-xs>.btn,.btn-xs{font-size:11px;padding:0 5px}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-block{display:block;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:10px}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-justified{display:table;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:3px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn,.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn,.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle,.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child,.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.pagination{display:inline-block;padding-left:0}.pager li,.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{line-height:1.42857143;position:relative;float:left;margin-left:-1px;padding:6px 12px;text-decoration:none;border-width:1px;border-style:solid}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0}.pagination-lg>li>a,.pagination-lg>li>span{font-size:18px;padding:10px 16px}.pagination-sm>li>a,.pagination-sm>li>span{font-size:12px;padding:5px 10px}.pager{margin-top:0;padding-left:0;list-style:none;text-align:center}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;border:1px solid #ddd;border-radius:15px;background-color:#fff}.btn>.icon-separator,.icon-separator.float-right{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{cursor:not-allowed;color:#999;background-color:#fff}.btn>.icon-separator{position:absolute;top:0;left:0;width:32px;height:100%;border-top-right-radius:0!important}.icon-separator+.button-content{margin-left:32px}.btn-xs .icon-separator{width:22px}.btn-xs .icon-separator+.button-content{margin-left:22px}.btn-sm .icon-separator{width:25px}.btn-sm .icon-separator+.button-content{margin-left:25px}.btn-lg .icon-separator{width:44px}.btn-lg .icon-separator+.button-content{margin-left:44px}.icon-separator.float-right{border-top-left-radius:0!important}.vertical-button{line-height:1.6em;height:auto;padding:10px 0 5px}.vertical-button .button-content{opacity:.7;filter:alpha(opacity=70)}.icon-separator-vertical{font-size:25px;display:block;margin:5px auto}.dashboard-buttons .btn{width:93px;margin:5px 3px}.btn-outline,.btn-outline-inverse{display:inline-block;text-align:center;color:#fff;box-sizing:initial;border-width:2px;border-style:solid;text-transform:uppercase}.btn-outline-inverse{border-color:rgba(255,255,255,.47)}.btn-outline-inverse:hover{background:rgba(255,255,255,.2);border-color:#fff}.btn-outline-inverse.hero-btn{color:#fff}.btn-outline{color:rgba(0,0,0,.8);border-color:rgba(0,0,0,.6)}.btn-outline:hover{color:#fff;border-color:rgba(0,0,0,.8);background:rgba(0,0,0,.8)}.btn.btn-round{border-radius:150px;padding:0}.btn-round.btn-lg{width:46px;min-width:46px}.btn-round.btn-xlg{width:66px;min-width:66px;height:66px;line-height:66px}.btn-round.btn-xlg .glyph-icon{font-size:24px}.btn-round.btn-md{width:34px}.btn-round.btn-sm{width:30px}.btn-round.btn-xs{width:22px}.btn-alt{font-size:12px}.btn-hover span{padding:0 20px;left:0;position:relative;transition:opacity .2s ease-out,left .2s ease-out;-webkit-transition:opacity .2s ease-out,left .2s ease-out}.btn-hover .glyph-icon{opacity:0;-ms-filter:"alpha(opacity=0)";position:absolute;right:20px;transition:all .2s ease-out;-webkit-transition:all .2s ease-out}.btn-hover:hover .glyph-icon{opacity:1;right:15px;-ms-filter:"alpha(opacity=100)"}.btn-hover:hover span{left:-15px}.btn-border{border-width:2px;border-style:solid}.btn-border span{opacity:.75;filter:alpha(opacity=75)}.btn-border:hover span{opacity:1;filter:alpha(opacity=100)}.btn-group-justified>.btn,.btn-group-justified>.btn-group{width:auto}.demo-margin .btn{margin-bottom:10px}.content-box{background:#fff;margin-bottom:20px}.content-box,.content-box-header{position:relative;border-width:1px;border-style:solid}.content-box-header{font-size:14px;text-transform:uppercase;margin:-1px -1px 0;padding:15px;border-color:transparent}.content-box-header small+.font-size-11.float-right{position:absolute;top:14px;right:10px}.content-box-header-alt{padding:15px 10px 14px;font-size:12px}.content-box-header-alt small{font-size:13px;font-weight:400;display:block;padding:5px 0 0;text-transform:none;opacity:.7;filter:alpha(opacity: 70)}.content-box .ui-widget-overlay{position:absolute}.content-box .ui-widget-overlay img{position:absolute;top:50%;left:50%;margin:-27px 0 0 -27px}.content-box .content-box-wrapper{line-height:1.6em;padding:15px}.content-box .content-box-wrapper .scrollable-content,.content-box .content-box-wrapper p:last-child{margin-bottom:0}.content-box .content-box-header>.glyph-icon{margin-right:5px;opacity:.7;filter:alpha(opacity: 70)}.content-box-header-alt .icon-separator .glyph-icon,.content-box-header-alt>.glyph-icon{font-size:22px;line-height:30px;position:absolute;top:50%;left:15px;width:30px;height:30px;margin-top:-15px}.content-box-header>.icon-separator{position:relative;top:1px;left:-15px;padding:18px 15px 16px;text-align:center}.content-box-header>.icon-separator .glyph-icon{margin-left:3px}.content-box-header-alt>.header-wrapper{overflow:hidden;display:block;margin-left:40px}.content-box-header-alt>.icon-separator+.header-wrapper{margin-left:65px}.content-box-header-alt>.icon-separator{position:absolute;top:0;left:0;width:60px;height:100%}.content-box-header-alt>.icon-separator .glyph-icon{left:50%;margin-left:-15px}.header-buttons{position:absolute;top:0;right:10px;height:100%;display:block}.header-buttons .btn-xs{top:13px}.header-buttons .btn-sm{top:10px}.header-buttons .btn-sm:last-child{margin-right:0}.header-buttons>.btn-group:last-child{margin-right:-2px}.content-box-header-alt .header-buttons .btn-xs{top:24px}.content-box-header-alt .header-buttons .btn-sm{top:20px}.content-box-header-alt .header-buttons .btn-sm:last-child{margin-right:5px}.header-buttons-separator{position:absolute;top:0;right:0;height:100%}.header-buttons-separator .icon-separator{top:0;left:0;display:block;float:left;min-width:20px;height:100%;padding:0 10px}.header-buttons-separator .icon-separator .glyph-icon{line-height:30px;position:relative;top:50%;display:block;min-width:30px;height:30px;margin:-15px 0 0;text-align:center}.header-buttons>.btn-group{margin-top:8px}.header-buttons .btn-group-xs{margin-top:14px}.header-buttons .btn-group-xs:last-child{margin-right:0}.ui-dialog-buttonpane,body .button-pane{padding:10px;text-align:center;border-width:1px 0 0;border-style:solid;border-top-left-radius:0;border-top-right-radius:0}body .button-pane-top{border-width:0 0 1px;border-radius:0}.scrollable-content{overflow-y:scroll;overflow-x:hidden;height:300px;padding-right:0}.scrollable-xs{overflow-y:scroll;height:200px}.scrollable-sm{overflow-y:scroll;height:400px}.scrollable-lg{overflow-y:scroll;height:500px}.toggle-button .glyph-icon{-webkit-transition-duration:.5s;-moz-transition-duration:.5s;-o-transition-duration:.5s;transition-duration:.5s;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;transition-property:transform}.hidden-button .content-box-header .btn,.hidden-button .content-box-header a,.hidden-button .content-box-header button{display:none}.content-box.border-top .content-box-header{font-size:18px;margin:0}.content-box.border-top .content-box-header small{opacity:.8;-moz-opacity:.8;filter:alpha(opacity: 80)}.content-box.border-top .content-box-header+.content-box-wrapper{padding-top:0}.box-xs{width:200px}.box-sm{width:324px}.box-md{width:400px}.box-lg{width:500px}.content-box-header>.ui-tabs-nav{position:absolute;top:2px;right:0;padding:0;list-style:none;border:0}.content-box-header>.ui-tabs-nav li>a{line-height:49px;height:49px;margin:0 2px;color:rgba(255,255,255,.7);border:0;background:0 0}.content-box-header>.ui-tabs-nav li>a:hover{color:#fff;background:rgba(255,255,255,.2)}.panel-heading>.dropdown .dropdown-toggle,.panel-title,.panel-title>a{color:inherit}.content-box-header.bg-default>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a,.content-box-header.bg-default>.ui-tabs-nav li.ui-tabs-active>a,.content-box-header.bg-gray>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a,.content-box-header.bg-gray>.ui-tabs-nav li.ui-tabs-active>a,.content-box-header.bg-white>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a,.content-box-header.bg-white>.ui-tabs-nav li.ui-tabs-active>a{line-height:46px;height:46px;background:#F6F6F9}.content-box-header.bg-default>.ui-tabs-nav li>a,.content-box-header.bg-gray>.ui-tabs-nav li>a,.content-box-header.bg-white>.ui-tabs-nav li>a{line-height:50px;height:50px;margin:0;border-radius:0}.content-box-header.bg-default>.ui-tabs-nav,.content-box-header.bg-gray>.ui-tabs-nav,.content-box-header.bg-white>.ui-tabs-nav{top:0}.content-box-header>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a,.content-box-header>.ui-tabs-nav li.ui-tabs-active>a{line-height:47px;height:49px;background:#fff}.panel{margin-bottom:20px;border-width:1px;border-style:solid;border-radius:4px;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-title,.panel>.list-group{margin-bottom:0}.panel-body{padding:15px 20px;position:relative}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent}.panel-title{font-size:16px;margin-top:0}.panel-footer{padding:10px 15px;border-top:1px solid transparent}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel-group .panel-heading,.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel-group{margin-bottom:20px}.panel-group .panel{overflow:hidden;margin-bottom:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid transparent}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid transparent}fieldset,legend{padding:0;border:0}fieldset{margin:0}legend{font-size:21px;line-height:inherit;display:block;width:100%;margin-bottom:20px;color:#333;border-bottom:1px solid #dfe8f1}label{font-weight:700;display:inline-block}.checkbox,.radio,input[type=file],output{display:block}input[type=checkbox],input[type=radio]{line-height:normal}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}output{font-size:14px;line-height:1.428571429;padding-top:7px;vertical-align:middle;color:#555}.bootstrap-timepicker-widget table td input,.chosen-container-multi,.chosen-container-single .chosen-search input,.dataTables_length select,.form-control,.input,.ui-toolbar input,.ui-toolbar select,div.dataTables_filter input{font-size:13px;display:block;float:none;background:#fff;width:100%;height:34px;padding:6px 12px;color:#2b2f33;border:1px solid #dfe8f1;-webkit-box-shadow:inset 1px 1px 3px #f6f6f6;-moz-box-shadow:inset 1px 1px 3px #f6f6f6;box-shadow:inset 1px 1px 3px #f6f6f6}.chosen-container-multi.chosen-with-drop.chosen-container-active{border:1px solid #ddd;border-bottom-right-radius:0;border-bottom-left-radius:0;box-shadow:0 0 0 transparent}.bootstrap-timepicker-widget table td input:focus,.chosen-container-active,.chosen-container-multi.chosen-container-active,.form-control:focus,.input:focus,.selector.focus,.ui-toolbar input:focus,.ui-toolbar select:focus,div.dataTables_filter input:focus{color:#333;border-color:#3da6ff}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.form-group label{margin-bottom:5px}.form-group .switch-toggle{margin-top:6px}.checkbox,.radio{min-height:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.checkbox label,.radio label{font-weight:400;display:inline;margin-bottom:0;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{float:left}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{font-weight:400;line-height:19px;display:inline-block;height:19px;margin-bottom:0;cursor:pointer;vertical-align:middle}.checkbox-inline label,.radio-inline label{font-weight:400;line-height:17px}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.checkbox-inline[disabled],.checkbox[disabled],.radio-inline[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.input-sm{font-size:12px;line-height:1.5;height:30px;padding:5px 10px;border-radius:3px}select.input-sm{line-height:30px;height:30px}textarea.input-sm{height:auto}.input-lg{font-size:18px;line-height:1.33;height:45px;padding:10px 16px;border-radius:6px}select.input-lg{line-height:45px;height:45px}textarea.input-lg{height:auto}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:0;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{float:none;margin-left:0}.form-horizontal .control-label{text-align:right}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .radio-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal>.form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:after,.form-horizontal .form-group:before{display:table;content:' '}.form-horizontal .form-control-static{padding-top:7px}.input-group{position:relative;display:table;width:100%;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{font-size:18px;line-height:1.33;height:45px;padding:10px 16px;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{line-height:45px;height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{font-size:12px;line-height:1.5;height:30px;padding:5px 10px;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{line-height:30px;height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon div[id^=uniform-]{margin:0 -3px}.input-group-addon,.input-group-btn{width:1%;vertical-align:middle;white-space:nowrap}.input-group-addon{font-size:14px;font-weight:400;line-height:1;padding:6px 12px;text-align:center;color:#2b2f33;background-color:rgba(239,244,246,.36);border:1px solid #dfe8f1;border-radius:4px}body,label{color:#3e4855}.input-group-addon .glyph-icon{display:block;min-width:20px;margin:0 -4px;text-align:center}.input-group-addon.addon-inside{line-height:24px;position:absolute;top:5px;left:6px;display:block;width:32px;height:24px;padding:0;border-width:1px;border-style:solid}.input-group-btn,.input-group-btn>.btn,.ui-spinner{position:relative}.input-group-lg .input-group-addon.addon-inside{top:10px;left:10px;z-index:999}.input-group-addon.addon-inside .glyph-icon{margin:0}.input-group-addon.addon-inside+input{padding-left:48px}.input-group-addon.input-sm{font-size:12px;padding:5px 10px;border-radius:3px}.input-group-addon.input-lg{font-size:18px;padding:10px 16px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group-addon.addon-inside:first-child{border-right-width:1px;border-right-style:solid;border-color:transparent;z-index:999}.input-group-addon+.form-control,.input-group-addon:last-child,.input-group-btn+.form-control,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn:first-child>.btn{margin-right:-1px}.input-group-btn:last-child>.btn{margin-left:-1px}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:active,.input-group-btn>.btn:hover{z-index:2}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}textarea.textarea-autoresize,textarea.textarea-no-resize{resize:none}.textarea-autosize{transition:height .3s;-webkit-transition:height .3s;-moz-transition:height .3s}textarea.form-control{line-height:1.6em;padding:8px 12px}textarea.textarea-xs{height:50px}textarea.textarea-sm{height:125px}textarea.textarea-md{height:200px}textarea.textarea-lg{height:275px}.ui-spinner{display:block}.xchart .color0.comp .fill,.xchart .color1.comp .fill{display:none}.ui-spinner .ui-spinner-button{font-size:9px;line-height:17px;position:absolute;right:0;width:17px;height:17px;cursor:pointer;text-align:center;border-width:1px;border-style:solid}.ui-spinner .ui-spinner-up{top:0}.ui-spinner .ui-spinner-down{bottom:0}.parsley-errors-list li{font-size:12px;padding-top:5px}.bordered-row>.form-group{padding:20px 0;margin-bottom:0;border-top-width:1px;border-top-style:dashed}.bordered-row>.form-group:last-child{padding-bottom:0}.form-group .ui-slider{margin-top:14px}.form-group .ui-slider+.input-group{margin-top:20px}body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;background-color:#fff;line-height:1.42857143}#page-title>h2,#page-title>p,h1,h2,h3,h4,h5,h6{font-family:Raleway,"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}#page-header .user-account-btn>a.user-profile .glyph-icon,.logo-bg{background-color:rgba(255,255,255,.1);color:#fff}#page-header .user-account-btn>a.user-profile{color:#fff}#header-nav-right .dropdown>a .glyph-icon,#header-nav-right .header-btn .glyph-icon{color:rgba(255,255,255,.8)}#header-nav-right .dropdown>a:hover .glyph-icon,#header-nav-right .header-btn:hover .glyph-icon{color:rgba(255,255,255,.95)}#header-nav-right .dropdown>a,#header-nav-right .header-btn{border-color:rgba(255,255,255,.2)}#header-nav-right .dropdown>a:hover,#header-nav-right .header-btn:hover{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.25)}#page-content{background:#fafcfe}#page-sidebar ul li.header{color:#000}#page-sidebar ul li a .glyph-icon{color:#0093d9}#page-sidebar ul li a:hover,#page-sidebar ul li.sfHover>a.sf-with-ul{border-color:#d1d9dd}#sidebar-menu li .sidebar-submenu{border-color:#f6f7f8}#sidebar-menu li .sidebar-submenu ul li{border-color:#f8f9fa}#sidebar-menu li .sidebar-submenu ul li a.sfActive,#sidebar-menu li .sidebar-submenu ul li a:hover{background:#fcfdfe}#sidebar-menu li .sidebar-submenu ul li a.sfActive{color:#1c82e1}#page-sidebar.font-inverse ul li.header{color:rgba(255,255,255,.95)}#page-sidebar.font-inverse ul li.divider{background:rgba(255,255,255,.1)}#page-sidebar.font-inverse #sidebar-menu>li>a{color:rgba(255,255,255,.62)}#page-sidebar.font-inverse #sidebar-menu li a:hover,#page-sidebar.font-inverse #sidebar-menu li.sfHover>a.sf-with-ul{border-color:rgba(255,255,255,.26);color:rgba(255,255,255,.96)}#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu{border-color:rgba(255,255,255,.08);background:rgba(255,255,255,.05)}#page-sidebar.font-inverse #sidebar-menu li a{color:rgba(255,255,255,.62)}#page-sidebar.font-inverse #sidebar-menu li a:hover{color:rgba(255,255,255,.96)}#page-sidebar.font-inverse#page-sidebar ul li a .glyph-icon{color:rgba(255,255,255,.8)}#page-sidebar.font-inverse#page-sidebar ul li a:hover .glyph-icon{color:rgba(255,255,255,1);opacity:.9;-moz-opacity:.9;filter:alpha(opacity: 90)}#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu ul li{border-color:rgba(255,255,255,.07)}#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu ul li a:hover{background:rgba(255,255,255,.05)}.btn-link,.chosen-disabled .chosen-single,.content-box-header.bg-default>.ui-tabs-nav li>a,.content-box-header.bg-gray>.ui-tabs-nav li>a,.content-box-header.bg-white>.ui-tabs-nav li>a,.content-box-header>.ui-tabs-nav li.ui-tabs-active>a,.pagination>li>a,.pagination>li>span,.table,a,body .content-box-header>.ui-tabs-nav li.ui-tabs-active>a:hover,div.selector{color:#8da0aa}#page-sidebar ul li.sfHover>a.sf-with-ul,.btn-link:hover,.content-box-header.bg-default>.ui-tabs-nav li>a:hover,.content-box-header.bg-gray>.ui-tabs-nav li>a:hover,.content-box-header.bg-white>.ui-tabs-nav li>a:hover,.features-tour-box h3,.font-primary,.tabs-nav li a:hover,.tabs-nav li.active a,a:hover,table.dataTable thead th.sorting_asc:after,table.dataTable thead th.sorting_desc:after{color:#1c82e1}.border-primary,.btn-primary,.nav>li.active>a,.nav>li.active>a:focus,.nav>li.active>a:hover,.ui-accordion .ui-accordion-header.ui-accordion-header-active,.ui-datepicker .ui-datepicker-next,.ui-datepicker .ui-datepicker-prev,.ui-dialog-buttonset button,.ui-spinner .ui-spinner-button:hover,a.list-group-item.active,a.list-group-item.active:focus,a.list-group-item.active:hover,a.thumbnail:hover,div[id^=uniform-] span.checked,li.active a.list-group-item,li.active a.list-group-item:focus,li.active a.list-group-item:hover{border-color:#00a792}a:focus{outline:0!important}#loadingbar,#nav-toggle span:after,#nav-toggle span:before,#nav-toggle.collapsed span,.badge-primary,.bg-primary,.bootstrap-switch-primary,.btn-primary,.chosen-container .chosen-results li.active-result.highlighted,.daterangepicker .ranges li.active,.daterangepicker .ranges li.active:hover,.fc-event,.form-wizard>ul>li.active .wizard-step,.irs-line-left,.irs-line-mid,.irs-line-right,.label-primary,.ms-hover.ui-state-focus,.ms-list .ms-hover,.nav>li.active>a,.nav>li.active>a:focus,.nav>li.active>a:hover,.owl-controls .owl-page span,.ui-accordion-header.ui-accordion-header-active,.ui-datepicker .ui-datepicker-current-day a,.ui-datepicker .ui-datepicker-current-day span,.ui-datepicker .ui-datepicker-next,.ui-datepicker .ui-datepicker-prev,.ui-dialog-buttonset button,.ui-menu li>a:hover,.ui-rangeSlider-bar,.ui-slider-handle,.ui-spinner .ui-spinner-button:hover,.ui-tabs-nav li.ui-state-active.ui-state-hover>a,.ui-tabs-nav li.ui-state-active>a,a.list-group-item.active,a.list-group-item.active:focus,a.list-group-item.active:hover,div.switch-toggle.switch-on,div[id^=uniform-] span.checked,li.active a.list-group-item,li.active a.list-group-item:focus,li.active a.list-group-item:hover{color:#fff;background:#00bca4}.font-secondary,.inverse.carousel-wrapper .owl-controls .owl-buttons .owl-next,.inverse.carousel-wrapper .owl-controls .owl-buttons .owl-prev,.post-box .post-title{color:#00bca4}.post-box .post-title:hover{color:#3e4855}.bg-default,.bg-white.dashboard-box .button-pane,.bg-white.tile-box .tile-footer,.border-default,.bordered-row .form-group,.btn-default,.button-pane,.chosen-container,.chosen-container .chosen-drop,.chosen-container-active.chosen-with-drop .chosen-single div,.chosen-container-multi .chosen-choices li.search-choice,.chosen-container-single .chosen-single div,.content-box,.content-box-header.bg-default,.content-box-header.bg-gray,.content-box-header.bg-white,.dashboard-buttons .btn,.daterangepicker .calendar-date,.dropdown-menu,.email-body,.fc-state-default,.fc-widget-content,.fc-widget-header,.img-thumbnail,.jvectormap-label,.jvectormap-zoomin,.jvectormap-zoomout,.list-group-item,.mail-toolbar,.mailbox-wrapper .nav-list li a,.minicolors-panel,.ms-container .ms-list,.ms-container .ms-selectable li.ms-elem-selectable,.ms-container .ms-selection li.ms-elem-selection,.nav .open>a,.nav .open>a:focus,.nav .open>a:hover,.nav-tabs,.nav-tabs>li>a:focus,.nav-tabs>li>a:hover,.pagination>li>a,.pagination>li>span,.panel,.panel-box.bg-default,.panel-box.bg-gray,.panel-box.bg-white,.panel-content.bg-default,.panel-content.bg-gray,.panel-content.bg-white,.panel-footer,.panel-group .panel-footer+.panel-collapse .panel-body,.panel-group .panel-heading+.panel-collapse .panel-body,.panel-heading,.popover,.popover-title,.posts-list li,.selector i,.table-bordered,.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th,.tabs-navigation>ul,.tabs-navigation>ul li.ui-state-hover>a,.tabs-navigation>ul li>a,.thumb-pane,.thumbnail,.timeline-box .tl-item .popover,.timeline-box:before,.ui-accordion .ui-accordion-header,.ui-datepicker,.ui-datepicker .ui-datepicker-buttonpane button,.ui-datepicker-buttonpane,.ui-dialog,.ui-dialog .ui-dialog-titlebar,.ui-dialog-buttonpane,.ui-menu,.ui-spinner .ui-spinner-button,.ui-tabs-nav,div.selector,div[id^=uniform-] span{border-color:#dfe8f1}.divider,.nav-divider,.timeline-horizontal.timeline-box:before{background:#dfe8f1}.content-box.border-top{border-right-color:#dfe8f1!important;border-bottom-color:#dfe8f1!important;border-left-color:#dfe8f1!important}.bg-default,.bg-white.dashboard-box .button-pane,.bg-white.tile-box .tile-footer,.bootstrap-switch-default,.btn-default,.button-pane,.jvectormap-label,.jvectormap-zoomin,.jvectormap-zoomout,.label-default,.mail-toolbar,.panel-footer,.panel-heading,.popover-title,.ui-accordion-header,.ui-datepicker td a,.ui-datepicker td span,.ui-dialog .ui-dialog-titlebar,.ui-spinner .ui-spinner-button,div[id^=uniform-] span{color:#555a60;background-color:#FEFEFF}.irs-diapason,.ui-datepicker-buttonpane,.ui-dialog-buttonpane,.ui-rangeSlider-container,.ui-slider-range{background-color:#FEFEFF}.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>th{color:#4b5056;background-color:#f9fafe}.btn-default.active,.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default:active,.btn-default:focus,.btn-default:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,.fc-state-active,.fc-state-disabled,.fc-state-down,.fc-state-hover,.jvectormap-zoomin:hover,.jvectormap-zoomout:hover,.open .dropdown-toggle.btn-default,.open.dropdown-submenu a,.ui-accordion-header.ui-state-hover,.ui-datepicker .ui-datepicker-buttonpane button:hover,.ui-tabs-nav>li.ui-state-hover>a{color:#2b2f33;border-color:#bfc8d1;background-color:#f3f3f9}.btn-default.active .glyph-icon{color:#2b2f33!important}.bsdatepicker td span:hover,.bsdatepicker td.active,.bsdatepicker td.day.active:hover,.bsdatepicker th.next:hover,.bsdatepicker th.prev:hover,.btn-primary.active,.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,.daterangepicker .calendar th.next:hover,.daterangepicker .calendar th.prev:hover,.daterangepicker td.active,.daterangepicker td.available.active:hover,.hover-primary:hover,.label-primary[href]:focus,.label-primary[href]:hover,.open .dropdown-toggle.btn-primary,.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover,.ui-accordion-header.ui-accordion-header-active.ui-state-hover,.ui-datepicker .ui-datepicker-next.ui-state-hover,.ui-datepicker .ui-datepicker-prev.ui-state-hover,.ui-datepicker td a:hover,.ui-dialog-buttonset button:hover,.ui-rangeSlider-bar:active,.ui-rangeSlider-bar:hover,.ui-slider-handle.ui-state-active,.ui-slider-handle.ui-state-hover{color:#fff;border-color:#00b19b;background-color:#00ceb4}.bsdatepicker td span,.bsdatepicker td.day:hover,.bsdatepicker thead tr:first-child th.switch:hover,.chosen-container-multi .chosen-choices li.search-choice,.chosen-container-single .chosen-single div,.daterangepicker .ranges li:hover,.daterangepicker td.available:hover,.nav>li>a:focus,.nav>li>a:hover,.pager li>a:focus,.pager li>a:hover,.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover,.selector i,.ui-datepicker-title,a.list-group-item:focus,a.list-group-item:hover{color:#2b2f33;background:#eff4f6}.pager li>a:focus,.pager li>a:hover,.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#2b2f33;background-color:#f3f3f9}.dropdown-menu .active>a,.dropdown-menu .active>a:focus,.dropdown-menu .active>a:hover,.dropdown-menu li>a:hover{color:#2b2f33;background:#eff4f6}.active>.badge,.active>.bs-badge,.active>.bs-label{color:#666!important;background:#fff!important}.active>.glyph-icon,a.list-group-item.active>.glyph-icon,li.active a.list-group-item>.glyph-icon{color:#fff!important}.icon-separator{border-right:rgba(255,255,255,.21) solid 1px;background:rgba(255,255,255,.2)}.content-box-header.bg-default .icon-separator,.content-box-header.bg-gray .icon-separator,.content-box-header.bg-white .icon-separator,.tile-box.bg-default .tile-header,.tile-box.bg-gray .tile-header,.tile-box.bg-white .tile-header,.tile-box.btn-default .tile-header{border-right:#dfe8f1 solid 1px;background:rgba(255,255,255,.1)}.content-box-header .header-buttons-separator .icon-separator{border-right:0;border-left:rgba(255,255,255,.21) solid 1px}.header-buttons-separator .icon-separator{color:rgba(255,255,255,.8)}.header-buttons-separator .icon-separator:hover{color:#fff;background:rgba(255,255,255,.3)}.content-box-header.bg-default .header-buttons-separator .icon-separator,.content-box-header.bg-gray .header-buttons-separator .icon-separator,.content-box-header.bg-white .header-buttons-separator .icon-separator{border-right:0;border-left:#dfe8f1 solid 1px;color:rgba(0,0,0,.6)}.content-box-header.bg-default .header-buttons-separator .icon-separator:hover,.content-box-header.bg-gray .header-buttons-separator .icon-separator:hover,.content-box-header.bg-white .header-buttons-separator .icon-separator:hover{color:rgba(0,0,0,.9)}.dashboard-panel .button-pane{background:rgba(0,0,0,.1)!important}.xchart .color0 rect{fill:#00bca4}.xchart .color0 circle{fill:#fff}.xchart .color0 .fill{fill:rgba(0,188,164,.06)}.xchart .color0.comp .pointer,.xchart .color0.comp circle,.xchart .color0.comp rect{fill:#00bca4}.xchart .color1 .line,.xchart .color1 circle,.xchart .color1.comp .line{stroke:#52a7e0}.xchart .color1 rect{fill:#52a7e0}.xchart .color1 circle{fill:#fff}.xchart .color1 .fill{fill:rgba(82,167,224,.06)}.xchart .color1.comp .pointer,.xchart .color1.comp circle,.xchart .color1.comp rect{fill:#52a7e0}body .popover.top .arrow:after{border-top-color:#fff}body .popover.right .arrow:after{border-right-color:#fff}body .popover.bottom .arrow:after{border-bottom-color:#fff}body .popover.left .arrow:after{border-left-color:#fff} +pre, pre code { + white-space: pre-wrap +} + +.clear, .form-row:after, .row:after { + clear: both +} + +.btn-group-vertical>.btn:focus, .btn-group>.btn:focus, :active, :focus, :visited, a, a:active, a:focus, a:visited { + outline: 0 +} + +.xchart .color0 .line, .xchart .color0 circle, .xchart .color0.comp .line { + stroke: #00bca4 +} + +.xchart .color0 .line .fill, .xchart .color1 .line .fill { + pointer-events: none +} + +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block +} + +audio, canvas, video { + display: inline-block +} + +audio:not([controls]) { + display: none; + height: 0 +} + +[hidden] { + display: none +} + +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100% +} + +body, button, figure { + margin: 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, strong { + font-weight: 700 +} + +dfn { + font-style: italic +} + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0 +} + +mark { + color: #000; + background: #ff0 +} + +code, kbd, pre, samp { + font-size: 1em +} + +q { + quotes: '\201C''\201D''\2018''\2019' +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +button, input, select, textarea { + font-family: inherit; + font-size: 100% +} + +button, input { + line-height: normal +} + +button, select { + text-transform: none +} + +button, html input[type=button], input[type=reset], input[type=submit] { + cursor: pointer; + -webkit-appearance: button +} + +input[type=checkbox], input[type=radio] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0 +} + +input[type=search] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield +} + +input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +button::-moz-focus-inner, input::-moz-focus-inner { + padding: 0; + border: 0 +} + +textarea { + overflow: auto; + vertical-align: top +} + +.collapsing, .divider, .overflow-hidden, .sr-only { + overflow: hidden +} + +table { + border-spacing: 0; + border-collapse: collapse +} + +@media print { + blockquote, img, pre, tr { + page-break-inside: avoid + } + + * { + color: #000 !important; + background: 0 0 !important; + box-shadow: none !important; + text-shadow: none !important + } + + a, a:visited { + text-decoration: underline + } + + a[href]:after { + content: ' ('attr(href)')' + } + + abbr[title]:after { + content: ' ('attr(title)')' + } + + .ir a:after, a[href^='javascript:']:after, a[href^='#']:after { + content: '' + } + + blockquote, pre { + border: 1px solid #999 + } + + thead { + display: table-header-group + } + + img { + max-width: 100% !important + } + + @page { + margin: 2cm .5cm + } + + h2, h3, p { + orphans: 3; + widows: 3 + } + + h2, h3 { + page-break-after: avoid + } + + .jGrowl { + display: none + } +} + +small { + font-size: 85% +} + +a { + text-decoration: none +} + +html { + font-size: 62.5%; + -webkit-tap-highlight-color: transparent +} + +*, :after, :before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box +} + +.jqstooltip { + box-sizing: content-box +} + +.form-row, .row { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin-right: -10px; + margin-left: -10px +} + +.form-row:after, .form-row:before, .row:after, .row:before { + display: table; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + content: ' ' +} + +blockquote small, pre { + line-height: 1.428571429; + display: block +} + +[class*=col-] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box +} + +.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { + position: relative; + min-height: 1px; + padding-right: 10px; + padding-left: 10px +} + +.col-xs-1, .col-xs-10, .col-xs-11, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { + float: left +} + +.col-xs-1 { + width: 8.333333333333332% +} + +.col-xs-2 { + width: 16.666666666666664% +} + +.col-xs-3 { + width: 25% +} + +.col-xs-4 { + width: 33.33333333333333% +} + +.col-xs-5 { + width: 41.66666666666667% +} + +.col-xs-6 { + width: 50% +} + +.col-xs-7 { + width: 58.333333333333336% +} + +.col-xs-8 { + width: 66.66666666666666% +} + +.col-xs-9 { + width: 75% +} + +.col-xs-10 { + width: 83.33333333333334% +} + +.col-xs-11 { + width: 91.66666666666666% +} + +.col-xs-12 { + width: 100% +} + +@media (min-width:768px) { + .boxed-layout #page-header, .boxed-layout #page-wrapper, .container { + max-width: 750px + } + + .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9 { + float: left + } + + .col-sm-1 { + width: 8.333333333333332% + } + + .col-sm-2 { + width: 16.666666666666664% + } + + .col-sm-3 { + width: 25% + } + + .col-sm-4 { + width: 33.33333333333333% + } + + .col-sm-5 { + width: 41.66666666666667% + } + + .col-sm-6 { + width: 50% + } + + .col-sm-7 { + width: 58.333333333333336% + } + + .col-sm-8 { + width: 66.66666666666666% + } + + .col-sm-9 { + width: 75% + } + + .col-sm-10 { + width: 83.33333333333334% + } + + .col-sm-11 { + width: 91.66666666666666% + } + + .col-sm-12 { + width: 100% + } + + .col-sm-push-1 { + left: 8.333333333333332% + } + + .col-sm-push-2 { + left: 16.666666666666664% + } + + .col-sm-push-3 { + left: 25% + } + + .col-sm-push-4 { + left: 33.33333333333333% + } + + .col-sm-push-5 { + left: 41.66666666666667% + } + + .col-sm-push-6 { + left: 50% + } + + .col-sm-push-7 { + left: 58.333333333333336% + } + + .col-sm-push-8 { + left: 66.66666666666666% + } + + .col-sm-push-9 { + left: 75% + } + + .col-sm-push-10 { + left: 83.33333333333334% + } + + .col-sm-push-11 { + left: 91.66666666666666% + } + + .col-sm-pull-1 { + right: 8.333333333333332% + } + + .col-sm-pull-2 { + right: 16.666666666666664% + } + + .col-sm-pull-3 { + right: 25% + } + + .col-sm-pull-4 { + right: 33.33333333333333% + } + + .col-sm-pull-5 { + right: 41.66666666666667% + } + + .col-sm-pull-6 { + right: 50% + } + + .col-sm-pull-7 { + right: 58.333333333333336% + } + + .col-sm-pull-8 { + right: 66.66666666666666% + } + + .col-sm-pull-9 { + right: 75% + } + + .col-sm-pull-10 { + right: 83.33333333333334% + } + + .col-sm-pull-11 { + right: 91.66666666666666% + } + + .col-sm-offset-1 { + margin-left: 8.333333333333332% + } + + .col-sm-offset-2 { + margin-left: 16.666666666666664% + } + + .col-sm-offset-3 { + margin-left: 25% + } + + .col-sm-offset-4 { + margin-left: 33.33333333333333% + } + + .col-sm-offset-5 { + margin-left: 41.66666666666667% + } + + .col-sm-offset-6 { + margin-left: 50% + } + + .col-sm-offset-7 { + margin-left: 58.333333333333336% + } + + .col-sm-offset-8 { + margin-left: 66.66666666666666% + } + + .col-sm-offset-9 { + margin-left: 75% + } + + .col-sm-offset-10 { + margin-left: 83.33333333333334% + } + + .col-sm-offset-11 { + margin-left: 91.66666666666666% + } +} + +@media (min-width:992px) { + .boxed-layout #page-header, .boxed-layout #page-wrapper, .container { + max-width: 970px + } + + .col-md-1, .col-md-10, .col-md-11, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9 { + float: left + } + + .col-md-1 { + width: 8.333333333333332% + } + + .col-md-2 { + width: 16.666666666666664% + } + + .col-md-3 { + width: 25% + } + + .col-md-4 { + width: 33.33333333333333% + } + + .col-md-5 { + width: 41.66666666666667% + } + + .col-md-6 { + width: 50% + } + + .col-md-7 { + width: 58.333333333333336% + } + + .col-md-8 { + width: 66.66666666666666% + } + + .col-md-9 { + width: 75% + } + + .col-md-10 { + width: 83.33333333333334% + } + + .col-md-11 { + width: 91.66666666666666% + } + + .col-md-12 { + width: 100% + } + + .col-md-push-0 { + left: auto + } + + .col-md-push-1 { + left: 8.333333333333332% + } + + .col-md-push-2 { + left: 16.666666666666664% + } + + .col-md-push-3 { + left: 25% + } + + .col-md-push-4 { + left: 33.33333333333333% + } + + .col-md-push-5 { + left: 41.66666666666667% + } + + .col-md-push-6 { + left: 50% + } + + .col-md-push-7 { + left: 58.333333333333336% + } + + .col-md-push-8 { + left: 66.66666666666666% + } + + .col-md-push-9 { + left: 75% + } + + .col-md-push-10 { + left: 83.33333333333334% + } + + .col-md-push-11 { + left: 91.66666666666666% + } + + .col-md-pull-0 { + right: auto + } + + .col-md-pull-1 { + right: 8.333333333333332% + } + + .col-md-pull-2 { + right: 16.666666666666664% + } + + .col-md-pull-3 { + right: 25% + } + + .col-md-pull-4 { + right: 33.33333333333333% + } + + .col-md-pull-5 { + right: 41.66666666666667% + } + + .col-md-pull-6 { + right: 50% + } + + .col-md-pull-7 { + right: 58.333333333333336% + } + + .col-md-pull-8 { + right: 66.66666666666666% + } + + .col-md-pull-9 { + right: 75% + } + + .col-md-pull-10 { + right: 83.33333333333334% + } + + .col-md-pull-11 { + right: 91.66666666666666% + } + + .col-md-offset-0 { + margin-left: 0 + } + + .col-md-offset-1 { + margin-left: 8.333333333333332% + } + + .col-md-offset-2 { + margin-left: 16.666666666666664% + } + + .col-md-offset-3 { + margin-left: 25% + } + + .col-md-offset-4 { + margin-left: 33.33333333333333% + } + + .col-md-offset-5 { + margin-left: 41.66666666666667% + } + + .col-md-offset-6 { + margin-left: 50% + } + + .col-md-offset-7 { + margin-left: 58.333333333333336% + } + + .col-md-offset-8 { + margin-left: 66.66666666666666% + } + + .col-md-offset-9 { + margin-left: 75% + } + + .col-md-offset-10 { + margin-left: 83.33333333333334% + } + + .col-md-offset-11 { + margin-left: 91.66666666666666% + } +} + +@media (min-width:1200px) { + .boxed-layout #page-header, .boxed-layout #page-wrapper, .container { + max-width: 1170px + } + + .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9 { + float: left + } + + .col-lg-1 { + width: 8.333333333333332% + } + + .col-lg-2 { + width: 16.666666666666664% + } + + .col-lg-3 { + width: 25% + } + + .col-lg-4 { + width: 33.33333333333333% + } + + .col-lg-5 { + width: 41.66666666666667% + } + + .col-lg-6 { + width: 50% + } + + .col-lg-7 { + width: 58.333333333333336% + } + + .col-lg-8 { + width: 66.66666666666666% + } + + .col-lg-9 { + width: 75% + } + + .col-lg-10 { + width: 83.33333333333334% + } + + .col-lg-11 { + width: 91.66666666666666% + } + + .col-lg-12 { + width: 100% + } + + .col-lg-push-0 { + left: auto + } + + .col-lg-push-1 { + left: 8.333333333333332% + } + + .col-lg-push-2 { + left: 16.666666666666664% + } + + .col-lg-push-3 { + left: 25% + } + + .col-lg-push-4 { + left: 33.33333333333333% + } + + .col-lg-push-5 { + left: 41.66666666666667% + } + + .col-lg-push-6 { + left: 50% + } + + .col-lg-push-7 { + left: 58.333333333333336% + } + + .col-lg-push-8 { + left: 66.66666666666666% + } + + .col-lg-push-9 { + left: 75% + } + + .col-lg-push-10 { + left: 83.33333333333334% + } + + .col-lg-push-11 { + left: 91.66666666666666% + } + + .col-lg-pull-0 { + right: auto + } + + .col-lg-pull-1 { + right: 8.333333333333332% + } + + .col-lg-pull-2 { + right: 16.666666666666664% + } + + .col-lg-pull-3 { + right: 25% + } + + .col-lg-pull-4 { + right: 33.33333333333333% + } + + .col-lg-pull-5 { + right: 41.66666666666667% + } + + .col-lg-pull-6 { + right: 50% + } + + .col-lg-pull-7 { + right: 58.333333333333336% + } + + .col-lg-pull-8 { + right: 66.66666666666666% + } + + .col-lg-pull-9 { + right: 75% + } + + .col-lg-pull-10 { + right: 83.33333333333334% + } + + .col-lg-pull-11 { + right: 91.66666666666666% + } + + .col-lg-offset-0 { + margin-left: 0 + } + + .col-lg-offset-1 { + margin-left: 8.333333333333332% + } + + .col-lg-offset-2 { + margin-left: 16.666666666666664% + } + + .col-lg-offset-3 { + margin-left: 25% + } + + .col-lg-offset-4 { + margin-left: 33.33333333333333% + } + + .col-lg-offset-5 { + margin-left: 41.66666666666667% + } + + .col-lg-offset-6 { + margin-left: 50% + } + + .col-lg-offset-7 { + margin-left: 58.333333333333336% + } + + .col-lg-offset-8 { + margin-left: 66.66666666666666% + } + + .col-lg-offset-9 { + margin-left: 75% + } + + .col-lg-offset-10 { + margin-left: 83.33333333333334% + } + + .col-lg-offset-11 { + margin-left: 91.66666666666666% + } +} + +.row.no-gutter { + margin-left: 0; + margin-right: 0 +} + +.no-gutter>[class*=col-] { + padding-left: 0; + padding-right: 0 +} + +.pad5A { + padding: 5px !important +} + +.pad5T { + padding-top: 5px !important +} + +.pad5R { + padding-right: 5px !important +} + +.pad5B { + padding-bottom: 5px !important +} + +.pad5L { + padding-left: 5px !important +} + +.pad10A { + padding: 10px !important +} + +.pad10T { + padding-top: 10px !important +} + +.pad10R { + padding-right: 10px !important +} + +.pad10B { + padding-bottom: 10px !important +} + +.pad10L { + padding-left: 10px !important +} + +.pad15A { + padding: 15px !important +} + +.pad15T { + padding-top: 15px !important +} + +.pad15R { + padding-right: 15px !important +} + +.pad15B { + padding-bottom: 15px !important +} + +.pad15L { + padding-left: 15px !important +} + +.pad20A { + padding: 20px !important +} + +.pad20T { + padding-top: 20px !important +} + +.pad20R { + padding-right: 20px !important +} + +.pad20B { + padding-bottom: 20px !important +} + +.pad20L { + padding-left: 20px !important +} + +.pad25A { + padding: 25px !important +} + +.pad25T { + padding-top: 25px !important +} + +.pad25R { + padding-right: 25px !important +} + +.pad25B { + padding-bottom: 25px !important +} + +.pad25L { + padding-left: 25px !important +} + +.pad45A { + padding: 45px !important +} + +.pad45T { + padding-top: 45px !important +} + +.pad45R { + padding-right: 45px !important +} + +.pad45B { + padding-bottom: 45px !important +} + +.pad45L { + padding-left: 45px !important +} + +.pad0A { + padding: 0 !important +} + +.pad0T { + padding-top: 0 !important +} + +.pad0R { + padding-right: 0 !important +} + +.pad0B { + padding-bottom: 0 !important +} + +.pad0L { + padding-left: 0 !important +} + +.mrg5A { + margin: 5px !important +} + +.mrg5T { + margin-top: 5px !important +} + +.mrg5R { + margin-right: 5px !important +} + +.mrg5B { + margin-bottom: 5px !important +} + +.mrg5L { + margin-left: 5px !important +} + +.mrg10A { + margin: 10px !important +} + +.mrg10T { + margin-top: 10px !important +} + +.mrg10R { + margin-right: 10px !important +} + +.mrg10B { + margin-bottom: 10px !important +} + +.mrg10L { + margin-left: 10px !important +} + +.mrg15A { + margin: 15px !important +} + +.mrg15T { + margin-top: 15px !important +} + +.mrg15R { + margin-right: 15px !important +} + +.mrg15B { + margin-bottom: 15px !important +} + +.mrg15L { + margin-left: 15px !important +} + +.mrg20A { + margin: 20px !important +} + +.mrg20T { + margin-top: 20px !important +} + +.mrg20R { + margin-right: 20px !important +} + +.mrg20B { + margin-bottom: 20px !important +} + +.mrg20L { + margin-left: 20px !important +} + +.mrg25A { + margin: 25px !important +} + +.mrg25T { + margin-top: 25px !important +} + +.mrg25R { + margin-right: 25px !important +} + +.mrg25B { + margin-bottom: 25px !important +} + +.mrg25L { + margin-left: 25px !important +} + +.mrg45A { + margin: 45px !important +} + +.mrg45T { + margin-top: 45px !important +} + +.mrg45R { + margin-right: 45px !important +} + +.mrg45B { + margin-bottom: 45px !important +} + +.mrg45L { + margin-left: 45px !important +} + +.mrg0A { + margin: 0 !important +} + +.mrg0T { + margin-top: 0 !important +} + +.mrg0R { + margin-right: 0 !important +} + +.mrg0B { + margin-bottom: 0 !important +} + +.mrg0L { + margin-left: 0 !important +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + font-weight: 500; + margin: 0 +} + +.h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + font-weight: 400 +} + +.h1, h1 { + font-size: 38px +} + +.h2, h2 { + font-size: 26px +} + +.h3, h3 { + font-size: 20px +} + +.h4, h4 { + font-size: 16px +} + +.h5, h5 { + font-size: 14px +} + +.h6, h6 { + font-size: 12px +} + +.h1 small, h1 small { + font-size: 24px +} + +.h2 small, h2 small { + font-size: 18px +} + +.h3 small, .h4 small, h3 small, h4 small { + font-size: 14px +} + +h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small { + font-size: 75% +} + +blockquote { + margin: 0 0 20px; + padding: 10px 20px; + border-left: 5px solid #eee +} + +blockquote p { + font-size: 17.5px; + font-weight: 50; + line-height: 1.25 +} + +blockquote p:last-child { + margin-bottom: 0 +} + +blockquote small { + color: #999 +} + +blockquote small:before { + content: '\2014 \00A0' +} + +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eee; + border-left: 0 +} + +blockquote.pull-right .small, blockquote.pull-right p, blockquote.pull-right small { + text-align: right +} + +blockquote.pull-right .small:before, blockquote.pull-right small:before { + content: '' +} + +blockquote.pull-right .small:after, blockquote.pull-right small:after { + content: '\00A0 \2014' +} + +blockquote:after, blockquote:before { + content: '' +} + +address { + font-style: normal; + line-height: 1.428571429; + margin-bottom: 20px +} + +code, kbd, pre, samp { + font-family: Menlo, Monaco, Consolas, 'Courier New', monospace +} + +code { + font-size: 90%; + padding: 0 4px; + white-space: nowrap; + color: #d05; + border: 1px solid #dfe8f1; + border-radius: 3px; + background: #fafafa +} + +pre { + font-size: 13px; + margin: 0 0 10px; + padding: 9.5px; + word-wrap: break-word; + word-break: break-all; + color: #333; + border: 1px solid #ccc; + border-radius: 4px; + background-color: #f5f5f5 +} + +pre code { + font-size: inherit; + padding: 0; + color: inherit; + border-radius: 0; + background-color: transparent +} + +.btn, .fc-button, .input-group-btn, .text-no-wrap { + white-space: nowrap +} + +p { + line-height: 1.6em; + margin: 0 +} + +.title-hero { + margin: 0 0 15px; + padding: 0; + text-transform: uppercase; + font-size: 14px; + opacity: .7 +} + +h4.title-hero { + font-size: 15px +} + +.title-lead { + color: #3F3F3F +} + +.title-hero .title-lead { + font-size: 65%; + margin: 5px 0 0 +} + +.title-hero+.title-lead { + margin-top: -10px +} + +.jumbotron { + font-size: 21px; + font-weight: 200; + line-height: 2.1428571435; + margin-bottom: 30px; + padding: 30px; + color: inherit; + background-color: #eee +} + +.jumbotron h1 { + line-height: 1; + color: inherit +} + +.jumbotron p { + line-height: 1.4 +} + +.container .jumbotron { + border-radius: 6px +} + +@media screen and (min-width:768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px + } + + .container .jumbotron { + padding-right: 60px; + padding-left: 60px + } + + .jumbotron h1 { + font-size: 63px + } +} + +.float-left, .pull-left { + float: left !important +} + +.float-right, .pull-right { + float: right !important +} + +.float-none { + float: none !important +} + +.font-size-10 { + font-size: 10px !important +} + +.font-size-11 { + font-size: 11px !important +} + +.font-size-12 { + font-size: 12px !important +} + +.font-size-13 { + font-size: 13px !important +} + +.font-size-14 { + font-size: 14px !important +} + +.font-size-15 { + font-size: 15px !important +} + +.font-size-16 { + font-size: 16px !important +} + +.font-size-17 { + font-size: 17px !important +} + +.font-size-18 { + font-size: 18px !important +} + +.font-size-20 { + font-size: 20px !important +} + +.font-size-23 { + font-size: 23px !important +} + +.font-size-26 { + font-size: 26px !important +} + +.font-size-28 { + font-size: 28px !important +} + +.font-size-35 { + font-size: 35px !important +} + +.font-size-50 { + font-size: 50px !important +} + +.text-center { + text-align: center !important +} + +.text-left { + text-align: left !important +} + +.text-right { + text-align: right !important +} + +.text-justify { + text-align: justify +} + +.text-transform-none { + text-transform: none +} + +.text-transform-upr { + text-transform: uppercase +} + +.text-transform-low { + text-transform: lowercase +} + +.text-transform-cap { + text-transform: capitalize +} + +.font-bold { + font-weight: 700 !important +} + +.btn, .fc-button, .font-normal { + font-weight: 400 +} + +.font-italic { + font-style: italic +} + +.font-none { + font-style: none +} + +.clear-none { + clear: none !important +} + +#page-wrapper:after, .btn-group:after, .btn-toolbar:after, .button-pane:after, .chat-box li:after, .clearfix:after, .comments-list li .panel-body:after, .container:after, .content-box-header:after, .example-box-wrapper:after, .files-box li:after, .form-horizontal .form-group:after, .form-input-prepend:after, .form-row:after, .info-box:after, .messages-box li:after, .nav-list li:after, .nav:after, .notifications-box li:after, .pager:after, .posts-list li:after, .tl-item:after, .tl-row:after, .todo-box li:after, .ui-datepicker-buttonpane:after, .ui-helper-clearfix:after { + clear: both +} + +.ui-front { + z-index: 100 +} + +.wrapper-sticky { + z-index: 15 +} + +.hide, .lazy, .mix, .tab-pane, [data-toggle=buttons]>.btn>input[type=checkbox], [data-toggle=buttons]>.btn>input[type=radio] { + display: none +} + +.tab-pane { + padding: 15px +} + +.hidden, .ui-helper-hidden-accessible { + display: none !important +} + +.display-block { + position: relative !important; + display: block !important +} + +.display-block .button-content { + float: none +} + +.display-block.dropdown-menu { + position: static !important +} + +.display-inline { + display: inline-block +} + +.no-border { + border-color: transparent !important +} + +.dropdown-menu.pad0A .hasDatepicker .ui-datepicker, .remove-border { + border: 0 !important +} + +.border-top { + border-top-width: 3px !important; + border-top-style: solid !important +} + +.width-100 { + box-sizing: border-box; + width: 100% +} + +.center-margin { + float: none !important; + margin: 0 auto +} + +.center-block, .container { + display: block; + margin-right: auto; + margin-left: auto +} + +.center-vertical { + position: relative; + z-index: 15; + top: 0; + left: 0; + display: table; + width: 100%; + height: 100% +} + +.center-vertical .center-content { + display: table-cell; + vertical-align: middle +} + +.position-absolute { + position: absolute +} + +.show { + display: block !important +} + +.hidden { + display: none !important; + visibility: hidden !important +} + +.invisible { + visibility: hidden +} + +.center-div { + float: none !important; + margin-right: auto !important; + margin-left: auto !important; + text-align: center !important +} + +.btn-group>.btn-group, .btn-toolbar .btn-group, .btn-toolbar .input-group, .demo-icon { + float: left +} + +.divider, .nav-divider { + ityity: .7; + -moz-opacity: .7; + filter: alpha(opacity: 70) +} + +.divider { + height: 1px; + margin: 10px 0; + padding: 0 +} + +.divider-header { + font-size: 11px; + padding: 10px 15px; + text-transform: uppercase; + opacity: .2; + color: #fff +} + +.width-reset { + width: auto !important +} + +.opacity-10 { + opacity: .1 !important; + -moz-opacity: .1 !important; + filter: alpha(opacity: 10) !important +} + +.info-box b, .info-box.icon-wrapper .icon-large, .opacity-30 { + opacity: .3 !important; + -moz-opacity: .3 !important; + filter: alpha(opacity: 30) !important +} + +.opacity-40 { + opacity: .4 !important; + -moz-opacity: .4 !important; + filter: alpha(opacity: 40) !important +} + +.info-box b, .label-description span, .opacity-60, .opacity-hover { + opacity: .6 !important; + -moz-opacity: .6 !important; + filter: alpha(opacity: 60) !important +} + +.no-shadow.transparent.btn:hover i, .opacity-80, .ui-datepicker-current.ui-priority-secondary { + opacity: .8 !important; + -moz-opacity: .8 !important; + filter: alpha(opacity: 80) !important +} + +.opacity-100, .opacity-hover:hover { + opacity: 1 !important; + -moz-opacity: 1 !important; + filter: alpha(opacity: 100) !important +} + +.btn-link .glyph-icon.opacity-hover { + margin: 0 -5px +} + +.transparent { + border-color: transparent !important; + background: 0 0 !important; + box-shadow: 0 0 0 0 transparent !important +} + +.no-shadow { + box-shadow: 0 0 0 transparent !important +} + +.remove-bg { + background: 0 0 +} + +.nicescroll-rails { + background: 0 0 !important +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent +} + +#loading, .login-img, .ui-widget-overlay { + width: 100%; + height: 100% +} + +.dropup .caret, .navbar-fixed-bottom .dropdown .caret { + content: ''; + border-top: 0; + border-bottom: 4px solid +} + +.chosen-results, .form-wizard>ul, .nav-list ul, .nav-list-horizontal ul, .parsley-errors-list, .reset-ul, .tabs-navigation>ul, ul.messages-box, ul.notifications-box, ul.progress-box { + margin: 0; + padding: 0; + list-style: none +} + +#page-wrapper:after, #page-wrapper:before, .btn-group:after, .btn-group:before, .btn-toolbar:after, .btn-toolbar:before, .button-pane:after, .button-pane:before, .chat-box li:after, .chat-box li:before, .clearfix:after, .clearfix:before, .comments-list li .panel-body:after, .comments-list li .panel-body:before, .container:after, .container:before, .content-box-header:after, .content-box-header:before, .example-box-wrapper:after, .example-box-wrapper:before, .files-box li:after, .files-box li:before, .form-input-prepend:after, .form-input-prepend:before, .form-row:after, .form-row:before, .info-box:after, .info-box:before, .messages-box li:after, .messages-box li:before, .nav-list li:after, .nav-list li:before, .nav:after, .nav:before, .notifications-box li:after, .notifications-box li:before, .pager:after, .pager:before, .posts-list li:after, .posts-list li:before, .tl-item:after, .tl-item:before, .tl-row:after, .tl-row:before, .todo-box li:after, .todo-box li:before, .ui-datepicker-buttonpane:after, .ui-datepicker-buttonpane:before, .ui-helper-clearfix:after, .ui-helper-clearfix:before { + display: table; + content: '' +} + +.ui-sortable-placeholder { + visibility: visible !important; + border: 1px dashed #efda2c !important; + background: #fffce5 !important +} + +.daterangepicker td.available.in-range:hover, .daterangepicker td.in-range { + background: #fffce5 +} + +.checker.disabled, .checker.disabled span, .chosen-disabled, .disabled, .radio.disabled, .radio.disabled span, .ui-rangeSlider-disabled .ui-rangeSlider-arrow, .ui-rangeSlider-disabled .ui-rangeSlider-container, .ui-rangeSlider-disabled .ui-rangeSlider-label, .ui-state-disabled, button[disabled] { + cursor: not-allowed !important; + opacity: .65; + filter: alpha(opacity: 65) +} + +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control, input[disabled], select[disabled], textarea[disabled] { + cursor: not-allowed; + opacity: .65; + background: #fafafa; + filter: alpha(opacity: 65) +} + +input[readonly], select[readonly], textarea[readonly] { + opacity: .8; + background: #fdfdfd; + -moz-opacity: .8; + filter: alpha(opacity: 80) +} + +.login-img { + position: fixed !important; + top: 0; + left: 0 +} + +.fixed-bg { + background-repeat: no-repeat; + background-attachment: fixed; + background-position: center center; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover +} + +.ui-widget-overlay { + position: fixed; + left: 0; + top: 0; + bottom: 0; + right: 0; + text-align: center; + z-index: 16 +} + +.ui-widget-overlay img { + position: absolute; + top: 50%; + left: 50%; + margin: -26px 0 0 -26px +} + +#loading { + z-index: 5555; + position: fixed; + left: 0; + top: 0; + background: #fff +} + +.fade { + -webkit-transition: opacity .15s linear; + transition: opacity .15s linear +} + +.collapse { + display: none +} + +.collapse.in, .tab-pane.active { + display: block +} + +.collapsing { + position: relative; + height: 0; + -webkit-transition: height .35s ease; + transition: height .35s ease +} + +.small-padding { + padding: 25px 0 +} + +.medium-padding { + padding: 55px 0 +} + +.large-padding { + padding: 85px 0 +} + +.xlarge-padding { + padding: 115px 0 +} + +.glyph-icon { + text-align: center +} + +#page-sidebar li a.sf-with-ul:after, #page-sidebar li ul li a:before, .dataTables_paginate a i:before, .fc-icon, .glyph-icon:before, .search-choice-close:before, .ui-dialog-titlebar-close:before, .ui-icon:before { + font-family: FontAwesome; + font-weight: 400; + font-style: normal; + display: inline-block; + text-align: center; + text-decoration: none; + background: 0 0; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +.dropdown-menu>.disabled>a:focus, .dropdown-menu>.disabled>a:hover { + cursor: not-allowed; + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid: DXImageTransform.Microsoft.gradient(enabled=false) +} + +.sr-only { + position: absolute; + clip: rect(0, 0, 0, 0); + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + border: 0 +} + +.rm-transition { + -webkit-transition: none !important; + -moz-transition: none !important; + -ms-transition: none !important; + -o-transition: none !important +} + +.btn, a, button, div[id^=uniform-] span { + -webkit-transition: all .1s ease-in-out; + -moz-transition: all .1s ease-in-out; + -ms-transition: all .1s ease-in-out; + -o-transition: all .1s ease-in-out +} + +#page-header, #page-sidebar, .main-header, .top-bar { + -webkit-transition: all .5s ease-in-out; + -moz-transition: all .5s ease-in-out; + -ms-transition: all .5s ease-in-out; + -o-transition: all .5s ease-in-out +} + +.example-box-wrapper { + margin-bottom: 15px; + position: relative +} + +.example-box-wrapper .ui-datepicker-inline { + position: relative; + width: 100% +} + +.panel-body .col-md-6 .example-box-wrapper:last-child, .panel-body .example-box-wrapper:last-child { + margin-bottom: 0 +} + +.example-box-wrapper .alert, .example-box-wrapper .content-box, .example-box-wrapper .dashboard-box, .example-box-wrapper .dataTables_wrapper, .example-box-wrapper .icon-box, .example-box-wrapper .image-box, .example-box-wrapper .jcrop-holder, .example-box-wrapper .jvectormap-container, .example-box-wrapper .list-group, .example-box-wrapper .loading-spinner, .example-box-wrapper .loading-stick, .example-box-wrapper .minicolors, .example-box-wrapper .nav, .example-box-wrapper .panel-layout, .example-box-wrapper .scrollable-content, .example-box-wrapper .tile-box, .example-box-wrapper .ui-accordion, .example-box-wrapper .ui-rangeSlider, .example-box-wrapper .ui-slider, .example-box-wrapper .ui-tabs, .example-box-wrapper>.btn, .example-box-wrapper>.btn-group, .example-box-wrapper>.btn-group-vertical, .example-box-wrapper>.btn-toolbar, .example-box-wrapper>.display-block.dropdown-menu, .example-box-wrapper>.dropdown, .example-box-wrapper>.dropup, .example-box-wrapper>.hasDatepicker, .example-box-wrapper>.img-humbnail, .example-box-wrapper>.minicolors, .example-box-wrapper>.pagination, .example-box-wrapper>.panel-layout, .example-box-wrapper>.progressbar, .example-box-wrapper>.thumbnail, .example-box-wrapper>form, .example-box-wrapper>h6, .example-box-wrapper>img { + margin-bottom: 20px +} + +.demo-icon { + font-size: 22px; + line-height: 40px; + width: 40px; + height: 40px; + margin: 10px; + text-align: center; + color: #92A0B3; + border: 1px solid rgba(220, 233, 255, .54); + border-radius: 3px +} + +.btn-block, .btn-group-justified, .btn-group-justified>.btn-group .btn, input[type=button].btn-block, input[type=reset].btn-block, input[type=submit].btn-block { + width: 100% +} + +.demo-icon:hover { + color: #59606c; + border-color: #92A0B3 +} + +.font-black { + color: #464646 !important +} + +.font-blue { + color: #1f6dca !important +} + +.font-blue-alt { + color: #65a6ff !important +} + +.font-azure { + color: #41e5c0 !important +} + +.font-gray, .text-muted { + color: #c2c2c2 !important +} + +.font-gray-dark, .text-info { + color: #828282 !important +} + +.font-green, .text-success { + color: #2ecc71 !important +} + +.font-orange, .text-warning { + color: #fa7753 !important +} + +.font-yellow { + color: #fc0 !important +} + +.font-purple { + color: #984dff !important +} + +.font-red, .has-error .help-block, .parsley-required, .text-danger { + color: #ff5757 !important +} + +.font-white { + color: #fff !important +} + +.alert-info, .alert-info a { + color: #6c6c6c; + border-color: #c9c9c9; + background: #dfe8f1 +} + +.alert-notice, .alert-notice a { + color: #0f2c62; + border-color: #62baf6; + background: #c6e8ff +} + +.alert-success, .alert-success a, .parsley-success { + color: #1e620f; + border-color: #7cd362; + background: #d3ffc6 +} + +.parsley-success { + background: #fff +} + +.alert-warning, .alert-warning a, .warning { + color: #624b0f; + border-color: #ebc875; + background: #ffeec6 +} + +.alert-danger, .alert-danger a, .danger, .parsley-error { + color: #620f0f; + border-color: #db6a6a; + background: #ffc6c6 +} + +.bg-facebook, .bg-google, .bg-twitter { + color: #fff !important +} + +.parsley-error { + background: #fff +} + +.bg-facebook { + background: #3b5998 +} + +.btn.bg-facebook:hover { + background: #304b85 +} + +.bg-twitter { + background: #3a92c8 +} + +.btn.bg-twitter:hover { + background: #2b80b4 +} + +.bg-google { + background: #dd4b39 +} + +.btn.bg-google:hover { + background: #c93b2a +} + +.badge-info, .bg-blue, .bootstrap-switch-info, .btn-info, .checkbox-info div[id^=uniform-] span.checked, .hover-blue:hover, .hover-info:hover, .label-info, .progress-bar-info, .radio-info div[id^=uniform-] span.checked { + color: #fff; + border-color: #308dcc; + background: #3498db +} + +.btn-info.active, .btn-info.disabled, .btn-info.disabled.active, .btn-info.disabled:active, .btn-info.disabled:focus, .btn-info.disabled:hover, .btn-info:active, .btn-info:focus, .btn-info:hover, .btn-info[disabled], .btn-info[disabled].active, .btn-info[disabled]:active, .btn-info[disabled]:focus, .btn-info[disabled]:hover, .label-info[href]:focus, .label-info[href]:hover, .open .dropdown-toggle.btn-info { + color: #fff; + border-color: #308dcc; + background: #52a7e0 +} + +.badge-danger, .bg-danger, .bg-red, .bootstrap-switch-danger, .btn-danger, .checkbox-danger div[id^=uniform-] span.checked, .hover-danger:hover, .hover-red:hover, .label-danger, .progress-bar-danger, .radio-danger div[id^=uniform-] span.checked { + color: #fff; + border-color: #cf4436; + background: #e74c3c +} + +.btn-danger.active, .btn-danger.disabled, .btn-danger.disabled.active, .btn-danger.disabled:active, .btn-danger.disabled:focus, .btn-danger.disabled:hover, .btn-danger:active, .btn-danger:focus, .btn-danger:hover, .btn-danger[disabled], .btn-danger[disabled].active, .btn-danger[disabled]:active, .btn-danger[disabled]:focus, .btn-danger[disabled]:hover, .label-danger[href]:focus, .label-danger[href]:hover, .open .dropdown-toggle.btn-danger { + color: #fff; + border-color: #cf4436; + background: #eb6759 +} + +.badge-gray, .bg-gray, .btn-gray, .hover-gray:hover, .label-gray { + color: #666; + background: #efefef +} + +.btn-gray.active, .btn-gray.disabled, .btn-gray.disabled.active, .btn-gray.disabled:active, .btn-gray.disabled:focus, .btn-gray.disabled:hover, .btn-gray:active, .btn-gray:focus, .btn-gray:hover, .btn-gray[disabled], .btn-gray[disabled].active, .btn-gray[disabled]:active, .btn-gray[disabled]:focus, .btn-gray[disabled]:hover, .label-gray[href]:focus, .label-gray[href]:hover, .open .dropdown-toggle.btn-gray { + color: #333; + background: #e7e7e7 +} + +.badge-gray-alt, .bg-gray-alt, .btn-gray-alt, .hover-gray-alt:hover, .label-gray-alt { + color: #888; + background: #f6f6f6 +} + +.btn-gray-alt.active, .btn-gray-alt.disabled, .btn-gray-alt.disabled.active, .btn-gray-alt.disabled:active, .btn-gray-alt.disabled:focus, .btn-gray-alt.disabled:hover, .btn-gray-alt:active, .btn-gray-alt:focus, .btn-gray-alt:hover, .btn-gray-alt[disabled], .btn-gray-alt[disabled].active, .btn-gray-alt[disabled]:active, .btn-gray-alt[disabled]:focus, .btn-gray-alt[disabled]:hover, .label-gray-alt[href]:focus, .label-gray-alt[href]:hover, .open .dropdown-toggle.btn-gray-alt { + color: #444; + background: #ededed +} + +.badge-black, .bg-black, .btn-black, .hover-black:hover, .label-black { + color: #ccc; + border-color: #000; + background: #2d2d2d +} + +.boxed-layout.bg-black { + background: #2d2d2d +} + +.btn-black.active, .btn-black.disabled, .btn-black.disabled.active, .btn-black.disabled:active, .btn-black.disabled:focus, .btn-black.disabled:hover, .btn-black:active, .btn-black:focus, .btn-black:hover, .btn-black[disabled], .btn-black[disabled].active, .btn-black[disabled]:active, .btn-black[disabled]:focus, .btn-black[disabled]:hover, .label-black[href]:focus, .label-black[href]:hover, .open .dropdown-toggle.btn-black { + color: #fdfdfd; + background: #151515 +} + +.badge-black-opacity, .bg-black-opacity, .btn-black-opacity, .hover-black-opacity:hover, .label-black-opacity { + color: #a9b3bb; + background: #2b323d +} + +.btn-black-opacity.active, .btn-black-opacity.disabled, .btn-black-opacity.disabled.active, .btn-black-opacity.disabled:active, .btn-black-opacity.disabled:focus, .btn-black-opacity.disabled:hover, .btn-black-opacity:active, .btn-black-opacity:focus, .btn-black-opacity:hover, .btn-black-opacity[disabled], .btn-black-opacity[disabled].active, .btn-black-opacity[disabled]:active, .btn-black-opacity[disabled]:focus, .btn-black-opacity[disabled]:hover, .label-black-opacity[href]:focus, .label-black-opacity[href]:hover, .open .dropdown-toggle.btn-black-opacity { + color: #fff; + background: #14171c +} + +.badge-black-opacity-alt, .bg-black-opacity-alt, .btn-black-opacity-alt, .hover-black-opacity-alt:hover, .label-black-opacity-alt { + color: #fff; + background: rgba(0, 0, 0, .2); + border-color: transparent +} + +.btn-black-opacity-alt.active, .btn-black-opacity-alt.disabled, .btn-black-opacity-alt.disabled.active, .btn-black-opacity-alt.disabled:active, .btn-black-opacity-alt.disabled:focus, .btn-black-opacity-alt.disabled:hover, .btn-black-opacity-alt:active, .btn-black-opacity-alt:focus, .btn-black-opacity-alt:hover, .btn-black-opacity-alt[disabled], .btn-black-opacity-alt[disabled].active, .btn-black-opacity-alt[disabled]:active, .btn-black-opacity-alt[disabled]:focus, .btn-black-opacity-alt[disabled]:hover, .label-black-opacity-alt[href]:focus, .label-black-opacity-alt[href]:hover, .open .dropdown-toggle.btn-black-opacity-alt { + color: #fff; + background: rgba(0, 0, 0, .3) +} + +.badge-success, .bg-green, .bootstrap-switch-success, .btn-success, .checkbox-success div[id^=uniform-] span.checked, .hover-green:hover, .hover-success:hover, .label-success, .progress-bar-success, .radio-success div[id^=uniform-] span.checked { + color: #fff; + border-color: #29b765; + background: #2ecc71 +} + +.btn-success.active, .btn-success.disabled, .btn-success.disabled.active, .btn-success.disabled:active, .btn-success.disabled:focus, .btn-success.disabled:hover, .btn-success:active, .btn-success:focus, .btn-success:hover, .btn-success[disabled], .btn-success[disabled].active, .btn-success[disabled]:active, .btn-success[disabled]:focus, .btn-success[disabled]:hover, .label-success[href]:focus, .label-success[href]:hover, .open .dropdown-toggle.btn-success { + color: #fff; + border-color: #29b765; + background: #58d68d +} + +.badge-warning, .bg-orange, .bg-warning, .bootstrap-switch-warning, .btn-warning, .checkbox-warning div[id^=uniform-] span.checked, .hover-orange:hover, .hover-warning:hover, .label-warning, .progress-bar-warning, .radio-warning div[id^=uniform-] span.checked { + color: #fff; + border-color: #d67520; + background: #e67e22 +} + +.btn-warning.active, .btn-warning.disabled, .btn-warning.disabled.active, .btn-warning.disabled:active, .btn-warning.disabled:focus, .btn-warning.disabled:hover, .btn-warning:active, .btn-warning:focus, .btn-warning:hover, .btn-warning[disabled], .btn-warning[disabled].active, .btn-warning[disabled]:active, .btn-warning[disabled]:focus, .btn-warning[disabled]:hover, .label-warning[href]:focus, .label-warning[href]:hover, .open .dropdown-toggle.btn-warning { + color: #fff; + border-color: #d67520; + background: #ea9143 +} + +.bg-white, .label-white, .table { + background: #fff +} + +.bg-white-opacity { + background: rgba(255, 255, 255, .85) +} + +.hover-white:hover { + background: #fafafa +} + +.badge-yellow, .bg-yellow, .btn-yellow, .hover-yellow:hover, .label-yellow { + color: #fff; + background: #fc0; + border-color: #deb200 +} + +.btn-yellow.active, .btn-yellow.disabled, .btn-yellow.disabled.active, .btn-yellow.disabled:active, .btn-yellow.disabled:focus, .btn-yellow.disabled:hover, .btn-yellow:active, .btn-yellow:focus, .btn-yellow:hover, .btn-yellow[disabled], .btn-yellow[disabled].active, .btn-yellow[disabled]:active, .btn-yellow[disabled]:focus, .btn-yellow[disabled]:hover, .label-yellow[href]:focus, .label-yellow[href]:hover, .open .dropdown-toggle.btn-yellow { + color: #fff; + background: #e1b400; + border-color: #c59e00 +} + +.badge-purple, .bg-purple, .btn-purple, .hover-purple:hover, .label-purple { + color: #fff; + background: #984dff; + border-color: #7a3ecc +} + +.btn-purple.active, .btn-purple.disabled, .btn-purple.disabled.active, .btn-purple.disabled:active, .btn-purple.disabled:focus, .btn-purple.disabled:hover, .btn-purple:active, .btn-purple:focus, .btn-purple:hover, .btn-purple[disabled], .btn-purple[disabled].active, .btn-purple[disabled]:active, .btn-purple[disabled]:focus, .btn-purple[disabled]:hover, .label-purple[href]:focus, .label-purple[href]:hover, .open .dropdown-toggle.btn-purple { + color: #fff; + background: #8134eb; + border-color: #752fd6 +} + +.badge-blue-alt, .bg-blue-alt, .btn-blue-alt, .hover-blue-alt:hover, .label-blue-alt { + color: #fff; + background: #65a6ff; + border-color: #5388d1 +} + +.btn-blue-alt.active, .btn-blue-alt.disabled, .btn-blue-alt.disabled.active, .btn-blue-alt.disabled:active, .btn-blue-alt.disabled:focus, .btn-blue-alt.disabled:hover, .btn-blue-alt:active, .btn-blue-alt:focus, .btn-blue-alt:hover, .btn-blue-alt[disabled], .btn-blue-alt[disabled].active, .btn-blue-alt[disabled]:active, .btn-blue-alt[disabled]:focus, .btn-blue-alt[disabled]:hover, .label-blue-alt[href]:focus, .label-blue-alt[href]:hover, .open .dropdown-toggle.btn-blue-alt { + color: #fff; + background: #478ded; + border-color: #4c7ec1 +} + +.badge-azure, .bg-azure, .btn-azure, .hover-azure:hover, .label-azure { + color: #fff; + background: #41e5c0; + border-color: #3acead +} + +.btn-azure.active, .btn-azure.disabled, .btn-azure.disabled.active, .btn-azure.disabled:active, .btn-azure.disabled:focus, .btn-azure.disabled:hover, .btn-azure:active, .btn-azure:focus, .btn-azure:hover, .btn-azure[disabled], .btn-azure[disabled].active, .btn-azure[disabled]:active, .btn-azure[disabled]:focus, .btn-azure[disabled]:hover, .label-azure[href]:focus, .label-azure[href]:hover, .open .dropdown-toggle.btn-azure { + color: #fff; + background: #27d1ab; + border-color: #24c19e +} + +.border-black { + border-color: #212121 !important +} + +.border-blue { + border-color: #5bccf6 !important +} + +.border-blue-alt { + border-color: #65a6ff !important +} + +.border-azure { + border-color: #41e5c0 !important +} + +.border-gray { + border-color: #c2c2c2 !important +} + +.border-gray-dark { + border-color: #828282 !important +} + +.border-green { + border-color: #2ecc71 !important +} + +.border-orange { + border-color: #fa7753 !important +} + +.border-yellow { + border-color: #fc0 !important +} + +.border-purple { + border-color: #984dff !important +} + +.border-red { + border-color: #ff5757 !important +} + +.parsley-success { + border-color: #77e038 !important +} + +.parsley-error { + border-color: #e03838 !important +} + +.btn, .fc-button { + font-size: 14px; + position: relative; + display: inline-block; + padding: 0 12px; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-align: center; + border-width: 1px; + border-style: solid; + border-color: transparent; + background-image: none; + -o-user-select: none +} + +.btn-alt, .content-box-header-alt { + font-weight: 700; + text-transform: uppercase +} + +.btn, .fc-button, .size-md { + line-height: 32px; + height: 34px; + min-width: 34px +} + +.btn-abs { + position: absolute; + top: 50%; + right: 0; + margin-top: -17px +} + +.btn.hover-round:hover { + border-radius: 100px +} + +.btn-group-vertical>.btn:not(:first-child):not(:last-child), .btn-link { + border-radius: 0 +} + +.btn.active, .btn:active, .fc-state-active, .fc-state-down, .ui-datepicker .ui-datepicker-buttonpane button:active, .ui-datepicker .ui-datepicker-next:active, .ui-datepicker .ui-datepicker-prev:active, .ui-dialog .ui-dialog-titlebar-close:active, .ui-dialog-buttonset button:active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125) +} + +.btn.disabled, .btn[disabled], .disabled, .fc-state-disabled, fieldset[disabled] .btn { + cursor: not-allowed; + pointer-events: none; + opacity: .65; + -webkit-box-shadow: none; + box-shadow: none; + filter: alpha(opacity=65) +} + +.btn-link { + cursor: pointer +} + +.btn-link, .btn-link:active, .btn-link[disabled] { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none +} + +.btn-link:focus, .btn-link:hover { + text-decoration: underline; + background-color: transparent +} + +.btn-border:hover, .pager li>a:focus, .pager li>a:hover { + text-decoration: none +} + +.btn-group-lg>.btn, .btn-lg, .size-lg { + line-height: 44px; + min-width: 56px; + height: 46px +} + +.btn-lg-abs { + margin-top: -23px +} + +.btn-group-lg>.btn, .btn-lg { + font-size: 18px; + padding: 0 16px +} + +.btn-group-sm>.btn, .btn-sm, .size-sm { + line-height: 28px; + height: 30px +} + +.btn-sm-abs { + margin-top: -15px +} + +.btn-group-sm>.btn, .btn-sm { + font-size: 13px; + padding: 0 10px +} + +.btn-group-xs>.btn, .btn-xs, .size-xs { + line-height: 20px; + min-width: 22px; + height: 22px +} + +.btn-xs-abs { + margin-top: -11px +} + +.btn-group-xs>.btn, .btn-xs { + font-size: 11px; + padding: 0 5px +} + +.btn .caret { + margin-left: 0 +} + +.btn-lg .caret { + border-width: 5px 5px 0 +} + +.dropup .btn-lg .caret { + border-width: 0 5px 5px +} + +.btn-block { + display: block; + padding-right: 0; + padding-left: 0 +} + +.btn-block+.btn-block { + margin-top: 5px +} + +.btn-group, .btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle +} + +.btn-group-vertical>.btn, .btn-group>.btn { + position: relative; + float: left +} + +.btn-group-vertical>.btn.active, .btn-group-vertical>.btn:active, .btn-group-vertical>.btn:focus, .btn-group-vertical>.btn:hover, .btn-group>.btn.active, .btn-group>.btn:active, .btn-group>.btn:focus, .btn-group>.btn:hover { + z-index: 2 +} + +.btn-group .btn+.btn, .btn-group .btn+.btn-group, .btn-group .btn-group+.btn, .btn-group .btn-group+.btn-group { + margin-left: -1px +} + +.btn-toolbar { + margin-left: -5px +} + +.btn-toolbar>.btn, .btn-toolbar>.btn-group, .btn-toolbar>.input-group { + margin-left: 10px +} + +.btn-group>.btn:first-child { + margin-left: 0 +} + +.btn-group>.btn+.dropdown-toggle { + padding-right: 8px; + padding-left: 8px +} + +.btn-group>.btn-lg+.dropdown-toggle { + padding-right: 12px; + padding-left: 12px +} + +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125) +} + +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none +} + +.btn-group-vertical>.btn, .btn-group-vertical>.btn-group, .btn-group-vertical>.btn-group>.btn { + display: block; + float: none; + width: 100%; + max-width: 100% +} + +.btn-group-vertical>.btn-group>.btn { + float: none +} + +.btn-group-vertical>.btn+.btn, .btn-group-vertical>.btn+.btn-group, .btn-group-vertical>.btn-group+.btn, .btn-group-vertical>.btn-group+.btn-group { + margin-top: -1px; + margin-left: 0 +} + +.btn-group-justified { + display: table; + table-layout: fixed; + border-collapse: separate +} + +.btn-group-justified>.btn, .btn-group-justified>.btn-group { + display: table-cell; + float: none +} + +.btn-group-vertical>.btn:first-child:not(:last-child) { + border-top-right-radius: 3px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical>.btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 3px +} + +.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn, .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn, .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0 +} + +.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child, .btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.btn-group>.btn-group:first-child>.btn:last-child, .btn-group>.btn-group:first-child>.dropdown-toggle, .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group>.btn-group:last-child>.btn:first-child, .btn-group>.btn:last-child:not(:first-child), .btn-group>.dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.pagination { + display: inline-block; + padding-left: 0 +} + +.pager li, .pagination>li { + display: inline +} + +.pagination>li>a, .pagination>li>span { + line-height: 1.42857143; + position: relative; + float: left; + margin-left: -1px; + padding: 6px 12px; + text-decoration: none; + border-width: 1px; + border-style: solid +} + +.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover, .pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover { + z-index: 2 +} + +.pagination>li:first-child>a, .pagination>li:first-child>span { + margin-left: 0 +} + +.pagination-lg>li>a, .pagination-lg>li>span { + font-size: 18px; + padding: 10px 16px +} + +.pagination-sm>li>a, .pagination-sm>li>span { + font-size: 12px; + padding: 5px 10px +} + +.pager { + margin-top: 0; + padding-left: 0; + list-style: none; + text-align: center +} + +.pager li>a, .pager li>span { + display: inline-block; + padding: 5px 14px; + border: 1px solid #ddd; + border-radius: 15px; + background-color: #fff +} + +.btn>.icon-separator, .icon-separator.float-right { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important +} + +.pager .next>a, .pager .next>span { + float: right +} + +.pager .previous>a, .pager .previous>span { + float: left +} + +.pager .disabled>a, .pager .disabled>a:focus, .pager .disabled>a:hover, .pager .disabled>span, .pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, .pagination>.disabled>span:focus, .pagination>.disabled>span:hover { + cursor: not-allowed; + color: #999; + background-color: #fff +} + +.btn>.icon-separator { + position: absolute; + top: 0; + left: 0; + width: 32px; + height: 100%; + border-top-right-radius: 0 !important +} + +.icon-separator+.button-content { + margin-left: 32px +} + +.btn-xs .icon-separator { + width: 22px +} + +.btn-xs .icon-separator+.button-content { + margin-left: 22px +} + +.btn-sm .icon-separator { + width: 25px +} + +.btn-sm .icon-separator+.button-content { + margin-left: 25px +} + +.btn-lg .icon-separator { + width: 44px +} + +.btn-lg .icon-separator+.button-content { + margin-left: 44px +} + +.icon-separator.float-right { + border-top-left-radius: 0 !important +} + +.vertical-button { + line-height: 1.6em; + height: auto; + padding: 10px 0 5px +} + +.vertical-button .button-content { + opacity: .7; + filter: alpha(opacity=70) +} + +.icon-separator-vertical { + font-size: 25px; + display: block; + margin: 5px auto +} + +.dashboard-buttons .btn { + width: 93px; + margin: 5px 3px +} + +.btn-outline, .btn-outline-inverse { + display: inline-block; + text-align: center; + color: #fff; + box-sizing: initial; + border-width: 2px; + border-style: solid; + text-transform: uppercase +} + +.btn-outline-inverse { + border-color: rgba(255, 255, 255, .47) +} + +.btn-outline-inverse:hover { + background: rgba(255, 255, 255, .2); + border-color: #fff +} + +.btn-outline-inverse.hero-btn { + color: #fff +} + +.btn-outline { + color: rgba(0, 0, 0, .8); + border-color: rgba(0, 0, 0, .6) +} + +.btn-outline:hover { + color: #fff; + border-color: rgba(0, 0, 0, .8); + background: rgba(0, 0, 0, .8) +} + +.btn.btn-round { + border-radius: 150px; + padding: 0 +} + +.btn-round.btn-lg { + width: 46px; + min-width: 46px +} + +.btn-round.btn-xlg { + width: 66px; + min-width: 66px; + height: 66px; + line-height: 66px +} + +.btn-round.btn-xlg .glyph-icon { + font-size: 24px +} + +.btn-round.btn-md { + width: 34px +} + +.btn-round.btn-sm { + width: 30px +} + +.btn-round.btn-xs { + width: 22px +} + +.btn-alt { + font-size: 12px +} + +.btn-hover span { + padding: 0 20px; + left: 0; + position: relative; + transition: opacity .2s ease-out, left .2s ease-out; + -webkit-transition: opacity .2s ease-out, left .2s ease-out +} + +.btn-hover .glyph-icon { + opacity: 0; + -ms-filter: "alpha(opacity=0)"; + position: absolute; + right: 20px; + transition: all .2s ease-out; + -webkit-transition: all .2s ease-out +} + +.btn-hover:hover .glyph-icon { + opacity: 1; + right: 15px; + -ms-filter: "alpha(opacity=100)" +} + +.btn-hover:hover span { + left: -15px +} + +.btn-border { + border-width: 2px; + border-style: solid +} + +.btn-border span { + opacity: .75; + filter: alpha(opacity=75) +} + +.btn-border:hover span { + opacity: 1; + filter: alpha(opacity=100) +} + +.btn-group-justified>.btn, .btn-group-justified>.btn-group { + width: auto +} + +.demo-margin .btn { + margin-bottom: 10px +} + +.content-box { + background: #fff; + margin-bottom: 20px +} + +.content-box, .content-box-header { + position: relative; + border-width: 1px; + border-style: solid +} + +.content-box-header { + font-size: 14px; + text-transform: uppercase; + margin: -1px -1px 0; + padding: 15px; + border-color: transparent +} + +.content-box-header small+.font-size-11.float-right { + position: absolute; + top: 14px; + right: 10px +} + +.content-box-header-alt { + padding: 15px 10px 14px; + font-size: 12px +} + +.content-box-header-alt small { + font-size: 13px; + font-weight: 400; + display: block; + padding: 5px 0 0; + text-transform: none; + opacity: .7; + filter: alpha(opacity: 70) +} + +.content-box .ui-widget-overlay { + position: absolute +} + +.content-box .ui-widget-overlay img { + position: absolute; + top: 50%; + left: 50%; + margin: -27px 0 0 -27px +} + +.content-box .content-box-wrapper { + line-height: 1.6em; + padding: 15px +} + +.content-box .content-box-wrapper .scrollable-content, .content-box .content-box-wrapper p:last-child { + margin-bottom: 0 +} + +.content-box .content-box-header>.glyph-icon { + margin-right: 5px; + opacity: .7; + filter: alpha(opacity: 70) +} + +.content-box-header-alt .icon-separator .glyph-icon, .content-box-header-alt>.glyph-icon { + font-size: 22px; + line-height: 30px; + position: absolute; + top: 50%; + left: 15px; + width: 30px; + height: 30px; + margin-top: -15px +} + +.content-box-header>.icon-separator { + position: relative; + top: 1px; + left: -15px; + padding: 18px 15px 16px; + text-align: center +} + +.content-box-header>.icon-separator .glyph-icon { + margin-left: 3px +} + +.content-box-header-alt>.header-wrapper { + overflow: hidden; + display: block; + margin-left: 40px +} + +.content-box-header-alt>.icon-separator+.header-wrapper { + margin-left: 65px +} + +.content-box-header-alt>.icon-separator { + position: absolute; + top: 0; + left: 0; + width: 60px; + height: 100% +} + +.content-box-header-alt>.icon-separator .glyph-icon { + left: 50%; + margin-left: -15px +} + +.header-buttons { + position: absolute; + top: 0; + right: 10px; + height: 100%; + display: block +} + +.header-buttons .btn-xs { + top: 13px +} + +.header-buttons .btn-sm { + top: 10px +} + +.header-buttons .btn-sm:last-child { + margin-right: 0 +} + +.header-buttons>.btn-group:last-child { + margin-right: -2px +} + +.content-box-header-alt .header-buttons .btn-xs { + top: 24px +} + +.content-box-header-alt .header-buttons .btn-sm { + top: 20px +} + +.content-box-header-alt .header-buttons .btn-sm:last-child { + margin-right: 5px +} + +.header-buttons-separator { + position: absolute; + top: 0; + right: 0; + height: 100% +} + +.header-buttons-separator .icon-separator { + top: 0; + left: 0; + display: block; + float: left; + min-width: 20px; + height: 100%; + padding: 0 10px +} + +.header-buttons-separator .icon-separator .glyph-icon { + line-height: 30px; + position: relative; + top: 50%; + display: block; + min-width: 30px; + height: 30px; + margin: -15px 0 0; + text-align: center +} + +.header-buttons>.btn-group { + margin-top: 8px +} + +.header-buttons .btn-group-xs { + margin-top: 14px +} + +.header-buttons .btn-group-xs:last-child { + margin-right: 0 +} + +.ui-dialog-buttonpane, body .button-pane { + padding: 10px; + text-align: center; + border-width: 1px 0 0; + border-style: solid; + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +body .button-pane-top { + border-width: 0 0 1px; + border-radius: 0 +} + +.scrollable-content { + overflow-y: scroll; + overflow-x: hidden; + height: 300px; + padding-right: 0 +} + +.scrollable-xs { + overflow-y: scroll; + height: 200px +} + +.scrollable-sm { + overflow-y: scroll; + height: 400px +} + +.scrollable-lg { + overflow-y: scroll; + height: 500px +} + +.toggle-button .glyph-icon { + -webkit-transition-duration: .5s; + -moz-transition-duration: .5s; + -o-transition-duration: .5s; + transition-duration: .5s; + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + -o-transition-property: -o-transform; + transition-property: transform +} + +.hidden-button .content-box-header .btn, .hidden-button .content-box-header a, .hidden-button .content-box-header button { + display: none +} + +.content-box.border-top .content-box-header { + font-size: 18px; + margin: 0 +} + +.content-box.border-top .content-box-header small { + opacity: .8; + -moz-opacity: .8; + filter: alpha(opacity: 80) +} + +.content-box.border-top .content-box-header+.content-box-wrapper { + padding-top: 0 +} + +.box-xs { + width: 200px +} + +.box-sm { + width: 324px +} + +.box-md { + width: 400px +} + +.box-lg { + width: 500px +} + +.content-box-header>.ui-tabs-nav { + position: absolute; + top: 2px; + right: 0; + padding: 0; + list-style: none; + border: 0 +} + +.content-box-header>.ui-tabs-nav li>a { + line-height: 49px; + height: 49px; + margin: 0 2px; + color: rgba(255, 255, 255, .7); + border: 0; + background: 0 0 +} + +.content-box-header>.ui-tabs-nav li>a:hover { + color: #fff; + background: rgba(255, 255, 255, .2) +} + +.panel-heading>.dropdown .dropdown-toggle, .panel-title, .panel-title>a { + color: inherit +} + +.content-box-header.bg-default>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a, .content-box-header.bg-default>.ui-tabs-nav li.ui-tabs-active>a, .content-box-header.bg-gray>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a, .content-box-header.bg-gray>.ui-tabs-nav li.ui-tabs-active>a, .content-box-header.bg-white>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a, .content-box-header.bg-white>.ui-tabs-nav li.ui-tabs-active>a { + line-height: 46px; + height: 46px; + background: #F6F6F9 +} + +.content-box-header.bg-default>.ui-tabs-nav li>a, .content-box-header.bg-gray>.ui-tabs-nav li>a, .content-box-header.bg-white>.ui-tabs-nav li>a { + line-height: 50px; + height: 50px; + margin: 0; + border-radius: 0 +} + +.content-box-header.bg-default>.ui-tabs-nav, .content-box-header.bg-gray>.ui-tabs-nav, .content-box-header.bg-white>.ui-tabs-nav { + top: 0 +} + +.content-box-header>.ui-tabs-nav li.ui-tabs-active.ui-state-hover>a, .content-box-header>.ui-tabs-nav li.ui-tabs-active>a { + line-height: 47px; + height: 49px; + background: #fff +} + +.panel { + margin-bottom: 20px; + border-width: 1px; + border-style: solid; + border-radius: 4px; + background-color: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, .05) +} + +.panel-title, .panel>.list-group { + margin-bottom: 0 +} + +.panel-body { + padding: 15px 20px; + position: relative +} + +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent +} + +.panel-title { + font-size: 16px; + margin-top: 0 +} + +.panel-footer { + padding: 10px 15px; + border-top: 1px solid transparent +} + +.panel>.list-group .list-group-item { + border-width: 1px 0; + border-radius: 0 +} + +.panel-group .panel-heading, .panel>.list-group:last-child .list-group-item:last-child { + border-bottom: 0 +} + +.panel>.list-group:first-child .list-group-item:first-child { + border-top: 0 +} + +.panel-heading+.list-group .list-group-item:first-child { + border-top-width: 0 +} + +.panel-group { + margin-bottom: 20px +} + +.panel-group .panel { + overflow: hidden; + margin-bottom: 0 +} + +.panel-group .panel+.panel { + margin-top: 5px +} + +.panel-group .panel-heading+.panel-collapse .panel-body { + border-top: 1px solid transparent +} + +.panel-group .panel-footer { + border-top: 0 +} + +.panel-group .panel-footer+.panel-collapse .panel-body { + border-bottom: 1px solid transparent +} + +fieldset, legend { + padding: 0; + border: 0 +} + +fieldset { + margin: 0 +} + +legend { + font-size: 21px; + line-height: inherit; + display: block; + width: 100%; + margin-bottom: 20px; + color: #333; + border-bottom: 1px solid #dfe8f1 +} + +label { + font-weight: 700; + display: inline-block +} + +.checkbox, .radio, input[type=file], output { + display: block +} + +input[type=checkbox], input[type=radio] { + line-height: normal +} + +select[multiple], select[size] { + height: auto +} + +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit +} + +input[type=file]:focus, input[type=checkbox]:focus, input[type=radio]:focus { + outline: #333 dotted thin; + outline: -webkit-focus-ring-color auto 5px; + outline-offset: -2px +} + +input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { + height: auto +} + +output { + font-size: 14px; + line-height: 1.428571429; + padding-top: 7px; + vertical-align: middle; + color: #555 +} + +.bootstrap-timepicker-widget table td input, .chosen-container-multi, .chosen-container-single .chosen-search input, .dataTables_length select, .form-control, .input, .ui-toolbar input, .ui-toolbar select, div.dataTables_filter input { + font-size: 13px; + display: block; + float: none; + background: #fff; + width: 100%; + height: 34px; + padding: 6px 12px; + color: #2b2f33; + border: 1px solid #dfe8f1; + -webkit-box-shadow: inset 1px 1px 3px #f6f6f6; + -moz-box-shadow: inset 1px 1px 3px #f6f6f6; + box-shadow: inset 1px 1px 3px #f6f6f6 +} + +.chosen-container-multi.chosen-with-drop.chosen-container-active { + border: 1px solid #ddd; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + box-shadow: 0 0 0 transparent +} + +.bootstrap-timepicker-widget table td input:focus, .chosen-container-active, .chosen-container-multi.chosen-container-active, .form-control:focus, .input:focus, .selector.focus, .ui-toolbar input:focus, .ui-toolbar select:focus, div.dataTables_filter input:focus { + color: #333; + border-color: #3da6ff +} + +.form-control:-moz-placeholder { + color: #999 +} + +.form-control::-moz-placeholder { + color: #999 +} + +.form-control:-ms-input-placeholder { + color: #999 +} + +.form-control::-webkit-input-placeholder { + color: #999 +} + +textarea.form-control { + height: auto +} + +.form-group { + margin-bottom: 15px +} + +.form-group label { + margin-bottom: 5px +} + +.form-group .switch-toggle { + margin-top: 6px +} + +.checkbox, .radio { + min-height: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle +} + +.checkbox label, .radio label { + font-weight: 400; + display: inline; + margin-bottom: 0; + cursor: pointer +} + +.checkbox input[type=checkbox], .checkbox-inline input[type=checkbox], .radio input[type=radio], .radio-inline input[type=radio] { + float: left +} + +.checkbox+.checkbox, .radio+.radio { + margin-top: -5px +} + +.checkbox-inline, .radio-inline { + font-weight: 400; + line-height: 19px; + display: inline-block; + height: 19px; + margin-bottom: 0; + cursor: pointer; + vertical-align: middle +} + +.checkbox-inline label, .radio-inline label { + font-weight: 400; + line-height: 17px +} + +.checkbox-inline+.checkbox-inline, .radio-inline+.radio-inline { + margin-top: 0; + margin-left: 10px +} + +.checkbox-inline[disabled], .checkbox[disabled], .radio-inline[disabled], .radio[disabled], fieldset[disabled] .checkbox, fieldset[disabled] .checkbox-inline, fieldset[disabled] .radio, fieldset[disabled] .radio-inline, fieldset[disabled] input[type=checkbox], fieldset[disabled] input[type=radio], input[type=checkbox][disabled], input[type=radio][disabled] { + cursor: not-allowed +} + +.input-sm { + font-size: 12px; + line-height: 1.5; + height: 30px; + padding: 5px 10px; + border-radius: 3px +} + +select.input-sm { + line-height: 30px; + height: 30px +} + +textarea.input-sm { + height: auto +} + +.input-lg { + font-size: 18px; + line-height: 1.33; + height: 45px; + padding: 10px 16px; + border-radius: 6px +} + +select.input-lg { + line-height: 45px; + height: 45px +} + +textarea.input-lg { + height: auto +} + +.form-control-static { + margin-bottom: 0 +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 0; + color: #737373 +} + +@media (min-width:768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle + } + + .form-inline .form-control { + display: inline-block + } + + .form-inline .checkbox, .form-inline .radio { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + padding-left: 0 + } + + .form-inline .checkbox input[type=checkbox], .form-inline .radio input[type=radio] { + float: none; + margin-left: 0 + } + + .form-horizontal .control-label { + text-align: right + } +} + +.form-horizontal .checkbox, .form-horizontal .checkbox-inline, .form-horizontal .control-label, .form-horizontal .radio, .form-horizontal .radio-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px +} + +.form-horizontal>.form-group { + margin-right: -15px; + margin-left: -15px +} + +.form-horizontal .form-group:after, .form-horizontal .form-group:before { + display: table; + content: ' ' +} + +.form-horizontal .form-control-static { + padding-top: 7px +} + +.input-group { + position: relative; + display: table; + width: 100%; + border-collapse: separate +} + +.input-group.col { + float: none; + padding-right: 0; + padding-left: 0 +} + +.input-group .form-control { + width: 100%; + margin-bottom: 0 +} + +.input-group-lg>.form-control, .input-group-lg>.input-group-addon, .input-group-lg>.input-group-btn>.btn { + font-size: 18px; + line-height: 1.33; + height: 45px; + padding: 10px 16px; + border-radius: 6px +} + +select.input-group-lg>.form-control, select.input-group-lg>.input-group-addon, select.input-group-lg>.input-group-btn>.btn { + line-height: 45px; + height: 45px +} + +textarea.input-group-lg>.form-control, textarea.input-group-lg>.input-group-addon, textarea.input-group-lg>.input-group-btn>.btn { + height: auto +} + +.input-group-sm>.form-control, .input-group-sm>.input-group-addon, .input-group-sm>.input-group-btn>.btn { + font-size: 12px; + line-height: 1.5; + height: 30px; + padding: 5px 10px; + border-radius: 3px +} + +select.input-group-sm>.form-control, select.input-group-sm>.input-group-addon, select.input-group-sm>.input-group-btn>.btn { + line-height: 30px; + height: 30px +} + +textarea.input-group-sm>.form-control, textarea.input-group-sm>.input-group-addon, textarea.input-group-sm>.input-group-btn>.btn { + height: auto +} + +.input-group .form-control, .input-group-addon, .input-group-btn { + display: table-cell +} + +.input-group .form-control:not(:first-child):not(:last-child), .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child) { + border-radius: 0 +} + +.input-group-addon div[id^=uniform-] { + margin: 0 -3px +} + +.input-group-addon, .input-group-btn { + width: 1%; + vertical-align: middle; + white-space: nowrap +} + +.input-group-addon { + font-size: 14px; + font-weight: 400; + line-height: 1; + padding: 6px 12px; + text-align: center; + color: #2b2f33; + background-color: rgba(239, 244, 246, .36); + border: 1px solid #dfe8f1; + border-radius: 4px +} + +body, label { + color: #3e4855 +} + +.input-group-addon .glyph-icon { + display: block; + min-width: 20px; + margin: 0 -4px; + text-align: center +} + +.input-group-addon.addon-inside { + line-height: 24px; + position: absolute; + top: 5px; + left: 6px; + display: block; + width: 32px; + height: 24px; + padding: 0; + border-width: 1px; + border-style: solid +} + +.input-group-btn, .input-group-btn>.btn, .ui-spinner { + position: relative +} + +.input-group-lg .input-group-addon.addon-inside { + top: 10px; + left: 10px; + z-index: 999 +} + +.input-group-addon.addon-inside .glyph-icon { + margin: 0 +} + +.input-group-addon.addon-inside+input { + padding-left: 48px +} + +.input-group-addon.input-sm { + font-size: 12px; + padding: 5px 10px; + border-radius: 3px +} + +.input-group-addon.input-lg { + font-size: 18px; + padding: 10px 16px; + border-radius: 6px +} + +.input-group-addon input[type=checkbox], .input-group-addon input[type=radio] { + margin-top: 0 +} + +.input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child>.btn, .input-group-btn:first-child>.dropdown-toggle, .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group-addon:first-child { + border-right: 0 +} + +.input-group-addon.addon-inside:first-child { + border-right-width: 1px; + border-right-style: solid; + border-color: transparent; + z-index: 999 +} + +.input-group-addon+.form-control, .input-group-addon:last-child, .input-group-btn+.form-control, .input-group-btn:first-child>.btn:not(:first-child), .input-group-btn:last-child>.btn, .input-group-btn:last-child>.dropdown-toggle { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.input-group-addon:last-child { + border-left: 0 +} + +.input-group-btn:first-child>.btn { + margin-right: -1px +} + +.input-group-btn:last-child>.btn { + margin-left: -1px +} + +.input-group-btn>.btn+.btn { + margin-left: -4px +} + +.input-group-btn>.btn:active, .input-group-btn>.btn:hover { + z-index: 2 +} + +[data-toggle=buttons]>.btn>input[type=checkbox], [data-toggle=buttons]>.btn>input[type=radio] { + display: none +} + +textarea.textarea-autoresize, textarea.textarea-no-resize { + resize: none +} + +.textarea-autosize { + transition: height .3s; + -webkit-transition: height .3s; + -moz-transition: height .3s +} + +textarea.form-control { + line-height: 1.6em; + padding: 8px 12px +} + +textarea.textarea-xs { + height: 50px +} + +textarea.textarea-sm { + height: 125px +} + +textarea.textarea-md { + height: 200px +} + +textarea.textarea-lg { + height: 275px +} + +.ui-spinner { + display: block +} + +.xchart .color0.comp .fill, .xchart .color1.comp .fill { + display: none +} + +.ui-spinner .ui-spinner-button { + font-size: 9px; + line-height: 17px; + position: absolute; + right: 0; + width: 17px; + height: 17px; + cursor: pointer; + text-align: center; + border-width: 1px; + border-style: solid +} + +.ui-spinner .ui-spinner-up { + top: 0 +} + +.ui-spinner .ui-spinner-down { + bottom: 0 +} + +.parsley-errors-list li { + font-size: 12px; + padding-top: 5px +} + +.bordered-row>.form-group { + padding: 20px 0; + margin-bottom: 0; + border-top-width: 1px; + border-top-style: dashed +} + +.bordered-row>.form-group:last-child { + padding-bottom: 0 +} + +.form-group .ui-slider { + margin-top: 14px +} + +.form-group .ui-slider+.input-group { + margin-top: 20px +} + +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + background-color: #fff; + line-height: 1.42857143 +} + +#page-title>h2, #page-title>p, h1, h2, h3, h4, h5, h6 { + font-family: Raleway, "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300 +} + +#page-header .user-account-btn>a.user-profile .glyph-icon, .logo-bg { + background-color: rgba(255, 255, 255, .1); + color: #fff +} + +#page-header .user-account-btn>a.user-profile { + color: #fff +} + +#header-nav-right .dropdown>a .glyph-icon, #header-nav-right .header-btn .glyph-icon { + color: rgba(255, 255, 255, .8) +} + +#header-nav-right .dropdown>a:hover .glyph-icon, #header-nav-right .header-btn:hover .glyph-icon { + color: rgba(255, 255, 255, .95) +} + +#header-nav-right .dropdown>a, #header-nav-right .header-btn { + border-color: rgba(255, 255, 255, .2) +} + +#header-nav-right .dropdown>a:hover, #header-nav-right .header-btn:hover { + background: rgba(255, 255, 255, .05); + border-color: rgba(255, 255, 255, .25) +} + +#page-content { + background: #fafcfe +} + +#page-sidebar ul li.header { + color: #000 +} + +#page-sidebar ul li a .glyph-icon { + color: #0093d9 +} + +#page-sidebar ul li a:hover, #page-sidebar ul li.sfHover>a.sf-with-ul { + border-color: #d1d9dd +} + +#sidebar-menu li .sidebar-submenu { + border-color: #f6f7f8 +} + +#sidebar-menu li .sidebar-submenu ul li { + border-color: #f8f9fa +} + +#sidebar-menu li .sidebar-submenu ul li a.sfActive, #sidebar-menu li .sidebar-submenu ul li a:hover { + background: #fcfdfe +} + +#sidebar-menu li .sidebar-submenu ul li a.sfActive { + color: #1c82e1 +} + +#page-sidebar.font-inverse ul li.header { + color: rgba(255, 255, 255, .95) +} + +#page-sidebar.font-inverse ul li.divider { + background: rgba(255, 255, 255, .1) +} + +#page-sidebar.font-inverse #sidebar-menu>li>a { + color: rgba(255, 255, 255, .62) +} + +#page-sidebar.font-inverse #sidebar-menu li a:hover, #page-sidebar.font-inverse #sidebar-menu li.sfHover>a.sf-with-ul { + border-color: rgba(255, 255, 255, .26); + color: rgba(255, 255, 255, .96) +} + +#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu { + border-color: rgba(255, 255, 255, .08); + background: rgba(255, 255, 255, .05) +} + +#page-sidebar.font-inverse #sidebar-menu li a { + color: rgba(255, 255, 255, .62) +} + +#page-sidebar.font-inverse #sidebar-menu li a:hover { + color: rgba(255, 255, 255, .96) +} + +#page-sidebar.font-inverse#page-sidebar ul li a .glyph-icon { + color: rgba(255, 255, 255, .8) +} + +#page-sidebar.font-inverse#page-sidebar ul li a:hover .glyph-icon { + color: rgba(255, 255, 255, 1); + opacity: .9; + -moz-opacity: .9; + filter: alpha(opacity: 90) +} + +#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu ul li { + border-color: rgba(255, 255, 255, .07) +} + +#page-sidebar.font-inverse #sidebar-menu li .sidebar-submenu ul li a:hover { + background: rgba(255, 255, 255, .05) +} + +.btn-link, .chosen-disabled .chosen-single, .content-box-header.bg-default>.ui-tabs-nav li>a, .content-box-header.bg-gray>.ui-tabs-nav li>a, .content-box-header.bg-white>.ui-tabs-nav li>a, .content-box-header>.ui-tabs-nav li.ui-tabs-active>a, .pagination>li>a, .pagination>li>span, .table, a, body .content-box-header>.ui-tabs-nav li.ui-tabs-active>a:hover, div.selector { + color: #8da0aa +} + +#page-sidebar ul li.sfHover>a.sf-with-ul, .btn-link:hover, .content-box-header.bg-default>.ui-tabs-nav li>a:hover, .content-box-header.bg-gray>.ui-tabs-nav li>a:hover, .content-box-header.bg-white>.ui-tabs-nav li>a:hover, .features-tour-box h3, .font-primary, .tabs-nav li a:hover, .tabs-nav li.active a, a:hover, table.dataTable thead th.sorting_asc:after, table.dataTable thead th.sorting_desc:after { + color: #1c82e1 +} + +.border-primary, .btn-primary, .nav>li.active>a, .nav>li.active>a:focus, .nav>li.active>a:hover, .ui-accordion .ui-accordion-header.ui-accordion-header-active, .ui-datepicker .ui-datepicker-next, .ui-datepicker .ui-datepicker-prev, .ui-dialog-buttonset button, .ui-spinner .ui-spinner-button:hover, a.list-group-item.active, a.list-group-item.active:focus, a.list-group-item.active:hover, a.thumbnail:hover, div[id^=uniform-] span.checked, li.active a.list-group-item, li.active a.list-group-item:focus, li.active a.list-group-item:hover { + border-color: #00a792 +} + +a:focus { + outline: 0 !important +} + +#loadingbar, #nav-toggle span:after, #nav-toggle span:before, #nav-toggle.collapsed span, .badge-primary, .bg-primary, .bootstrap-switch-primary, .btn-primary, .chosen-container .chosen-results li.active-result.highlighted, .daterangepicker .ranges li.active, .daterangepicker .ranges li.active:hover, .fc-event, .form-wizard>ul>li.active .wizard-step, .irs-line-left, .irs-line-mid, .irs-line-right, .label-primary, .ms-hover.ui-state-focus, .ms-list .ms-hover, .nav>li.active>a, .nav>li.active>a:focus, .nav>li.active>a:hover, .owl-controls .owl-page span, .ui-accordion-header.ui-accordion-header-active, .ui-datepicker .ui-datepicker-current-day a, .ui-datepicker .ui-datepicker-current-day span, .ui-datepicker .ui-datepicker-next, .ui-datepicker .ui-datepicker-prev, .ui-dialog-buttonset button, .ui-menu li>a:hover, .ui-rangeSlider-bar, .ui-slider-handle, .ui-spinner .ui-spinner-button:hover, .ui-tabs-nav li.ui-state-active.ui-state-hover>a, .ui-tabs-nav li.ui-state-active>a, a.list-group-item.active, a.list-group-item.active:focus, a.list-group-item.active:hover, div.switch-toggle.switch-on, div[id^=uniform-] span.checked, li.active a.list-group-item, li.active a.list-group-item:focus, li.active a.list-group-item:hover { + color: #fff; + background: #00bca4 +} + +.font-secondary, .inverse.carousel-wrapper .owl-controls .owl-buttons .owl-next, .inverse.carousel-wrapper .owl-controls .owl-buttons .owl-prev, .post-box .post-title { + color: #00bca4 +} + +.post-box .post-title:hover { + color: #3e4855 +} + +.bg-default, .bg-white.dashboard-box .button-pane, .bg-white.tile-box .tile-footer, .border-default, .bordered-row .form-group, .btn-default, .button-pane, .chosen-container, .chosen-container .chosen-drop, .chosen-container-active.chosen-with-drop .chosen-single div, .chosen-container-multi .chosen-choices li.search-choice, .chosen-container-single .chosen-single div, .content-box, .content-box-header.bg-default, .content-box-header.bg-gray, .content-box-header.bg-white, .dashboard-buttons .btn, .daterangepicker .calendar-date, .dropdown-menu, .email-body, .fc-state-default, .fc-widget-content, .fc-widget-header, .img-thumbnail, .jvectormap-label, .jvectormap-zoomin, .jvectormap-zoomout, .list-group-item, .mail-toolbar, .mailbox-wrapper .nav-list li a, .minicolors-panel, .ms-container .ms-list, .ms-container .ms-selectable li.ms-elem-selectable, .ms-container .ms-selection li.ms-elem-selection, .nav .open>a, .nav .open>a:focus, .nav .open>a:hover, .nav-tabs, .nav-tabs>li>a:focus, .nav-tabs>li>a:hover, .pagination>li>a, .pagination>li>span, .panel, .panel-box.bg-default, .panel-box.bg-gray, .panel-box.bg-white, .panel-content.bg-default, .panel-content.bg-gray, .panel-content.bg-white, .panel-footer, .panel-group .panel-footer+.panel-collapse .panel-body, .panel-group .panel-heading+.panel-collapse .panel-body, .panel-heading, .popover, .popover-title, .posts-list li, .selector i, .table-bordered, .table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th, .tabs-navigation>ul, .tabs-navigation>ul li.ui-state-hover>a, .tabs-navigation>ul li>a, .thumb-pane, .thumbnail, .timeline-box .tl-item .popover, .timeline-box:before, .ui-accordion .ui-accordion-header, .ui-datepicker, .ui-datepicker .ui-datepicker-buttonpane button, .ui-datepicker-buttonpane, .ui-dialog, .ui-dialog .ui-dialog-titlebar, .ui-dialog-buttonpane, .ui-menu, .ui-spinner .ui-spinner-button, .ui-tabs-nav, div.selector, div[id^=uniform-] span { + border-color: #dfe8f1 +} + +.divider, .nav-divider, .timeline-horizontal.timeline-box:before { + background: #dfe8f1 +} + +.content-box.border-top { + border-right-color: #dfe8f1 !important; + border-bottom-color: #dfe8f1 !important; + border-left-color: #dfe8f1 !important +} + +.bg-default, .bg-white.dashboard-box .button-pane, .bg-white.tile-box .tile-footer, .bootstrap-switch-default, .btn-default, .button-pane, .jvectormap-label, .jvectormap-zoomin, .jvectormap-zoomout, .label-default, .mail-toolbar, .panel-footer, .panel-heading, .popover-title, .ui-accordion-header, .ui-datepicker td a, .ui-datepicker td span, .ui-dialog .ui-dialog-titlebar, .ui-spinner .ui-spinner-button, div[id^=uniform-] span { + color: #555a60; + background-color: #FEFEFF +} + +.irs-diapason, .ui-datepicker-buttonpane, .ui-dialog-buttonpane, .ui-rangeSlider-container, .ui-slider-range { + background-color: #FEFEFF +} + +.table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>th { + color: #4b5056; + background-color: #f9fafe +} + +.btn-default.active, .btn-default.disabled, .btn-default.disabled.active, .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, .btn-default:active, .btn-default:focus, .btn-default:hover, .btn-default[disabled], .btn-default[disabled].active, .btn-default[disabled]:active, .btn-default[disabled]:focus, .btn-default[disabled]:hover, .fc-state-active, .fc-state-disabled, .fc-state-down, .fc-state-hover, .jvectormap-zoomin:hover, .jvectormap-zoomout:hover, .open .dropdown-toggle.btn-default, .open.dropdown-submenu a, .ui-accordion-header.ui-state-hover, .ui-datepicker .ui-datepicker-buttonpane button:hover, .ui-tabs-nav>li.ui-state-hover>a { + color: #2b2f33; + border-color: #bfc8d1; + background-color: #f3f3f9 +} + +.btn-default.active .glyph-icon { + color: #2b2f33 !important +} + +.bsdatepicker td span:hover, .bsdatepicker td.active, .bsdatepicker td.day.active:hover, .bsdatepicker th.next:hover, .bsdatepicker th.prev:hover, .btn-primary.active, .btn-primary.disabled, .btn-primary.disabled.active, .btn-primary.disabled:active, .btn-primary.disabled:focus, .btn-primary.disabled:hover, .btn-primary:active, .btn-primary:focus, .btn-primary:hover, .btn-primary[disabled], .btn-primary[disabled].active, .btn-primary[disabled]:active, .btn-primary[disabled]:focus, .btn-primary[disabled]:hover, .daterangepicker .calendar th.next:hover, .daterangepicker .calendar th.prev:hover, .daterangepicker td.active, .daterangepicker td.available.active:hover, .hover-primary:hover, .label-primary[href]:focus, .label-primary[href]:hover, .open .dropdown-toggle.btn-primary, .pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover, .pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover, .ui-accordion-header.ui-accordion-header-active.ui-state-hover, .ui-datepicker .ui-datepicker-next.ui-state-hover, .ui-datepicker .ui-datepicker-prev.ui-state-hover, .ui-datepicker td a:hover, .ui-dialog-buttonset button:hover, .ui-rangeSlider-bar:active, .ui-rangeSlider-bar:hover, .ui-slider-handle.ui-state-active, .ui-slider-handle.ui-state-hover { + color: #fff; + border-color: #00b19b; + background-color: #00ceb4 +} + +.bsdatepicker td span, .bsdatepicker td.day:hover, .bsdatepicker thead tr:first-child th.switch:hover, .chosen-container-multi .chosen-choices li.search-choice, .chosen-container-single .chosen-single div, .daterangepicker .ranges li:hover, .daterangepicker td.available:hover, .nav>li>a:focus, .nav>li>a:hover, .pager li>a:focus, .pager li>a:hover, .pagination>li>a:focus, .pagination>li>a:hover, .pagination>li>span:focus, .pagination>li>span:hover, .selector i, .ui-datepicker-title, a.list-group-item:focus, a.list-group-item:hover { + color: #2b2f33; + background: #eff4f6 +} + +.pager li>a:focus, .pager li>a:hover, .pagination>li>a:focus, .pagination>li>a:hover, .pagination>li>span:focus, .pagination>li>span:hover { + color: #2b2f33; + background-color: #f3f3f9 +} + +.dropdown-menu .active>a, .dropdown-menu .active>a:focus, .dropdown-menu .active>a:hover, .dropdown-menu li>a:hover { + color: #2b2f33; + background: #eff4f6 +} + +.active>.badge, .active>.bs-badge, .active>.bs-label { + color: #666 !important; + background: #fff !important +} + +.active>.glyph-icon, a.list-group-item.active>.glyph-icon, li.active a.list-group-item>.glyph-icon { + color: #fff !important +} + +.icon-separator { + border-right: rgba(255, 255, 255, .21) solid 1px; + background: rgba(255, 255, 255, .2) +} + +.content-box-header.bg-default .icon-separator, .content-box-header.bg-gray .icon-separator, .content-box-header.bg-white .icon-separator, .tile-box.bg-default .tile-header, .tile-box.bg-gray .tile-header, .tile-box.bg-white .tile-header, .tile-box.btn-default .tile-header { + border-right: #dfe8f1 solid 1px; + background: rgba(255, 255, 255, .1) +} + +.content-box-header .header-buttons-separator .icon-separator { + border-right: 0; + border-left: rgba(255, 255, 255, .21) solid 1px +} + +.header-buttons-separator .icon-separator { + color: rgba(255, 255, 255, .8) +} + +.header-buttons-separator .icon-separator:hover { + color: #fff; + background: rgba(255, 255, 255, .3) +} + +.content-box-header.bg-default .header-buttons-separator .icon-separator, .content-box-header.bg-gray .header-buttons-separator .icon-separator, .content-box-header.bg-white .header-buttons-separator .icon-separator { + border-right: 0; + border-left: #dfe8f1 solid 1px; + color: rgba(0, 0, 0, .6) +} + +.content-box-header.bg-default .header-buttons-separator .icon-separator:hover, .content-box-header.bg-gray .header-buttons-separator .icon-separator:hover, .content-box-header.bg-white .header-buttons-separator .icon-separator:hover { + color: rgba(0, 0, 0, .9) +} + +.dashboard-panel .button-pane { + background: rgba(0, 0, 0, .1) !important +} + +.xchart .color0 rect { + fill: #00bca4 +} + +.xchart .color0 circle { + fill: #fff +} + +.xchart .color0 .fill { + fill: rgba(0, 188, 164, .06) +} + +.xchart .color0.comp .pointer, .xchart .color0.comp circle, .xchart .color0.comp rect { + fill: #00bca4 +} + +.xchart .color1 .line, .xchart .color1 circle, .xchart .color1.comp .line { + stroke: #52a7e0 +} + +.xchart .color1 rect { + fill: #52a7e0 +} + +.xchart .color1 circle { + fill: #fff +} + +.xchart .color1 .fill { + fill: rgba(82, 167, 224, .06) +} + +.xchart .color1.comp .pointer, .xchart .color1.comp circle, .xchart .color1.comp rect { + fill: #52a7e0 +} + +body .popover.top .arrow:after { + border-top-color: #fff +} + +body .popover.right .arrow:after { + border-right-color: #fff +} + +body .popover.bottom .arrow:after { + border-bottom-color: #fff +} + +body .popover.left .arrow:after { + border-left-color: #fff +} @font-face { - font-family: 'FontAwesome'; - src: url('fontawesome-webfont.eot?v=4.0.3'); - src: url('fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), - url('fontawesome-webfont.woff?v=4.0.3') format('woff'), - url('fontawesome-webfont.ttf?v=4.0.3') format('truetype'), - url('fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); - font-weight: normal; - font-style: normal; + font-family: 'FontAwesome'; + src: url('fontawesome-webfont.eot?v=4.0.3'); + src: url('fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), + url('fontawesome-webfont.woff?v=4.0.3') format('woff'), + url('fontawesome-webfont.ttf?v=4.0.3') format('truetype'), + url('fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; } .icon-glass:before { - content: "\f000"; + content: "\f000"; } + .icon-music:before { - content: "\f001"; + content: "\f001"; } + .icon-search:before { - content: "\f002"; + content: "\f002"; } + .icon-envelope-o:before { - content: "\f003"; + content: "\f003"; } + .icon-heart:before { - content: "\f004"; + content: "\f004"; } + .icon-star:before { - content: "\f005"; + content: "\f005"; } + .icon-star-o:before { - content: "\f006"; + content: "\f006"; } + .icon-user:before { - content: "\f007"; + content: "\f007"; } + .icon-film:before { - content: "\f008"; + content: "\f008"; } + .icon-th-large:before { - content: "\f009"; + content: "\f009"; } + .icon-th:before { - content: "\f00a"; + content: "\f00a"; } + .icon-th-list:before { - content: "\f00b"; + content: "\f00b"; } + .icon-check:before { - content: "\f00c"; + content: "\f00c"; } + .icon-times:before, .icon-remove:before, .search-choice-close:before, @@ -57,1589 +4111,2075 @@ pre,pre code{white-space:pre-wrap}.clear,.form-row:after,.row:after{clear:both}. .ui-dialog-titlebar-close:before, .icon-clock-os:before, .icon-close:before { - content: "\f00d"; + content: "\f00d"; } + .icon-search-plus:before { - content: "\f00e"; + content: "\f00e"; } + .icon-search-minus:before { - content: "\f010"; + content: "\f010"; } + .icon-power-off:before { - content: "\f011"; + content: "\f011"; } + .icon-signal:before { - content: "\f012"; + content: "\f012"; } + .icon-gear:before, .icon-cog:before { - content: "\f013"; + content: "\f013"; } + .icon-trash-o:before { - content: "\f014"; + content: "\f014"; } + .icon-home:before { - content: "\f015"; + content: "\f015"; } + .icon-file-o:before { - content: "\f016"; + content: "\f016"; } + .icon-clock-o:before { - content: "\f017"; + content: "\f017"; } + .icon-road:before { - content: "\f018"; + content: "\f018"; } + .icon-download:before { - content: "\f019"; + content: "\f019"; } + .icon-arrow-circle-o-down:before { - content: "\f01a"; + content: "\f01a"; } + .icon-arrow-circle-o-up:before { - content: "\f01b"; + content: "\f01b"; } + .icon-inbox:before { - content: "\f01c"; + content: "\f01c"; } + .icon-play-circle-o:before { - content: "\f01d"; + content: "\f01d"; } + .icon-rotate-right:before, .icon-repeat:before { - content: "\f01e"; + content: "\f01e"; } + .icon-refresh:before { - content: "\f021"; + content: "\f021"; } + .icon-list-alt:before { - content: "\f022"; + content: "\f022"; } + .icon-lock:before { - content: "\f023"; + content: "\f023"; } + .icon-flag:before { - content: "\f024"; + content: "\f024"; } + .icon-headphones:before { - content: "\f025"; + content: "\f025"; } + .icon-volume-off:before { - content: "\f026"; + content: "\f026"; } + .icon-volume-down:before { - content: "\f027"; + content: "\f027"; } + .icon-volume-up:before { - content: "\f028"; + content: "\f028"; } + .icon-qrcode:before { - content: "\f029"; + content: "\f029"; } + .icon-barcode:before { - content: "\f02a"; + content: "\f02a"; } + .icon-tag:before { - content: "\f02b"; + content: "\f02b"; } + .icon-tags:before { - content: "\f02c"; + content: "\f02c"; } + .icon-book:before { - content: "\f02d"; + content: "\f02d"; } + .icon-bookmark:before { - content: "\f02e"; + content: "\f02e"; } + .icon-print:before { - content: "\f02f"; + content: "\f02f"; } + .icon-camera:before { - content: "\f030"; + content: "\f030"; } + .icon-font:before { - content: "\f031"; + content: "\f031"; } + .icon-bold:before { - content: "\f032"; + content: "\f032"; } + .icon-italic:before { - content: "\f033"; + content: "\f033"; } + .icon-text-height:before { - content: "\f034"; + content: "\f034"; } + .icon-text-width:before { - content: "\f035"; + content: "\f035"; } + .icon-align-left:before { - content: "\f036"; + content: "\f036"; } + .icon-align-center:before { - content: "\f037"; + content: "\f037"; } + .icon-align-right:before { - content: "\f038"; + content: "\f038"; } + .icon-align-justify:before { - content: "\f039"; + content: "\f039"; } + .icon-list:before { - content: "\f03a"; + content: "\f03a"; } + .icon-dedent:before, .icon-outdent:before { - content: "\f03b"; + content: "\f03b"; } + .icon-indent:before { - content: "\f03c"; + content: "\f03c"; } + .icon-video-camera:before { - content: "\f03d"; + content: "\f03d"; } + .icon-photo:before, .icon-image:before, .icon-picture-o:before { - content: "\f03e"; + content: "\f03e"; } + .icon-pencil:before { - content: "\f040"; + content: "\f040"; } + .icon-map-marker:before { - content: "\f041"; + content: "\f041"; } + .icon-adjust:before { - content: "\f042"; + content: "\f042"; } + .icon-tint:before { - content: "\f043"; + content: "\f043"; } + .icon-edit:before, .icon-pencil-square-o:before { - content: "\f044"; + content: "\f044"; } + .icon-share-square-o:before { - content: "\f045"; + content: "\f045"; } + .icon-check-square-o:before { - content: "\f046"; + content: "\f046"; } + .icon-arrows:before { - content: "\f047"; + content: "\f047"; } + .icon-step-backward:before { - content: "\f048"; + content: "\f048"; } + .icon-fast-backward:before { - content: "\f049"; + content: "\f049"; } + .icon-backward:before { - content: "\f04a"; + content: "\f04a"; } + .icon-play:before { - content: "\f04b"; + content: "\f04b"; } + .icon-pause:before { - content: "\f04c"; + content: "\f04c"; } + .icon-stop:before { - content: "\f04d"; + content: "\f04d"; } + .icon-forward:before { - content: "\f04e"; + content: "\f04e"; } + .icon-fast-forward:before { - content: "\f050"; + content: "\f050"; } + .icon-step-forward:before { - content: "\f051"; + content: "\f051"; } + .icon-eject:before { - content: "\f052"; + content: "\f052"; } + .icon-chevron-left:before { - content: "\f053"; + content: "\f053"; } + .icon-chevron-right:before { - content: "\f054"; + content: "\f054"; } + .icon-plus-circle:before { - content: "\f055"; + content: "\f055"; } + .icon-minus-circle:before { - content: "\f056"; + content: "\f056"; } + .icon-times-circle:before { - content: "\f057"; + content: "\f057"; } + .icon-check-circle:before { - content: "\f058"; + content: "\f058"; } + .icon-question-circle:before { - content: "\f059"; + content: "\f059"; } + .icon-info-circle:before { - content: "\f05a"; + content: "\f05a"; } + .icon-crosshairs:before { - content: "\f05b"; + content: "\f05b"; } + .icon-times-circle-o:before { - content: "\f05c"; + content: "\f05c"; } + .icon-check-circle-o:before { - content: "\f05d"; + content: "\f05d"; } + .icon-ban:before { - content: "\f05e"; + content: "\f05e"; } + .icon-arrow-left:before { - content: "\f060"; + content: "\f060"; } + .icon-arrow-right:before { - content: "\f061"; + content: "\f061"; } + .icon-arrow-up:before { - content: "\f062"; + content: "\f062"; } + .icon-arrow-down:before { - content: "\f063"; + content: "\f063"; } + .icon-mail-forward:before, .icon-share:before { - content: "\f064"; + content: "\f064"; } + .icon-expand:before { - content: "\f065"; + content: "\f065"; } + .icon-compress:before { - content: "\f066"; + content: "\f066"; } + .icon-plus:before { - content: "\f067"; + content: "\f067"; } + .icon-minus:before { - content: "\f068"; + content: "\f068"; } + .icon-asterisk:before { - content: "\f069"; + content: "\f069"; } + .icon-exclamation-circle:before { - content: "\f06a"; + content: "\f06a"; } + .icon-gift:before { - content: "\f06b"; + content: "\f06b"; } + .icon-leaf:before { - content: "\f06c"; + content: "\f06c"; } + .icon-fire:before { - content: "\f06d"; + content: "\f06d"; } + .icon-eye:before { - content: "\f06e"; + content: "\f06e"; } + .icon-eye-slash:before { - content: "\f070"; + content: "\f070"; } + .icon-warning:before, .icon-exclamation-triangle:before { - content: "\f071"; + content: "\f071"; } + .icon-plane:before { - content: "\f072"; + content: "\f072"; } + .icon-calendar:before { - content: "\f073"; + content: "\f073"; } + .icon-random:before { - content: "\f074"; + content: "\f074"; } + .icon-comment:before { - content: "\f075"; + content: "\f075"; } + .icon-magnet:before { - content: "\f076"; + content: "\f076"; } + .icon-chevron-up:before { - content: "\f077"; + content: "\f077"; } + .icon-chevron-down:before { - content: "\f078"; + content: "\f078"; } + .icon-retweet:before { - content: "\f079"; + content: "\f079"; } + .icon-shopping-cart:before { - content: "\f07a"; + content: "\f07a"; } + .icon-folder:before { - content: "\f07b"; + content: "\f07b"; } + .icon-folder-open:before { - content: "\f07c"; + content: "\f07c"; } + .icon-arrows-v:before { - content: "\f07d"; + content: "\f07d"; } + .icon-arrows-h:before { - content: "\f07e"; + content: "\f07e"; } + .icon-bar-chart-o:before, .icon-bar-chart:before { - content: "\f080"; + content: "\f080"; } + .icon-twitter-square:before { - content: "\f081"; + content: "\f081"; } + .icon-facebook-square:before { - content: "\f082"; + content: "\f082"; } + .icon-camera-retro:before { - content: "\f083"; + content: "\f083"; } + .icon-key:before { - content: "\f084"; + content: "\f084"; } + .icon-gears:before, .icon-cogs:before { - content: "\f085"; + content: "\f085"; } + .icon-comments:before { - content: "\f086"; + content: "\f086"; } + .icon-thumbs-o-up:before { - content: "\f087"; + content: "\f087"; } + .icon-thumbs-o-down:before { - content: "\f088"; + content: "\f088"; } + .icon-star-half:before { - content: "\f089"; + content: "\f089"; } + .icon-heart-o:before { - content: "\f08a"; + content: "\f08a"; } + .icon-sign-out:before { - content: "\f08b"; + content: "\f08b"; } + .icon-linkedin-square:before { - content: "\f08c"; + content: "\f08c"; } + .icon-thumb-tack:before { - content: "\f08d"; + content: "\f08d"; } + .icon-external-link:before { - content: "\f08e"; + content: "\f08e"; } + .icon-sign-in:before { - content: "\f090"; + content: "\f090"; } + .icon-trophy:before { - content: "\f091"; + content: "\f091"; } + .icon-github-square:before { - content: "\f092"; + content: "\f092"; } + .icon-upload:before { - content: "\f093"; + content: "\f093"; } + .icon-lemon-o:before { - content: "\f094"; + content: "\f094"; } + .icon-phone:before { - content: "\f095"; + content: "\f095"; } + .icon-square-o:before { - content: "\f096"; + content: "\f096"; } + .icon-bookmark-o:before { - content: "\f097"; + content: "\f097"; } + .icon-phone-square:before { - content: "\f098"; + content: "\f098"; } + .icon-twitter:before { - content: "\f099"; + content: "\f099"; } + .icon-facebook:before { - content: "\f09a"; + content: "\f09a"; } + .icon-github:before { - content: "\f09b"; + content: "\f09b"; } + .icon-unlock:before { - content: "\f09c"; + content: "\f09c"; } + .icon-credit-card:before { - content: "\f09d"; + content: "\f09d"; } + .icon-rss:before { - content: "\f09e"; + content: "\f09e"; } + .icon-hdd-o:before { - content: "\f0a0"; + content: "\f0a0"; } + .icon-bullhorn:before { - content: "\f0a1"; + content: "\f0a1"; } + .icon-bell:before { - content: "\f0f3"; + content: "\f0f3"; } + .icon-certificate:before { - content: "\f0a3"; + content: "\f0a3"; } + .icon-hand-o-right:before { - content: "\f0a4"; + content: "\f0a4"; } + .icon-hand-o-left:before { - content: "\f0a5"; + content: "\f0a5"; } + .icon-hand-o-up:before { - content: "\f0a6"; + content: "\f0a6"; } + .icon-hand-o-down:before { - content: "\f0a7"; + content: "\f0a7"; } + .icon-arrow-circle-left:before { - content: "\f0a8"; + content: "\f0a8"; } + .icon-arrow-circle-right:before { - content: "\f0a9"; + content: "\f0a9"; } + .icon-arrow-circle-up:before { - content: "\f0aa"; + content: "\f0aa"; } + .icon-arrow-circle-down:before { - content: "\f0ab"; + content: "\f0ab"; } + .icon-globe:before { - content: "\f0ac"; + content: "\f0ac"; } + .icon-wrench:before { - content: "\f0ad"; + content: "\f0ad"; } + .icon-tasks:before { - content: "\f0ae"; + content: "\f0ae"; } + .icon-filter:before { - content: "\f0b0"; + content: "\f0b0"; } + .icon-briefcase:before { - content: "\f0b1"; + content: "\f0b1"; } + .icon-arrows-alt:before { - content: "\f0b2"; + content: "\f0b2"; } + .icon-group:before, .icon-users:before { - content: "\f0c0"; + content: "\f0c0"; } + .icon-chain:before, .icon-link:before { - content: "\f0c1"; + content: "\f0c1"; } + .icon-cloud:before { - content: "\f0c2"; + content: "\f0c2"; } + .icon-flask:before { - content: "\f0c3"; + content: "\f0c3"; } + .icon-cut:before, .icon-scissors:before { - content: "\f0c4"; + content: "\f0c4"; } + .icon-copy:before, .icon-files-o:before { - content: "\f0c5"; + content: "\f0c5"; } + .icon-paperclip:before { - content: "\f0c6"; + content: "\f0c6"; } + .icon-save:before, .icon-floppy-o:before { - content: "\f0c7"; + content: "\f0c7"; } + .icon-square:before { - content: "\f0c8"; + content: "\f0c8"; } + .icon-navicon:before, .icon-reorder:before, .icon-bars:before { - content: "\f0c9"; + content: "\f0c9"; } + .icon-list-ul:before { - content: "\f0ca"; + content: "\f0ca"; } + .icon-list-ol:before { - content: "\f0cb"; + content: "\f0cb"; } + .icon-strikethrough:before { - content: "\f0cc"; + content: "\f0cc"; } + .icon-underline:before { - content: "\f0cd"; + content: "\f0cd"; } + .icon-table:before { - content: "\f0ce"; + content: "\f0ce"; } + .icon-magic:before { - content: "\f0d0"; + content: "\f0d0"; } + .icon-truck:before { - content: "\f0d1"; + content: "\f0d1"; } + .icon-pinterest:before { - content: "\f0d2"; + content: "\f0d2"; } + .icon-pinterest-square:before { - content: "\f0d3"; + content: "\f0d3"; } + .icon-google-plus-square:before { - content: "\f0d4"; + content: "\f0d4"; } + .icon-google-plus:before { - content: "\f0d5"; + content: "\f0d5"; } + .icon-money:before { - content: "\f0d6"; + content: "\f0d6"; } + .ui-accordion-header-icon.ui-icon-triangle-1-s:before, .icon-caret-down:before { - content: "\f0d7"; + content: "\f0d7"; } + .icon-caret-up:before { - content: "\f0d8"; + content: "\f0d8"; } + .icon-caret-left:before { - content: "\f0d9"; + content: "\f0d9"; } + .ui-icon-triangle-1-e:before, .icon-caret-right:before { - content: "\f0da"; + content: "\f0da"; } + .icon-columns:before { - content: "\f0db"; + content: "\f0db"; } + .dataTable .sorting .glyph-icon:before, .dataTable .ui-icon-carat-2-n-s:before, .icon-unsorted:before, .icon-sort:before { - content: "\f0dc"; + content: "\f0dc"; } + .dataTable .sorting_asc .glyph-icon:before, .icon-sort-down:before, .icon-sort-asc:before { - content: "\f0dd"; + content: "\f0dd"; } + .dataTable .sorting_desc .glyph-icon:before, .dataTable .ui-icon-triangle-1-n:before, .icon-sort-up:before, .icon-sort-desc:before { - content: "\f0de"; + content: "\f0de"; } + .icon-envelope:before { - content: "\f0e0"; + content: "\f0e0"; } + .icon-linkedin:before { - content: "\f0e1"; + content: "\f0e1"; } + .icon-rotate-left:before, .icon-undo:before { - content: "\f0e2"; + content: "\f0e2"; } + .icon-legal:before, .icon-gavel:before { - content: "\f0e3"; + content: "\f0e3"; } + .icon-dashboard:before, .icon-tachometer:before { - content: "\f0e4"; + content: "\f0e4"; } + .icon-comment-o:before { - content: "\f0e5"; + content: "\f0e5"; } + .icon-comments-o:before { - content: "\f0e6"; + content: "\f0e6"; } + .icon-flash:before, .icon-bolt:before { - content: "\f0e7"; + content: "\f0e7"; } + .icon-sitemap:before { - content: "\f0e8"; + content: "\f0e8"; } + .icon-umbrella:before { - content: "\f0e9"; + content: "\f0e9"; } + .icon-paste:before, .icon-clipboard:before { - content: "\f0ea"; + content: "\f0ea"; } + .icon-lightbulb-o:before { - content: "\f0eb"; + content: "\f0eb"; } + .icon-exchange:before { - content: "\f0ec"; + content: "\f0ec"; } + .icon-cloud-download:before { - content: "\f0ed"; + content: "\f0ed"; } + .icon-cloud-upload:before { - content: "\f0ee"; + content: "\f0ee"; } + .icon-user-md:before { - content: "\f0f0"; + content: "\f0f0"; } + .icon-stethoscope:before { - content: "\f0f1"; + content: "\f0f1"; } + .icon-suitcase:before { - content: "\f0f2"; + content: "\f0f2"; } + .icon-bell-o:before { - content: "\f0a2"; + content: "\f0a2"; } + .icon-coffee:before { - content: "\f0f4"; + content: "\f0f4"; } + .icon-cutlery:before { - content: "\f0f5"; + content: "\f0f5"; } + .icon-file-text-o:before { - content: "\f0f6"; + content: "\f0f6"; } + .icon-building-o:before { - content: "\f0f7"; + content: "\f0f7"; } + .icon-hospital-o:before { - content: "\f0f8"; + content: "\f0f8"; } + .icon-ambulance:before { - content: "\f0f9"; + content: "\f0f9"; } + .icon-medkit:before { - content: "\f0fa"; + content: "\f0fa"; } + .icon-fighter-jet:before { - content: "\f0fb"; + content: "\f0fb"; } + .icon-beer:before { - content: "\f0fc"; + content: "\f0fc"; } + .icon-h-square:before { - content: "\f0fd"; + content: "\f0fd"; } + .icon-plus-square:before { - content: "\f0fe"; + content: "\f0fe"; } + .icon-angle-double-left:before { - content: "\f100"; + content: "\f100"; } + .icon-angle-double-right:before { - content: "\f101"; + content: "\f101"; } + .icon-angle-double-up:before { - content: "\f102"; + content: "\f102"; } + .icon-angle-double-down:before { - content: "\f103"; + content: "\f103"; } + .icon-angle-left:before { - content: "\f104"; + content: "\f104"; } + #page-sidebar li a.sf-with-ul:after, .icon-angle-right:before { - content: "\f105"; + content: "\f105"; } + .icon-angle-up:before { - content: "\f106"; + content: "\f106"; } + .icon-angle-down:before { - content: "\f107"; + content: "\f107"; } + .icon-desktop:before { - content: "\f108"; + content: "\f108"; } + .icon-laptop:before { - content: "\f109"; + content: "\f109"; } + .icon-tablet:before { - content: "\f10a"; + content: "\f10a"; } + .icon-mobile-phone:before, .icon-mobile:before { - content: "\f10b"; + content: "\f10b"; } + .icon-circle-o:before { - content: "\f10c"; + content: "\f10c"; } + .icon-quote-left:before { - content: "\f10d"; + content: "\f10d"; } + .icon-quote-right:before { - content: "\f10e"; + content: "\f10e"; } + .icon-spinner:before { - content: "\f110"; + content: "\f110"; } + #page-sidebar li ul li a:before, .icon-circle:before { - content: "\f111"; + content: "\f111"; } + .icon-mail-reply:before, .icon-reply:before { - content: "\f112"; + content: "\f112"; } + .icon-github-alt:before { - content: "\f113"; + content: "\f113"; } + .icon-folder-o:before { - content: "\f114"; + content: "\f114"; } + .icon-folder-open-o:before { - content: "\f115"; + content: "\f115"; } + .icon-smile-o:before { - content: "\f118"; + content: "\f118"; } + .icon-frown-o:before { - content: "\f119"; + content: "\f119"; } + .icon-meh-o:before { - content: "\f11a"; + content: "\f11a"; } + .icon-gamepad:before { - content: "\f11b"; + content: "\f11b"; } + .icon-keyboard-o:before { - content: "\f11c"; + content: "\f11c"; } + .icon-flag-o:before { - content: "\f11d"; + content: "\f11d"; } + .icon-flag-checkered:before { - content: "\f11e"; + content: "\f11e"; } + .icon-terminal:before { - content: "\f120"; + content: "\f120"; } + .icon-code:before { - content: "\f121"; + content: "\f121"; } + .icon-mail-reply-all:before, .icon-reply-all:before { - content: "\f122"; + content: "\f122"; } + .icon-star-half-empty:before, .icon-star-half-full:before, .icon-star-half-o:before { - content: "\f123"; + content: "\f123"; } + .icon-location-arrow:before { - content: "\f124"; + content: "\f124"; } + .icon-crop:before { - content: "\f125"; + content: "\f125"; } + .icon-code-fork:before { - content: "\f126"; + content: "\f126"; } + .icon-unlink:before, .icon-chain-broken:before { - content: "\f127"; + content: "\f127"; } + .icon-question:before { - content: "\f128"; + content: "\f128"; } + .icon-info:before { - content: "\f129"; + content: "\f129"; } + .icon-exclamation:before { - content: "\f12a"; + content: "\f12a"; } + .icon-superscript:before { - content: "\f12b"; + content: "\f12b"; } + .icon-subscript:before { - content: "\f12c"; + content: "\f12c"; } + .icon-eraser:before { - content: "\f12d"; + content: "\f12d"; } + .icon-puzzle-piece:before { - content: "\f12e"; + content: "\f12e"; } + .icon-microphone:before { - content: "\f130"; + content: "\f130"; } + .icon-microphone-slash:before { - content: "\f131"; + content: "\f131"; } + .icon-shield:before { - content: "\f132"; + content: "\f132"; } + .icon-calendar-o:before { - content: "\f133"; + content: "\f133"; } + .icon-fire-extinguisher:before { - content: "\f134"; + content: "\f134"; } + .icon-rocket:before { - content: "\f135"; + content: "\f135"; } + .icon-maxcdn:before { - content: "\f136"; + content: "\f136"; } + .ui-icon-circle-triangle-w:before, .icon-chevron-circle-left:before { - content: "\f137"; + content: "\f137"; } + .ui-icon-circle-triangle-e:before, .icon-chevron-circle-right:before { - content: "\f138"; + content: "\f138"; } + .icon-chevron-circle-up:before { - content: "\f139"; + content: "\f139"; } + .icon-chevron-circle-down:before { - content: "\f13a"; + content: "\f13a"; } + .icon-html5:before { - content: "\f13b"; + content: "\f13b"; } + .icon-css3:before { - content: "\f13c"; + content: "\f13c"; } + .icon-anchor:before { - content: "\f13d"; + content: "\f13d"; } + .icon-unlock-alt:before { - content: "\f13e"; + content: "\f13e"; } + .icon-bullseye:before { - content: "\f140"; + content: "\f140"; } + .icon-ellipsis-h:before { - content: "\f141"; + content: "\f141"; } + .icon-ellipsis-v:before { - content: "\f142"; + content: "\f142"; } + .icon-rss-square:before { - content: "\f143"; + content: "\f143"; } + .icon-play-circle:before { - content: "\f144"; + content: "\f144"; } + .icon-ticket:before { - content: "\f145"; + content: "\f145"; } + .icon-minus-square:before { - content: "\f146"; + content: "\f146"; } + .icon-minus-square-o:before { - content: "\f147"; + content: "\f147"; } + .icon-level-up:before { - content: "\f148"; + content: "\f148"; } + .icon-level-down:before { - content: "\f149"; + content: "\f149"; } + .icon-check-square:before { - content: "\f14a"; + content: "\f14a"; } + .icon-pencil-square:before { - content: "\f14b"; + content: "\f14b"; } + .icon-external-link-square:before { - content: "\f14c"; + content: "\f14c"; } + .icon-share-square:before { - content: "\f14d"; + content: "\f14d"; } + .icon-compass:before { - content: "\f14e"; + content: "\f14e"; } + .icon-toggle-down:before, .icon-caret-square-o-down:before { - content: "\f150"; + content: "\f150"; } + .icon-toggle-up:before, .icon-caret-square-o-up:before { - content: "\f151"; + content: "\f151"; } + .icon-toggle-right:before, .icon-caret-square-o-right:before { - content: "\f152"; + content: "\f152"; } + .icon-euro:before, .icon-eur:before { - content: "\f153"; + content: "\f153"; } + .icon-gbp:before { - content: "\f154"; + content: "\f154"; } + .icon-dollar:before, .icon-usd:before { - content: "\f155"; + content: "\f155"; } + .icon-rupee:before, .icon-inr:before { - content: "\f156"; + content: "\f156"; } + .icon-cny:before, .icon-rmb:before, .icon-yen:before, .icon-jpy:before { - content: "\f157"; + content: "\f157"; } + .icon-ruble:before, .icon-rouble:before, .icon-rub:before { - content: "\f158"; + content: "\f158"; } + .icon-won:before, .icon-krw:before { - content: "\f159"; + content: "\f159"; } + .icon-bitcoin:before, .icon-btc:before { - content: "\f15a"; + content: "\f15a"; } + .icon-file:before { - content: "\f15b"; + content: "\f15b"; } + .icon-file-text:before { - content: "\f15c"; + content: "\f15c"; } + .icon-sort-alpha-asc:before { - content: "\f15d"; + content: "\f15d"; } + .icon-sort-alpha-desc:before { - content: "\f15e"; + content: "\f15e"; } + .icon-sort-amount-asc:before { - content: "\f160"; + content: "\f160"; } + .icon-sort-amount-desc:before { - content: "\f161"; + content: "\f161"; } + .icon-sort-numeric-asc:before { - content: "\f162"; + content: "\f162"; } + .icon-sort-numeric-desc:before { - content: "\f163"; + content: "\f163"; } + .icon-thumbs-up:before { - content: "\f164"; + content: "\f164"; } + .icon-thumbs-down:before { - content: "\f165"; + content: "\f165"; } + .icon-youtube-square:before { - content: "\f166"; + content: "\f166"; } + .icon-youtube:before { - content: "\f167"; + content: "\f167"; } + .icon-xing:before { - content: "\f168"; + content: "\f168"; } + .icon-xing-square:before { - content: "\f169"; + content: "\f169"; } + .icon-youtube-play:before { - content: "\f16a"; + content: "\f16a"; } + .icon-dropbox:before { - content: "\f16b"; + content: "\f16b"; } + .icon-stack-overflow:before { - content: "\f16c"; + content: "\f16c"; } + .icon-instagram:before { - content: "\f16d"; + content: "\f16d"; } + .icon-flickr:before { - content: "\f16e"; + content: "\f16e"; } + .icon-adn:before { - content: "\f170"; + content: "\f170"; } + .icon-bitbucket:before { - content: "\f171"; + content: "\f171"; } + .icon-bitbucket-square:before { - content: "\f172"; + content: "\f172"; } + .icon-tumblr:before { - content: "\f173"; + content: "\f173"; } + .icon-tumblr-square:before { - content: "\f174"; + content: "\f174"; } + .icon-long-arrow-down:before { - content: "\f175"; + content: "\f175"; } + .icon-long-arrow-up:before { - content: "\f176"; + content: "\f176"; } + .icon-long-arrow-left:before { - content: "\f177"; + content: "\f177"; } + .icon-long-arrow-right:before { - content: "\f178"; + content: "\f178"; } + .icon-apple:before { - content: "\f179"; + content: "\f179"; } + .icon-windows:before { - content: "\f17a"; + content: "\f17a"; } + .icon-android:before { - content: "\f17b"; + content: "\f17b"; } + .icon-linux:before { - content: "\f17c"; + content: "\f17c"; } + .icon-dribbble:before { - content: "\f17d"; + content: "\f17d"; } + .icon-skype:before { - content: "\f17e"; + content: "\f17e"; } + .icon-foursquare:before { - content: "\f180"; + content: "\f180"; } + .icon-trello:before { - content: "\f181"; + content: "\f181"; } + .icon-female:before { - content: "\f182"; + content: "\f182"; } + .icon-male:before { - content: "\f183"; + content: "\f183"; } + .icon-gittip:before { - content: "\f184"; + content: "\f184"; } + .icon-sun-o:before { - content: "\f185"; + content: "\f185"; } + .icon-moon-o:before { - content: "\f186"; + content: "\f186"; } + .icon-archive:before { - content: "\f187"; + content: "\f187"; } + .icon-bug:before { - content: "\f188"; + content: "\f188"; } + .icon-vk:before { - content: "\f189"; + content: "\f189"; } + .icon-weibo:before { - content: "\f18a"; + content: "\f18a"; } + .icon-renren:before { - content: "\f18b"; + content: "\f18b"; } + .icon-pagelines:before { - content: "\f18c"; + content: "\f18c"; } + .icon-stack-exchange:before { - content: "\f18d"; + content: "\f18d"; } + .icon-arrow-circle-o-right:before { - content: "\f18e"; + content: "\f18e"; } + .icon-arrow-circle-o-left:before { - content: "\f190"; + content: "\f190"; } + .icon-toggle-left:before, .icon-caret-square-o-left:before { - content: "\f191"; + content: "\f191"; } + .icon-dot-circle-o:before { - content: "\f192"; + content: "\f192"; } + .icon-wheelchair:before { - content: "\f193"; + content: "\f193"; } + .icon-vimeo-square:before { - content: "\f194"; + content: "\f194"; } + .icon-turkish-lira:before, .icon-try:before { - content: "\f195"; + content: "\f195"; } + .icon-plus-square-o:before { - content: "\f196"; + content: "\f196"; } + .icon-space-shuttle:before { - content: "\f197"; + content: "\f197"; } + .icon-slack:before { - content: "\f198"; + content: "\f198"; } + .icon-envelope-square:before { - content: "\f199"; + content: "\f199"; } + .icon-wordpress:before { - content: "\f19a"; + content: "\f19a"; } + .icon-openid:before { - content: "\f19b"; + content: "\f19b"; } + .icon-institution:before, .icon-bank:before, .icon-university:before { - content: "\f19c"; + content: "\f19c"; } + .icon-mortar-board:before, .icon-graduation-cap:before { - content: "\f19d"; + content: "\f19d"; } + .icon-yahoo:before { - content: "\f19e"; + content: "\f19e"; } + .icon-google:before { - content: "\f1a0"; + content: "\f1a0"; } + .icon-reddit:before { - content: "\f1a1"; + content: "\f1a1"; } + .icon-reddit-square:before { - content: "\f1a2"; + content: "\f1a2"; } + .icon-stumbleupon-circle:before { - content: "\f1a3"; + content: "\f1a3"; } + .icon-stumbleupon:before { - content: "\f1a4"; + content: "\f1a4"; } + .icon-delicious:before { - content: "\f1a5"; + content: "\f1a5"; } + .icon-digg:before { - content: "\f1a6"; + content: "\f1a6"; } + .icon-pied-piper:before { - content: "\f1a7"; + content: "\f1a7"; } + .icon-pied-piper-alt:before { - content: "\f1a8"; + content: "\f1a8"; } + .icon-drupal:before { - content: "\f1a9"; + content: "\f1a9"; } + .icon-joomla:before { - content: "\f1aa"; + content: "\f1aa"; } + .icon-language:before { - content: "\f1ab"; + content: "\f1ab"; } + .icon-fax:before { - content: "\f1ac"; + content: "\f1ac"; } + .icon-building:before { - content: "\f1ad"; + content: "\f1ad"; } + .icon-child:before { - content: "\f1ae"; + content: "\f1ae"; } + .icon-paw:before { - content: "\f1b0"; + content: "\f1b0"; } + .icon-spoon:before { - content: "\f1b1"; + content: "\f1b1"; } + .icon-cube:before { - content: "\f1b2"; + content: "\f1b2"; } + .icon-cubes:before { - content: "\f1b3"; + content: "\f1b3"; } + .icon-behance:before { - content: "\f1b4"; + content: "\f1b4"; } + .icon-behance-square:before { - content: "\f1b5"; + content: "\f1b5"; } + .icon-steam:before { - content: "\f1b6"; + content: "\f1b6"; } + .icon-steam-square:before { - content: "\f1b7"; + content: "\f1b7"; } + .icon-recycle:before { - content: "\f1b8"; + content: "\f1b8"; } + .icon-automobile:before, .icon-car:before { - content: "\f1b9"; + content: "\f1b9"; } + .icon-cab:before, .icon-taxi:before { - content: "\f1ba"; + content: "\f1ba"; } + .icon-tree:before { - content: "\f1bb"; + content: "\f1bb"; } + .icon-spotify:before { - content: "\f1bc"; + content: "\f1bc"; } + .icon-deviantart:before { - content: "\f1bd"; + content: "\f1bd"; } + .icon-soundcloud:before { - content: "\f1be"; + content: "\f1be"; } + .icon-database:before { - content: "\f1c0"; + content: "\f1c0"; } + .icon-file-pdf-o:before { - content: "\f1c1"; + content: "\f1c1"; } + .icon-file-word-o:before { - content: "\f1c2"; + content: "\f1c2"; } + .icon-file-excel-o:before { - content: "\f1c3"; + content: "\f1c3"; } + .icon-file-powerpoint-o:before { - content: "\f1c4"; + content: "\f1c4"; } + .icon-file-photo-o:before, .icon-file-picture-o:before, .icon-file-image-o:before { - content: "\f1c5"; + content: "\f1c5"; } + .icon-file-zip-o:before, .icon-file-archive-o:before { - content: "\f1c6"; + content: "\f1c6"; } + .icon-file-sound-o:before, .icon-file-audio-o:before { - content: "\f1c7"; + content: "\f1c7"; } + .icon-file-movie-o:before, .icon-file-video-o:before { - content: "\f1c8"; + content: "\f1c8"; } + .icon-file-code-o:before { - content: "\f1c9"; + content: "\f1c9"; } + .icon-vine:before { - content: "\f1ca"; + content: "\f1ca"; } + .icon-codepen:before { - content: "\f1cb"; + content: "\f1cb"; } + .icon-jsfiddle:before { - content: "\f1cc"; + content: "\f1cc"; } + .icon-life-bouy:before, .icon-life-buoy:before, .icon-life-saver:before, .icon-support:before, .icon-life-ring:before { - content: "\f1cd"; + content: "\f1cd"; } + .icon-circle-o-notch:before { - content: "\f1ce"; + content: "\f1ce"; } + .icon-ra:before, .icon-rebel:before { - content: "\f1d0"; + content: "\f1d0"; } + .icon-ge:before, .icon-empire:before { - content: "\f1d1"; + content: "\f1d1"; } + .icon-git-square:before { - content: "\f1d2"; + content: "\f1d2"; } + .icon-git:before { - content: "\f1d3"; + content: "\f1d3"; } + .icon-hacker-news:before { - content: "\f1d4"; + content: "\f1d4"; } + .icon-tencent-weibo:before { - content: "\f1d5"; + content: "\f1d5"; } + .icon-qq:before { - content: "\f1d6"; + content: "\f1d6"; } + .icon-wechat:before, .icon-weixin:before { - content: "\f1d7"; + content: "\f1d7"; } + .icon-send:before, .icon-paper-plane:before { - content: "\f1d8"; + content: "\f1d8"; } + .icon-send-o:before, .icon-paper-plane-o:before { - content: "\f1d9"; + content: "\f1d9"; } + .icon-history:before { - content: "\f1da"; + content: "\f1da"; } + .icon-circle-thin:before { - content: "\f1db"; + content: "\f1db"; } + .icon-header:before { - content: "\f1dc"; + content: "\f1dc"; } + .icon-paragraph:before { - content: "\f1dd"; + content: "\f1dd"; } + .icon-sliders:before { - content: "\f1de"; + content: "\f1de"; } + .icon-share-alt:before { - content: "\f1e0"; + content: "\f1e0"; } + .icon-share-alt-square:before { - content: "\f1e1"; + content: "\f1e1"; } + .icon-bomb:before { - content: "\f1e2"; + content: "\f1e2"; } + .icon-soccer-ball-o:before, .icon-futbol-o:before { - content: "\f1e3"; + content: "\f1e3"; } + .icon-tty:before { - content: "\f1e4"; + content: "\f1e4"; } + .icon-binoculars:before { - content: "\f1e5"; + content: "\f1e5"; } + .icon-plug:before { - content: "\f1e6"; + content: "\f1e6"; } + .icon-slideshare:before { - content: "\f1e7"; + content: "\f1e7"; } + .icon-twitch:before { - content: "\f1e8"; + content: "\f1e8"; } + .icon-yelp:before { - content: "\f1e9"; + content: "\f1e9"; } + .icon-newspaper-o:before { - content: "\f1ea"; + content: "\f1ea"; } + .icon-wifi:before { - content: "\f1eb"; + content: "\f1eb"; } + .icon-calculator:before { - content: "\f1ec"; + content: "\f1ec"; } + .icon-paypal:before { - content: "\f1ed"; + content: "\f1ed"; } + .icon-google-wallet:before { - content: "\f1ee"; + content: "\f1ee"; } + .icon-cc-visa:before { - content: "\f1f0"; + content: "\f1f0"; } + .icon-cc-mastercard:before { - content: "\f1f1"; + content: "\f1f1"; } + .icon-cc-discover:before { - content: "\f1f2"; + content: "\f1f2"; } + .icon-cc-amex:before { - content: "\f1f3"; + content: "\f1f3"; } + .icon-cc-paypal:before { - content: "\f1f4"; + content: "\f1f4"; } + .icon-cc-stripe:before { - content: "\f1f5"; + content: "\f1f5"; } + .icon-bell-slash:before { - content: "\f1f6"; + content: "\f1f6"; } + .icon-bell-slash-o:before { - content: "\f1f7"; + content: "\f1f7"; } + .icon-trash:before { - content: "\f1f8"; + content: "\f1f8"; } + .icon-copyright:before { - content: "\f1f9"; + content: "\f1f9"; } + .icon-at:before { - content: "\f1fa"; + content: "\f1fa"; } + .icon-eyedropper:before { - content: "\f1fb"; + content: "\f1fb"; } + .icon-paint-brush:before { - content: "\f1fc"; + content: "\f1fc"; } + .icon-birthday-cake:before { - content: "\f1fd"; + content: "\f1fd"; } + .icon-area-chart:before { - content: "\f1fe"; + content: "\f1fe"; } + .icon-pie-chart:before { - content: "\f200"; + content: "\f200"; } + .icon-line-chart:before { - content: "\f201"; + content: "\f201"; } + .icon-lastfm:before { - content: "\f202"; + content: "\f202"; } + .icon-lastfm-square:before { - content: "\f203"; + content: "\f203"; } + .icon-toggle-off:before { - content: "\f204"; + content: "\f204"; } + .icon-toggle-on:before { - content: "\f205"; + content: "\f205"; } + .icon-bicycle:before { - content: "\f206"; + content: "\f206"; } + .icon-bus:before { - content: "\f207"; + content: "\f207"; } + .icon-ioxhost:before { - content: "\f208"; + content: "\f208"; } + .icon-angellist:before { - content: "\f209"; + content: "\f209"; } + .icon-cc:before { - content: "\f20a"; + content: "\f20a"; } + .icon-shekel:before, .icon-sheqel:before, .icon-ils:before { - content: "\f20b"; + content: "\f20b"; } + .icon-meanpath:before { - content: "\f20c"; + content: "\f20c"; } /*customized mzou*/ .text-white { - color: #FFFFFF; + color: #FFFFFF; } + .mt-5 { - margin-top: 5px; + margin-top: 5px; } + .mt-10 { - margin-top: 10px; + margin-top: 10px; } + .mt-20 { - margin-top: 20px; + margin-top: 20px; } + .mt-30 { - margin-top: 30px; + margin-top: 30px; } + .mr-10 { - margin-right: 10px; + margin-right: 10px; } + .mb-10 { - margin-bottom: 10px; + margin-bottom: 10px; } + .mb-20 { - margin-bottom: 20px; + margin-bottom: 20px; } + .mb-30 { - margin-bottom: 30px; + margin-bottom: 30px; } + .ml-10 { - margin-left: 10px; + margin-left: 10px; } + .my-10 { - margin-top: 10px; - margin-bottom: 10px; + margin-top: 10px; + margin-bottom: 10px; } + .my-20 { - margin-top: 20px; - margin-bottom: 20px; + margin-top: 20px; + margin-bottom: 20px; } + .my-30 { - margin-top: 30px; - margin-bottom: 30px; + margin-top: 30px; + margin-bottom: 30px; } .mx-5 { - margin-left: 5px; - margin-right: 5px; + margin-left: 5px; + margin-right: 5px; } + .mx-10 { - margin-left: 10px; - margin-right: 10px; + margin-left: 10px; + margin-right: 10px; } + .mx-20 { - margin-left: 20px; - margin-right: 20px; + margin-left: 20px; + margin-right: 20px; } + .mx-30 { - margin-left: 30px; - margin-right: 30px; + margin-left: 30px; + margin-right: 30px; } + .text-bold { - font-weight: 600; + font-weight: 600; } + .rounded { - border-radius: 3px; + border-radius: 3px; } .btn-outline-light { - color: #f8f9fa; - background-color: transparent; - background-image: none; - border-color: #f8f9fa; + color: #f8f9fa; + background-color: transparent; + background-image: none; + border-color: #f8f9fa; } + .btn-outline-light:hover { - color: #212529; - background-color: #f8f9fa; - border-color: #f8f9fa; - text-decoration: none; + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; + text-decoration: none; } .flex { - display: flex; + display: flex; } + .flex-wrap { - flex-wrap: wrap; + flex-wrap: wrap; } + @media (max-width: 992px) { -.hidden-md { + .hidden-md { display: none; + } } -} + .img-thumbnail { - padding: .25rem; - background-color: #fff; - border: 1px solid #dee2e6; - border-radius: .25rem; - max-width: 100%; - height: auto; + padding: .25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: .25rem; + max-width: 100%; + height: auto; } img { -vertical-align: middle; -border-style: none; + vertical-align: middle; + border-style: none; } @media (max-width: 720px) { - .text-center-sm { - text-align: center; -} \ No newline at end of file + .text-center-sm { + text-align: center; + } diff --git a/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css b/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css index 5b602b8dc..704e7c221 100755 --- a/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css +++ b/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css @@ -528,9 +528,9 @@ body #nav-toggle.collapsed span { width: 100px; } .closed-sidebar #header-logo .logo-content-small { - width: 62px; + width: 50px; margin-left: 0; - left: 0px; + left: 15px; display: block; } .closed-sidebar #header-logo .logo-content-big { diff --git a/baseTemplate/static/baseTemplate/custom-js/system-status.js b/baseTemplate/static/baseTemplate/custom-js/system-status.js index 41680df3f..00807bd6b 100755 --- a/baseTemplate/static/baseTemplate/custom-js/system-status.js +++ b/baseTemplate/static/baseTemplate/custom-js/system-status.js @@ -98,6 +98,23 @@ app.filter('getwebsitename', function () { }; }); +function getWebsiteName(domain){ + if (domain !== undefined) { + + domain = domain.replace(/-/g, ''); + + var domainName = domain.split("."); + + var finalDomainName = domainName[0]; + + if (finalDomainName.length > 5) { + finalDomainName = finalDomainName.substring(0, 4); + } + + return finalDomainName; + } +} + app.controller('systemStatusInfo', function ($scope, $http, $timeout) { //getStuff(); @@ -300,8 +317,8 @@ app.controller('adminController', function ($scope, $http, $timeout) { $('.addDeleteDestinations').hide(); } - if (!Boolean(response.data.scheDuleBackups)) { - $('.scheDuleBackups').hide(); + if (!Boolean(response.data.scheduleBackups)) { + $('.scheduleBackups').hide(); } if (!Boolean(response.data.remoteBackups)) { diff --git a/baseTemplate/templates/baseTemplate/error.html b/baseTemplate/templates/baseTemplate/error.html new file mode 100755 index 000000000..4ccefce2f --- /dev/null +++ b/baseTemplate/templates/baseTemplate/error.html @@ -0,0 +1,42 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Home - CyberPanel" %}{% endblock %} +{% block content %} + + +{% get_current_language as LANGUAGE_CODE %} + + +
+
+

{% trans "Home" %}

+

{% trans "Use the tabs to navigate through the control panel." %}

+
+ + + + +
+
+

+ {% trans "Something went wrong..." %} +

+ +
+
+

Error

+

Error: {{ error_message }}

+
+
+ +
+ +
+ + + + +
+ + +{% endblock %} diff --git a/baseTemplate/templates/baseTemplate/homePage.html b/baseTemplate/templates/baseTemplate/homePage.html index 80282c078..fb0ec8827 100755 --- a/baseTemplate/templates/baseTemplate/homePage.html +++ b/baseTemplate/templates/baseTemplate/homePage.html @@ -4,29 +4,28 @@ {% block content %} -{% get_current_language as LANGUAGE_CODE %} - + {% get_current_language as LANGUAGE_CODE %} + -
-
-

{% trans "Home" %}

-

{% trans "Use the tabs to navigate through the control panel." %}

-
+
- - - {% if admin %} -
-
-

- {% trans "Resources" %} -

- -
- -
-
-
-

- {% trans "CPU Usage" %} -

-
-
-
-
- {$ cpuUsage $}% -
-
-
-
-
-
-
-
-
-
- -
-
-

- {% trans "Ram Usage" %} -

-
-
-
-
- {$ ramUsage $}% -
-
-
-
-
-
-
-
-
-
- -
-
-

- {% trans "Disk Usage '/'" %} -

-
-
-
-
- {$ diskUsage $}% -
-
-
-
-
-
-
-
-
-
- -
- -
+ + + {% if admin %} +
+
+

+ {% trans "Resources" %} +

+ +
+ +
+
+
+

+ {% trans "CPU Usage" %} +

+
+
+
+
+ {$ cpuUsage $}% +
+
+
+
+
+
+
+
+
+
+ +
+
+

+ {% trans "Ram Usage" %} +

+
+
+
+
+ {$ ramUsage $}% +
+
+
+
+
+
+
+
+
+
+ +
+
+

+ {% trans "Disk Usage '/'" %} +

+
+
+
+
+ {$ diskUsage $}% +
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+ {% endif %} + +
- {% endif %} - - - - -
{% endblock %} diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 915172653..70a269a00 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -62,7 +62,8 @@ - + {% block title %}Page Title{% endblock %} @@ -75,926 +76,980 @@ - + {% with version="2.1.2" %} - + - + - + + + + + + + + {% block styles %} + {% endblock %} - + + + + - - + {% block header_scripts %} + {% endblock %} - - - - - - - - - - {% block styles %} - {% endblock %} - - - - - - - {% block header_scripts %} - {% endblock %} - - + - + - -
+ + +
+
+
- +
-
-
-
+ -
-
- - -
-
-
-
-
-
-
- -
- +
+
+
+
+
+
+
-
- - - {$ one $} - - - - {$ two $} - - - - {$ three $} - - -