diff --git a/check_process b/check_process new file mode 100644 index 0000000..c315f0d --- /dev/null +++ b/check_process @@ -0,0 +1,33 @@ +;; Test complet + ; Manifest + domain="domain.tld" (DOMAIN) + path="/path" (PATH) + user="john" (USER) + ; Checks + pkg_linter=1 + setup_sub_dir=1 + setup_root=1 + setup_nourl=0 + setup_private=0 + setup_public=0 + upgrade=1 + backup_restore=1 + multi_instance=0 + incorrect_path=1 + port_already_use=1 (8081) + change_url=0 +;;; Levels + Level 1=auto + Level 2=auto + Level 3=auto +# Level 4: Not relevant + Level 4=na + Level 5=auto + Level 6=auto + Level 7=auto + Level 8=0 + Level 9=0 + Level 10=0 +;;; Options +Email= +Notification=none diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..0a7b75c --- /dev/null +++ b/conf/app.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/afaqurk/linux-dash/archive/59d4787d3147e79a816a5c88ed8af482a0661e88.zip +SOURCE_SUM=9c3112c93bb20be8b719335b20bf161e11a8095ecf639baab6ea8c95ef289928 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=zip +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/app.src.2.0 b/conf/app.src.2.0 new file mode 100644 index 0000000..136f8ad --- /dev/null +++ b/conf/app.src.2.0 @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/afaqurk/linux-dash/archive/2.0.tar.gz +SOURCE_SUM=f7342807ecadd22410614336378311a356e04a18569f64935ea67b9bc27ccd56 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/nginx.conf b/conf/nginx.conf index beea8dd..3ad0143 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,9 +1,14 @@ -location YNH_WWW_PATH/ { - rewrite ^YNH_WWW_PATH$ YNH_WWW_PATH/ permanent; - proxy_pass http://localhost:8081/; - proxy_set_header Host $host; - proxy_buffering off; +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location __PATH__/ { - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + + proxy_pass http://localhost:__PORT__/; + proxy_set_header Host $host; + proxy_buffering off; + + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; } diff --git a/conf/supervisor.conf b/conf/supervisor.conf index 0c0655d..148e08d 100644 --- a/conf/supervisor.conf +++ b/conf/supervisor.conf @@ -1,5 +1,7 @@ -[program:linuxdash] -directory=/var/www/linuxdash/ +[program:__APP__] +directory=__FINALPATH__/ +;command=python app/server/index.py (v2.0) command=python python-server.py autostart=true autorestart=true +user=__USER__ diff --git a/manifest.json b/manifest.json index 733d4f0..a8f2fd4 100644 --- a/manifest.json +++ b/manifest.json @@ -1,18 +1,23 @@ { "name": "Linux-Dash", "id": "linuxdash", + "packaging_format": 1, "description": { "en": "A drop-in, low-overhead monitoring web dashboard for GNU/linux machine.", "fr": "Tableau de bord léger pour le monitoring d’un serveur GNU/linux." }, + "version": "2.0", "url": "https://github.com/afaqurk/linux-dash", - "license": "free", + "license": "MIT", "maintainer": { "name": "Moul", "email": "moul@moul.re", "url": "https://moul.re" }, - "multi_instance": "false", + "requirements": { + "yunohost": ">= 2.7.2" + }, + "multi_instance": false, "services": [ "nginx" ], @@ -20,7 +25,7 @@ "install" : [ { "name": "domain", - "type": "domain", + "type": "domain", "ask": { "en": "Choose a domain name for Linux-Dash", "fr": "Choisissez un nom de domaine pour Linux-Dash" @@ -29,7 +34,7 @@ }, { "name": "path", - "type": "path", + "type": "path", "ask": { "en": "Choose a path for Linux-Dash", "fr": "Choisissez un chemin pour Linux-Dash" @@ -39,7 +44,7 @@ }, { "name": "user", - "type": "user", + "type": "user", "ask": { "en": "Choose the YunoHost user which have access to Linux-Dash", "fr": "Choisissez l’utilisateur YunoHost qui a accès à Linux-Dash" diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..24bd7ba --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# ============= FUTURE YUNOHOST HELPER ============= +# Delete a file checksum from the app settings +# +# $app should be defined when calling this helper +# +# usage: ynh_remove_file_checksum file +# | arg: file - The file for which the checksum will be deleted +ynh_delete_file_checksum () { + local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_' + ynh_app_setting_delete $app $checksum_setting_name +} diff --git a/scripts/backup b/scripts/backup new file mode 100755 index 0000000..d192288 --- /dev/null +++ b/scripts/backup @@ -0,0 +1,53 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + chmod a+rx _common.sh +fi +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +final_path=$(ynh_app_setting_get $app final_path) +domain=$(ynh_app_setting_get $app domain) + +#================================================= +# STANDARD BACKUP STEPS +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= + +ynh_backup "$final_path" + +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= + +ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# SPECIFIC BACKUP +#================================================= +# BACKUP SUPERVISOR CONFIG +#================================================= + +ynh_backup "/etc/supervisor/conf.d/$app.conf" diff --git a/scripts/install b/scripts/install index 7f6b41b..8b6be88 100755 --- a/scripts/install +++ b/scripts/install @@ -1,48 +1,141 @@ #!/bin/bash -app=linuxdash +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -domain=$1 -path=$2 -user=$3 +source _common.sh +source /usr/share/yunohost/helpers -# Check domain/path availability -sudo yunohost app checkurl $domain$path -a $app -if [[ ! $? -eq 0 ]]; then - exit 1 -fi +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= -# Check port availability -sudo yunohost app checkport 8081 -if [[ ! $? -eq 0 ]]; then - exit 1 -fi +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +user=$YNH_APP_ARG_USER + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= -# Copy files to the right place final_path=/var/www/$app -sudo mkdir -p $final_path -sudo cp -a ../sources/* $final_path +test ! -e "$final_path" || ynh_die "This path already contains a folder" -# Set permissions -sudo chown -R www-data: $final_path +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) + +# Check web path availability +ynh_webpath_available $domain $path_url +# Register (book) web path +ynh_webpath_register $app $domain $path_url + +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= + +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path $path_url +ynh_app_setting_set $app user $user + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# INSTALL DEPENDENCIES +#================================================= + +ynh_install_app_dependencies supervisor + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +ynh_app_setting_set $app final_path $final_path +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" + +#================================================= +# FIND AND OPEN A PORT +#================================================= + +# Find a free port +port=$(ynh_find_port 8081) +# Open this port +yunohost firewall allow --no-upnp TCP $port 2>&1 +ynh_app_setting_set $app port $port + +# For v2.0 only +# ynh_replace_string "default=80" "default=$port" "$final_path/app/server/index.py" +ynh_replace_string "'localhost', 8081" "'localhost', $port" "$final_path/python-server.py" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Create a dedicated nginx config +if [ "$path_url" != "/" ] +then + ynh_replace_string "^#sub_path_only" "" "../conf/nginx.conf" +fi +ynh_add_nginx_config + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create $app + +#================================================= +# SPECIFIC SETUP +#================================================= +# SET SUPERVISOR +#================================================= # Set as a service with supervisor -sudo apt-get -y -qq install supervisor -sudo cp ../conf/supervisor.conf /etc/supervisor/conf.d/$app.conf -sudo supervisorctl update -sudo supervisorctl start $app +cp ../conf/supervisor.conf /etc/supervisor/conf.d/$app.conf +ynh_replace_string "__APP__" "$app" "/etc/supervisor/conf.d/$app.conf" +ynh_replace_string "__FINALPATH__" "$final_path" "/etc/supervisor/conf.d/$app.conf" +ynh_replace_string "__USER__" "$app" "/etc/supervisor/conf.d/$app.conf" -# Modify Nginx configuration file and copy it to Nginx conf directory -sed -i "s@YNH_WWW_PATH@$path@g" ../conf/nginx.conf -nginxconf=/etc/nginx/conf.d/$domain.d/$app.conf -sudo cp ../conf/nginx.conf $nginxconf -sudo chown root: $nginxconf -sudo chmod 600 $nginxconf +supervisorctl update +supervisorctl restart $app -# Only give one user access to this app -sudo yunohost app removeaccess $app -sudo yunohost app addaccess $app -u $user +#================================================= +# REMOVE GOOGLE !!! +#================================================= -# Reload web server -sudo service nginx reload +sed --in-place "/googlecode\|googleapis/d" "$final_path/index.html" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# Set permissions to app files +chown -R root: $final_path + +#================================================= +# SETUP SSOWAT +#================================================= + +# Restrict access to admin only +yunohost app addaccess --users=$user $app + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/scripts/remove b/scripts/remove index 6d28ede..97e3c87 100755 --- a/scripts/remove +++ b/scripts/remove @@ -1,19 +1,72 @@ #!/bin/bash -app=linuxdash -domain=$(sudo yunohost app setting $app domain) +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Remove sources and nginx configuration -sudo rm -rf /var/www/$app -sudo rm -f /etc/nginx/conf.d/$domain.d/$app.conf +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +port=$(ynh_app_setting_get $app port) +final_path=$(ynh_app_setting_get $app final_path) + +#================================================= +# STANDARD REMOVE +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "$final_path" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= + +# Remove the dedicated nginx config +ynh_remove_nginx_config + +#================================================= +# CLOSE A PORT +#================================================= + +if yunohost firewall list | grep -q "\- $port$" +then + echo "Close port $port" + yunohost firewall disallow TCP $port 2>&1 +fi + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE SUPERVISOR +#================================================= # Remove service -sudo supervisorctl stop $app -sudo rm -f /etc/supervisor/conf.d/$app.conf +supervisorctl stop $app +ynh_secure_remove /etc/supervisor/conf.d/$app.conf -# Remove supervisor package -# Need to be manage with future manifest/moulinette Debian package management -# sudo apt-get -y -qq remove supervisor +#================================================= +# REMOVE DEPENDENCIES +#================================================= -# Reload nginx configuration -sudo service nginx reload +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete $app diff --git a/scripts/restore b/scripts/restore new file mode 100755 index 0000000..0f7f62b --- /dev/null +++ b/scripts/restore @@ -0,0 +1,95 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + chmod a+rx _common.sh +fi +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path) +final_path=$(ynh_app_setting_get $app final_path) + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= + +ynh_webpath_available $domain $path_url \ + || ynh_die "Path not available: ${domain}${path_url}" +test ! -d $final_path \ + || ynh_die "There is already a directory: $final_path " + +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= + +ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= + +ynh_restore_file "$final_path" + +#================================================= +# RECREATE THE DEDICATED USER +#================================================= + +# Create the dedicated user (if not existing) +ynh_system_user_create $app + +#================================================= +# RESTORE USER RIGHTS +#================================================= + +# Restore permissions on app files +chown -R root: $final_path + +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= + +# Define and install dependencies +ynh_install_app_dependencies supervisor + +#================================================= +# RESTORE THE SUPERVISOR CONFIGURATION +#================================================= + +ynh_restore_file "/etc/supervisor/conf.d/$app.conf" + +supervisorctl update +supervisorctl restart $app + +#================================================= +# GENERIC FINALIZATION +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/scripts/upgrade b/scripts/upgrade index 90d4dca..33445c0 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,30 +1,122 @@ #!/bin/bash -# Retrieve settings -app=linuxdash -domain=$(sudo yunohost app setting $app domain) -path=$(sudo yunohost app setting $app path) +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Remove trailing "/" for next commands -path=${path%/} +source _common.sh +source /usr/share/yunohost/helpers -# Copy files to the right place -final_path=/var/www/$app -sudo mkdir -p $final_path -sudo cp -a ../sources/* $final_path +#================================================= +# LOAD SETTINGS +#================================================= -# Set permissions -sudo chown -R www-data: $final_path +app=$YNH_APP_INSTANCE_NAME -# Modify Nginx configuration file and copy it to Nginx conf directory -sed -i "s@YNH_WWW_PATH@$path@g" ../conf/nginx.conf -nginxconf=/etc/nginx/conf.d/$domain.d/$app.conf -sudo cp ../conf/nginx.conf $nginxconf -sudo chown root: $nginxconf -sudo chmod 600 $nginxconf +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path) +user=$(ynh_app_setting_get $app admin) +final_path=$(ynh_app_setting_get $app final_path) +port=$(ynh_app_setting_get $app port) -# Restart Linux-dash service -sudo supervisorctl restart $app +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= -# Reload web server & sso -sudo service nginx reload +# If final_path doesn't exist, create it +if [ -z $final_path ]; then + final_path=/var/www/$app + ynh_app_setting_set $app final_path $final_path +fi + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# CHECK THE PATH +#================================================= + +# Normalize the URL path syntax +path_url=$(ynh_normalize_url_path $path_url) + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Create a dedicated nginx config +if [ "$path_url" != "/" ] +then + ynh_replace_string "^#sub_path_only" "" "../conf/nginx.conf" +fi +ynh_add_nginx_config + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create $app + +#================================================= +# SPECIFIC UPGRADE +#================================================= +# UPGRADE SUPERVISOR +#================================================= + +# Set as a service with supervisor +cp ../conf/supervisor.conf /etc/supervisor/conf.d/$app.conf +ynh_replace_string "__APP__" "$app" "/etc/supervisor/conf.d/$app.conf" +ynh_replace_string "__FINALPATH__" "$final_path" "/etc/supervisor/conf.d/$app.conf" +ynh_replace_string "__USER__" "$app" "/etc/supervisor/conf.d/$app.conf" + +supervisorctl update +supervisorctl restart $app + +#================================================= +# REMOVE GOOGLE !!! +#================================================= + +sed --in-place "/googlecode\|googleapis/d" "$final_path/index.html" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# Set right permissions for curl installation +chown -R root: $final_path + +#================================================= +# SETUP SSOWAT +#================================================= + +# Restrict access to admin only +yunohost app addaccess --users=$user $app + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/sources/.editorconfig b/sources/.editorconfig deleted file mode 100755 index 4a7ea30..0000000 --- a/sources/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false diff --git a/sources/.gitignore b/sources/.gitignore deleted file mode 100644 index 91be243..0000000 --- a/sources/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -vendor -node_modules diff --git a/sources/LICENSE.md b/sources/LICENSE.md deleted file mode 100644 index ec1c59a..0000000 --- a/sources/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 afaqurk - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/sources/README.md b/sources/README.md deleted file mode 100644 index a6a8a51..0000000 --- a/sources/README.md +++ /dev/null @@ -1,54 +0,0 @@ -
-

Linux Dash

- -
- A simple, low-overhead web dashboard for Linux -
- -

- - Demo  |  - Features  |  - - Installation  |  - Support - -

- -

- - Linux Dash Gitter chat - -

- -
-

- - Linux Dash screenshot - -

- -
- -## Features -* A beautiful, simple web-based dashboard for monitoring a linux server -* Only ~1MB on disk! *(.git removed)* -* Live graphs, refresh-able widgets, and a growing # of supported modules -* Drop-in installation for PHP, Node.js, Python, and Go - -## Support - -For help with general setup and configuration issues please use the [Linux Dash Gitter chat room](https://gitter.im/afaqurk/linux-dash). - -The following distributions are supported: -* Arch -* Debian 6,7 -* Ubuntu 11.04+ -* Linux Mint 16+ -* CentOS 5, 6 -* openSUSE diff --git a/sources/composer.json b/sources/composer.json deleted file mode 100644 index 3e62760..0000000 --- a/sources/composer.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "afaqurk/linux-dash", - "description": "A drop-in, low-overhead monitoring web dashboard for a linux machine.", - "license": "MIT", - "version": "1.2.0", - "keywords": ["linux", "dashboard", "linux-dash", "server dashboard"], - "authors": [ - { - "name": "Afaq Tariq", - "email": "afaq05@gmail.com" - } - ], - "minimum-stability": "stable", - "require": { - "php": ">=5.4.0" - }, - "support": { - "issues": "https://github.com/afaqurk/linux-dash/issues?state=open", - "forum": "https://gitter.im/afaqurk/linux-dash", - "source": "https://github.com/afaqurk/linux-dash" - } -} diff --git a/sources/css/animate.css b/sources/css/animate.css deleted file mode 100644 index 14afba9..0000000 --- a/sources/css/animate.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! -Animate.css - http://daneden.me/animate -Licensed under the MIT license - http://opensource.org/licenses/MIT - -Copyright (c) 2015 Daniel Eden -*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(.755,.050,.855,.060);transition-timing-function:cubic-bezier(.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(.755,.050,.855,.060);transition-timing-function:cubic-bezier(.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(.755,.050,.855,.060);transition-timing-function:cubic-bezier(.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(.755,.050,.855,.060);transition-timing-function:cubic-bezier(.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/sources/css/main.css b/sources/css/main.css deleted file mode 100644 index 2bb5a92..0000000 --- a/sources/css/main.css +++ /dev/null @@ -1,488 +0,0 @@ -/***** Template ****/ -* { - font-family: 'Merriweather', Arial, sans-serif; - letter-spacing: .1rem; -} -html { - margin-top: 0px; - padding-top: 0; - border-top: 1px solid #4F8EF7; - - background: url(../img/themes/crossword.png); - - -webkit-transition: all 1s ease; - -moz-transition: all 1s ease; - -ms-transition: all 1s ease; - -o-transition: all 1s ease; - transition: all 1s ease; -} -body { - padding: 0; -} -.title { - color: rgb(34, 34, 34); - display: block; - font-size: 30px; - font-weight: 300; - height: 32px; - letter-spacing: .1rem; - line-height: 52.5px; - margin-bottom: 20px; - margin-top: 0px; - text-align: center; -} -.plugin ::-webkit-scrollbar { - width: 5px; -} -.plugin ::-webkit-scrollbar-button { - width: 8px; - height:5px; -} -.plugin ::-webkit-scrollbar-track { - background:#eee; - border: thin solid lightgray; - box-shadow: 0px 0px 3px #dfdfdf inset; - border-radius:10px; -} -.plugin ::-webkit-scrollbar-thumb { - background: #999; - border: thin solid gray; - border-radius:10px; -} -.plugin ::-webkit-scrollbar-thumb:hover { - background:#7d7d7d; -} -.centered { - margin: 0 auto; -} -.hero { - padding: 10px 0 20px 0; - text-align: center; -} -.hero nav-bar { - display: block; -} -.hero nav-bar ul { - margin: 0; - padding: 0; - list-style-type: none; - display: inline; -} -.hero nav-bar ul li a { - font-size: 11px; - text-transform: uppercase; - font-weight: 600; - letter-spacing: .2rem; - margin-right: 35px; - text-decoration: none; - line-height: 2.3rem; - color: #222; -} -.hero nav-bar ul li.active a, -.hero nav-bar ul li a:hover { - color: #1EAEDB; -} -.hero nav-bar ul li { - margin-left: 20px; - display: inline; -} -.hero nav-bar ul li a { - display: inline; -} -#theme-switcher { - position: fixed; - top: 25px; - right: -371px; - border-radius: 5px 0px 0px 5px; - padding: 4px; - z-index: 999999; - cursor: pointer; - color: rgb(255, 255, 255); - background-color: #517fa4; - - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -ms-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - transition: all 0.5s ease; -} -#theme-switcher .settings-icon{ - font-size: 25px; - height: 100%; - margin-top: 5px; - float: left; - display: inline-block; -} -#theme-switcher .settings-icon:hover{ - color: #243949; -} -#theme-switcher.open { - right: 0; -} -#theme-switcher .option { - margin: 5px; - border: 1px solid transparent; - display: inline-block; - padding: 5px; - color: black; - background-color: #ececec; - border-radius: 2px; - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -ms-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - transition: all 0.5s ease; -} -#theme-switcher .option:hover, -#theme-switcher .option.selected { - box-shadow: 0 5px 10px rgba(0,0,0,.53),0 3px 10px rgba(0,0,0,.16); - background-color: #FFF94C; -} -#theme-switcher .option.selected:hover { - background-color: lightgrey; -} -@media (min-width: 1080px) { - #plugins { - float: none; - margin: 0 auto; - clear: both; - } -} -@media (max-width: 1079px) { - #plugins { - float: none; - margin: 0 auto; - clear: both; - } -} - -/***** Plugins Container ****/ -#plugins { - padding: 20px; - padding-top: 0; - margin-top: 0; - border: 1px; -} - -/***** Plugin ****/ -.plugin { - float: left; - padding: 0; - background-color: #FFFFFF; - color: black; - text-align: center; - border-radius: 2px; - box-shadow: 0 5px 10px rgba(0,0,0,.53),0 3px 10px rgba(0,0,0,.16); - margin-top: 10px; - margin: 0 auto; - margin-top: 20px; - margin-left: 50px; - margin-bottom: 50px; -} -@media (max-width: 768px) { - .plugin { - max-width: 80%; - float: none; - margin: 0 auto; - margin-bottom: 10px; - } - .plugin-body { - max-height: 400px; - } -} -.plugin .top-bar { - height: 25px; - max-width: 100%; - padding: 20px; - letter-spacing: .1rem; - line-height: 1.3rem; - font-size: 11px; - text-transform: uppercase; - font-weight: 600; - color: #009587; - text-align: center; -} -.plugin .no-padding { - padding: 0px; -} -.plugin-body { - height: 400px; - font-size: 12px; - padding: 10px; - line-height: 30px; - overflow: auto; - border-top: 1px solid #ececec; -} -.plugin last-update{ - font-size: 11px; - float: left; -} - -no-data { - font-style: italic; -} -refresh-btn button { - background-color: #009587; - border: 0; - float: right; - font-size: 15px; - color: white; - border-radius: 50%; - width: 30px; - height: 30px; - padding: 5px; - - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -ms-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - transition: all 0.5s ease; - - box-shadow: 0 1px 6px rgba(0,0,0,.12),0 1px 6px rgba(0,0,0,.5); -} -refresh-btn button:hover { - background-color: #ffeb3b; - color: black; -} -refresh-btn button:active { - background-color: #0f9d58; -} - -/**** Loader ****/ -.spinner { - margin: 100px auto; - width: 50px; - height: 30px; - text-align: center; - font-size: 10px; -} - -.spinner > div { - background-color: #009587; - height: 100%; - width: 6px; - display: inline-block; - - -webkit-animation: stretchdelay 1.2s infinite ease-in-out; - animation: stretchdelay 1.2s infinite ease-in-out; -} - -.spinner .rect2 { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} - -.spinner .rect3 { - -webkit-animation-delay: -1.0s; - animation-delay: -1.0s; -} - -.spinner .rect4 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} - -.spinner .rect5 { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} - -@-webkit-keyframes stretchdelay { - 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } - 20% { -webkit-transform: scaleY(1.0) } -} - -@keyframes stretchdelay { - 0%, 40%, 100% { - transform: scaleY(0.4); - -webkit-transform: scaleY(0.4); - } 20% { - transform: scaleY(1.0); - -webkit-transform: scaleY(1.0); - } -} - -/**** General Elements ****/ -table -{ - font-size: 10px; - margin: 0; - min-width: 400px; - border-collapse: collapse; - text-align: left; - table-layout:fixed; -} -table th, -table td { - padding: 5px; - max-width: 250px; - word-wrap: break-word; -} -table th -{ - font-weight: 600; - text-transform: uppercase; - border-bottom: 1px solid #f1f1f1; -} -table td { - border-bottom: 1px solid #f1f1f1; - padding: 9px 8px; - font-family: Arial, sans-serif; - font-size: 11px; - letter-spacing: .1em; - color: rgba(0,0,0,.65); -} -table tbody tr:hover td -{ - background-color: #fafafa; -} -table.metrics-table { - text-align: center; -} -canvas { - float: none; - margin: 0 auto; - width: 100%; - max-width: 100%; -} -/********************************************* - Widget Elements -*********************************************/ -.progress-bar { - background-color: #eec; - border-radius: 10px; /* (height of inner div) / 2 + padding */ - padding: 0px; - clear: both; - display: inline-block; - overflow: hidden; - white-space: nowrap; -} -.progress-bar > div { - background-color: #1EAEDB; - width: 0%; - height: 5px; - border-radius: 5px; -} -.table-data-plugin .filter-container { - padding-bottom: 0; - margin: 0; -} -.table-data-plugin .filter, -.table-data-plugin .filter:focus, -.table-data-plugin .filter:active { - height: 20px; - padding: 5px; - margin: 5px; - border: none; - outline-color: transparent; - background: transparent; - width: 100%; - margin: 0; - text-align: center; - font-size: 15px; -} -.table-data-plugin .filter:focus { - border-bottom: 1px solid #ff5722; -} -.table-data-plugin thead tr th a, -.table-data-plugin thead tr th a:visited { - color: black; - text-decoration: none; -} -.table-data-plugin .column-sort-caret { - font-size: 10px; - color: #1EAEDB; -} -/* - * Popover - * http://codepen.io/derekpcollins/pen/JCLhG/ - */ - -/* The element to hover over */ -.qs { - cursor: default; - display: inline-block; - position: relative; -} -.qs .popover { - text-transform: none; - background-color: rgba(0, 0, 0, 0.85); - border-radius: 5px; - bottom: 42px; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.4); - color: #fff; - display: none; - font-size: 12px; - font-family: 'Helvetica',sans-serif; - padding: 7px 10px; - position: absolute; - left: -80px; - width: 200px; - z-index: 4; -} -.qs .popover:before { - border-top: 7px solid rgba(0, 0, 0, 0.85); - border-right: 7px solid transparent; - border-left: 7px solid transparent; - bottom: -7px; - content: ''; - display: block; - left: 50%; - margin-left: -7px; - position: absolute; -} -.qs:hover .popover { - display: block; - -webkit-animation: fade-in .3s linear 1, move-up .3s linear 1; - -moz-animation: fade-in .3s linear 1, move-up .3s linear 1; - -ms-animation: fade-in .3s linear 1, move-up .3s linear 1; -} - -@-webkit-keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@-moz-keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@-ms-keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@-webkit-keyframes move-up { - from { - bottom: 30px; - } - to { - bottom: 42px; - } -} -@-moz-keyframes move-up { - from { - bottom: 30px; - } - to { - bottom: 42px; - } -} -@-ms-keyframes move-up { - from { - bottom: 30px; - } - to { - bottom: 42px; - } -} diff --git a/sources/css/theme-old.css b/sources/css/theme-old.css deleted file mode 100644 index 0e02cdd..0000000 --- a/sources/css/theme-old.css +++ /dev/null @@ -1,170 +0,0 @@ -/************************************** - Theme: linux-dash beta -**************************************/ -html.old { - background: #F9F6F1; -} -html.old body { - margin: 0; -} -html.old body * { - font-family: "Open Sans"; - letter-spacing: 0; -} -html.old body .hero { - background: #00BA8B; - color: #ffffff; - padding: 0; -} -html.old body .hero h4 { - color: #ffffff; - display: inline-block; - font-size: 20px; - font-weight: 600; - height: 40px; - line-height: 35px; - margin: 0; - vertical-align: middle; -} -html.old body .hero small { - letter-spacing: 0.1rem; - line-height: 40px; - margin-left: 20px; - opacity: 0.9; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} -html.old body .hero #theme-switcher { - right: -315px; -} -html.old body .hero #theme-switcher.open { - right: 0; -} -html.old body .hero nav-bar { - background: #ffffff; - border-bottom: 1px solid #d6d6d6; - color: #333333; -} -html.old body .hero nav-bar br { - display: none; -} -html.old body .hero nav-bar ul { - display: inline-block; -} -html.old body .hero nav-bar ul li { - display: inline-block; - margin: 0; -} -html.old body .hero nav-bar ul li:not(:first-child) { - border-left: 1px solid #e6e6e6; -} -html.old body .hero nav-bar ul li a { - color: #B2AFAA; - display: block; - font-size: 12px; - font-weight: bold; - line-height: 30px; - margin: 0; - padding: 0 15px; - text-transform: capitalize; -} -html.old body .hero nav-bar ul li:hover a { - color: #888888; -} -html.old body #plugins { - display: flex; - flex-flow: row wrap; - justify-content: flex-start; -} -html.old body .plugin { - border: 1px solid #d5d5d5; - border-radius: 0 0 5px 5px; - box-shadow: none; - margin: 10px; -} -html.old body .plugin .top-bar { - background: transparent linear-gradient(to bottom, #f9f6f1 0%, #f2efea 100%) repeat scroll 0px 0px; - border-bottom: 1px solid #d6d6d6; - color: #525252; - font-size: 14px; - font-weight: bold; - height: 40px; - line-height: 40px; - padding: 0 0 0 15px; - position: relative; - text-align: left; - text-transform: none; -} -html.old body .plugin .top-bar last-update { - float: right; - margin: 0 10px; - opacity: 0.8; -} -html.old body .plugin .top-bar refresh-btn { - float: right; -} -html.old body .plugin .top-bar refresh-btn button { - background: #ffffff; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1) inset, 0px 1px 2px rgba(0, 0, 0, 0.1); - color: #555555; - cursor: pointer; - box-shadow: none; - display: inline-block; - float: none; - font-size: 14px; - height: auto; - margin: 0 -5px 0 10px; - padding: 0 4px; - width: auto; -} -html.old body .plugin .top-bar refresh-btn button:hover { - background: #e6e6e6; -} -html.old body .plugin .plugin-body { - border: none; - height: auto; - line-height: normal; - max-height: 300px; - padding: 0; -} -html.old body .plugin .plugin-body table { - border-collapse: separate; - border-spacing: 0; - font-size: 12px; - min-width: 300px; -} -html.old body .plugin .plugin-body table tr:not(:first-child) th { - border-top: 1px solid #dddddd; -} -html.old body .plugin .plugin-body table td, -html.old body .plugin .plugin-body table th { - border-bottom: none; - padding: 4px 5px; -} -html.old body .plugin .plugin-body table td:not(:first-child), -html.old body .plugin .plugin-body table th:not(:first-child) { - border-left: 1px solid #dddddd; -} -html.old body .plugin .plugin-body table th:not(.filter-container) { - background: transparent -moz-linear-gradient(center top, #fafafa 0%, #e9e9e9 100%) repeat scroll 0% 0%; - text-transform: uppercase; -} -html.old body .plugin .plugin-body table th.filter-container .filter { - border-bottom: none; - font-size: 12px; - height: auto; - padding: 2px; -} -html.old body .plugin .plugin-body table th.filter-container .filter::before { - content: 'Search >'; - opacity: 0.5; - position: absolute; - left: 0; -} -html.old body .plugin .plugin-body table td { - border-top: 1px solid #dddddd; -} -html.old body .plugin canvas { - width: 100%; -} diff --git a/sources/css/themes.css b/sources/css/themes.css deleted file mode 100644 index e3a18aa..0000000 --- a/sources/css/themes.css +++ /dev/null @@ -1,88 +0,0 @@ -@import "theme-old.css"; - -/************************************** - Theme: Winter -**************************************/ - -html.winter { - background: url(../img/themes/contemporary_china_2.png) ; -} -html.winter .hero nav-bar ul li.active a, -html.winter .hero nav-bar ul li a:hover { - color: #23568f; -} -html.winter .plugin { - background-color: rgba(255, 255, 255, 0.60); -} -html.winter .plugin .top-bar { - color: #012e40; -} -html.winter .plugin refresh-btn button { - background-color: #4c6c73; -} -table th { - color: #012e40; -} - -/************************************** - Theme: Summer -**************************************/ - -html.summer { - clear: both; - background: url(../img/themes/congruent_pentagon.png); -} -html.summer .hero nav-bar ul li.active a, -html.summer .hero nav-bar ul li a:hover { - color: #D84315; -} -html.summer .plugin{ - background-color: rgba(255, 255, 255, 0.8); -} -html.summer .plugin .top-bar { - color: #BF360C; -} -html.summer .plugin refresh-btn button { - background-color: #BF360C; -} - -/************************************** - Theme: Spring -**************************************/ - -html.spring { - clear: both; - background: url(../img/themes/food.png); -} -html.spring .hero nav-bar ul li.active a, -html.spring .hero nav-bar ul li a:hover { - color: #E65100; -} -html.spring .plugin { - background-color: rgba(255,255,255,0.95); -} -html.spring .plugin .top-bar { - color: #FF6D00; -} -html.spring .plugin refresh-btn button { - background-color: #E65100; -} - -/************************************** - Theme: Fall -**************************************/ - -html.fall { - background: url(../img/themes/skulls.png); -} -html.fall .plugin { - background: url(../img/themes/crossword.png); -} -html.fall .hero nav-bar ul li.active a, -html.fall .hero nav-bar ul li a:hover, -html.fall .plugin .top-bar { - color: #F09819; -} -html.fall .plugin refresh-btn button { - background-color: #FF512F; -} diff --git a/sources/demo.html b/sources/demo.html deleted file mode 100644 index e228927..0000000 --- a/sources/demo.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - linux-dash : Server Monitoring Web Dashboard - - - - - - - - - - - - - - - - - - - - Fork me on GitHub - - -
-

Linux Dash

- - A simple linux dashboard - - - - - -
- -
-

Setting server...

- -
- - -
- - - - - - - - - - - - diff --git a/sources/favicon.ico b/sources/favicon.ico deleted file mode 100644 index cf41009..0000000 Binary files a/sources/favicon.ico and /dev/null differ diff --git a/sources/img/themes/congruent_pentagon.png b/sources/img/themes/congruent_pentagon.png deleted file mode 100644 index c712660..0000000 Binary files a/sources/img/themes/congruent_pentagon.png and /dev/null differ diff --git a/sources/img/themes/contemporary_china_2.png b/sources/img/themes/contemporary_china_2.png deleted file mode 100644 index 4bd667d..0000000 Binary files a/sources/img/themes/contemporary_china_2.png and /dev/null differ diff --git a/sources/img/themes/crossword.png b/sources/img/themes/crossword.png deleted file mode 100644 index 2f9f1ad..0000000 Binary files a/sources/img/themes/crossword.png and /dev/null differ diff --git a/sources/img/themes/food.png b/sources/img/themes/food.png deleted file mode 100644 index 14b6bbc..0000000 Binary files a/sources/img/themes/food.png and /dev/null differ diff --git a/sources/img/themes/skulls.png b/sources/img/themes/skulls.png deleted file mode 100644 index 93508ff..0000000 Binary files a/sources/img/themes/skulls.png and /dev/null differ diff --git a/sources/index.html b/sources/index.html deleted file mode 100644 index 0c02756..0000000 --- a/sources/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - linux-dash : Server Monitoring Web Dashboard - - - - - - - - - - - - - - - - - - -
-

Linux Dash

- A simple linux dashboard - - -
- - -
-
- - - - - - - - diff --git a/sources/js/angular-route.js b/sources/js/angular-route.js deleted file mode 100644 index 6820318..0000000 --- a/sources/js/angular-route.js +++ /dev/null @@ -1,996 +0,0 @@ -/** - * @license AngularJS v1.3.4 - * (c) 2010-2014 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -/** - * @ngdoc module - * @name ngRoute - * @description - * - * # ngRoute - * - * The `ngRoute` module provides routing and deeplinking services and directives for angular apps. - * - * ## Example - * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. - * - * - *
- */ - /* global -ngRouteModule */ -var ngRouteModule = angular.module('ngRoute', ['ng']). - provider('$route', $RouteProvider), - $routeMinErr = angular.$$minErr('ngRoute'); - -/** - * @ngdoc provider - * @name $routeProvider - * - * @description - * - * Used for configuring routes. - * - * ## Example - * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. - * - * ## Dependencies - * Requires the {@link ngRoute `ngRoute`} module to be installed. - */ -function $RouteProvider() { - function inherit(parent, extra) { - return angular.extend(Object.create(parent), extra); - } - - var routes = {}; - - /** - * @ngdoc method - * @name $routeProvider#when - * - * @param {string} path Route path (matched against `$location.path`). If `$location.path` - * contains redundant trailing slash or is missing one, the route will still match and the - * `$location.path` will be updated to add or drop the trailing slash to exactly match the - * route definition. - * - * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up - * to the next slash are matched and stored in `$routeParams` under the given `name` - * when the route matches. - * * `path` can contain named groups starting with a colon and ending with a star: - * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name` - * when the route matches. - * * `path` can contain optional named groups with a question mark: e.g.`:name?`. - * - * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match - * `/color/brown/largecode/code/with/slashes/edit` and extract: - * - * * `color: brown` - * * `largecode: code/with/slashes`. - * - * - * @param {Object} route Mapping information to be assigned to `$route.current` on route - * match. - * - * Object properties: - * - * - `controller` – `{(string|function()=}` – Controller fn that should be associated with - * newly created scope or the name of a {@link angular.Module#controller registered - * controller} if passed as a string. - * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be - * published to scope under the `controllerAs` name. - * - `template` – `{string=|function()=}` – html template as a string or a function that - * returns an html template as a string which should be used by {@link - * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. - * This property takes precedence over `templateUrl`. - * - * If `template` is a function, it will be called with the following parameters: - * - * - `{Array.}` - route parameters extracted from the current - * `$location.path()` by applying the current route - * - * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html - * template that should be used by {@link ngRoute.directive:ngView ngView}. - * - * If `templateUrl` is a function, it will be called with the following parameters: - * - * - `{Array.}` - route parameters extracted from the current - * `$location.path()` by applying the current route - * - * - `resolve` - `{Object.=}` - An optional map of dependencies which should - * be injected into the controller. If any of these dependencies are promises, the router - * will wait for them all to be resolved or one to be rejected before the controller is - * instantiated. - * If all the promises are resolved successfully, the values of the resolved promises are - * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is - * fired. If any of the promises are rejected the - * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object - * is: - * - * - `key` – `{string}`: a name of a dependency to be injected into the controller. - * - `factory` - `{string|function}`: If `string` then it is an alias for a service. - * Otherwise if function, then it is {@link auto.$injector#invoke injected} - * and the return value is treated as the dependency. If the result is a promise, it is - * resolved before its value is injected into the controller. Be aware that - * `ngRoute.$routeParams` will still refer to the previous route within these resolve - * functions. Use `$route.current.params` to access the new route parameters, instead. - * - * - `redirectTo` – {(string|function())=} – value to update - * {@link ng.$location $location} path with and trigger route redirection. - * - * If `redirectTo` is a function, it will be called with the following parameters: - * - * - `{Object.}` - route parameters extracted from the current - * `$location.path()` by applying the current route templateUrl. - * - `{string}` - current `$location.path()` - * - `{Object}` - current `$location.search()` - * - * The custom `redirectTo` function is expected to return a string which will be used - * to update `$location.path()` and `$location.search()`. - * - * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()` - * or `$location.hash()` changes. - * - * If the option is set to `false` and url in the browser changes, then - * `$routeUpdate` event is broadcasted on the root scope. - * - * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive - * - * If the option is set to `true`, then the particular route can be matched without being - * case sensitive - * - * @returns {Object} self - * - * @description - * Adds a new route definition to the `$route` service. - */ - this.when = function(path, route) { - //copy original route object to preserve params inherited from proto chain - var routeCopy = angular.copy(route); - if (angular.isUndefined(routeCopy.reloadOnSearch)) { - routeCopy.reloadOnSearch = true; - } - if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) { - routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch; - } - routes[path] = angular.extend( - routeCopy, - path && pathRegExp(path, routeCopy) - ); - - // create redirection for trailing slashes - if (path) { - var redirectPath = (path[path.length - 1] == '/') - ? path.substr(0, path.length - 1) - : path + '/'; - - routes[redirectPath] = angular.extend( - {redirectTo: path}, - pathRegExp(redirectPath, routeCopy) - ); - } - - return this; - }; - - /** - * @ngdoc property - * @name $routeProvider#caseInsensitiveMatch - * @description - * - * A boolean property indicating if routes defined - * using this provider should be matched using a case sensitive - * algorithm. Defaults to `false`. - */ - this.caseInsensitiveMatch = false; - - /** - * @param path {string} path - * @param opts {Object} options - * @return {?Object} - * - * @description - * Normalizes the given path, returning a regular expression - * and the original path. - * - * Inspired by pathRexp in visionmedia/express/lib/utils.js. - */ - function pathRegExp(path, opts) { - var insensitive = opts.caseInsensitiveMatch, - ret = { - originalPath: path, - regexp: path - }, - keys = ret.keys = []; - - path = path - .replace(/([().])/g, '\\$1') - .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { - var optional = option === '?' ? option : null; - var star = option === '*' ? option : null; - keys.push({ name: key, optional: !!optional }); - slash = slash || ''; - return '' - + (optional ? '' : slash) - + '(?:' - + (optional ? slash : '') - + (star && '(.+?)' || '([^/]+)') - + (optional || '') - + ')' - + (optional || ''); - }) - .replace(/([\/$\*])/g, '\\$1'); - - ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); - return ret; - } - - /** - * @ngdoc method - * @name $routeProvider#otherwise - * - * @description - * Sets route definition that will be used on route change when no other route definition - * is matched. - * - * @param {Object|string} params Mapping information to be assigned to `$route.current`. - * If called with a string, the value maps to `redirectTo`. - * @returns {Object} self - */ - this.otherwise = function(params) { - if (typeof params === 'string') { - params = {redirectTo: params}; - } - this.when(null, params); - return this; - }; - - - this.$get = ['$rootScope', - '$location', - '$routeParams', - '$q', - '$injector', - '$templateRequest', - '$sce', - function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) { - - /** - * @ngdoc service - * @name $route - * @requires $location - * @requires $routeParams - * - * @property {Object} current Reference to the current route definition. - * The route definition contains: - * - * - `controller`: The controller constructor as define in route definition. - * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for - * controller instantiation. The `locals` contain - * the resolved values of the `resolve` map. Additionally the `locals` also contain: - * - * - `$scope` - The current route scope. - * - `$template` - The current route template HTML. - * - * @property {Object} routes Object with all route configuration Objects as its properties. - * - * @description - * `$route` is used for deep-linking URLs to controllers and views (HTML partials). - * It watches `$location.url()` and tries to map the path to an existing route definition. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. - * - * The `$route` service is typically used in conjunction with the - * {@link ngRoute.directive:ngView `ngView`} directive and the - * {@link ngRoute.$routeParams `$routeParams`} service. - * - * @example - * This example shows how changing the URL hash causes the `$route` to match a route against the - * URL, and the `ngView` pulls in the partial. - * - * - * - *
- * Choose: - * Moby | - * Moby: Ch1 | - * Gatsby | - * Gatsby: Ch4 | - * Scarlet Letter
- * - *
- * - *
- * - *
$location.path() = {{$location.path()}}
- *
$route.current.templateUrl = {{$route.current.templateUrl}}
- *
$route.current.params = {{$route.current.params}}
- *
$route.current.scope.name = {{$route.current.scope.name}}
- *
$routeParams = {{$routeParams}}
- *
- *
- * - * - * controller: {{name}}
- * Book Id: {{params.bookId}}
- *
- * - * - * controller: {{name}}
- * Book Id: {{params.bookId}}
- * Chapter Id: {{params.chapterId}} - *
- * - * - * angular.module('ngRouteExample', ['ngRoute']) - * - * .controller('MainController', function($scope, $route, $routeParams, $location) { - * $scope.$route = $route; - * $scope.$location = $location; - * $scope.$routeParams = $routeParams; - * }) - * - * .controller('BookController', function($scope, $routeParams) { - * $scope.name = "BookController"; - * $scope.params = $routeParams; - * }) - * - * .controller('ChapterController', function($scope, $routeParams) { - * $scope.name = "ChapterController"; - * $scope.params = $routeParams; - * }) - * - * .config(function($routeProvider, $locationProvider) { - * $routeProvider - * .when('/Book/:bookId', { - * templateUrl: 'book.html', - * controller: 'BookController', - * resolve: { - * // I will cause a 1 second delay - * delay: function($q, $timeout) { - * var delay = $q.defer(); - * $timeout(delay.resolve, 1000); - * return delay.promise; - * } - * } - * }) - * .when('/Book/:bookId/ch/:chapterId', { - * templateUrl: 'chapter.html', - * controller: 'ChapterController' - * }); - * - * // configure html5 to get links working on jsfiddle - * $locationProvider.html5Mode(true); - * }); - * - * - * - * - * it('should load and compile correct template', function() { - * element(by.linkText('Moby: Ch1')).click(); - * var content = element(by.css('[ng-view]')).getText(); - * expect(content).toMatch(/controller\: ChapterController/); - * expect(content).toMatch(/Book Id\: Moby/); - * expect(content).toMatch(/Chapter Id\: 1/); - * - * element(by.partialLinkText('Scarlet')).click(); - * - * content = element(by.css('[ng-view]')).getText(); - * expect(content).toMatch(/controller\: BookController/); - * expect(content).toMatch(/Book Id\: Scarlet/); - * }); - * - *
- */ - - /** - * @ngdoc event - * @name $route#$routeChangeStart - * @eventType broadcast on root scope - * @description - * Broadcasted before a route change. At this point the route services starts - * resolving all of the dependencies needed for the route change to occur. - * Typically this involves fetching the view template as well as any dependencies - * defined in `resolve` route property. Once all of the dependencies are resolved - * `$routeChangeSuccess` is fired. - * - * The route change (and the `$location` change that triggered it) can be prevented - * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} - * for more details about event object. - * - * @param {Object} angularEvent Synthetic event object. - * @param {Route} next Future route information. - * @param {Route} current Current route information. - */ - - /** - * @ngdoc event - * @name $route#$routeChangeSuccess - * @eventType broadcast on root scope - * @description - * Broadcasted after a route dependencies are resolved. - * {@link ngRoute.directive:ngView ngView} listens for the directive - * to instantiate the controller and render the view. - * - * @param {Object} angularEvent Synthetic event object. - * @param {Route} current Current route information. - * @param {Route|Undefined} previous Previous route information, or undefined if current is - * first route entered. - */ - - /** - * @ngdoc event - * @name $route#$routeChangeError - * @eventType broadcast on root scope - * @description - * Broadcasted if any of the resolve promises are rejected. - * - * @param {Object} angularEvent Synthetic event object - * @param {Route} current Current route information. - * @param {Route} previous Previous route information. - * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. - */ - - /** - * @ngdoc event - * @name $route#$routeUpdate - * @eventType broadcast on root scope - * @description - * - * The `reloadOnSearch` property has been set to false, and we are reusing the same - * instance of the Controller. - */ - - var forceReload = false, - preparedRoute, - preparedRouteIsUpdateOnly, - $route = { - routes: routes, - - /** - * @ngdoc method - * @name $route#reload - * - * @description - * Causes `$route` service to reload the current route even if - * {@link ng.$location $location} hasn't changed. - * - * As a result of that, {@link ngRoute.directive:ngView ngView} - * creates new scope and reinstantiates the controller. - */ - reload: function() { - forceReload = true; - $rootScope.$evalAsync(function() { - // Don't support cancellation of a reload for now... - prepareRoute(); - commitRoute(); - }); - }, - - /** - * @ngdoc method - * @name $route#updateParams - * - * @description - * Causes `$route` service to update the current URL, replacing - * current route parameters with those specified in `newParams`. - * Provided property names that match the route's path segment - * definitions will be interpolated into the location's path, while - * remaining properties will be treated as query params. - * - * @param {Object} newParams mapping of URL parameter names to values - */ - updateParams: function(newParams) { - if (this.current && this.current.$$route) { - var searchParams = {}, self=this; - - angular.forEach(Object.keys(newParams), function(key) { - if (!self.current.pathParams[key]) searchParams[key] = newParams[key]; - }); - - newParams = angular.extend({}, this.current.params, newParams); - $location.path(interpolate(this.current.$$route.originalPath, newParams)); - $location.search(angular.extend({}, $location.search(), searchParams)); - } - else { - throw $routeMinErr('norout', 'Tried updating route when with no current route'); - } - } - }; - - $rootScope.$on('$locationChangeStart', prepareRoute); - $rootScope.$on('$locationChangeSuccess', commitRoute); - - return $route; - - ///////////////////////////////////////////////////// - - /** - * @param on {string} current url - * @param route {Object} route regexp to match the url against - * @return {?Object} - * - * @description - * Check if the route matches the current url. - * - * Inspired by match in - * visionmedia/express/lib/router/router.js. - */ - function switchRouteMatcher(on, route) { - var keys = route.keys, - params = {}; - - if (!route.regexp) return null; - - var m = route.regexp.exec(on); - if (!m) return null; - - for (var i = 1, len = m.length; i < len; ++i) { - var key = keys[i - 1]; - - var val = m[i]; - - if (key && val) { - params[key.name] = val; - } - } - return params; - } - - function prepareRoute($locationEvent) { - var lastRoute = $route.current; - - preparedRoute = parseRoute(); - preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route - && angular.equals(preparedRoute.pathParams, lastRoute.pathParams) - && !preparedRoute.reloadOnSearch && !forceReload; - - if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) { - if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) { - if ($locationEvent) { - $locationEvent.preventDefault(); - } - } - } - } - - function commitRoute() { - var lastRoute = $route.current; - var nextRoute = preparedRoute; - - if (preparedRouteIsUpdateOnly) { - lastRoute.params = nextRoute.params; - angular.copy(lastRoute.params, $routeParams); - $rootScope.$broadcast('$routeUpdate', lastRoute); - } else if (nextRoute || lastRoute) { - forceReload = false; - $route.current = nextRoute; - if (nextRoute) { - if (nextRoute.redirectTo) { - if (angular.isString(nextRoute.redirectTo)) { - $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params) - .replace(); - } else { - $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search())) - .replace(); - } - } - } - - $q.when(nextRoute). - then(function() { - if (nextRoute) { - var locals = angular.extend({}, nextRoute.resolve), - template, templateUrl; - - angular.forEach(locals, function(value, key) { - locals[key] = angular.isString(value) ? - $injector.get(value) : $injector.invoke(value, null, null, key); - }); - - if (angular.isDefined(template = nextRoute.template)) { - if (angular.isFunction(template)) { - template = template(nextRoute.params); - } - } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) { - if (angular.isFunction(templateUrl)) { - templateUrl = templateUrl(nextRoute.params); - } - templateUrl = $sce.getTrustedResourceUrl(templateUrl); - if (angular.isDefined(templateUrl)) { - nextRoute.loadedTemplateUrl = templateUrl; - template = $templateRequest(templateUrl); - } - } - if (angular.isDefined(template)) { - locals['$template'] = template; - } - return $q.all(locals); - } - }). - // after route change - then(function(locals) { - if (nextRoute == $route.current) { - if (nextRoute) { - nextRoute.locals = locals; - angular.copy(nextRoute.params, $routeParams); - } - $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute); - } - }, function(error) { - if (nextRoute == $route.current) { - $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error); - } - }); - } - } - - - /** - * @returns {Object} the current active route, by matching it against the URL - */ - function parseRoute() { - // Match a route - var params, match; - angular.forEach(routes, function(route, path) { - if (!match && (params = switchRouteMatcher($location.path(), route))) { - match = inherit(route, { - params: angular.extend({}, $location.search(), params), - pathParams: params}); - match.$$route = route; - } - }); - // No route matched; fallback to "otherwise" route - return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); - } - - /** - * @returns {string} interpolation of the redirect path with the parameters - */ - function interpolate(string, params) { - var result = []; - angular.forEach((string || '').split(':'), function(segment, i) { - if (i === 0) { - result.push(segment); - } else { - var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/); - var key = segmentMatch[1]; - result.push(params[key]); - result.push(segmentMatch[2] || ''); - delete params[key]; - } - }); - return result.join(''); - } - }]; -} - -ngRouteModule.provider('$routeParams', $RouteParamsProvider); - - -/** - * @ngdoc service - * @name $routeParams - * @requires $route - * - * @description - * The `$routeParams` service allows you to retrieve the current set of route parameters. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * The route parameters are a combination of {@link ng.$location `$location`}'s - * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}. - * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. - * - * In case of parameter name collision, `path` params take precedence over `search` params. - * - * The service guarantees that the identity of the `$routeParams` object will remain unchanged - * (but its properties will likely change) even when a route change occurs. - * - * Note that the `$routeParams` are only updated *after* a route change completes successfully. - * This means that you cannot rely on `$routeParams` being correct in route resolve functions. - * Instead you can use `$route.current.params` to access the new route's parameters. - * - * @example - * ```js - * // Given: - * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby - * // Route: /Chapter/:chapterId/Section/:sectionId - * // - * // Then - * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'} - * ``` - */ -function $RouteParamsProvider() { - this.$get = function() { return {}; }; -} - -ngRouteModule.directive('ngView', ngViewFactory); -ngRouteModule.directive('ngView', ngViewFillContentFactory); - - -/** - * @ngdoc directive - * @name ngView - * @restrict ECA - * - * @description - * # Overview - * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by - * including the rendered template of the current route into the main layout (`index.html`) file. - * Every time the current route changes, the included view changes with it according to the - * configuration of the `$route` service. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * @animations - * enter - animation is used to bring new content into the browser. - * leave - animation is used to animate existing content away. - * - * The enter and leave animation occur concurrently. - * - * @scope - * @priority 400 - * @param {string=} onload Expression to evaluate whenever the view updates. - * - * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll - * $anchorScroll} to scroll the viewport after the view is updated. - * - * - If the attribute is not set, disable scrolling. - * - If the attribute is set without value, enable scrolling. - * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated - * as an expression yields a truthy value. - * @example - - -
- Choose: - Moby | - Moby: Ch1 | - Gatsby | - Gatsby: Ch4 | - Scarlet Letter
- -
-
-
-
- -
$location.path() = {{main.$location.path()}}
-
$route.current.templateUrl = {{main.$route.current.templateUrl}}
-
$route.current.params = {{main.$route.current.params}}
-
$routeParams = {{main.$routeParams}}
-
-
- - -
- controller: {{book.name}}
- Book Id: {{book.params.bookId}}
-
-
- - -
- controller: {{chapter.name}}
- Book Id: {{chapter.params.bookId}}
- Chapter Id: {{chapter.params.chapterId}} -
-
- - - .view-animate-container { - position:relative; - height:100px!important; - position:relative; - background:white; - border:1px solid black; - height:40px; - overflow:hidden; - } - - .view-animate { - padding:10px; - } - - .view-animate.ng-enter, .view-animate.ng-leave { - -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; - transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; - - display:block; - width:100%; - border-left:1px solid black; - - position:absolute; - top:0; - left:0; - right:0; - bottom:0; - padding:10px; - } - - .view-animate.ng-enter { - left:100%; - } - .view-animate.ng-enter.ng-enter-active { - left:0; - } - .view-animate.ng-leave.ng-leave-active { - left:-100%; - } - - - - angular.module('ngViewExample', ['ngRoute', 'ngAnimate']) - .config(['$routeProvider', '$locationProvider', - function($routeProvider, $locationProvider) { - $routeProvider - .when('/Book/:bookId', { - templateUrl: 'book.html', - controller: 'BookCtrl', - controllerAs: 'book' - }) - .when('/Book/:bookId/ch/:chapterId', { - templateUrl: 'chapter.html', - controller: 'ChapterCtrl', - controllerAs: 'chapter' - }); - - $locationProvider.html5Mode(true); - }]) - .controller('MainCtrl', ['$route', '$routeParams', '$location', - function($route, $routeParams, $location) { - this.$route = $route; - this.$location = $location; - this.$routeParams = $routeParams; - }]) - .controller('BookCtrl', ['$routeParams', function($routeParams) { - this.name = "BookCtrl"; - this.params = $routeParams; - }]) - .controller('ChapterCtrl', ['$routeParams', function($routeParams) { - this.name = "ChapterCtrl"; - this.params = $routeParams; - }]); - - - - - it('should load and compile correct template', function() { - element(by.linkText('Moby: Ch1')).click(); - var content = element(by.css('[ng-view]')).getText(); - expect(content).toMatch(/controller\: ChapterCtrl/); - expect(content).toMatch(/Book Id\: Moby/); - expect(content).toMatch(/Chapter Id\: 1/); - - element(by.partialLinkText('Scarlet')).click(); - - content = element(by.css('[ng-view]')).getText(); - expect(content).toMatch(/controller\: BookCtrl/); - expect(content).toMatch(/Book Id\: Scarlet/); - }); - -
- */ - - -/** - * @ngdoc event - * @name ngView#$viewContentLoaded - * @eventType emit on the current ngView scope - * @description - * Emitted every time the ngView content is reloaded. - */ -ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate']; -function ngViewFactory($route, $anchorScroll, $animate) { - return { - restrict: 'ECA', - terminal: true, - priority: 400, - transclude: 'element', - link: function(scope, $element, attr, ctrl, $transclude) { - var currentScope, - currentElement, - previousLeaveAnimation, - autoScrollExp = attr.autoscroll, - onloadExp = attr.onload || ''; - - scope.$on('$routeChangeSuccess', update); - update(); - - function cleanupLastView() { - if (previousLeaveAnimation) { - $animate.cancel(previousLeaveAnimation); - previousLeaveAnimation = null; - } - - if (currentScope) { - currentScope.$destroy(); - currentScope = null; - } - if (currentElement) { - previousLeaveAnimation = $animate.leave(currentElement); - previousLeaveAnimation.then(function() { - previousLeaveAnimation = null; - }); - currentElement = null; - } - } - - function update() { - var locals = $route.current && $route.current.locals, - template = locals && locals.$template; - - if (angular.isDefined(template)) { - var newScope = scope.$new(); - var current = $route.current; - - // Note: This will also link all children of ng-view that were contained in the original - // html. If that content contains controllers, ... they could pollute/change the scope. - // However, using ng-view on an element with additional content does not make sense... - // Note: We can't remove them in the cloneAttchFn of $transclude as that - // function is called before linking the content, which would apply child - // directives to non existing elements. - var clone = $transclude(newScope, function(clone) { - $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() { - if (angular.isDefined(autoScrollExp) - && (!autoScrollExp || scope.$eval(autoScrollExp))) { - $anchorScroll(); - } - }); - cleanupLastView(); - }); - - currentElement = clone; - currentScope = current.scope = newScope; - currentScope.$emit('$viewContentLoaded'); - currentScope.$eval(onloadExp); - } else { - cleanupLastView(); - } - } - } - }; -} - -// This directive is called during the $transclude call of the first `ngView` directive. -// It will replace and compile the content of the element with the loaded template. -// We need this directive so that the element content is already filled when -// the link function of another directive on the same element as ngView -// is called. -ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route']; -function ngViewFillContentFactory($compile, $controller, $route) { - return { - restrict: 'ECA', - priority: -400, - link: function(scope, $element) { - var current = $route.current, - locals = current.locals; - - $element.html(locals.$template); - - var link = $compile($element.contents()); - - if (current.controller) { - locals.$scope = scope; - var controller = $controller(current.controller, locals); - if (current.controllerAs) { - scope[current.controllerAs] = controller; - } - $element.data('$ngControllerController', controller); - $element.children().data('$ngControllerController', controller); - } - - link(scope); - } - }; -} - - -})(window, window.angular); diff --git a/sources/js/angular.min.js b/sources/js/angular.min.js deleted file mode 100644 index 836aa1e..0000000 --- a/sources/js/angular.min.js +++ /dev/null @@ -1,250 +0,0 @@ -/* - AngularJS v1.3.4 - (c) 2010-2014 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(U,V,u){'use strict';function z(b){return function(){var a=arguments[0],c;c="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.3.4/"+(b?b+"/":"")+a;for(a=1;a").append(b).html();try{return b[0].nodeType===mb?R(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+R(b)})}catch(d){return R(c)}}function pc(b){try{return decodeURIComponent(b)}catch(a){}}function qc(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g, -"%20").split("="),d=pc(c[0]),y(d)&&(b=y(c[1])?pc(c[1]):!0,Jb.call(a,d)?D(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Kb(b){var a=[];r(b,function(b,d){D(b)?r(b,function(b){a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))}):a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))});return a.length?a.join("&"):""}function nb(b){return Da(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Da(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g, -"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,a?"%20":"+")}function Fd(b,a){var c,d,e=ob.length;b=A(b);for(d=0;d/,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);c.debugInfoEnabled&&a.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);a.unshift("ng");d=Lb(a,c.strictDi);d.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return d},e= -/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;U&&e.test(U.name)&&(c.debugInfoEnabled=!0,U.name=U.name.replace(e,""));if(U&&!f.test(U.name))return d();U.name=U.name.replace(f,"");ha.resumeBootstrap=function(b){r(b,function(b){a.push(b)});d()}}function Hd(){U.name="NG_ENABLE_DEBUG_INFO!"+U.name;U.location.reload()}function Id(b){return ha.element(b).injector().get("$$testability")}function Mb(b,a){a=a||"_";return b.replace(Jd,function(b,d){return(d?a:"")+b.toLowerCase()})}function Kd(){var b;sc|| -((qa=U.jQuery)&&qa.fn.on?(A=qa,C(qa.fn,{scope:Ka.scope,isolateScope:Ka.isolateScope,controller:Ka.controller,injector:Ka.injector,inheritedData:Ka.inheritedData}),b=qa.cleanData,qa.cleanData=function(a){var c;if(Nb)Nb=!1;else for(var d=0,e;null!=(e=a[d]);d++)(c=qa._data(e,"events"))&&c.$destroy&&qa(e).triggerHandler("$destroy");b(a)}):A=S,ha.element=A,sc=!0)}function Ob(b,a,c){if(!b)throw Wa("areq",a||"?",c||"required");return b}function pb(b,a,c){c&&D(b)&&(b=b[b.length-1]);Ob(F(b),a,"not a function, got "+ -(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function La(b,a){if("hasOwnProperty"===b)throw Wa("badname",a);}function tc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g")+d[2];for(d=d[0];d--;)c=c.lastChild;f=Xa(f,c.childNodes);c=e.firstChild;c.textContent=""}else f.push(a.createTextNode(b));e.textContent="";e.innerHTML="";r(f,function(a){e.appendChild(a)});return e}function S(b){if(b instanceof S)return b;var a;I(b)&&(b=P(b),a=!0);if(!(this instanceof -S)){if(a&&"<"!=b.charAt(0))throw Qb("nosel");return new S(b)}if(a){a=V;var c;b=(c=cf.exec(b))?[a.createElement(c[1])]:(c=Dc(b,a))?c.childNodes:[]}Ec(this,b)}function Rb(b){return b.cloneNode(!0)}function tb(b,a){a||ub(b);if(b.querySelectorAll)for(var c=b.querySelectorAll("*"),d=0,e=c.length;d 4096 bytes)!"));else{if(p.cookie!==y)for(y=p.cookie,d=y.split("; "),aa={},f=0;fl&&this.remove(s.key),b},get:function(a){if(l").parent()[0])});var f=ea(a,b,a,c,d,e);B.$$addScopeClass(a);var g=null;return function(b, -c,d){Ob(b,"scope");d=d||{};var e=d.parentBoundTranscludeFn,h=d.transcludeControllers;d=d.futureParentElement;e&&e.$$boundTransclude&&(e=e.$$boundTransclude);g||(g=(d=d&&d[0])?"foreignobject"!==ta(d)&&d.toString().match(/SVG/)?"svg":"html":"html");d="html"!==g?A(U(g,A("
").append(a).html())):c?Ka.clone.call(a):a;if(h)for(var k in h)d.data("$"+k+"Controller",h[k].instance);B.$$addScopeInfo(d,b);c&&c(d,b);f&&f(b,d,d,e);return d}}function ea(a,b,c,d,e,f){function g(a,c,d,e){var f,k,l,q,s,n,w;if(p)for(w= -Array(c.length),q=0;qJ.priority)break;if(z=J.scope)J.templateUrl||(K(z)?(ya("new/isolated scope",L||M,J,T),L=J):ya("new/isolated scope",L,J,T)),M=M||J;ga=J.name;!J.templateUrl&&J.controller&&(z=J.controller,E=E||{},ya("'"+ga+"' controller",E[ga],J,T),E[ga]=J);if(z=J.transclude)x=!0,J.$$tlb||(ya("transclusion",da,J,T),da=J),"element"==z?(C=!0,v=J.priority,z=T,T=e.$$element=A(V.createComment(" "+ga+": "+ -e[ga]+" ")),d=T[0],Ab(g,Ya.call(z,0),d),Ga=B(z,f,v,k&&k.name,{nonTlbTranscludeDirective:da})):(z=A(Rb(d)).contents(),T.empty(),Ga=B(z,f));if(J.template)if(Na=!0,ya("template",aa,J,T),aa=J,z=F(J.template)?J.template(T,e):J.template,z=Pc(z),J.replace){k=J;z=Pb.test(z)?Qc(U(J.templateNamespace,P(z))):[];d=z[0];if(1!=z.length||d.nodeType!==na)throw ka("tplrt",ga,"");Ab(g,T,d);za={$attr:{}};z=W(d,[],za);var mf=a.splice(S+1,a.length-(S+1));L&&y(z);a=a.concat(z).concat(mf);Oc(e,za);za=a.length}else T.html(z); -if(J.templateUrl)Na=!0,ya("template",aa,J,T),aa=J,J.replace&&(k=J),H=G(a.splice(S,a.length-S),T,e,g,x&&Ga,l,q,{controllerDirectives:E,newIsolateScopeDirective:L,templateDirective:aa,nonTlbTranscludeDirective:da}),za=a.length;else if(J.compile)try{R=J.compile(T,e,Ga),F(R)?w(null,R,zb,$):R&&w(R.pre,R.post,zb,$)}catch(ca){c(ca,va(T))}J.terminal&&(H.terminal=!0,v=Math.max(v,J.priority))}H.scope=M&&!0===M.scope;H.transcludeOnThisElement=x;H.elementTranscludeOnThisElement=C;H.templateOnThisElement=Na;H.transclude= -Ga;p.hasElementTranscludeDirective=C;return H}function y(a){for(var b=0,c=a.length;bq.priority)&&-1!=q.restrict.indexOf(f)){if(k){var w={$$start:k,$$end:l};q=C(Object.create(q),w)}b.push(q);h=q}}catch(N){c(N)}}return h}function Oc(a,b){var c=b.$attr,d=a.$attr,e=a.$$element; -r(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(M(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function G(a,b,c,d,e,f,g,h){var k=[],l,s,p=b[0],n=a.shift(),w=C({},n,{templateUrl:null,transclude:null,replace:null,$$originalDirective:n}),N=F(n.templateUrl)?n.templateUrl(b, -c):n.templateUrl,t=n.templateNamespace;b.empty();q(O.getTrustedResourceUrl(N)).then(function(q){var v,O;q=Pc(q);if(n.replace){q=Pb.test(q)?Qc(U(t,P(q))):[];v=q[0];if(1!=q.length||v.nodeType!==na)throw ka("tplrt",n.name,N);q={$attr:{}};Ab(d,b,v);var H=W(v,[],q);K(n.scope)&&y(H);a=H.concat(a);Oc(c,q)}else v=p,b.html(q);a.unshift(w);l=aa(a,v,c,e,b,n,f,g,h);r(d,function(a,c){a==v&&(d[c]=b[0])});for(s=ea(b[0].childNodes,e);k.length;){q=k.shift();O=k.shift();var E=k.shift(),B=k.shift(),H=b[0];if(!q.$$destroyed){if(O!== -p){var Q=O.className;h.hasElementTranscludeDirective&&n.replace||(H=Rb(v));Ab(E,A(O),H);M(A(H),Q)}O=l.transcludeOnThisElement?L(q,l.transclude,B):B;l(s,q,H,d,O)}}k=null});return function(a,b,c,d,e){a=e;b.$$destroyed||(k?k.push(b,c,d,a):(l.transcludeOnThisElement&&(a=L(b,l.transclude,e)),l(s,b,c,d,a)))}}function z(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name"+b+"";return c.childNodes[0].childNodes;default:return b}}function Ga(a,b){if("srcdoc"==b)return O.HTML;var c=ta(a);if("xlinkHref"== -b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return O.RESOURCE_URL}function S(a,c,d,e,f){var h=b(d,!0);if(h){if("multiple"===e&&"select"===ta(a))throw ka("selmulti",va(a));c.push({priority:100,compile:function(){return{pre:function(c,d,l){d=l.$$observers||(l.$$observers={});if(k.test(e))throw ka("nodomevents");l[e]&&(h=b(l[e],!0,Ga(a,e),g[e]||f))&&(l[e]=h(c),(d[e]||(d[e]=[])).$$inter=!0,(l.$$observers&&l.$$observers[e].$$scope||c).$watch(h,function(a,b){"class"===e&&a!=b?l.$updateClass(a, -b):l.$set(e,a)}))}}}})}}function Ab(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g=a)return b;for(;a--;)8===b[a].nodeType&&of.call(b,a,1);return b}function Ce(){var b={},a=!1,c=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,c){La(a,"controller");K(a)?C(b,a):b[a]=c};this.allowGlobals=function(){a=!0};this.$get=["$injector","$window",function(d,e){function f(a, -b,c,d){if(!a||!K(a.$scope))throw z("$controller")("noscp",d,b);a.$scope[b]=c}return function(g,h,k,l){var m,p,s;k=!0===k;l&&I(l)&&(s=l);I(g)&&(l=g.match(c),p=l[1],s=s||l[3],g=b.hasOwnProperty(p)?b[p]:tc(h.$scope,p,!0)||(a?tc(e,p,!0):u),pb(g,p,!0));if(k)return k=(D(g)?g[g.length-1]:g).prototype,m=Object.create(k),s&&f(h,s,m,p||g.name),C(function(){d.invoke(g,m,h,p);return m},{instance:m,identifier:s});m=d.instantiate(g,h,p);s&&f(h,s,m,p||g.name);return m}}]}function De(){this.$get=["$window",function(b){return A(b.document)}]} -function Ee(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Yb(b,a){if(I(b)){b=b.replace(pf,"");var c=a("Content-Type");if(c&&0===c.indexOf(Sc)&&b.trim()||qf.test(b)&&rf.test(b))b=oc(b)}return b}function Tc(b){var a=ia(),c,d,e;if(!b)return a;r(b.split("\n"),function(b){e=b.indexOf(":");c=R(P(b.substr(0,e)));d=P(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function Uc(b){var a=K(b)?b:u;return function(c){a||(a=Tc(b));return c?(c=a[R(c)],void 0=== -c&&(c=null),c):a}}function Vc(b,a,c){if(F(c))return c(b,a);r(c,function(c){b=c(b,a)});return b}function He(){var b=this.defaults={transformResponse:[Yb],transformRequest:[function(a){return K(a)&&"[object File]"!==Ja.call(a)&&"[object Blob]"!==Ja.call(a)?Za(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:ua(Zb),put:ua(Zb),patch:ua(Zb)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},a=!1;this.useApplyAsync=function(b){return y(b)?(a=!!b,this):a};var c=this.interceptors= -[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(d,e,f,g,h,k){function l(a){function c(a){var b=C({},a);b.data=a.data?Vc(a.data,a.headers,d.transformResponse):a.data;a=a.status;return 200<=a&&300>a?b:h.reject(b)}var d={method:"get",transformRequest:b.transformRequest,transformResponse:b.transformResponse},e=function(a){var c=b.headers,d=C({},a.headers),e,f,c=C({},c.common,c[R(a.method)]);a:for(e in c){a=R(e);for(f in d)if(R(f)===a)continue a;d[e]=c[e]}(function(a){var b; -r(a,function(c,d){F(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(d);return d}(a);if(!ha.isObject(a))throw z("$http")("badreq",a);C(d,a);d.headers=e;d.method=rb(d.method);var f=[function(a){e=a.headers;var d=Vc(a.data,Uc(e),a.transformRequest);G(d)&&r(e,function(a,b){"content-type"===R(b)&&delete e[b]});G(a.withCredentials)&&!G(b.withCredentials)&&(a.withCredentials=b.withCredentials);return m(a,d,e).then(c,c)},u],g=h.when(d);for(r(t,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError); -(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),g=g.then(a,k)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,d)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,d)});return g};return g}function m(c,f,k){function m(b,c,d,e){function f(){w(c,b,d,e)}M&&(200<=b&&300>b?M.put(r,[b,c,Tc(d),e]):M.remove(r));a?g.$applyAsync(f):(f(),g.$$phase||g.$apply())}function w(a,b,d,e){b=Math.max(b,0);(200<= -b&&300>b?E.resolve:E.reject)({data:a,status:b,headers:Uc(d),config:c,statusText:e})}function t(){var a=l.pendingRequests.indexOf(c);-1!==a&&l.pendingRequests.splice(a,1)}var E=h.defer(),H=E.promise,M,B,r=p(c.url,c.params);l.pendingRequests.push(c);H.then(t,t);!c.cache&&!b.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(M=K(c.cache)?c.cache:K(b.cache)?b.cache:s);if(M)if(B=M.get(r),y(B)){if(B&&F(B.then))return B.then(t,t),B;D(B)?w(B[1],B[0],ua(B[2]),B[3]):w(B,200,{},"OK")}else M.put(r,H); -G(B)&&((B=Wc(c.url)?e.cookies()[c.xsrfCookieName||b.xsrfCookieName]:u)&&(k[c.xsrfHeaderName||b.xsrfHeaderName]=B),d(c.method,r,f,m,k,c.timeout,c.withCredentials,c.responseType));return H}function p(a,b){if(!b)return a;var c=[];Bd(b,function(a,b){null===a||G(a)||(D(a)||(a=[a]),r(a,function(a){K(a)&&(a=fa(a)?a.toISOString():Za(a));c.push(Da(b)+"="+Da(a))}))});0=k&&(q.resolve(s), -p(N.$$intervalId),delete f[N.$$intervalId]);t||b.$apply()},h);f[N.$$intervalId]=q;return N}var f={};e.cancel=function(b){return b&&b.$$intervalId in f?(f[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete f[b.$$intervalId],!0):!1};return e}]}function Od(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4", -posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y", -mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function ac(b){b=b.split("/");for(var a=b.length;a--;)b[a]=nb(b[a]);return b.join("/")}function Xc(b,a){var c=Aa(b);a.$$protocol=c.protocol;a.$$host=c.hostname;a.$$port=$(c.port)||uf[c.protocol]||null}function Yc(b,a){var c="/"!==b.charAt(0);c&&(b="/"+b);var d=Aa(b);a.$$path=decodeURIComponent(c&&"/"===d.pathname.charAt(0)?d.pathname.substring(1):d.pathname);a.$$search= -qc(d.search);a.$$hash=decodeURIComponent(d.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function xa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Fa(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function bc(b){return b.substr(0,Fa(b).lastIndexOf("/")+1)}function cc(b,a){this.$$html5=!0;a=a||"";var c=bc(b);Xc(b,this);this.$$parse=function(a){var b=xa(c,a);if(!I(b))throw eb("ipthprfx",a,c);Yc(b,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose= -function(){var a=Kb(this.$$search),b=this.$$hash?"#"+nb(this.$$hash):"";this.$$url=ac(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;(f=xa(b,d))!==u?(g=f,g=(f=xa(a,f))!==u?c+(xa("/",f)||f):b+g):(f=xa(c,d))!==u?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function dc(b,a){var c=bc(b);Xc(b,this);this.$$parse=function(d){var e=xa(b,d)||xa(c,d),e="#"==e.charAt(0)?xa(a,e):this.$$html5?e: -"";if(!I(e))throw eb("ihshprfx",d,a);Yc(e,this);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Kb(this.$$search),e=this.$$hash?"#"+nb(this.$$hash):"";this.$$url=ac(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Fa(b)==Fa(a)?(this.$$parse(a),!0):!1}}function Zc(b,a){this.$$html5=!0;dc.apply(this,arguments); -var c=bc(b);this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;b==Fa(d)?f=d:(g=xa(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=function(){var c=Kb(this.$$search),e=this.$$hash?"#"+nb(this.$$hash):"";this.$$url=ac(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function Bb(b){return function(){return this[b]}}function $c(b,a){return function(c){if(G(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Je(){var b= -"",a={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return Ua(b)?(a.enabled=b,this):K(b)?(Ua(b.enabled)&&(a.enabled=b.enabled),Ua(b.requireBase)&&(a.requireBase=b.requireBase),Ua(b.rewriteLinks)&&(a.rewriteLinks=b.rewriteLinks),this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a,b,c){var e=k.url(),f=k.$$state;try{d.url(a,b,c),k.$$state=d.state()}catch(g){throw k.url(e),k.$$state= -f,g;}}function h(a,b){c.$broadcast("$locationChangeSuccess",k.absUrl(),a,k.$$state,b)}var k,l;l=d.baseHref();var m=d.url(),p;if(a.enabled){if(!l&&a.requireBase)throw eb("nobase");p=m.substring(0,m.indexOf("/",m.indexOf("//")+2))+(l||"/");l=e.history?cc:Zc}else p=Fa(m),l=dc;k=new l(p,"#"+b);k.$$parseLinkUrl(m,m);k.$$state=d.state();var s=/^\s*(javascript|mailto):/i;f.on("click",function(b){if(a.rewriteLinks&&!b.ctrlKey&&!b.metaKey&&2!=b.which){for(var e=A(b.target);"a"!==ta(e[0]);)if(e[0]===f[0]|| -!(e=e.parent())[0])return;var g=e.prop("href"),h=e.attr("href")||e.attr("xlink:href");K(g)&&"[object SVGAnimatedString]"===g.toString()&&(g=Aa(g.animVal).href);s.test(g)||!g||e.attr("target")||b.isDefaultPrevented()||!k.$$parseLinkUrl(g,h)||(b.preventDefault(),k.absUrl()!=d.url()&&(c.$apply(),U.angular["ff-684208-preventDefault"]=!0))}});k.absUrl()!=m&&d.url(k.absUrl(),!0);var t=!0;d.onUrlChange(function(a,b){c.$evalAsync(function(){var d=k.absUrl(),e=k.$$state,f;k.$$parse(a);k.$$state=b;f=c.$broadcast("$locationChangeStart", -a,d,b,e).defaultPrevented;k.absUrl()===a&&(f?(k.$$parse(d),k.$$state=e,g(d,!1,e)):(t=!1,h(d,e)))});c.$$phase||c.$digest()});c.$watch(function(){var a=d.url(),b=d.state(),f=k.$$replace,l=a!==k.absUrl()||k.$$html5&&e.history&&b!==k.$$state;if(t||l)t=!1,c.$evalAsync(function(){var d=k.absUrl(),e=c.$broadcast("$locationChangeStart",d,a,k.$$state,b).defaultPrevented;k.absUrl()===d&&(e?(k.$$parse(a),k.$$state=b):(l&&g(d,f,b===k.$$state?null:k.$$state),h(a,b)))});k.$$replace=!1});return k}]}function Ke(){var b= -!0,a=this;this.debugEnabled=function(a){return y(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||x;a=!1;try{a=!!e.apply}catch(k){}return a?function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"), -info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function ra(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw la("isecfld",a);return b}function sa(b,a){if(b){if(b.constructor===b)throw la("isecfn",a);if(b.window===b)throw la("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw la("isecdom",a);if(b===Object)throw la("isecobj", -a);}return b}function ec(b){return b.constant}function Oa(b,a,c,d){sa(b,d);a=a.split(".");for(var e,f=0;1h?ad(g[0],g[1],g[2],g[3],g[4],c,d):function(a,b){var e=0,f;do f=ad(g[e++],g[e++],g[e++],g[e++],g[e++],c,d)(a,b),b=u,a=f;while(e=this.promise.$$state.status&&d&&d.length&&b(function(){for(var b,e,f=0,g=d.length;fa)for(b in l++,f)e.hasOwnProperty(b)||(n--,delete f[b])}else f!==e&&(f=e,l++);return l}}c.$stateful=!0;var d=this,e,f,h,k=1r&&(y=4-r,u[y]||(u[y]=[]),u[y].push({msg:F(e.exp)?"fn: "+(e.exp.name||e.exp.toString()):e.exp,newVal:g,oldVal:k})); -else if(e===c){v=!1;break a}}catch(A){f(A)}if(!(m=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(m=L.$$nextSibling);)L=L.$parent}while(L=m);if((v||N.length)&&!r--)throw q.$$phase=null,a("infdig",b,u);}while(v||N.length);for(q.$$phase=null;n.length;)try{n.shift()()}catch(da){f(da)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(this!==q){for(var b in this.$$listenerCount)m(this,this.$$listenerCount[b],b);a.$$childHead==this&& -(a.$$childHead=this.$$nextSibling);a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=x;this.$on=this.$watch=this.$watchGroup=function(){return x};this.$$listeners={};this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=this.$$watchers= -null}}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){q.$$phase||N.length||h.defer(function(){N.length&&q.$digest()});N.push({scope:this,expression:a})},$$postDigest:function(a){n.push(a)},$apply:function(a){try{return l("$apply"),this.$eval(a)}catch(b){f(b)}finally{q.$$phase=null;try{q.$digest()}catch(c){throw f(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&v.push(b);t()},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b); -var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=c.indexOf(b);-1!==d&&(c[d]=null,m(e,1,a))}},$emit:function(a,b){var c=[],d,e=this,g=!1,h={name:a,targetScope:e,stopPropagation:function(){g=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},k=Xa([h],arguments,1),l,m;do{d=e.$$listeners[a]||c;h.currentScope=e;l=0;for(m=d.length;lHa)throw Ba("iequirks");var d=ua(ma);d.isEnabled=function(){return b};d.trustAs=c.trustAs;d.getTrusted=c.getTrusted;d.valueOf= -c.valueOf;b||(d.trustAs=d.getTrusted=function(a,b){return b},d.valueOf=oa);d.parseAs=function(b,c){var e=a(c);return e.literal&&e.constant?e:a(c,function(a){return d.getTrusted(b,a)})};var e=d.parseAs,f=d.getTrusted,g=d.trustAs;r(ma,function(a,b){var c=R(b);d[bb("parse_as_"+c)]=function(b){return e(a,b)};d[bb("get_trusted_"+c)]=function(b){return f(a,b)};d[bb("trust_as_"+c)]=function(b){return g(a,b)}});return d}]}function Re(){this.$get=["$window","$document",function(b,a){var c={},d=$((/android (\d+)/.exec(R((b.navigator|| -{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g,h=/^(Moz|webkit|ms)(?=[A-Z])/,k=f.body&&f.body.style,l=!1,m=!1;if(k){for(var p in k)if(l=h.exec(p)){g=l[0];g=g.substr(0,1).toUpperCase()+g.substr(1);break}g||(g="WebkitOpacity"in k&&"webkit");l=!!("transition"in k||g+"Transition"in k);m=!!("animation"in k||g+"Animation"in k);!d||l&&m||(l=I(f.body.style.webkitTransition),m=I(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hasEvent:function(a){if("input"== -a&&9==Ha)return!1;if(G(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:$a(),vendorPrefix:g,transitions:l,animations:m,android:d}}]}function Te(){this.$get=["$templateCache","$http","$q",function(b,a,c){function d(e,f){d.totalPendingRequests++;var g=a.defaults&&a.defaults.transformResponse;if(D(g))for(var h=g,g=[],k=0;kb;b=Math.abs(b);var g=b+"",h="",k=[],l=!1;if(-1!==g.indexOf("e")){var m=g.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?(g="0",b=0):(h=g,l=!0)}if(l)0b&&(h=b.toFixed(e));else{g=(g.split(ld)[1]||"").length;G(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(ld);g=b[0];b=b[1]||"";var m=0,p=a.lgSize,s=a.gSize;if(g.length>=p+s)for(m=g.length-p,l=0;lb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Cb(e,a,d)}}function Db(b,a){return function(c, -d){var e=c["get"+b](),f=rb(a?"SHORT"+b:b);return d[f][e]}}function md(b){var a=(new Date(b,0,1)).getDay();return new Date(b,0,(4>=a?5:12)-a)}function nd(b){return function(a){var c=md(a.getFullYear());a=+new Date(a.getFullYear(),a.getMonth(),a.getDate()+(4-a.getDay()))-+c;a=1+Math.round(a/6048E5);return Cb(a,b)}}function hd(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,k=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=$(b[9]+b[10]),g=$(b[9]+b[11])); -h.call(a,$(b[1]),$(b[2])-1,$(b[3]));f=$(b[4]||0)-f;g=$(b[5]||0)-g;h=$(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));k.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e,f){var g="",h=[],k,l;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;I(c)&&(c=Ff.test(c)?$(c):a(c));X(c)&&(c=new Date(c));if(!fa(c))return c;for(;e;)(l=Gf.exec(e))?(h=Xa(h,l,1),e=h.pop()):(h.push(e),e=null);f&&"UTC"===f&&(c= -new Date(c.getTime()),c.setMinutes(c.getMinutes()+c.getTimezoneOffset()));r(h,function(a){k=Hf[a];g+=k?k(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Bf(){return function(b){return Za(b,!0)}}function Cf(){return function(b,a){X(b)&&(b=b.toString());if(!D(b)&&!I(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):$(a);if(I(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0b||37<=b&&40>=b||s(a)});if(e.hasEvent("paste"))a.on("paste cut",s)}a.on("change",m);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)? -"":d.$viewValue)}}function Gb(b,a){return function(c,d){var e,f;if(fa(c))return c;if(I(c)){'"'==c.charAt(0)&&'"'==c.charAt(c.length-1)&&(c=c.substring(1,c.length-1));if(If.test(c))return new Date(c);b.lastIndex=0;if(e=b.exec(c))return e.shift(),f=d?{yyyy:d.getFullYear(),MM:d.getMonth()+1,dd:d.getDate(),HH:d.getHours(),mm:d.getMinutes(),ss:d.getSeconds(),sss:d.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0,mm:0,ss:0,sss:0},r(e,function(b,c){c=r};g.$observe("min",function(a){r=s(a);h.$validate()})}if(y(g.max)||g.ngMax){var n;h.$validators.max=function(a){return!p(a)||G(n)||c(a)<=n};g.$observe("max",function(a){n=s(a);h.$validate()})}}}function qd(b,a,c,d){(d.$$hasNativeValidators=K(a[0].validity))&&d.$parsers.push(function(b){var c=a.prop("validity")|| -{};return c.badInput&&!c.typeMismatch?u:b})}function rd(b,a,c,d,e){if(y(d)){b=b(d);if(!b.constant)throw z("ngModel")("constexpr",c,d);return b(a)}return e}function pd(b){function a(a,b){b&&!f[a]?(l.addClass(e,a),f[a]=!0):!b&&f[a]&&(l.removeClass(e,a),f[a]=!1)}function c(b,c){b=b?"-"+Mb(b,"-"):"";a(ib+b,!0===c);a(sd+b,!1===c)}var d=b.ctrl,e=b.$element,f={},g=b.set,h=b.unset,k=b.parentForm,l=b.$animate;f[sd]=!(f[ib]=e.hasClass(ib));d.$setValidity=function(b,e,f){e===u?(d.$pending||(d.$pending={}),g(d.$pending, -b,f)):(d.$pending&&h(d.$pending,b,f),td(d.$pending)&&(d.$pending=u));Ua(e)?e?(h(d.$error,b,f),g(d.$$success,b,f)):(g(d.$error,b,f),h(d.$$success,b,f)):(h(d.$error,b,f),h(d.$$success,b,f));d.$pending?(a(ud,!0),d.$valid=d.$invalid=u,c("",null)):(a(ud,!1),d.$valid=td(d.$error),d.$invalid=!d.$valid,c("",d.$valid));e=d.$pending&&d.$pending[b]?u:d.$error[b]?!1:d.$$success[b]?!0:null;c(b,e);k.$setValidity(b,e,d)}}function td(b){if(b)for(var a in b)return!1;return!0}function ic(b,a){b="ngClass"+b;return["$animate", -function(c){function d(a,b){var c=[],d=0;a:for(;d(?:<\/\1>|)$/,Pb=/<|&#?\w+;/,af=/<([\w:]+)/,bf=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, -ja={option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ja.optgroup=ja.option;ja.tbody=ja.tfoot=ja.colgroup=ja.caption=ja.thead;ja.th=ja.td;var Ka=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===V.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),S(U).on("load",a))}, -toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?A(this[b]):A(this[this.length+b])},length:0,push:Kf,sort:[].sort,splice:[].splice},yb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){yb[R(b)]=b});var Kc={};r("input select option textarea button form details".split(" "),function(b){Kc[b]=!0});var Lc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"}; -r({data:Sb,removeData:ub},function(b,a){S[a]=b});r({data:Sb,inheritedData:xb,scope:function(b){return A.data(b,"$scope")||xb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return A.data(b,"$isolateScope")||A.data(b,"$isolateScopeNoTemplate")},controller:Gc,injector:function(b){return xb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Tb,css:function(b,a,c){a=bb(a);if(y(c))b.style[a]=c;else return b.style[a]},attr:function(b,a,c){var d=R(a);if(yb[d])if(y(c))c? -(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||x).specified?d:u;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?u:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(a,b){if(G(b)){var d=a.nodeType;return d===na||d===mb?a.textContent:""}a.textContent=b}b.$dv="";return b}(),val:function(b,a){if(G(a)){if(b.multiple&&"select"===ta(b)){var c=[];r(b.options,function(a){a.selected&& -c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(G(a))return b.innerHTML;tb(b,!0);b.innerHTML=a},empty:Hc},function(b,a){S.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==Hc&&(2==b.length&&b!==Tb&&b!==Gc?a:d)===u){if(K(a)){for(e=0;e":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"!":function(a,c,d){return!d(a,c)},"=":!0,"|":!0}),Sf={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},gc=function(a){this.options=a};gc.prototype={constructor:gc,lex:function(a){this.text=a;this.index=0;for(this.tokens= -[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"=== -a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.indexa){a=this.tokens[a];var g=a.text;if(g===c||g===d||g===e||g===f||!(c||d||e||f))return a}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){if(0===this.tokens.length)throw la("ueoe",this.text);var c=this.expect(a);c||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return c},unaryFn:function(a,c){var d=jb[a];return C(function(a,f){return d(a, -f,c)},{constant:c.constant,inputs:[c]})},binaryFn:function(a,c,d,e){var f=jb[c];return C(function(c,e){return f(c,e,a,d)},{constant:a.constant&&d.constant,inputs:!e&&[a,d]})},identifier:function(){for(var a=this.consume().text;this.peek(".")&&this.peekAhead(1).identifier&&!this.peekAhead(2,"(");)a+=this.consume().text+this.consume().text;return Ib[a]||bd(a,this.options,this.text)},constant:function(){var a=this.consume().value;return C(function(){return a},{constant:!0,literal:!0})},statements:function(){for(var a= -[];;)if(0","<=",">="))a=this.binaryFn(a,c.text,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.text,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.text,this.unary());return a},unary:function(){var a;return this.expect("+")? -this.primary():(a=this.expect("-"))?this.binaryFn(fb.ZERO,a.text,this.unary()):(a=this.expect("!"))?this.unaryFn(a.text,this.unary()):this.primary()},fieldAccess:function(a){var c=this.text,d=this.consume().text,e=bd(d,this.options,c);return C(function(c,d,h){return e(h||a(c,d))},{assign:function(e,g,h){(h=a(e,h))||a.assign(e,h={});return Oa(h,d,g,c)}})},objectIndex:function(a){var c=this.text,d=this.expression();this.consume("]");return C(function(e,f){var g=a(e,f),h=d(e,f);ra(h,c);return g?sa(g[h], -c):u},{assign:function(e,f,g){var h=ra(d(e,g),c);(g=sa(a(e,g),c))||a.assign(e,g={});return g[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this.text,f=d.length?[]:null;return function(g,h){var k=c?c(g,h):g,l=a(g,h,k)||x;if(f)for(var m=d.length;m--;)f[m]=sa(d[m](g,h),e);sa(k,e);if(l){if(l.constructor===l)throw la("isecfn",e);if(l===Pf||l===Qf||l===Rf)throw la("isecff",e);}k=l.apply?l.apply(k, -f):l(f[0],f[1],f[2],f[3],f[4]);return sa(k,e)}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break;a.push(this.expression())}while(this.expect(","))}this.consume("]");return C(function(c,d){for(var e=[],f=0,g=a.length;fa.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<= -a?"+":"")+(Cb(Math[0=h};d.$observe("min",function(a){y(a)&&!X(a)&&(a=parseFloat(a,10));h=X(a)&&!isNaN(a)?a:u;e.$validate()})}if(d.max||d.ngMax){var k;e.$validators.max=function(a){return e.$isEmpty(a)||G(k)||a<=k};d.$observe("max",function(a){y(a)&&!X(a)&&(a=parseFloat(a,10));k=X(a)&&!isNaN(a)?a:u;e.$validate()})}},url:function(a,c,d,e,f,g){gb(a,c,d,e,f,g);hc(e);e.$$parserName="url";e.$validators.url=function(a, -c){var d=a||c;return e.$isEmpty(d)||Tf.test(d)}},email:function(a,c,d,e,f,g){gb(a,c,d,e,f,g);hc(e);e.$$parserName="email";e.$validators.email=function(a,c){var d=a||c;return e.$isEmpty(d)||Uf.test(d)}},radio:function(a,c,d,e){G(d.name)&&c.attr("name",++kb);c.on("click",function(a){c[0].checked&&e.$setViewValue(d.value,a&&a.type)});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e,f,g,h,k){var l=rd(k,a,"ngTrueValue",d.ngTrueValue,!0), -m=rd(k,a,"ngFalseValue",d.ngFalseValue,!1);c.on("click",function(a){e.$setViewValue(c[0].checked,a&&a.type)});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return!1===a};e.$formatters.push(function(a){return pa(a,l)});e.$parsers.push(function(a){return a?l:m})},hidden:x,button:x,submit:x,reset:x,file:x},vc=["$browser","$sniffer","$filter","$parse",function(a,c,d,e){return{restrict:"E",require:["?ngModel"],link:{pre:function(f,g,h,k){k[0]&&(Ad[R(h.type)]||Ad.text)(f,g,h,k[0], -c,a,d,e)}}}}],ib="ng-valid",sd="ng-invalid",Qa="ng-pristine",Fb="ng-dirty",ud="ng-pending",Xf=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,c,d,e,f,g,h,k,l,m){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=u;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid= -!1;this.$error={};this.$$success={};this.$pending=u;this.$name=m(d.name||"",!1)(a);var p=f(d.ngModel),s=p.assign,t=p,q=s,N=null,n=this;this.$$setOptions=function(a){if((n.$options=a)&&a.getterSetter){var c=f(d.ngModel+"()"),g=f(d.ngModel+"($$$p)");t=function(a){var d=p(a);F(d)&&(d=c(a));return d};q=function(a,c){F(p(a))?g(a,{$$$p:n.$modelValue}):s(a,n.$modelValue)}}else if(!p.assign)throw Hb("nonassign",d.ngModel,va(e));};this.$render=x;this.$isEmpty=function(a){return G(a)||""===a||null===a||a!== -a};var v=e.inheritedData("$formController")||Eb,w=0;pd({ctrl:this,$element:e,set:function(a,c){a[c]=!0},unset:function(a,c){delete a[c]},parentForm:v,$animate:g});this.$setPristine=function(){n.$dirty=!1;n.$pristine=!0;g.removeClass(e,Fb);g.addClass(e,Qa)};this.$setDirty=function(){n.$dirty=!0;n.$pristine=!1;g.removeClass(e,Qa);g.addClass(e,Fb);v.$setDirty()};this.$setUntouched=function(){n.$touched=!1;n.$untouched=!0;g.setClass(e,"ng-untouched","ng-touched")};this.$setTouched=function(){n.$touched= -!0;n.$untouched=!1;g.setClass(e,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){h.cancel(N);n.$viewValue=n.$$lastCommittedViewValue;n.$render()};this.$validate=function(){if(!X(n.$modelValue)||!isNaN(n.$modelValue)){var a=n.$$rawModelValue,c=n.$valid,d=n.$modelValue,e=n.$options&&n.$options.allowInvalid;n.$$runValidators(n.$error[n.$$parserName||"parse"]?!1:u,a,n.$$lastCommittedViewValue,function(f){e||c===f||(n.$modelValue=f?a:u,n.$modelValue!==d&&n.$$writeModelToScope())})}};this.$$runValidators= -function(a,c,d,e){function f(){var a=!0;r(n.$validators,function(e,f){var g=e(c,d);a=a&&g;h(f,g)});return a?!0:(r(n.$asyncValidators,function(a,c){h(c,null)}),!1)}function g(){var a=[],e=!0;r(n.$asyncValidators,function(f,g){var k=f(c,d);if(!k||!F(k.then))throw Hb("$asyncValidators",k);h(g,u);a.push(k.then(function(){h(g,!0)},function(a){e=!1;h(g,!1)}))});a.length?l.all(a).then(function(){k(e)},x):k(!0)}function h(a,c){m===w&&n.$setValidity(a,c)}function k(a){m===w&&e(a)}w++;var m=w;(function(a){var c= -n.$$parserName||"parse";if(a===u)h(c,null);else if(h(c,a),!a)return r(n.$validators,function(a,c){h(c,null)}),r(n.$asyncValidators,function(a,c){h(c,null)}),!1;return!0})(a)?f()?g():k(!1):k(!1)};this.$commitViewValue=function(){var a=n.$viewValue;h.cancel(N);if(n.$$lastCommittedViewValue!==a||""===a&&n.$$hasNativeValidators)n.$$lastCommittedViewValue=a,n.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var c=n.$$lastCommittedViewValue,d=c,e=G(d)?u:!0;if(e)for(var f= -0;ff||e.$isEmpty(a)||c.length<=f}}}}},yc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=0;d.$observe("minlength",function(a){f=$(a)||0;e.$validate()});e.$validators.minlength=function(a,c){return e.$isEmpty(c)||c.length>=f}}}}},te=function(){return{restrict:"A",priority:100,require:"ngModel", -link:function(a,c,d,e){var f=c.attr(d.$attr.ngList)||", ",g="false"!==d.ngTrim,h=g?P(f):f;e.$parsers.push(function(a){if(!G(a)){var c=[];a&&r(a.split(h),function(a){a&&c.push(g?P(a):a)});return c}});e.$formatters.push(function(a){return D(a)?a.join(f):u});e.$isEmpty=function(a){return!a||!a.length}}}},Yf=/^(true|false|\d+)$/,ve=function(){return{restrict:"A",priority:100,compile:function(a,c){return Yf.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue, -function(a){f.$set("value",a)})}}}},we=function(){return{restrict:"A",controller:["$scope","$attrs",function(a,c){var d=this;this.$options=a.$eval(c.ngModelOptions);this.$options.updateOn!==u?(this.$options.updateOnDefault=!1,this.$options.updateOn=P(this.$options.updateOn.replace(Wf,function(){d.$options.updateOnDefault=!0;return" "}))):this.$options.updateOnDefault=!0}]}},Wd=["$compile",function(a){return{restrict:"AC",compile:function(c){a.$$addBindingClass(c);return function(c,e,f){a.$$addBindingInfo(e, -f.ngBind);e=e[0];c.$watch(f.ngBind,function(a){e.textContent=a===u?"":a})}}}}],Yd=["$interpolate","$compile",function(a,c){return{compile:function(d){c.$$addBindingClass(d);return function(d,f,g){d=a(f.attr(g.$attr.ngBindTemplate));c.$$addBindingInfo(f,d.expressions);f=f[0];g.$observe("ngBindTemplate",function(a){f.textContent=a===u?"":a})}}}}],Xd=["$sce","$parse","$compile",function(a,c,d){return{restrict:"A",compile:function(e,f){var g=c(f.ngBindHtml),h=c(f.ngBindHtml,function(a){return(a||"").toString()}); -d.$$addBindingClass(e);return function(c,e,f){d.$$addBindingInfo(e,f.ngBindHtml);c.$watch(h,function(){e.html(a.getTrustedHtml(g(c))||"")})}}}}],Zd=ic("",!0),ae=ic("Odd",0),$d=ic("Even",1),be=Ia({compile:function(a,c){c.$set("ngCloak",u);a.removeClass("ng-cloak")}}),ce=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ac={},Zf={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), -function(a){var c=wa("ng-"+a);Ac[c]=["$parse","$rootScope",function(d,e){return{restrict:"A",compile:function(f,g){var h=d(g[c],null,!0);return function(c,d){d.on(a,function(d){var f=function(){h(c,{$event:d})};Zf[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var fe=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,k,l;c.$watch(e.ngIf,function(c){c?k||g(function(c,f){k=f;c[c.length++]=V.createComment(" end ngIf: "+ -e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)}):(l&&(l.remove(),l=null),k&&(k.$destroy(),k=null),h&&(l=qb(h.clone),a.leave(l).then(function(){l=null}),h=null))})}}}],ge=["$templateRequest","$anchorScroll","$animate","$sce",function(a,c,d,e){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:ha.noop,compile:function(f,g){var h=g.ngInclude||g.src,k=g.onload||"",l=g.autoscroll;return function(f,g,s,r,q){var u=0,n,v,w,O=function(){v&&(v.remove(),v=null);n&&(n.$destroy(), -n=null);w&&(d.leave(w).then(function(){v=null}),v=w,w=null)};f.$watch(e.parseAsResourceUrl(h),function(e){var h=function(){!y(l)||l&&!f.$eval(l)||c()},s=++u;e?(a(e,!0).then(function(a){if(s===u){var c=f.$new();r.template=a;a=q(c,function(a){O();d.enter(a,null,g).then(h)});n=c;w=a;n.$emit("$includeContentLoaded",e);f.$eval(k)}},function(){s===u&&(O(),f.$emit("$includeContentError",e))}),f.$emit("$includeContentRequested",e)):(O(),r.template=null)})}}}}],xe=["$compile",function(a){return{restrict:"ECA", -priority:-400,require:"ngInclude",link:function(c,d,e,f){/SVG/.test(d[0].toString())?(d.empty(),a(Dc(f.template,V).childNodes)(c,function(a){d.append(a)},{futureParentElement:d})):(d.html(f.template),a(d.contents())(c))}}}],he=Ia({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),ie=Ia({terminal:!0,priority:1E3}),je=["$locale","$interpolate",function(a,c){var d=/{}/g,e=/^when(Minus)?(.+)$/;return{restrict:"EA",link:function(f,g,h){function k(a){g.text(a||"")}var l= -h.count,m=h.$attr.when&&g.attr(h.$attr.when),p=h.offset||0,s=f.$eval(m)||{},t={},m=c.startSymbol(),q=c.endSymbol(),u=m+l+"-"+p+q,n=ha.noop,v;r(h,function(a,c){var d=e.exec(c);d&&(d=(d[1]?"-":"")+R(d[2]),s[d]=g.attr(h.$attr[c]))});r(s,function(a,e){t[e]=c(a.replace(d,u))});f.$watch(l,function(c){c=parseFloat(c);var d=isNaN(c);d||c in s||(c=a.pluralCat(c-p));c===v||d&&isNaN(v)||(n(),n=f.$watch(t[c],k),v=c)})}}}],ke=["$parse","$animate",function(a,c){var d=z("ngRepeat"),e=function(a,c,d,e,l,m,p){a[d]= -e;l&&(a[l]=m);a.$index=c;a.$first=0===c;a.$last=c===p-1;a.$middle=!(a.$first||a.$last);a.$odd=!(a.$even=0===(c&1))};return{restrict:"A",multiElement:!0,transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,compile:function(f,g){var h=g.ngRepeat,k=V.createComment(" end ngRepeat: "+h+" "),l=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);if(!l)throw d("iexp",h);var m=l[1],p=l[2],s=l[3],t=l[4],l=m.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); -if(!l)throw d("iidexp",m);var q=l[3]||l[1],y=l[2];if(s&&(!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(s)||/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent)$/.test(s)))throw d("badident",s);var n,v,w,z,E={$id:Ma};t?n=a(t):(w=function(a,c){return Ma(c)},z=function(a){return a});return function(a,f,g,l,m){n&&(v=function(c,d,e){y&&(E[y]=c);E[q]=d;E.$index=e;return n(a,E)});var t=ia();a.$watchCollection(p,function(g){var l,n,p=f[0],B,E=ia(),C,x,G,T,D,F,I;s&&(a[s]=g);if(Ra(g))D=g,n=v|| -w;else{n=v||z;D=[];for(I in g)g.hasOwnProperty(I)&&"$"!=I.charAt(0)&&D.push(I);D.sort()}C=D.length;I=Array(C);for(l=0;lD;)d=q.pop(),m(Q,d.label,!1),d.element.remove();r(Q,function(a,c){0a&&s.removeOption(c)})}for(;R.length>x;)R.pop()[0].element.remove()}var p;if(!(p=q.match(d)))throw $f("iexp",q,va(f));var E=c(p[2]|| -p[1]),x=p[4]||p[6],A=/ as /.test(p[0])&&p[1],C=A?c(A):null,G=p[5],I=c(p[3]||""),H=c(p[2]?p[1]:x),M=c(p[7]),K=p[8]?c(p[8]):null,S={},R=[[{element:f,label:""}]],U={};z&&(a(z)(e),z.removeClass("ng-scope"),z.remove());f.empty();f.on("change",function(){e.$apply(function(){var a=M(e)||[],c;if(t)c=[],r(f.val(),function(d){d=K?S[d]:d;c.push("?"===d?u:""===d?null:h(C?C:H,d,a[d]))});else{var d=K?S[f.val()]:f.val();c="?"===d?u:""===d?null:h(C?C:H,d,a[d])}g.$setViewValue(c);n()})});g.$render=n;e.$watchCollection(M, -l);e.$watchCollection(function(){var a=M(e),c;if(a&&D(a)){c=Array(a.length);for(var d=0,f=a.length;d@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}'); -//# sourceMappingURL=angular.min.js.map diff --git a/sources/js/linuxDash.js b/sources/js/linuxDash.js deleted file mode 100644 index 3316cf4..0000000 --- a/sources/js/linuxDash.js +++ /dev/null @@ -1,783 +0,0 @@ -(function() { - - angular.module('linuxDash', ['ngRoute']); - - /** - * Routes for different tabs on UI - */ - angular.module('linuxDash').config(['$routeProvider', - function($routeProvider) { - - $routeProvider. - when('/loading', { - templateUrl: 'templates/app/loading.html', - controller: function appLoadController ($scope, $location, $rootScope) { - - var loadUrl = localStorage.getItem('currentTab') || 'system-status'; - - var loadLinuxDash = function () { - $location.path(loadUrl); - }; - - $rootScope.$on('start-linux-dash', loadLinuxDash); - - }, - }). - when('/system-status', { - templateUrl: 'templates/sections/system-status.html', - }). - when('/basic-info', { - templateUrl: 'templates/sections/basic-info.html', - }). - when('/network', { - templateUrl: 'templates/sections/network.html', - }). - when('/accounts', { - templateUrl: 'templates/sections/accounts.html', - }). - when('/apps', { - templateUrl: 'templates/sections/applications.html', - }). - otherwise({ - redirectTo: '/loading' - }); - - } - ]); - - - /** - * Service which gets data from server - * via HTTP or Websocket (if supported) - */ - angular.module('linuxDash').service('server', ['$http', '$rootScope', '$location', function($http, $rootScope, $location) { - - var websocket = { - connection: null, - onMessageEventHandlers: {} - }; - - /** - * @description: - * Establish a websocket connection with server - * - * @return Null - */ - var establishWebsocketConnection = function() { - - var websocketUrl = 'ws://' + window.location.hostname + ':' + window.location.port; - - if (websocket.connection === null) { - - websocket.connection = new WebSocket(websocketUrl, 'linux-dash'); - - websocket.connection.onopen = function() { - $rootScope.$broadcast("start-linux-dash", {}); - $rootScope.$apply(); - console.info('Websocket connection is open'); - }; - - websocket.connection.onmessage = function(event) { - - var response = JSON.parse(event.data); - var moduleName = response.moduleName; - var moduleData = JSON.parse(response.output); - - if (!!websocket.onMessageEventHandlers[moduleName]) { - websocket.onMessageEventHandlers[moduleName](moduleData); - } else { - console.info("Websocket could not find module", moduleName, "in:", websocket.onMessageEventHandlers); - } - - }; - - websocket.connection.onclose = function() { - websocket.connection = null; - } - } - - }; - - /** - * @description: - * Check if websockets are supported - * If so, call establishWebsocketConnection() - * - * @return Null - */ - this.checkIfWebsocketsAreSupported = function() { - - var websocketSupport = { - browser: null, - server: null, - }; - - // does browser support websockets? - if (window.WebSocket) { - - websocketSupport.browser = true; - - // does backend support websockets? - $http.get("/websocket").then(function(response) { - - // if websocket_support property exists and is trurthy - // websocketSupport.server will equal true. - websocketSupport.server = !!response.data["websocket_support"]; - - }).catch(function websocketNotSupportedByServer() { - - websocketSupport.server = false; - $rootScope.$broadcast("start-linux-dash", {}); - - }).then(function finalDecisionOnWebsocket() { - - if (websocketSupport.browser && websocketSupport.server) { - - establishWebsocketConnection(); - - } else { - // rootScope event not propogating from here. - // instead, we manually route to url - $location.path('/system-status'); - } - - }); - - } - - }; - - /** - * Handles requests from modules for data from server - * - * @param {String} moduleName - * @param {Function} callback - * @return {[ Null || callback(server response) ]} - */ - this.get = function(moduleName, callback) { - - // if we have a websocket connection - if (websocket.connection) { - - // and the connection is ready - if (websocket.connection.readyState === 1) { - - // set the callback as the event handler - // for server response. - // - // Callback instance needs to be overwritten - // each time for this to work. Not sure why. - websocket.onMessageEventHandlers[moduleName] = callback; - - // - websocket.connection.send(moduleName); - - } else { - console.log("Websocket not ready yet.", moduleName); - } - - } - // otherwise - else { - - var moduleAddress = 'server/?module=' + moduleName; - - return $http.get(moduleAddress).then(function(response) { - return callback(response.data); - }); - - } - - }; - - }]); - - /** - * Hook to run websocket support check. - */ - angular.module('linuxDash').run(function(server, $location, $rootScope) { - - server.checkIfWebsocketsAreSupported(); - - var currentRoute = $location.path(); - var currentTab = (currentRoute === '/loading')? 'system-status': currentRoute; - localStorage.setItem('currentTab', currentTab); - - $location.path('/loading'); - - }); - - /** - * Sidebar for SPA - */ - angular.module('linuxDash').directive('navBar', function($location) { - return { - restrict: 'E', - templateUrl: 'templates/app/navbar.html', - link: function(scope) { - scope.items = [ - 'system-status', - 'basic-info', - 'network', - 'accounts', - 'apps' - ]; - - scope.getNavItemName = function(url) { - return url.replace('-', ' '); - }; - - scope.isActive = function(route) { - return '/' + route === $location.path(); - }; - } - }; - - }); - - ////////////////////////////////////////////////////////////// - ////////////////// UI Element Directives ////////////////// // - ////////////////////////////////////////////////////////////// - - /** - * Shows loader - */ - angular.module('linuxDash').directive('loader', function() { - return { - restrict: 'E', - scope: { - width: '@' - }, - template: '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' - }; - }); - - /** - * Top Bar for widget - */ - angular.module('linuxDash').directive('topBar', function() { - return { - restrict: 'E', - scope: { - heading: '=', - refresh: '&', - lastUpdated: '=', - info: '=', - }, - templateUrl: 'templates/app/ui-elements/top-bar.html', - link: function(scope, element, attrs) { - var $refreshBtn = element.find('refresh-btn').eq(0); - - if (typeof attrs.noRefreshBtn !== 'undefined') { - $refreshBtn.remove(); - } - } - }; - }); - - /** - * Shows refresh button and calls - * provided expression on-click - */ - angular.module('linuxDash').directive('refreshBtn', function() { - return { - restrict: 'E', - scope: { - refresh: '&' - }, - template: '' - }; - }); - - /** - * Message shown when no data is found from server - */ - angular.module('linuxDash').directive('noData', function() { - return { - restrict: 'E', - template: 'No Data' - }; - }); - - /** - * Displays last updated timestamp for widget - */ - angular.module('linuxDash').directive('lastUpdate', function() { - return { - restrict: 'E', - scope: { - timestamp: '=' - }, - templateUrl: 'templates/app/ui-elements/last-update.html' - }; - }); - - - ////////////////// Plugin Directives ////////////////// - - /** - * Fetches and displays table data - */ - angular.module('linuxDash').directive('tableData', ['server', '$rootScope', function(server, $rootScope) { - return { - restrict: 'E', - scope: { - heading: '@', - info: '@', - moduleName: '@' - }, - templateUrl: 'templates/app/table-data-plugin.html', - link: function(scope, element) { - - scope.sortByColumn = null; - scope.sortReverse = null; - - // set the column to sort by - scope.setSortColumn = function(column) { - - // if the column is already being sorted - // reverse the order - if (column === scope.sortByColumn) { - scope.sortReverse = !scope.sortReverse; - } else { - scope.sortByColumn = column; - } - - scope.sortTableRows(); - }; - - scope.sortTableRows = function() { - scope.tableRows.sort(function(currentRow, nextRow) { - - var sortResult = 0; - - if (currentRow[scope.sortByColumn] < nextRow[scope.sortByColumn]) { - sortResult = -1; - } else if (currentRow[scope.sortByColumn] === nextRow[scope.sortByColumn]) { - sortResult = 0; - } else { - sortResult = 1; - } - - if (scope.sortReverse) { - sortResult = -1 * sortResult; - } - - return sortResult; - }); - }; - - scope.getData = function() { - delete scope.tableRows; - - server.get(scope.moduleName, function(serverResponseData) { - - if (serverResponseData.length > 0) { - scope.tableHeaders = Object.keys(serverResponseData[0]); - } - - scope.tableRows = serverResponseData; - - if (scope.sortByColumn) { - scope.sortTableRows(); - } - - scope.lastGet = new Date().getTime(); - - if (serverResponseData.length < 1) { - scope.emptyResult = true; - } - - if (!scope.$$phase && !$rootScope.$$phase) scope.$digest(); - }); - }; - - scope.getData(); - } - }; - }]); - - /** - * Fetches and displays table data - */ - angular.module('linuxDash').directive('keyValueList', ['server', '$rootScope', function(server, $rootScope) { - return { - restrict: 'E', - scope: { - heading: '@', - info: '@', - moduleName: '@', - }, - templateUrl: 'templates/app/key-value-list-plugin.html', - link: function(scope, element) { - - scope.getData = function() { - delete scope.tableRows; - - server.get(scope.moduleName, function(serverResponseData) { - scope.tableRows = serverResponseData; - scope.lastGet = new Date().getTime(); - - if (Object.keys(serverResponseData).length === 0) { - scope.emptyResult = true; - } - - if (!scope.$$phase && !$rootScope.$$phase) scope.$digest(); - }); - }; - - scope.getData(); - } - }; - }]); - - /** - * Fetches and displays data as line chart at a certain refresh rate - */ - angular.module('linuxDash').directive('lineChartPlugin', ['$interval', '$compile', 'server', function($interval, $compile, server) { - return { - restrict: 'E', - scope: { - heading: '@', - moduleName: '@', - refreshRate: '=', - maxValue: '=', - minValue: '=', - getDisplayValue: '=', - metrics: '=', - color: '@' - }, - templateUrl: 'templates/app/line-chart-plugin.html', - link: function(scope, element) { - - if (!scope.color) scope.color = '0, 255, 0'; - - var series; - - // smoothieJS - Create new chart - var chart = new SmoothieChart({ - borderVisible: false, - sharpLines: true, - grid: { - fillStyle: '#ffffff', - strokeStyle: 'rgba(232,230,230,0.93)', - sharpLines: true, - millisPerLine: 3000, - borderVisible: false - }, - labels: { - fontSize: 11, - precision: 0, - fillStyle: '#0f0e0e' - }, - maxValue: parseInt(scope.maxValue), - minValue: parseInt(scope.minValue), - horizontalLines: [{ - value: 5, - color: '#eff', - lineWidth: 1 - }] - }); - - // smoothieJS - set up canvas element for chart - canvas = element.find('canvas')[0]; - series = new TimeSeries(); - - chart.addTimeSeries(series, { - strokeStyle: 'rgba(' + scope.color + ', 1)', - fillStyle: 'rgba(' + scope.color + ', 0.2)', - lineWidth: 2 - }); - - chart.streamTo(canvas, 1000); - - var dataCallInProgress = false; - - // update data on chart - scope.getData = function() { - - if (dataCallInProgress) return; - - dataCallInProgress = true; - - server.get(scope.moduleName, function(serverResponseData) { - - dataCallInProgress = false; - scope.lastGet = new Date().getTime(); - - // change graph colour depending on usage - if (scope.maxValue / 4 * 3 < scope.getDisplayValue(serverResponseData)) { - chart.seriesSet[0].options.strokeStyle = 'rgba(255, 89, 0, 1)'; - chart.seriesSet[0].options.fillStyle = 'rgba(255, 89, 0, 0.2)'; - } else if (scope.maxValue / 3 < scope.getDisplayValue(serverResponseData)) { - chart.seriesSet[0].options.strokeStyle = 'rgba(255, 238, 0, 1)'; - chart.seriesSet[0].options.fillStyle = 'rgba(255, 238, 0, 0.2)'; - } else { - chart.seriesSet[0].options.strokeStyle = 'rgba(' + scope.color + ', 1)'; - chart.seriesSet[0].options.fillStyle = 'rgba(' + scope.color + ', 0.2)'; - } - - // update chart with this response - series.append(scope.lastGet, scope.getDisplayValue(serverResponseData)); - - // update the metrics for this chart - scope.metrics.forEach(function(metricObj) { - metricObj.data = metricObj.generate(serverResponseData); - }); - - }); - }; - - // set the directive-provided interval - // at which to run the chart update - var intervalRef = $interval(scope.getData, scope.refreshRate); - var removeInterval = function() { - $interval.cancel(intervalRef); - }; - - element.on("$destroy", removeInterval); - } - }; - }]); - - /** - * Fetches and displays data as line chart at a certain refresh rate - * - */ - angular.module('linuxDash').directive('multiLineChartPlugin', ['$interval', '$compile', 'server', function($interval, $compile, server) { - return { - restrict: 'E', - scope: { - heading: '@', - moduleName: '@', - refreshRate: '=', - getDisplayValue: '=', - units: '=', - delay: '=' - }, - templateUrl: 'templates/app/multi-line-chart-plugin.html', - link: function(scope, element) { - - // smoothieJS - Create new chart - var chart = new SmoothieChart({ - borderVisible: false, - sharpLines: true, - grid: { - fillStyle: '#ffffff', - strokeStyle: 'rgba(232,230,230,0.93)', - sharpLines: true, - borderVisible: false - }, - labels: { - fontSize: 12, - precision: 0, - fillStyle: '#0f0e0e' - }, - maxValue: 100, - minValue: 0, - horizontalLines: [{ - value: 1, - color: '#ecc', - lineWidth: 1 - }] - }); - - var seriesOptions = [{ - strokeStyle: 'rgba(255, 0, 0, 1)', - lineWidth: 2 - }, { - strokeStyle: 'rgba(0, 255, 0, 1)', - lineWidth: 2 - }, { - strokeStyle: 'rgba(0, 0, 255, 1)', - lineWidth: 2 - }, { - strokeStyle: 'rgba(255, 255, 0, 1)', - lineWidth: 1 - }]; - - // smoothieJS - set up canvas element for chart - var canvas = element.find('canvas')[0]; - scope.seriesArray = []; - scope.metricsArray = []; - - // get the data once to set up # of lines on chart - server.get(scope.moduleName, function(serverResponseData) { - - var numberOfLines = Object.keys(serverResponseData).length; - - for (var x = 0; x < numberOfLines; x++) { - - var keyForThisLine = Object.keys(serverResponseData)[x]; - - scope.seriesArray[x] = new TimeSeries(); - chart.addTimeSeries(scope.seriesArray[x], seriesOptions[x]); - scope.metricsArray[x] = { - name: keyForThisLine, - color: seriesOptions[x].strokeStyle, - }; - } - - }); - - var delay = 1000; - - if (angular.isDefined(scope.delay)) - delay = scope.delay; - - chart.streamTo(canvas, delay); - - var dataCallInProgress = false; - - // update data on chart - scope.getData = function() { - - if (dataCallInProgress) return; - - if (!scope.seriesArray.length) return; - - dataCallInProgress = true; - - server.get(scope.moduleName, function(serverResponseData) { - - dataCallInProgress = false; - scope.lastGet = new Date().getTime(); - var keyCount = 0; - var maxAvg = 100; - - // update chart with current response - for (var key in serverResponseData) { - scope.seriesArray[keyCount].append(scope.lastGet, serverResponseData[key]); - keyCount++; - maxAvg = Math.max(maxAvg, serverResponseData[key]); - } - - // update the metrics for this chart - scope.metricsArray.forEach(function(metricObj) { - metricObj.data = serverResponseData[metricObj.name].toString() + ' ' + scope.units; - }); - - // round up the average and set the maximum scale - var len = parseInt(Math.log(maxAvg) / Math.log(10)); - var div = Math.pow(10, len); - chart.options.maxValue = Math.ceil(maxAvg / div) * div; - - }); - - }; - - var refreshRate = (angular.isDefined(scope.refreshRate)) ? scope.refreshRate : 1000; - var intervalRef = $interval(scope.getData, refreshRate); - var removeInterval = function() { - $interval.cancel(intervalRef); - }; - - element.on("$destroy", removeInterval); - } - }; - }]); - - /** - * Base plugin structure - */ - angular.module('linuxDash').directive('plugin', function() { - return { - restrict: 'E', - transclude: true, - templateUrl: 'templates/app/base-plugin.html' - } - }); - - /** - * Progress bar element - */ - angular.module('linuxDash').directive('progressBarPlugin', function() { - return { - restrict: 'E', - scope: { - width: '@', - moduleName: '@', - name: '@', - value: '@', - max: '@' - }, - templateUrl: 'templates/app/progress-bar-plugin.html' - }; - }); - - - /** - * Theme switcher - */ - angular.module('linuxDash').directive('themeSwitcher', ['$location', function($location) { - return { - restrict: 'E', - templateUrl: 'templates/app/theme-switcher.html', - link: function(scope) { - - // alternate themes available - scope.themes = [{ - name: 'winter', - }, { - name: 'summer', - }, { - name: 'spring', - }, { - name: 'fall', - }, { - name: 'old', - }, ]; - - scope.themeSwitcherOpen = false; - - scope.switchTheme = function(theme) { - - if (theme.selected) { - scope.setDefaultTheme(); - return; - } - - scope.removeExistingThemes(); - theme.selected = true; - document.getElementsByTagName('html')[0].className = theme.name; - localStorage.setItem('theme', theme.name); - }; - - scope.toggleThemeSwitcher = function() { - scope.themeSwitcherOpen = !scope.themeSwitcherOpen; - }; - - scope.removeExistingThemes = function() { - scope.themes.forEach(function(item) { - item.selected = false; - }); - }; - - scope.setDefaultTheme = function() { - scope.removeExistingThemes(); - document.getElementsByTagName('html')[0].className = ''; - localStorage.setItem('theme', null); - }; - - // on load, check if theme was set in localStorage - if (localStorage.getItem('theme')) { - - scope.themes.forEach(function(theme) { - - if (theme.name === localStorage.getItem('theme')) { - scope.switchTheme(theme); - } - - }); - } - } - }; - }]); - -}()); diff --git a/sources/js/modules.js b/sources/js/modules.js deleted file mode 100644 index a899d01..0000000 --- a/sources/js/modules.js +++ /dev/null @@ -1,284 +0,0 @@ -(function() { - - "use strict"; - - /////////////////////////////////////////////////////////// - ////////////////// Module Directives /////////////////// // - /////////////////////////////////////////////////////////// - - angular.module('linuxDash').directive('diskSpace', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/disk-space.html', - link: function(scope) { - - scope.heading = "Disk Partitions"; - - scope.getData = function() { - server.get('disk_partitions', function(serverResponseData) { - scope.diskSpaceData = serverResponseData; - }); - - scope.lastGet = new Date().getTime(); - }; - - scope.getData(); - - scope.getKB = function(stringSize) { - var lastChar = stringSize.slice(-1), - size = parseInt(stringSize); - - switch (lastChar) { - case 'M': - return size * Math.pow(1024, 1); - case 'G': - return size * Math.pow(1024, 2); - case 'T': - return size * Math.pow(1024, 3); - case 'P': - return size * Math.pow(1024, 4); - case 'E': - return size * Math.pow(1024, 5); - case 'Z': - return size * Math.pow(1024, 6); - case 'Y': - return size * Math.pow(1024, 7); - default: - return size; - } - }; - } - }; - }]); - - angular.module('linuxDash').directive('ramChart', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/ram-chart.html', - link: function(scope) { - - // get max ram available on machine before we - // can start charting - server.get('current_ram', function(resp) { - scope.maxRam = resp.total; - scope.minRam = 0; - }); - - scope.ramToDisplay = function(serverResponseData) { - return serverResponseData.used; - }; - - var humanizeRam = function (ramInMB) { - var ram = { - value: parseInt(ramInMB, 10), - unit: 'MB', - }; - - // if ram > 1,000 MB, use GB - if (ram.value > 1000) { - ram = { - value: (ramInMB/1024).toFixed(2), - unit: 'GB', - }; - } - - return ram.value + ' ' + ram.unit; - }; - - scope.ramMetrics = [{ - name: 'Used', - generate: function(serverResponseData) { - var ratio = serverResponseData.used / serverResponseData.total; - var percentage = parseInt(ratio * 100); - - var usedRam = humanizeRam(serverResponseData.used); - return usedRam + ' (' + percentage.toString() + '%)'; - } - }, - { - name: 'Free', - generate: function(serverResponseData) { - - var freeRam = humanizeRam(serverResponseData.free); - var totalRam = humanizeRam(serverResponseData.total); - return freeRam + ' of ' + totalRam; - } - }]; - } - }; - }]); - - angular.module('linuxDash').directive('cpuAvgLoadChart', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/cpu-load.html', - link: function(scope) { - scope.units = '%'; - } - }; - }]); - - angular.module('linuxDash').directive('cpuUtilizationChart', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/cpu-utilization-chart.html', - link: function(scope) { - scope.min = 0; - scope.max = 100; - - scope.displayValue = function(serverResponseData) { - return serverResponseData; - }; - - scope.utilMetrics = [{ - name: 'Usage', - generate: function(serverResponseData) { - return serverResponseData + ' %'; - } - }]; - - } - }; - }]); - - angular.module('linuxDash').directive('uploadTransferRateChart', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/upload-transfer-rate.html', - link: function(scope) { - scope.delay = 2000; - scope.units = 'KB/s'; - } - }; - }]); - - angular.module('linuxDash').directive('downloadTransferRateChart', ['server', function(server) { - return { - restrict: 'E', - scope: {}, - templateUrl: 'templates/modules/download-transfer-rate.html', - link: function(scope) { - scope.delay = 2000; - scope.units = 'KB/s'; - } - }; - }]); - - ////////////////////////////////////////////////////////// - /////////////// Table Data Modules //////////////////// // - ////////////////////////////////////////////////////////// - var simpleTableModules = [ - { - name: 'machineInfo', - template: '' - }, - { - name: 'ipAddresses', - template: '' - }, - { - name: 'ramIntensiveProcesses', - template: '' - }, - { - name: 'cpuIntensiveProcesses', - template: '' - }, - { - name: 'networkConnections', - template: '' - }, - { - name: 'serverAccounts', - template: '' - }, - { - name: 'loggedInAccounts', - template: '' - }, - { - name: 'recentLogins', - template: '' - }, - { - name: 'arpCacheTable', - template: '' - }, - { - name: 'commonApplications', - template: '' - }, - { - name: 'pingSpeeds', - template: '' - }, - { - name: 'bandwidth', - template: '' - }, - { - name: 'swapUsage', - template: '' - }, - { - name: 'internetSpeed', - template: '' - }, - { - name: 'memcached', - template: '' - }, - { - name: 'redis', - template: '' - }, - { - name: 'memoryInfo', - template: '' - }, - { - name: 'cpuInfo', - template: '' - }, - { - name: 'ioStats', - template: '' - }, - { - name: 'scheduledCrons', - template: '' - }, - { - name: 'cronHistory', - template: '' - } - ]; - - simpleTableModules.forEach(function(module, key) { - - angular.module('linuxDash').directive(module.name, ['server', function(server) { - - var moduleDirective = { - restrict: 'E', - scope: {} - }; - - if (module.templateUrl) { - moduleDirective['templateUrl'] = 'templates/modules/' + module.templateUrl - } - - if (module.template) { - moduleDirective['template'] = module.template; - } - - return moduleDirective; - }]); - - }); - -}()); diff --git a/sources/js/smoothie.min.js b/sources/js/smoothie.min.js deleted file mode 100644 index 0c7823a..0000000 --- a/sources/js/smoothie.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e){function n(e){this.options=t.extend({},n.defaultOptions,e);this.clear()}function r(e){this.options=t.extend({},r.defaultChartOptions,e);this.seriesSet=[];this.currentValueRange=1;this.currentVisMinValue=0;this.lastRenderTimeMillis=0}var t={extend:function(){arguments[0]=arguments[0]||{};for(var e=1;ethis.maxValue){this.maxValue=t}if(t=0&&this.data[r][0]>e){r--}if(r===-1){this.data.splice(0,0,[e,t])}else if(this.data.length>0&&this.data[r][0]===e){if(n){this.data[r][1]+=t;t=this.data[r][1]}else{this.data[r][1]=t}}else if(r=t&&this.data[n+1][0]0){e.resetBoundsTimerId=setInterval(function(){e.resetBounds()},e.options.resetBoundsInterval)}};r.prototype.removeTimeSeries=function(e){var t=this.seriesSet.length;for(var n=0;n.1||Math.abs(a)>.1;this.currentValueRange+=e.scaleSmoothing*u;this.currentVisMinValue+=e.scaleSmoothing*a}this.valueRange={min:n,max:t}};r.prototype.render=function(e,t){var n=(new Date).getTime();if(!this.isAnimatingScale){var r=Math.min(1e3/6,this.options.millisPerPixel);if(n-this.lastRenderTimeMillis0){i.beginPath();for(var l=t-t%s.grid.millisPerLine;l>=u;l-=s.grid.millisPerLine){var c=f(l);if(s.grid.sharpLines){c-=.5}i.moveTo(c,0);i.lineTo(c,o.height)}i.stroke();i.closePath()}for(var h=1;h1){if(w.fillStyle){i.lineTo(o.width+w.lineWidth+1,x);i.lineTo(o.width+w.lineWidth+1,o.height+w.lineWidth+1);i.lineTo(E,o.height+w.lineWidth);i.fillStyle=w.fillStyle;i.fill()}if(w.strokeStyle&&w.strokeStyle!=="none"){i.stroke()}i.closePath()}i.restore()}if(!s.labels.disabled&&!isNaN(this.valueRange.min)&&!isNaN(this.valueRange.max)){var k=s.yMaxFormatter(this.valueRange.max,s.labels.precision),L=s.yMinFormatter(this.valueRange.min,s.labels.precision);i.fillStyle=s.labels.fillStyle;i.fillText(k,o.width-i.measureText(k).width-2,s.labels.fontSize);i.fillText(L,o.width-i.measureText(L).width-2,o.height-2)}if(s.timestampFormatter&&s.grid.millisPerLine>0){var A=o.width-i.measureText(L).width+4;for(var l=t-t%s.grid.millisPerLine;l>=u;l-=s.grid.millisPerLine){var c=f(l);if(c to stop' - server.serve_forever() diff --git a/sources/server/index.go b/sources/server/index.go deleted file mode 100644 index 4ec8787..0000000 --- a/sources/server/index.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "net/http" - "os" - "os/exec" - "path/filepath" -) - -var ( - listenAddress = flag.String("listen", "0.0.0.0:80", "Where the server listens for connections. [interface]:port") - staticPath = flag.String("static", "../", "Location of static files.") - scriptPath = flag.String("scripts", "./modules/shell_files", "Location of shell scripts used to gather stats.") -) - -func init() { - flag.Parse() -} - -func main() { - http.Handle("/", http.FileServer(http.Dir(*staticPath))) - http.HandleFunc("/server/", func(w http.ResponseWriter, r *http.Request) { - module := r.URL.Query().Get("module") - script := filepath.Join(*scriptPath, module+".sh") - if module == "" { - http.Error(w, "No module specified, or requested module doesn't exist.", 406) - return - } - - // Execute the command - cmd := exec.Command(script) - var output bytes.Buffer - cmd.Stdout = &output - err := cmd.Run() - if err != nil { - fmt.Printf("Error executing '%s': %s\n\tScript output: %s\n", script, err.Error(), output.String()) - http.Error(w, "Unable to execute module.", http.StatusInternalServerError) - return - } - - w.Write(output.Bytes()) - }) - - fmt.Println("Starting http server at:", *listenAddress) - err := http.ListenAndServe(*listenAddress, nil) - if err != nil { - fmt.Println("Error starting http server:", err) - os.Exit(1) - } -} diff --git a/sources/server/index.js b/sources/server/index.js deleted file mode 100644 index a05d4a0..0000000 --- a/sources/server/index.js +++ /dev/null @@ -1,107 +0,0 @@ -var express = require('express'); -var app = require('express')(); -var server = require('http').Server(app); -var path = require('path'); -var spawn = require('child_process').spawn; -var fs = require('fs'); -var ws = require('websocket').server; - -server.listen(80); -console.log('Linux Dash Server Started!'); - -app.use(express.static(path.resolve(__dirname + '/../'))); - -app.get('/', function (req, res) { - res.sendFile(path.resolve(__dirname + '/../index.html')); -}); - -app.get('/websocket', function (req, res) { - - res.send({ - websocket_support: true, - }); - -}); - -wsServer = new ws({ - httpServer: server -}); - -function getShellFilePath(moduleName) { - return __dirname + '/modules/shell_files/' + moduleName + '.sh'; -} - -function shellPathAndModuleNameAreValid(shellFilePath, moduleName) { - - var moduleInvalidName = moduleName.indexOf('.') > -1; - var moduleNameEmpty = !moduleName; - var moduleNotFound = !fs.existsSync(shellFilePath); - var isValid = true; - - if (moduleInvalidName || moduleNameEmpty || moduleNotFound) { - isValid = false; - } - - return isValid; -} - -wsServer.on('request', function(request) { - - var wsClient = request.accept('linux-dash', request.origin); - - wsClient.on('message', function(wsReq) { - - var moduleName = wsReq.utf8Data; - var shellFile = getShellFilePath(moduleName); - - if (!shellPathAndModuleNameAreValid(shellFile, moduleName)) { - return; - } - - var command = spawn(shellFile, [ wsReq.color || '' ]); - var output = []; - - command.stdout.on('data', function(chunk) { - output.push(chunk); - }); - - command.on('close', function(code) { - - if (code === 0) { - - var wsResponse = { - moduleName: moduleName, - output: output.toString(), - }; - - wsClient.sendUTF(JSON.stringify(wsResponse)); - } - - }); - - }); - -}); - -app.get('/server/', function (req, res) { - - var shellFile = getShellFilePath(req.query.module); - - if (!shellPathAndModuleNameAreValid(shellFile, req.query.module)) { - res.sendStatus(406); - return; - } - - var command = spawn(shellFile, [ req.query.color || '' ]); - var output = []; - - command.stdout.on('data', function(chunk) { - output.push(chunk); - }); - - command.on('close', function(code) { - if (code === 0) res.send(output.toString()); - else res.sendStatus(500); - }); - -}); diff --git a/sources/server/index.php b/sources/server/index.php deleted file mode 100644 index 296a551..0000000 --- a/sources/server/index.php +++ /dev/null @@ -1,8 +0,0 @@ -1 \ - {print "{ \"address\": \"" $1 "\", " \ - "\"hw_type\": \"" $2 "\", " \ - "\"hw_address\": \"" $3 "\", " \ - "\"flags\": \"" $4 "\", " \ - "\"mask\": \"" $5 "\" }, " \ - } \ - END {print "]"}' \ - | /bin/sed 'N;$s/},/}/;P;D') - -if [ -z "$result" ]; then echo {} -else echo $result -fi \ No newline at end of file diff --git a/sources/server/modules/shell_files/bandwidth.sh b/sources/server/modules/shell_files/bandwidth.sh deleted file mode 100755 index 51a2cd7..0000000 --- a/sources/server/modules/shell_files/bandwidth.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -/bin/cat /proc/net/dev \ -| awk 'BEGIN {print "["} NR>2 {print "{ \"interface\": \"" $1 "\"," \ - " \"tx\": " $2 "," \ - " \"rx\": " $10 " }," } END {print "]"}' \ -| /bin/sed 'N;$s/,\n/\n/;P;D' diff --git a/sources/server/modules/shell_files/common_applications.sh b/sources/server/modules/shell_files/common_applications.sh deleted file mode 100755 index d9e81bd..0000000 --- a/sources/server/modules/shell_files/common_applications.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -result=$(whereis php node mysql mongo vim python ruby java apache2 nginx openssl vsftpd make \ -| awk -F: '{if(length($2)==0) { installed="false"; } else { installed="true"; } \ - print \ - "{ \ - \"binary\": \""$1"\", \ - \"location\": \""$2"\", \ - \"installed\": "installed" \ - },"}') - -echo "[" ${result%?} "]" \ No newline at end of file diff --git a/sources/server/modules/shell_files/cpu_info.sh b/sources/server/modules/shell_files/cpu_info.sh deleted file mode 100755 index c00b603..0000000 --- a/sources/server/modules/shell_files/cpu_info.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -result=$(/usr/bin/lscpu \ - | /usr/bin/awk -F: '{print "\""$1"\": \""$2"\"," } '\ - ) - -echo "{" ${result%?} "}" \ No newline at end of file diff --git a/sources/server/modules/shell_files/cpu_intensive_processes.sh b/sources/server/modules/shell_files/cpu_intensive_processes.sh deleted file mode 100755 index a193bb2..0000000 --- a/sources/server/modules/shell_files/cpu_intensive_processes.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -result=$(/bin/ps axo pid,user,pcpu,rss,vsz,comm --sort -pcpu,-rss,-vsz \ - | head -n 15 \ - | /usr/bin/awk 'BEGIN{OFS=":"} NR>1 {print "{ \"pid\": " $1 \ - ", \"user\": \"" $2 "\"" \ - ", \"cpu%\": " $3 \ - ", \"rss\": " $4 \ - ", \"vsz\": " $5 \ - ", \"cmd\": \"" $6 "\"" "},"\ - }') - -echo "[" ${result%?} "]" \ No newline at end of file diff --git a/sources/server/modules/shell_files/cpu_utilization.sh b/sources/server/modules/shell_files/cpu_utilization.sh deleted file mode 100755 index 7d6c361..0000000 --- a/sources/server/modules/shell_files/cpu_utilization.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# by Paul Colby (http://colby.id.au), no rights reserved ;) - -PREV_TOTAL=0 -PREV_IDLE=0 -iteration=0 - -while [[ iteration -lt 2 ]]; do - # Get the total CPU statistics, discarding the 'cpu ' prefix. - CPU=(`sed -n 's/^cpu\s//p' /proc/stat`) - IDLE=${CPU[3]} # Just the idle CPU time. - - # Calculate the total CPU time. - TOTAL=0 - for VALUE in "${CPU[@]}"; do - let "TOTAL=$TOTAL+$VALUE" - done - - # Calculate the CPU usage since we last checked. - let "DIFF_IDLE=$IDLE-$PREV_IDLE" - let "DIFF_TOTAL=$TOTAL-$PREV_TOTAL" - let "DIFF_USAGE=(1000*($DIFF_TOTAL-$DIFF_IDLE)/$DIFF_TOTAL+5)/10" - #echo -en "\rCPU: $DIFF_USAGE% \b\b" - - # Remember the total and idle CPU times for the next check. - PREV_TOTAL="$TOTAL" - PREV_IDLE="$IDLE" - - # Wait before checking again. - sleep 1 - iteration="$iteration+1" -done -echo -en "$DIFF_USAGE" diff --git a/sources/server/modules/shell_files/cron_history.sh b/sources/server/modules/shell_files/cron_history.sh deleted file mode 100755 index df5f15d..0000000 --- a/sources/server/modules/shell_files/cron_history.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -grepCmd=$(which grep) -cronLog='/var/log/syslog' -numberOfLines='50' - -# Month, Day, Time, Hostname, tag, user, - -result=$($grepCmd -m$numberOfLines CRON $cronLog \ - | awk '{ s = ""; for (i = 6; i <= NF; i++) s = s $i " "; \ - print "{\"time\" : \"" $1" "$2" "$3 "\"," \ - "\"user\" : \"" $6 "\"," \ - "\"message\" : \"" $5" "s "\"" \ - "}," - }' - ) - -echo [${result%?}] \ No newline at end of file diff --git a/sources/server/modules/shell_files/current_ram.sh b/sources/server/modules/shell_files/current_ram.sh deleted file mode 100755 index 1a10920..0000000 --- a/sources/server/modules/shell_files/current_ram.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -awkCmd=`which awk` -catCmd=`which cat` -grepCmd=`which grep` -memInfoFile="/proc/meminfo" - -# References: -# Calculations: http://zcentric.com/2012/05/29/mapping-procmeminfo-to-output-of-free-command/ -# Fields: https://www.kernel.org/doc/Documentation/filesystems/proc.txt - -memInfo=`$catCmd $memInfoFile | $grepCmd 'MemTotal\|MemFree\|Buffers\|Cached'` - -echo $memInfo | $awkCmd '{print "{ \"total\": " ($2/1024) ", \"used\": " ( ($2-($5+$8+$11))/1024 ) ", \"free\": " (($5+$8+$11)/1024) " }" }' diff --git a/sources/server/modules/shell_files/disk_partitions.sh b/sources/server/modules/shell_files/disk_partitions.sh deleted file mode 100755 index d563d19..0000000 --- a/sources/server/modules/shell_files/disk_partitions.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -result=$(/bin/df -Ph | awk 'NR>1 {print "{\"file_system\": \"" $1 "\", \"size\": \"" $2 "\", \"used\": \"" $3 "\", \"avail\": \"" $4 "\", \"used%\": \"" $5 "\", \"mounted\": \"" $6 "\"},"}') - -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/download_transfer_rate.sh b/sources/server/modules/shell_files/download_transfer_rate.sh deleted file mode 100755 index 68b401a..0000000 --- a/sources/server/modules/shell_files/download_transfer_rate.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -files=(/sys/class/net/*) -pos=$(( ${#files[*]} - 1 )) -last=${files[$pos]} - -json_output="{" - -for interface in "${files[@]}" -do - basename=$(basename "$interface") - - # find the number of bytes transfered for this interface - in1=$(cat /sys/class/net/"$basename"/statistics/rx_bytes) - - # wait a second - sleep 1 - - # check same interface again - in2=$(cat /sys/class/net/"$basename"/statistics/rx_bytes) - - # get the difference (transfer rate) - in_bytes=$((in2 - in1)) - - # convert transfer rate to KB - in_kbytes=$((in_bytes / 1024)) - - # convert transfer rate to KB - json_output="$json_output \"$basename\": $in_kbytes" - - # if it is not the last line - if [[ ! $interface == $last ]] - then - # add a comma to the line (JSON formatting) - json_output="$json_output," - fi -done - -# close the JSON object & print to screen -echo "$json_output}" diff --git a/sources/server/modules/shell_files/general_info.sh b/sources/server/modules/shell_files/general_info.sh deleted file mode 100755 index a76b20c..0000000 --- a/sources/server/modules/shell_files/general_info.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -function displaytime { - local T=$1 - local D=$((T/60/60/24)) - local H=$((T/60/60%24)) - local M=$((T/60%60)) - local S=$((T%60)) - [[ $D > 0 ]] && printf '%d days ' $D - [[ $H > 0 ]] && printf '%d hours ' $H - [[ $M > 0 ]] && printf '%d minutes ' $M - [[ $D > 0 || $H > 0 || $M > 0 ]] && printf 'and ' - printf '%d seconds\n' $S -} - -lsbRelease=$(/usr/bin/lsb_release -ds | sed -e 's/^"//' -e 's/"$//') -uname=$(/bin/uname -r | sed -e 's/^"//' -e 's/"$//') -os=`echo $lsbRelease $uname` -hostname=$(/bin/hostname) -uptime_seconds=$(/bin/cat /proc/uptime | awk '{print $1}') -server_time=$(date) - -echo { \ - \"OS\": \"$os\", \ - \"Hostname\": \"$hostname\", \ - \"Uptime\": \" $(displaytime ${uptime_seconds%.*}) \", \ - \"Server Time\": \"$server_time\" \ - } diff --git a/sources/server/modules/shell_files/internet_speed.sh b/sources/server/modules/shell_files/internet_speed.sh deleted file mode 100755 index fa2478a..0000000 --- a/sources/server/modules/shell_files/internet_speed.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -SCRIPTPATH=`dirname $(readlink -f $0)` -SPEED_TEST_SCRIPT=$SCRIPTPATH"/../python_files/speedtest_cli.py" - -$SPEED_TEST_SCRIPT \ -| grep 'Upload\|Download' \ -| awk 'BEGIN {print "{"} {print "\"" $1 "\": \"" $2 " " $3 "\"," } END {print "}"}' \ -| /bin/sed 'N;$s/",/"/;P;D' \ No newline at end of file diff --git a/sources/server/modules/shell_files/io_stats.sh b/sources/server/modules/shell_files/io_stats.sh deleted file mode 100755 index 0e14d4e..0000000 --- a/sources/server/modules/shell_files/io_stats.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -result=$(/bin/cat /proc/diskstats | /usr/bin/awk \ - '{ if($4==0 && $8==0 && $12==0 && $13==0) next } \ - {print "{ \"device\": \"" $3 "\", \"reads\": \""$4"\", \"writes\": \"" $8 "\", \"in_progress\": \"" $12 "\", \"time_in_io\": \"" $13 "\"},"}' - ) - -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/ip_addresses.sh b/sources/server/modules/shell_files/ip_addresses.sh deleted file mode 100755 index 1c4e558..0000000 --- a/sources/server/modules/shell_files/ip_addresses.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -awkCmd=`which awk` -grepCmd=`which grep` -sedCmd=`which sed` -ifconfigCmd=`which ifconfig` -trCmd=`which tr` -digCmd=`which dig` - -externalIp=`$digCmd +short myip.opendns.com @resolver1.opendns.com` - -$ifconfigCmd \ -| $grepCmd -B1 "inet addr" \ -| $awkCmd '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' \ -| $awkCmd -v exIp="$externalIp" -F: 'BEGIN {print "["} { print "{ \"interface\": \"" $1 "\", \"ip\": \"" $3 "\" },"} END {print "{ \"interface\": \"external\", \"ip\": \""exIp"\" } ]"}' \ -| $trCmd -d '\r\n' diff --git a/sources/server/modules/shell_files/load_avg.sh b/sources/server/modules/shell_files/load_avg.sh deleted file mode 100755 index f2afcb0..0000000 --- a/sources/server/modules/shell_files/load_avg.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -numberOfCores=$(/bin/grep -c 'model name' /proc/cpuinfo) - -if [ $numberOfCores -eq 0 ]; then - numberOfCores=1 -fi - -result=$(/bin/cat /proc/loadavg | /usr/bin/awk '{print "{ \"1_min_avg\": " ($1*100)/'$numberOfCores' ", \"5_min_avg\": " ($2*100)/'$numberOfCores' ", \"15_min_avg\": " ($3*100)/'$numberOfCores' "}," }') - -echo ${result%?} \ No newline at end of file diff --git a/sources/server/modules/shell_files/logged_in_users.sh b/sources/server/modules/shell_files/logged_in_users.sh deleted file mode 100755 index 635163a..0000000 --- a/sources/server/modules/shell_files/logged_in_users.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -result=$(COLUMNS=300 /usr/bin/w -h | /usr/bin/awk '{print "{\"user\": \"" $1 "\", \"from\": \"" $3 "\", \"when\": \"" $4 "\"},"}') - -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/memcached.sh b/sources/server/modules/shell_files/memcached.sh deleted file mode 100755 index 88f8516..0000000 --- a/sources/server/modules/shell_files/memcached.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -echo "stats" \ - | /bin/nc -w 1 127.0.0.1 11211 \ - | /bin/grep 'bytes' \ - | /usr/bin/awk 'BEGIN {print "{"} {print "\"" $2 "\": " $3 } END {print "}"}' \ - | /usr/bin/tr '\r' ',' \ - | /bin/sed 'N;$s/,\n/\n/;P;D' \ No newline at end of file diff --git a/sources/server/modules/shell_files/memory_info.sh b/sources/server/modules/shell_files/memory_info.sh deleted file mode 100755 index 9b2ce6c..0000000 --- a/sources/server/modules/shell_files/memory_info.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -/bin/cat /proc/meminfo \ - | /usr/bin/awk -F: 'BEGIN {print "{"} {print "\"" $1 "\": \"" $2 "\"," } END {print "}"}' \ - | /bin/sed 'N;$s/,\n/\n/;P;D' diff --git a/sources/server/modules/shell_files/network_connections.sh b/sources/server/modules/shell_files/network_connections.sh deleted file mode 100755 index 9f952f8..0000000 --- a/sources/server/modules/shell_files/network_connections.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -netstatCmd=`which netstat` -awkCmd=`which awk` -sortCmd=`which sort` -uniqCmd=`which uniq` -sedCmd=`which sed` - -$netstatCmd -ntu \ -| $awkCmd 'NR>2 {print $5}' \ -| $sortCmd \ -| $uniqCmd -c \ -| $awkCmd 'BEGIN {print "["} {print "{ \"connections\": " $1 ", \"address\": \"" $2 "\" }," } END {print "]"}' \ -| $sedCmd 'N;$s/},/}/;P;D' diff --git a/sources/server/modules/shell_files/number_of_cpu_cores.sh b/sources/server/modules/shell_files/number_of_cpu_cores.sh deleted file mode 100755 index 42c20e5..0000000 --- a/sources/server/modules/shell_files/number_of_cpu_cores.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -numberOfCores=$(/bin/grep -c 'model name' /proc/cpuinfo) - -if [length($numberOfCores)]; then - echo "cannnot be found"; -fi \ No newline at end of file diff --git a/sources/server/modules/shell_files/ping.sh b/sources/server/modules/shell_files/ping.sh deleted file mode 100755 index 9852b14..0000000 --- a/sources/server/modules/shell_files/ping.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# http://askubuntu.com/questions/413367/ping-multiple-ips-using-bash - -# get absolute path to config file -SCRIPTPATH=`dirname $(readlink -f $0)` -CONFIG_PATH=$SCRIPTPATH"/../config/ping_hosts" - -catCmd=`which cat` -pingCmd=`which ping` -awkCmd=`which awk` -sedCmd=`which sed` -numOfLinesInConfig=`$sedCmd -n '$=' $CONFIG_PATH` -result='[' - -{ $catCmd $CONFIG_PATH; echo; } \ -| while read output - do - singlePing=$($pingCmd -qc 2 $output \ - | $awkCmd -F/ 'BEGIN { endLine="}," } /^rtt/ { if ('$numOfLinesInConfig'==1){endLine="}"} print "{" "\"host\": \"'$output'\", \"ping\": " $5 " " endLine }' \ - ) - numOfLinesInConfig=$(($numOfLinesInConfig-1)) - result=$result$singlePing - if [ $numOfLinesInConfig -eq 1 ] - then - echo $result"]" - fi - done \ -| $sedCmd 's/\},]/}]/g' diff --git a/sources/server/modules/shell_files/ram_intensive_processes.sh b/sources/server/modules/shell_files/ram_intensive_processes.sh deleted file mode 100755 index a86e120..0000000 --- a/sources/server/modules/shell_files/ram_intensive_processes.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -result=$(/bin/ps axo pid,user,pmem,rss,vsz,comm --sort -pmem,-rss,-vsz \ - | head -n 15 \ - | /usr/bin/awk 'NR>1 {print "{ \"pid\": " $1 \ - ", \"user\": \"" $2 \ - "\", \"mem%\": " $3 \ - ", \"rss\": " $4 \ - ", \"vsz\": " $5 \ - ", \"cmd\": \"" $6 \ - "\"},"}') - -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/recent_account_logins.sh b/sources/server/modules/shell_files/recent_account_logins.sh deleted file mode 100755 index de0b080..0000000 --- a/sources/server/modules/shell_files/recent_account_logins.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -result=$(/usr/bin/lastlog -t 365 \ - | /usr/bin/awk 'NR>1 {\ - print "{ \ - \"user\": \"" $1 "\", \ - \"ip\": \"" $3 "\","" \ - \"date\": \"" $5" "$6" "$7" "$8" "$9 "\"}," - }' - ) -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/redis.sh b/sources/server/modules/shell_files/redis.sh deleted file mode 100755 index 38bcaf4..0000000 --- a/sources/server/modules/shell_files/redis.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -########### Enter Your Redis Password HERE ######### -redisPassword='' -########### Enter Your Redis Password HERE ######### - -redisCommand=$(which redis-cli); - -if [ -n "$redisPassword" ]; then - redisCommand="$redisCommand -a $redisPassword" -fi - -result=$($redisCommand INFO \ - | grep 'redis_version\|connected_clients\|connected_slaves\|used_memory_human\|total_connections_received\|total_commands_processed' \ - | awk -F: '{print "\"" $1 "\":" "\"" $2 }' \ - | tr '\r' '"' | tr '\n' ',' - ) -echo { ${result%?} } \ No newline at end of file diff --git a/sources/server/modules/shell_files/scheduled_crons.sh b/sources/server/modules/shell_files/scheduled_crons.sh deleted file mode 100755 index d21fdd4..0000000 --- a/sources/server/modules/shell_files/scheduled_crons.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash -###### -# Credit: http://stackoverflow.com/questions/134906/how-do-i-list-all-cron-jobs-for-all-users#answer-137173 -###### - -catCmd=`which cat` -awkCmd=`which awk` -sedCmd=`which sed` -egrepCmd=`which egrep` -echoCmd=`which echo` -crontabCmd=`which crontab` - -# System-wide crontab file and cron job directory. Change these for your system. -CRONTAB='/etc/crontab' -CRONDIR='/etc/cron.d' - -# Single tab character. Annoyingly necessary. -tab=$(echo -en "\t") - -# Given a stream of crontab lines, exclude non-cron job lines, replace -# whitespace characters with a single space, and remove any spaces from the -# beginning of each line. -function clean_cron_lines() { - while read line ; do - $echoCmd "${line}" | - $egrepCmd --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' | - $sedCmd --regexp-extended "s/\s+/ /g" | - $sedCmd --regexp-extended "s/^ //" - done; -} - -# Given a stream of cleaned crontab lines, $echoCmd any that don't include the -# run-parts command, and for those that do, show each job file in the run-parts -# directory as if it were scheduled explicitly. -function lookup_run_parts() { - while read line ; do - match=$($echoCmd "${line}" | $egrepCmd -o 'run-parts (-{1,2}\S+ )*\S+') - - if [[ -z "${match}" ]] ; then - $echoCmd "${line}" - else - cron_fields=$($echoCmd "${line}" | cut -f1-6 -d' ') - cron_job_dir=$($echoCmd "${match}" | awk '{print $NF}') - - if [[ -d "${cron_job_dir}" ]] ; then - for cron_job_file in "${cron_job_dir}"/* ; do # */ - [[ -f "${cron_job_file}" ]] && $echoCmd "${cron_fields} ${cron_job_file}" - done - fi - fi - done; -} - -# Temporary file for crontab lines. -temp=$(mktemp) || exit 1 - -# Add all of the jobs from the system-wide crontab file. -$catCmd "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}" - -# Add all of the jobs from the system-wide cron directory. -$catCmd "${CRONDIR}"/* | clean_cron_lines >>"${temp}" # */ - -# Add each user's crontab (if it exists). Insert the user's name between the -# five time fields and the command. -while read user ; do - $crontabCmd -l -u "${user}" 2>/dev/null | - clean_cron_lines | - $sedCmd --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}" -done < <(cut --fields=1 --delimiter=: /etc/passwd) - -# Output the collected crontab lines. - -## Changes: Parses output into JSON - -$catCmd "${temp}" \ - | awk 'BEGIN {print "["} \ - {print "{ \"min(s)\": \"" $1 \ - "\", \"hours(s)\": \"" $2 "\", " \ - " \"day(s)\": \"" $3 "\", " \ - " \"month\": \"" $4 "\", " \ - " \"weekday\": \"" $5 "\", " \ - " \"user\": \"" $6 "\", " \ - " \"command\": \"" $7$8$9$10 "\" " \ - "}," } \ - END {print "]"}' \ - | $sedCmd 'N;$s/,\n/\n/;P;D' - -rm --force "${temp}" \ No newline at end of file diff --git a/sources/server/modules/shell_files/swap.sh b/sources/server/modules/shell_files/swap.sh deleted file mode 100755 index 4b3bcbf..0000000 --- a/sources/server/modules/shell_files/swap.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -result=$(/bin/cat /proc/swaps \ - | /usr/bin/awk 'NR>1 {print "{ \"filename\": \"" $1"\", \"type\": \""$2"\", \"size\": \""$3"\", \"used\": \""$4"\", \"priority\": \""$5"\"}," }' - ) -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/server/modules/shell_files/upload_transfer_rate.sh b/sources/server/modules/shell_files/upload_transfer_rate.sh deleted file mode 100755 index 711521f..0000000 --- a/sources/server/modules/shell_files/upload_transfer_rate.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -files=(/sys/class/net/*) -pos=$(( ${#files[*]} - 1 )) -last=${files[$pos]} - -json_output="{" - -for interface in "${files[@]}" -do - basename=$(basename "$interface") - - # find the number of bytes transfered for this interface - out1=$(cat /sys/class/net/"$basename"/statistics/tx_bytes) - - # wait a second - sleep 1 - - # check same interface again - out2=$(cat /sys/class/net/"$basename"/statistics/tx_bytes) - - # get the difference (transfer rate) - out_bytes=$((out2 - out1)) - - # convert transfer rate to KB - out_kbytes=$((out_bytes / 1024)) - - # convert transfer rate to KB - json_output="$json_output \"$basename\": $out_kbytes" - - # if it is not the last line - if [[ ! $interface == $last ]] - then - # add a comma to the line (JSON formatting) - json_output="$json_output," - fi -done - -# close the JSON object & print to screen -echo "$json_output}" diff --git a/sources/server/modules/shell_files/user_accounts.sh b/sources/server/modules/shell_files/user_accounts.sh deleted file mode 100755 index 599d6ba..0000000 --- a/sources/server/modules/shell_files/user_accounts.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -result=$(/usr/bin/awk -F: '{ \ - if ($3<=499){userType="system";} \ - else {userType="user";} \ - print "{ \"type\": \"" userType "\"" ", \"user\": \"" $1 "\", \"home\": \"" $6 "\" }," }' < /etc/passwd - ) - -length=$(echo ${#result}) - -if [ $length -eq 0 ]; then - result=$(getent passwd | /usr/bin/awk -F: '{ if ($3<=499){userType="system";} else {userType="user";} print "{ \"type\": \"" userType "\"" ", \"user\": \"" $1 "\", \"home\": \"" $6 "\" }," }') -fi - -echo [ ${result%?} ] \ No newline at end of file diff --git a/sources/templates/app/base-plugin.html b/sources/templates/app/base-plugin.html deleted file mode 100644 index 1f1a851..0000000 --- a/sources/templates/app/base-plugin.html +++ /dev/null @@ -1,10 +0,0 @@ -
- - - -
-
\ No newline at end of file diff --git a/sources/templates/app/key-value-list-plugin.html b/sources/templates/app/key-value-list-plugin.html deleted file mode 100644 index a5b312a..0000000 --- a/sources/templates/app/key-value-list-plugin.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
- - - - - - - -
{{ name }}{{ value }}
- -
- - -
diff --git a/sources/templates/app/line-chart-plugin.html b/sources/templates/app/line-chart-plugin.html deleted file mode 100644 index 8849bc1..0000000 --- a/sources/templates/app/line-chart-plugin.html +++ /dev/null @@ -1,20 +0,0 @@ -
- - - -
- - - - - - - - - - -
{{ metric.name }}{{ metric.data }}
- -
- - \ No newline at end of file diff --git a/sources/templates/app/loading.html b/sources/templates/app/loading.html deleted file mode 100644 index e6aeacd..0000000 --- a/sources/templates/app/loading.html +++ /dev/null @@ -1,4 +0,0 @@ -
- - Loading... -
diff --git a/sources/templates/app/multi-line-chart-plugin.html b/sources/templates/app/multi-line-chart-plugin.html deleted file mode 100644 index 42d9ef2..0000000 --- a/sources/templates/app/multi-line-chart-plugin.html +++ /dev/null @@ -1,26 +0,0 @@ -
- - -
- - - - - - - - - - - -
-
-
-
{{ metric.name }}{{ metric.data }}
- - -
- - \ No newline at end of file diff --git a/sources/templates/app/navbar.html b/sources/templates/app/navbar.html deleted file mode 100644 index b1d115b..0000000 --- a/sources/templates/app/navbar.html +++ /dev/null @@ -1,8 +0,0 @@ -
- diff --git a/sources/templates/app/progress-bar-plugin.html b/sources/templates/app/progress-bar-plugin.html deleted file mode 100644 index 85867ef..0000000 --- a/sources/templates/app/progress-bar-plugin.html +++ /dev/null @@ -1,5 +0,0 @@ -
-
-
-
-
\ No newline at end of file diff --git a/sources/templates/app/table-data-plugin.html b/sources/templates/app/table-data-plugin.html deleted file mode 100644 index 0b7d532..0000000 --- a/sources/templates/app/table-data-plugin.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - -
- - - - - - - - - - - - - - - -
- -
- {{ header }} - - {{ (header === sortByColumn && !sortReverse) ? '▲': ''; }} - {{ (header === sortByColumn && sortReverse) ? '▼': ''; }} - -
- {{ row[header] }} -
- -
- - -
diff --git a/sources/templates/app/theme-switcher.html b/sources/templates/app/theme-switcher.html deleted file mode 100644 index 36ff802..0000000 --- a/sources/templates/app/theme-switcher.html +++ /dev/null @@ -1,12 +0,0 @@ -
- -
- -
- {{ theme.name }} -
- -
\ No newline at end of file diff --git a/sources/templates/app/ui-elements/last-update.html b/sources/templates/app/ui-elements/last-update.html deleted file mode 100644 index d8d25cc..0000000 --- a/sources/templates/app/ui-elements/last-update.html +++ /dev/null @@ -1,4 +0,0 @@ -Loading... - - {{ timestamp | date:'hh:mm:ss a' }} - \ No newline at end of file diff --git a/sources/templates/app/ui-elements/top-bar.html b/sources/templates/app/ui-elements/top-bar.html deleted file mode 100644 index 88b5d1d..0000000 --- a/sources/templates/app/ui-elements/top-bar.html +++ /dev/null @@ -1,10 +0,0 @@ -
- - - {{ heading }} - - {{ info }} - - - -
\ No newline at end of file diff --git a/sources/templates/modules/cpu-load.html b/sources/templates/modules/cpu-load.html deleted file mode 100644 index e59abbc..0000000 --- a/sources/templates/modules/cpu-load.html +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/sources/templates/modules/cpu-utilization-chart.html b/sources/templates/modules/cpu-utilization-chart.html deleted file mode 100644 index 323976c..0000000 --- a/sources/templates/modules/cpu-utilization-chart.html +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/sources/templates/modules/disk-space.html b/sources/templates/modules/disk-space.html deleted file mode 100644 index 447c739..0000000 --- a/sources/templates/modules/disk-space.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - -
NameStatsUsedMount Path
{{partition['file_system']}} - - - - {{ partition['used'] }} / {{ partition['size'] }} - - {{ partition['used%'] }} - {{ partition['mounted'] }}
- -
diff --git a/sources/templates/modules/download-transfer-rate.html b/sources/templates/modules/download-transfer-rate.html deleted file mode 100644 index 32fe674..0000000 --- a/sources/templates/modules/download-transfer-rate.html +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/sources/templates/modules/ram-chart.html b/sources/templates/modules/ram-chart.html deleted file mode 100644 index 27a00d9..0000000 --- a/sources/templates/modules/ram-chart.html +++ /dev/null @@ -1,14 +0,0 @@ - - diff --git a/sources/templates/modules/upload-transfer-rate.html b/sources/templates/modules/upload-transfer-rate.html deleted file mode 100644 index 63f267e..0000000 --- a/sources/templates/modules/upload-transfer-rate.html +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/sources/templates/ping-speeds.html b/sources/templates/ping-speeds.html deleted file mode 100644 index df5a9b8..0000000 --- a/sources/templates/ping-speeds.html +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/sources/templates/sections/accounts.html b/sources/templates/sections/accounts.html deleted file mode 100644 index a3a7a33..0000000 --- a/sources/templates/sections/accounts.html +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/sources/templates/sections/applications.html b/sources/templates/sections/applications.html deleted file mode 100644 index 3958e63..0000000 --- a/sources/templates/sections/applications.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/sources/templates/sections/basic-info.html b/sources/templates/sections/basic-info.html deleted file mode 100644 index 9c8c7de..0000000 --- a/sources/templates/sections/basic-info.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/sources/templates/sections/network.html b/sources/templates/sections/network.html deleted file mode 100644 index e7fbe5f..0000000 --- a/sources/templates/sections/network.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/sources/templates/sections/system-status.html b/sources/templates/sections/system-status.html deleted file mode 100644 index cfc03b3..0000000 --- a/sources/templates/sections/system-status.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - -