From 2e888db44d81f4267f621d5f73560f13c218e9c3 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 19 Aug 2016 09:00:26 +0000 Subject: [PATCH] initial commit --- .gitignore | 6 + Doc.txt | 65 +++ abonapp/__init__.py | 0 abonapp/admin.py | 8 + abonapp/forms.py | 68 +++ abonapp/migrations/0001_initial.py | 110 +++++ abonapp/migrations/__init__.py | 0 abonapp/models.py | 349 ++++++++++++++ abonapp/tests.py | 50 ++ abonapp/urls.py | 21 + abonapp/urls_abon.py | 19 + abonapp/views.py | 439 ++++++++++++++++++ accounts_app/__init__.py | 0 accounts_app/admin.py | 4 + accounts_app/migrations/0001_initial.py | 42 ++ accounts_app/migrations/__init__.py | 0 accounts_app/models.py | 107 +++++ accounts_app/tests.py | 16 + accounts_app/urls.py | 27 ++ accounts_app/views.py | 258 ++++++++++ agent.py | 12 + agent/__init__.py | 3 + agent/db.py | 27 ++ agent/firewall.py | 48 ++ agent/ipfw.sh | 72 +++ agent/main.py | 120 +++++ agent/models.py | 143 ++++++ agent/netflow/__init__.py | 0 agent/netflow/netflow_handler.py | 49 ++ agent/netflow/netflow_handler.sh | 11 + agent/netflow/start_netflow.sh | 7 + agent/settings.py | 17 + agent/sslTransmitter.py | 226 +++++++++ agent/tariff.py | 1 + bugs.txt | 11 + cron.py | 18 + devapp/__init__.py | 0 devapp/admin.py | 6 + devapp/apps.py | 7 + devapp/base_intr.py | 109 +++++ devapp/dev_types.py | 30 ++ devapp/forms.py | 32 ++ devapp/migrations/0001_initial.py | 49 ++ devapp/migrations/__init__.py | 0 devapp/models.py | 52 +++ devapp/tests.py | 3 + devapp/urls.py | 10 + devapp/views.py | 59 +++ djing/__init__.py | 0 djing/settings.py | 143 ++++++ djing/urls.py | 26 ++ djing/views.py | 9 + djing/wsgi.py | 16 + install.sql | 17 + ip_pool/__init__.py | 1 + ip_pool/admin.py | 4 + ip_pool/apps.py | 6 + ip_pool/forms.py | 21 + ip_pool/migrations/0001_initial.py | 24 + ip_pool/migrations/__init__.py | 0 ip_pool/models.py | 60 +++ ip_pool/tests.py | 3 + ip_pool/urls.py | 13 + ip_pool/views.py | 76 +++ manage.py | 10 + mapapp/__init__.py | 0 mapapp/admin.py | 4 + mapapp/apps.py | 7 + mapapp/migrations/0001_initial.py | 25 + mapapp/migrations/__init__.py | 0 mapapp/models.py | 10 + mapapp/tests.py | 3 + mapapp/urls.py | 7 + mapapp/views.py | 18 + mydefs.py | 111 +++++ photo_app/__init__.py | 0 photo_app/admin.py | 4 + photo_app/migrations/0001_initial.py | 25 + photo_app/migrations/__init__.py | 0 photo_app/models.py | 69 +++ photo_app/tests.py | 16 + photo_app/urls.py | 12 + photo_app/views.py | 1 + privatemessage/__init__.py | 0 privatemessage/admin.py | 5 + privatemessage/context_processors.py | 7 + privatemessage/migrations/0001_initial.py | 39 ++ privatemessage/migrations/__init__.py | 0 privatemessage/models.py | 34 ++ privatemessage/tests.py | 22 + privatemessage/urls.py | 8 + privatemessage/views.py | 54 +++ requirements.txt | 4 + searchapp/__init__.py | 0 searchapp/admin.py | 3 + searchapp/apps.py | 7 + searchapp/migrations/__init__.py | 0 searchapp/models.py | 5 + searchapp/tests.py | 3 + searchapp/urls.py | 7 + searchapp/views.py | 32 ++ static/bad_ie.html | 11 + static/css/bootstrap-theme.min.css | 5 + static/css/bootstrap.min.css | 5 + static/css/custom.css | 145 ++++++ static/css/custom_login.css | 40 ++ static/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes static/fonts/glyphicons-halflings-regular.svg | 288 ++++++++++++ static/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes static/img/0ZKOa52wPuc.jpg | Bin 0 -> 43610 bytes static/img/favicon.ico | Bin 0 -> 2918 bytes static/img/favicon_m.ico | Bin 0 -> 1150 bytes static/img/gmarkers/dev.png | Bin 0 -> 3943 bytes static/img/gmarkers/dev.xcf | Bin 0 -> 7421 bytes static/img/gmarkers/dev_bug.png | Bin 0 -> 4190 bytes static/img/gmarkers/dev_ok.png | Bin 0 -> 4284 bytes static/img/gmarkers/flag_black.png | Bin 0 -> 885 bytes static/img/icon-port-64x64-grey.png | Bin 0 -> 284 bytes static/img/kpkLhcH5R4E.jpg | Bin 0 -> 4474 bytes static/img/user_ava.gif | Bin 0 -> 7656 bytes static/img/user_ava_min.gif | Bin 0 -> 7237 bytes static/js/bootstrap.min.js | 7 + static/js/jquery-2.2.4.min.js | 4 + static/js/my.js | 69 +++ statistics/__init__.py | 0 statistics/admin.py | 4 + statistics/apps.py | 5 + statistics/migrations/0001_initial.py | 33 ++ statistics/migrations/__init__.py | 0 statistics/models.py | 17 + statistics/tests.py | 3 + statistics/urls.py | 6 + statistics/views.py | 5 + tariff_app/__init__.py | 0 tariff_app/admin.py | 4 + tariff_app/base_intr.py | 16 + tariff_app/custom_tariffs.py | 61 +++ tariff_app/forms.py | 16 + tariff_app/migrations/0001_initial.py | 28 ++ tariff_app/migrations/__init__.py | 0 tariff_app/models.py | 34 ++ tariff_app/tests.py | 3 + tariff_app/urls.py | 9 + tariff_app/views.py | 51 ++ templates/abonapp/abonamount.html | 39 ++ templates/abonapp/addAbon.html | 67 +++ templates/abonapp/addGroup.html | 39 ++ templates/abonapp/addInvoice.html | 41 ++ templates/abonapp/buy_tariff.html | 31 ++ templates/abonapp/complete_service.html | 54 +++ templates/abonapp/editAbon.html | 88 ++++ templates/abonapp/ext.htm | 23 + templates/abonapp/group_list.html | 53 +++ templates/abonapp/invoiceForPayment.html | 49 ++ templates/abonapp/log.html | 45 ++ templates/abonapp/payHistory.html | 30 ++ templates/abonapp/peoples.html | 60 +++ templates/abonapp/services.html | 63 +++ templates/accounts/acc_list.html | 59 +++ templates/accounts/create_acc.html | 88 ++++ templates/accounts/ext.htm | 42 ++ templates/accounts/group.html | 38 ++ templates/accounts/group_list.html | 46 ++ templates/accounts/index.html | 39 ++ templates/accounts/login.html | 67 +++ templates/accounts/profile_chgroup.html | 31 ++ templates/accounts/settings/ch_info.html | 80 ++++ templates/accounts/settings/ext.htm | 43 ++ templates/bajax.html | 1 + templates/base.html | 195 ++++++++ templates/base_without_left.html | 73 +++ templates/devapp/dev.html | 64 +++ templates/devapp/devices.html | 48 ++ templates/devapp/ext.htm | 20 + templates/devapp/ports.html | 38 ++ templates/ip_pool/add_pool.html | 39 ++ templates/ip_pool/index.html | 51 ++ templates/ip_pool/ips.html | 47 ++ templates/maps/index.html | 66 +++ templates/nullcont.htm | 1 + templates/private_messages/index.html | 34 ++ templates/private_messages/item.html | 7 + templates/private_messages/send_form.html | 13 + templates/searchapp/index.html | 42 ++ templates/statistics/index.html | 37 ++ templates/tariff_app/editTarif.html | 76 +++ templates/tariff_app/tarifs.html | 53 +++ templates/toolbar_page.html | 19 + 190 files changed, 6690 insertions(+) create mode 100644 .gitignore create mode 100644 Doc.txt create mode 100644 abonapp/__init__.py create mode 100644 abonapp/admin.py create mode 100644 abonapp/forms.py create mode 100644 abonapp/migrations/0001_initial.py create mode 100644 abonapp/migrations/__init__.py create mode 100644 abonapp/models.py create mode 100644 abonapp/tests.py create mode 100644 abonapp/urls.py create mode 100644 abonapp/urls_abon.py create mode 100644 abonapp/views.py create mode 100644 accounts_app/__init__.py create mode 100644 accounts_app/admin.py create mode 100644 accounts_app/migrations/0001_initial.py create mode 100644 accounts_app/migrations/__init__.py create mode 100644 accounts_app/models.py create mode 100644 accounts_app/tests.py create mode 100644 accounts_app/urls.py create mode 100644 accounts_app/views.py create mode 100644 agent.py create mode 100644 agent/__init__.py create mode 100644 agent/db.py create mode 100644 agent/firewall.py create mode 100644 agent/ipfw.sh create mode 100644 agent/main.py create mode 100644 agent/models.py create mode 100644 agent/netflow/__init__.py create mode 100755 agent/netflow/netflow_handler.py create mode 100755 agent/netflow/netflow_handler.sh create mode 100755 agent/netflow/start_netflow.sh create mode 100644 agent/settings.py create mode 100644 agent/sslTransmitter.py create mode 100644 agent/tariff.py create mode 100644 bugs.txt create mode 100644 cron.py create mode 100644 devapp/__init__.py create mode 100644 devapp/admin.py create mode 100644 devapp/apps.py create mode 100644 devapp/base_intr.py create mode 100644 devapp/dev_types.py create mode 100644 devapp/forms.py create mode 100644 devapp/migrations/0001_initial.py create mode 100644 devapp/migrations/__init__.py create mode 100644 devapp/models.py create mode 100644 devapp/tests.py create mode 100644 devapp/urls.py create mode 100644 devapp/views.py create mode 100644 djing/__init__.py create mode 100644 djing/settings.py create mode 100644 djing/urls.py create mode 100644 djing/views.py create mode 100644 djing/wsgi.py create mode 100644 install.sql create mode 100644 ip_pool/__init__.py create mode 100644 ip_pool/admin.py create mode 100644 ip_pool/apps.py create mode 100644 ip_pool/forms.py create mode 100644 ip_pool/migrations/0001_initial.py create mode 100644 ip_pool/migrations/__init__.py create mode 100644 ip_pool/models.py create mode 100644 ip_pool/tests.py create mode 100644 ip_pool/urls.py create mode 100644 ip_pool/views.py create mode 100755 manage.py create mode 100644 mapapp/__init__.py create mode 100644 mapapp/admin.py create mode 100644 mapapp/apps.py create mode 100644 mapapp/migrations/0001_initial.py create mode 100644 mapapp/migrations/__init__.py create mode 100644 mapapp/models.py create mode 100644 mapapp/tests.py create mode 100644 mapapp/urls.py create mode 100644 mapapp/views.py create mode 100644 mydefs.py create mode 100644 photo_app/__init__.py create mode 100644 photo_app/admin.py create mode 100644 photo_app/migrations/0001_initial.py create mode 100644 photo_app/migrations/__init__.py create mode 100644 photo_app/models.py create mode 100644 photo_app/tests.py create mode 100644 photo_app/urls.py create mode 100644 photo_app/views.py create mode 100644 privatemessage/__init__.py create mode 100644 privatemessage/admin.py create mode 100644 privatemessage/context_processors.py create mode 100644 privatemessage/migrations/0001_initial.py create mode 100644 privatemessage/migrations/__init__.py create mode 100644 privatemessage/models.py create mode 100644 privatemessage/tests.py create mode 100644 privatemessage/urls.py create mode 100644 privatemessage/views.py create mode 100644 requirements.txt create mode 100644 searchapp/__init__.py create mode 100644 searchapp/admin.py create mode 100644 searchapp/apps.py create mode 100644 searchapp/migrations/__init__.py create mode 100644 searchapp/models.py create mode 100644 searchapp/tests.py create mode 100644 searchapp/urls.py create mode 100644 searchapp/views.py create mode 100644 static/bad_ie.html create mode 100644 static/css/bootstrap-theme.min.css create mode 100644 static/css/bootstrap.min.css create mode 100644 static/css/custom.css create mode 100644 static/css/custom_login.css create mode 100644 static/fonts/glyphicons-halflings-regular.eot create mode 100644 static/fonts/glyphicons-halflings-regular.svg create mode 100644 static/fonts/glyphicons-halflings-regular.ttf create mode 100644 static/fonts/glyphicons-halflings-regular.woff create mode 100644 static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 static/img/0ZKOa52wPuc.jpg create mode 100644 static/img/favicon.ico create mode 100644 static/img/favicon_m.ico create mode 100644 static/img/gmarkers/dev.png create mode 100644 static/img/gmarkers/dev.xcf create mode 100644 static/img/gmarkers/dev_bug.png create mode 100644 static/img/gmarkers/dev_ok.png create mode 100644 static/img/gmarkers/flag_black.png create mode 100644 static/img/icon-port-64x64-grey.png create mode 100644 static/img/kpkLhcH5R4E.jpg create mode 100644 static/img/user_ava.gif create mode 100644 static/img/user_ava_min.gif create mode 100644 static/js/bootstrap.min.js create mode 100644 static/js/jquery-2.2.4.min.js create mode 100644 static/js/my.js create mode 100644 statistics/__init__.py create mode 100644 statistics/admin.py create mode 100644 statistics/apps.py create mode 100644 statistics/migrations/0001_initial.py create mode 100644 statistics/migrations/__init__.py create mode 100644 statistics/models.py create mode 100644 statistics/tests.py create mode 100644 statistics/urls.py create mode 100644 statistics/views.py create mode 100644 tariff_app/__init__.py create mode 100644 tariff_app/admin.py create mode 100644 tariff_app/base_intr.py create mode 100644 tariff_app/custom_tariffs.py create mode 100644 tariff_app/forms.py create mode 100644 tariff_app/migrations/0001_initial.py create mode 100644 tariff_app/migrations/__init__.py create mode 100644 tariff_app/models.py create mode 100644 tariff_app/tests.py create mode 100644 tariff_app/urls.py create mode 100644 tariff_app/views.py create mode 100644 templates/abonapp/abonamount.html create mode 100644 templates/abonapp/addAbon.html create mode 100644 templates/abonapp/addGroup.html create mode 100644 templates/abonapp/addInvoice.html create mode 100644 templates/abonapp/buy_tariff.html create mode 100644 templates/abonapp/complete_service.html create mode 100644 templates/abonapp/editAbon.html create mode 100644 templates/abonapp/ext.htm create mode 100644 templates/abonapp/group_list.html create mode 100644 templates/abonapp/invoiceForPayment.html create mode 100644 templates/abonapp/log.html create mode 100644 templates/abonapp/payHistory.html create mode 100644 templates/abonapp/peoples.html create mode 100644 templates/abonapp/services.html create mode 100644 templates/accounts/acc_list.html create mode 100644 templates/accounts/create_acc.html create mode 100644 templates/accounts/ext.htm create mode 100644 templates/accounts/group.html create mode 100644 templates/accounts/group_list.html create mode 100644 templates/accounts/index.html create mode 100644 templates/accounts/login.html create mode 100644 templates/accounts/profile_chgroup.html create mode 100644 templates/accounts/settings/ch_info.html create mode 100644 templates/accounts/settings/ext.htm create mode 100644 templates/bajax.html create mode 100644 templates/base.html create mode 100644 templates/base_without_left.html create mode 100644 templates/devapp/dev.html create mode 100644 templates/devapp/devices.html create mode 100644 templates/devapp/ext.htm create mode 100644 templates/devapp/ports.html create mode 100644 templates/ip_pool/add_pool.html create mode 100644 templates/ip_pool/index.html create mode 100644 templates/ip_pool/ips.html create mode 100644 templates/maps/index.html create mode 100644 templates/nullcont.htm create mode 100644 templates/private_messages/index.html create mode 100644 templates/private_messages/item.html create mode 100644 templates/private_messages/send_form.html create mode 100644 templates/searchapp/index.html create mode 100644 templates/statistics/index.html create mode 100644 templates/tariff_app/editTarif.html create mode 100644 templates/tariff_app/tarifs.html create mode 100644 templates/toolbar_page.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18ad675 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.pyc +*.db +media/* +media/min/* +~*/migrations/000*.py +.idea/ diff --git a/Doc.txt b/Doc.txt new file mode 100644 index 0000000..92fb8be --- /dev/null +++ b/Doc.txt @@ -0,0 +1,65 @@ +// Формат общения NAS с базой +[ + { + "toa": 1, /* Тип события: + 0 - ничего не надо (пустое) + 1 - Активировать клиента (включить его) + 2 - Выключить клиента + 3 - Поставить заглушку + 4 - Открыть доступ в интернет + 5 - Закрыть доступ в интернет + 6 - Перечитать всю инфу (полная перезагрузка NAS) + 7 - Изменилась инфа об абоненте, переприменить его + */ + "id": 12, // ID объекта о котором событие (абонент там, или тариф) + "dt": "data" // Разная инфа, содержимое зависит от поля 'toa' + }, + { + "id": 13, + "toa": 3 + } +] + +// Формат передачи инфы об абонентах +{ + "subscribers": [ + { + "is_active": true, // Активен-ли абонент + "ip": 168558850, // Его ip + "tarif_id": 1, // id тарифа + "id": 2 // id абонента + }, + { + "is_active": true, + "ip": 168558850, + "tarif_id": 1, + "id": 2 + } + ], + "tariffs": [ + { + "tid": 1, // id тарифа + "amount": 0.0, // стоимость + "speedOut": 0.0, // Исходящая скорость + "speedIn": 0.0 // Входящая скорость + } + ] +} + + +------------------------------- +Состояние оплаты абонента определяется на основе присутствия у него тарифного плана, +если он есть - то значит всё оплачено (абонент его купил) и может пользоваться услугами. +Тарифный план имеет срок действия и стоимость. Его можно купить, как билет в интернет :) + + +ТАРИФНЫЙ ПЛАН С НАИМЕНЬШИМ ЧИСЛОМ ПРИОРИТЕТА ИМЕЕТ НАИВЫСШИЙ ПРИОРИТЕТ +В общем чем ближе приоритет к 0 тем он выше +0 - текущий тариф + + +Свою логику расчёта по тарифу можно добавить в файле tariff_app/custom_tariffs.py +Там надо добавить класс, наследованный от TariffBase и реализовать его абстрактные методы, +потом добавить этот класс в кортеж TARIFF_CHOICES указав: + код из 2х букв, сочетание должно быть уникальным + и ваш класс для своей логики расчёта тарифа diff --git a/abonapp/__init__.py b/abonapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/abonapp/admin.py b/abonapp/admin.py new file mode 100644 index 0000000..f62b3f7 --- /dev/null +++ b/abonapp/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +import models + +admin.site.register(models.AbonGroup) +admin.site.register(models.Abon) +admin.site.register(models.InvoiceForPayment) +admin.site.register(models.AbonLog) +admin.site.register(models.AbonTariff) diff --git a/abonapp/forms.py b/abonapp/forms.py new file mode 100644 index 0000000..059c8bc --- /dev/null +++ b/abonapp/forms.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +from django import forms +from django.core.validators import RegexValidator +import models +from mydefs import ip_addr_regex + + +class AbonForm(forms.Form): + username = forms.CharField(max_length=127, required=False, widget=forms.TextInput(attrs={ + 'placeholder': u'Логин', + 'class': "form-control", + 'id': "login" + })) + fio = forms.CharField(max_length=256, widget=forms.TextInput(attrs={ + 'placeholder': u'ФИО', + 'class': "form-control", + 'id': "fio" + }), required=False) + ip_address = forms.GenericIPAddressField(protocol='IPv4', required=False, widget=forms.TextInput(attrs={ + 'pattern': ip_addr_regex, + 'placeholder': u'127.0.0.1', + 'class': "form-control", + 'id': "ip" + })) + + telephone = forms.CharField( + max_length=16, + validators=[RegexValidator(r'^\+[7,8,9,3]\d{10,11}$')], + widget=forms.TextInput(attrs={ + 'placeholder': u'+[7,8,9,3] и 10,11 цифр', + 'pattern': r'^\+[7,8,9,3]\d{10,11}$', + 'required': '', + 'class': 'form-control', + 'id': 'telephone' + }) + ) + is_active = forms.BooleanField( + required=False, + widget=forms.Select(attrs={'class': 'form-control', 'id': 'isactive'}) + ) + + group = forms.ModelChoiceField( + queryset=models.AbonGroup.objects.all(), + required=False, + widget=forms.Select(attrs={'class': 'form-control', 'id': 'grp'}) + ) + address = forms.CharField( + max_length=256, + required=False, + widget = forms.TextInput(attrs={'class': 'form-control', 'id': 'address'}) + ) + + +class AbonGroupForm(forms.ModelForm): + class Meta: + model = models.AbonGroup + fields = ['title', 'address'] + widgets = { + 'class': 'form-control' + } + + +class BuyTariff(forms.Form): + tariff = forms.ModelChoiceField( + queryset=models.Tariff.objects.all(), + required=True, + widget=forms.Select(attrs={'class': 'form-control', 'id': 'tariff'}) + ) diff --git a/abonapp/migrations/0001_initial.py b/abonapp/migrations/0001_initial.py new file mode 100644 index 0000000..6d70506 --- /dev/null +++ b/abonapp/migrations/0001_initial.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('accounts_app', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('ip_pool', '0001_initial'), + ('tariff_app', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Abon', + fields=[ + ('userprofile_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ('ballance', models.FloatField(default=0.0, validators=[django.core.validators.DecimalValidator])), + ('address', models.CharField(max_length=256)), + ], + options={ + 'db_table': 'abonent', + }, + bases=('accounts_app.userprofile',), + ), + migrations.CreateModel( + name='AbonGroup', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=127)), + ('address', models.CharField(blank=True, max_length=256, null=True)), + ], + options={ + 'db_table': 'abonent_groups', + }, + ), + migrations.CreateModel( + name='AbonLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.FloatField(default=0.0)), + ('comment', models.CharField(max_length=128)), + ('date', models.DateTimeField(auto_now_add=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'abonent_log', + }, + ), + migrations.CreateModel( + name='AbonTariff', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tariff_priority', models.PositiveSmallIntegerField(default=0)), + ('time_start', models.DateTimeField(blank=True, default=None, null=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('tariff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='linkto_tariff', to='tariff_app.Tariff')), + ], + options={ + 'ordering': ('tariff_priority',), + 'db_table': 'abonent_tariff', + }, + ), + migrations.CreateModel( + name='InvoiceForPayment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.BooleanField(default=False)), + ('amount', models.FloatField(default=0.0)), + ('comment', models.CharField(max_length=128)), + ('date_create', models.DateTimeField(auto_now_add=True)), + ('date_pay', models.DateTimeField(blank=True, null=True)), + ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('date_create',), + 'db_table': 'abonent_inv_pay', + }, + ), + migrations.AddField( + model_name='abon', + name='current_tariffs', + field=models.ManyToManyField(through='abonapp.AbonTariff', to='tariff_app.Tariff'), + ), + migrations.AddField( + model_name='abon', + name='group', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonGroup'), + ), + migrations.AddField( + model_name='abon', + name='ip_address', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ip_pool.IpPoolItem'), + ), + migrations.AlterUniqueTogether( + name='abontariff', + unique_together=set([('abon', 'tariff', 'tariff_priority')]), + ), + ] diff --git a/abonapp/migrations/__init__.py b/abonapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/abonapp/models.py b/abonapp/models.py new file mode 100644 index 0000000..3ec1616 --- /dev/null +++ b/abonapp/models.py @@ -0,0 +1,349 @@ +# -*- coding: utf-8 -*- +from django.core.exceptions import MultipleObjectsReturned +from django.http import Http404 +from django.shortcuts import get_object_or_404 +from django.utils import timezone +from django.utils.datetime_safe import datetime +from agent import get_TransmitterClientKlass, Abonent, Tariff as AgentTariff +from ip_pool.models import IpPoolItem +from tariff_app.models import Tariff +from django.db import models +from djing import settings +from django.core.validators import DecimalValidator +from accounts_app.models import UserProfile + + +class LogicError(Exception): + def __init__(self, value): + self.value = value + def __unicode__(self): + return repr(self.value) + + +class AbonGroup(models.Model): + title = models.CharField(max_length=127) + address = models.CharField(max_length=256, blank=True, null=True) + + class Meta: + db_table = 'abonent_groups' + + def __unicode__(self): + return self.title + + +class AbonLog(models.Model): + abon = models.ForeignKey('Abon') + amount = models.FloatField(default=0.0) + author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+') + comment = models.CharField(max_length=128) + date = models.DateTimeField(auto_now_add=True) + + class Meta: + db_table = 'abonent_log' + + def __unicode__(self): + return self.comment + + +class AbonTariffManager(models.Manager): + + def update_priorities(self, abonent): + abon_tariff_list = AbonTariff.objects.filter(abon=abonent).order_by('tariff_priority') + + # Обновляем приоритеты, чтоб по порядку были + at_pr = 0 + for at in abon_tariff_list: + at.tariff_priority = at_pr + at_pr += 1 + at.save() + + +class AbonTariff(models.Model): + abon = models.ForeignKey('Abon') + tariff = models.ForeignKey(Tariff, related_name='linkto_tariff') + tariff_priority = models.PositiveSmallIntegerField(default=0) + + # время начала действия, остальные что не начали действие - NULL + time_start = models.DateTimeField(null=True, blank=True, default=None) + + objects = AbonTariffManager() + + def priority_up(self): + # ищем услугу с большим приоритетом(число приоритета меньше) + target_abtar = AbonTariff.objects.filter( + abon=self.abon, + tariff_priority__lt=self.tariff_priority + ).order_by('-tariff_priority')[:1] + if target_abtar.count() > 0: + target_abtar = target_abtar[0] + else: + return + + # Ищем текущий тариф абонента + active_abtar = AbonTariff.objects.filter( + abon=self.abon + )[:1] + if active_abtar.count() > 0: + active_abtar = active_abtar[0] + else: + return + + # Если услуга с которой хотим поменяться приоритетом является текущей то нельзя меняться + if active_abtar == target_abtar: + return + + # Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом) + tmp_prior = target_abtar.tariff_priority + target_abtar.tariff_priority = self.tariff_priority + target_abtar.save() + self.tariff_priority = tmp_prior + self.save() + + def priority_down(self): + # ищем услугу с меньшим приоритетом + target_abtar = AbonTariff.objects.filter( + abon=self.abon, + tariff_priority__gt=self.tariff_priority + )[:1] + if target_abtar.count() > 0: + target_abtar = target_abtar[0] + else: + # меньше нет, это самая последняя услуга + return + + # Swap приоритетов у текущего и найденного с большим tariff_priority (меньшим приоритетом) + tmp_pr = self.tariff_priority + self.tariff_priority = target_abtar.tariff_priority + target_abtar.tariff_priority = tmp_pr + target_abtar.save() + self.save() + + # Считает текущую стоимость услуг согласно выбранной для тарифа логики оплаты (см. в документации) + def calc_amount_service(self): + calc_obj = self.tariff.get_calc_type() + # calc_obj - instance of tariff_app.custom_tariffs.TariffBase + amount = calc_obj.calc_amount(self) + return round(amount, 2) + + # досрочно завершает услугу + def finish_and_activate_next_tariff(self, author): + + # выберем следующие по приоритету услуги + next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon)[:1] + + if next_tarifs.count() < 1: + raise LogicError(u'У абонента нет следующих назначенных услуг') + + # 0й элемент это следующая подключаемая услуга + next_tarifs[0].time_start = timezone.now() + next_tarifs[0].save() + + # сколько денег стоят потраченные ресурсы + used_services = self.calc_amount_service() + + #теперь к текущему баллансу добавляем сумму не потраченных ресурсов, т.к. полная сумма тарифа списывается при покупке тарифа + ret_amount = self.tariff.amount - used_services + self.abon.ballance += ret_amount + self.abon.save() + + AbonLog.objects.create( + abon = self.abon, + amount = ret_amount, + author = author, + comment = u'Досрочное завершение услуги %s' % (self.tariff.title) + ) + + def __unicode__(self): + return "%d: '%s' - '%s'" % ( + self.tariff_priority, + self.tariff.title, + self.abon.get_short_name() + ) + + class Meta: + ordering = ('tariff_priority',) + db_table = 'abonent_tariff' + unique_together = (('abon', 'tariff', 'tariff_priority'),) + + +class Abon(UserProfile): + current_tariffs = models.ManyToManyField(Tariff, through=AbonTariff) + group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True) + ballance = models.FloatField(default=0.0, validators=[DecimalValidator]) + ip_address = models.OneToOneField(IpPoolItem, on_delete=models.SET_NULL, null=True, blank=True) + address = models.CharField(max_length=256) + + _act_tar_cache = None + + def active_tariff(self): + if self._act_tar_cache: + return self._act_tar_cache + + ats = AbonTariff.objects.filter(abon=self)[:1] + + if ats.count() > 0: + self._act_tar_cache = ats[0].tariff + return ats[0].tariff + else: + self._act_tar_cache = None + return + + def save_form(self, abonform_instance): + try: + cd = abonform_instance.cleaned_data + tel = cd['telephone'] + self.username = cd['username'] or tel[1:] + self.fio = cd['fio'] + self.telephone = tel + self.is_admin = False + self.ip_address = get_object_or_404(IpPoolItem, ip=cd['ip_address']) + self.is_active = True + self.group = cd['group'] + self.address = cd['address'] + except Http404: + raise LogicError(u'Введённый IP адрес не добавлен в ip pool') + except MultipleObjectsReturned: + raise LogicError(u'Введённый IP адрес не определён') + + class Meta: + db_table = 'abonent' + + def make_pay(self, curuser, how_match_to_pay=0.0): + AbonLog.objects.create( + abon = self, + amount = -how_match_to_pay, + author = curuser, + comment = u'Снятие со счёта средств' + ) + self.ballance -= how_match_to_pay + + def add_ballance(self, current_user, amount): + AbonLog.objects.create( + abon = self, + amount = amount, + author = current_user, + comment = u'Пополнение счёта через админку' + ) + self.ballance += amount + + def buy_tariff(self, tariff, author): + if self.ballance >= tariff.amount: + # денег достаточно, можно покупать + self.ballance -= tariff.amount + + # выбераем связь ТарифАбонент с самым низким приоритетом + abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] + abtrf = abtrf[0] if abtrf.count() > 0 else None + + # создаём новую связь с приоритетом ещё ниже + new_abtar = AbonTariff( + abon=self, + tariff=tariff, + tariff_priority=abtrf.tariff_priority+1 if abtrf else -1 + ) + + # Если это первая услуга в списке (фильтр по приоритету ничего не вернул) + if not abtrf: + # значит она сразу стаёт активной + new_abtar.time_start = timezone.now() + + new_abtar.save() + + # шлём сигнал о том что абонент купил первую услугу, а значит можно пользоваться инетом + # сигнал можно слать только после того как будет сохранён новый объект AbonTariff + if self.is_active and not abtrf: + tc = get_TransmitterClientKlass()() + act_tar = self.active_tariff() + agent_abon = Abonent( + self.id, + self.ip_address.int_ip(), + AgentTariff( + act_tar.id if act_tar else 0, + act_tar.speedIn if act_tar else 0.0, + act_tar.speedOut if act_tar else 0.0 + ) + ) + tc.signal_abon_refresh_info(agent_abon) + tc.signal_abon_open_inet(agent_abon) + + # Запись об этом в лог + AbonLog.objects.create( + abon = self, amount = -tariff.amount, + author = author, + comment = u'Покупка тарифного плана через админку, тариф "%s"' % tariff.title + ) + else: + raise LogicError(u'Недостаточно денег на счету абонента') + + # Пробует подключить новую услугу если пришло время + def activate_next_tariff(self, author): + ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority') + + nw = datetime.now(tz=timezone.get_current_timezone()) + + for at in ats: + # Если времени активации нет, то это ещё не активированный тариф + if not at.time_start: + return + + # время к началу месяца + to_start_month = datetime(nw.year, nw.month, 1, tzinfo=timezone.get_current_timezone()) + + # проверяем расстояние от Сегодня до начала этого месяца. + # И от заказа тарифа до начала этого месяца + if (nw - at.time_start) > (nw - to_start_month): + # Заказ из прошлого месяца, срок действия закончен + print u'Заказ из прошлого месяца, срок действия закончен' + + # выберем следующую по приоритету + #next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon) + next_tarifs = filter(lambda tr: tr.tariff_priority > at.tariff_priority, ats)[:2] + + # и если что-нибудь вернулось то активируем, давая время начала действия + if next_tarifs.count() > 0: + next_tarifs[0].time_start = nw + next_tarifs[0].save() + + # завершаем текущую услугу. + at.delete() + + # Создаём лог о завершении услуги + AbonLog.objects.create( + abon = self, + amount = 0, + author = author, + comment = u'Завершение услуги по истечению срока действия' + ) + + +class InvoiceForPayment(models.Model): + abon = models.ForeignKey(Abon) + status = models.BooleanField(default=False) + amount = models.FloatField(default=0.0) + comment = models.CharField(max_length=128) + date_create = models.DateTimeField(auto_now_add=True) + date_pay = models.DateTimeField(blank=True, null=True) + author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+') + + def __unicode__(self): + return "%s -> %d $" % (self.abon.username, self.amount) + + def set_ok(self): + self.status = True + self.date_pay = datetime.now() + + def get_prev_invoice(self): + return self.objects.order + + class Meta: + ordering = ('date_create',) + db_table = 'abonent_inv_pay' + + +#def abon_save_signal(sender, instance, **kwargs): +# if not kwargs['created']: +# # if not create (change only) +# print "Kw1", instance.username, instance.is_active + + +#models.signals.post_save.connect(abon_save_signal, sender=Abon) diff --git a/abonapp/tests.py b/abonapp/tests.py new file mode 100644 index 0000000..82ce379 --- /dev/null +++ b/abonapp/tests.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from django.shortcuts import get_object_or_404 +from django.test import TestCase +from models import Abon, AbonTariff +from tariff_app.models import Tariff + + +class AbonTariffTestCase(TestCase): + + def setUp(self): + abon1 = Abon.objects.create( + telephone='+79784653751', + fio=u'ФИО абона', + username='аго мучич' + ) + tarif1 = Tariff.objects.create( + title=u'Тариф 1', + speedIn=120.3, + speedOut=53, + amount=38 + ) + tarif2 = Tariff.objects.create( + title=u'Тариф 2', + speedIn=130.3, + speedOut=23, + amount=82 + ) + AbonTariff.objects.create( + abon=abon1, + tariff=tarif1, + tariff_priority=0 + ) + AbonTariff.objects.create( + abon=abon1, + tariff=tarif2, + tariff_priority=1 + ) + + def test_activate_next(self): + # возьмём абонента для опытов + abn = get_object_or_404(Abon, username=u'аго мучич') + + # берём купленные услуги + ats = AbonTariff.objects.filter(abon=abn) + for at in ats: + + # и пробуем назначить + at.activate_next_tariff() + + AbonTariff.objects.update_priorities(ats) diff --git a/abonapp/urls.py b/abonapp/urls.py new file mode 100644 index 0000000..e5c3e37 --- /dev/null +++ b/abonapp/urls.py @@ -0,0 +1,21 @@ +from django.conf.urls import url, include +import views + +urlpatterns = [ + + url(r'^$', views.grouplist, name='abongroup_list_link'), + url(r'^addgroup$', views.addgroup, name='addgroup_link'), + url(r'^delgroup', views.delgroup, name='people_delgroup_link'), + + url(r'^(?P\d+)/', include('abonapp.urls_abon')), + + url(r'^log$', views.log_page, name='abonapp_log_link'), + + url(r'^del$', views.delentity, name='abonapp_del_link'), + + url(r'^pay$', views.terminal_pay, name='abonapp_terminalpay_link'), + + # Api's + url(r'^api/abons$', views.abons) + +] diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py new file mode 100644 index 0000000..dbbb62c --- /dev/null +++ b/abonapp/urls_abon.py @@ -0,0 +1,19 @@ +from django.conf.urls import url +import views + +urlpatterns = [ + url(r'^$', views.peoples, name='pays_people_list_link'), + url(r'^addabon$', views.addabon, name='addabon_link'), + url(r'^(?P\d+)$', views.abonhome, name='abonhome_link'), + + url(r'^(?P\d+)/services$', views.abon_services, name='abon_services_link'), + url(r'^(?P\d+)/amount', views.abonamount, name='abon_amount_link'), + url(r'^(?P\d+)/debts', views.invoice_for_payment, name='abon_debts_link'), + url(r'^(?P\d+)/pay_history', views.pay_history, name='abon_phistory_link'), + + + url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='abonapp_addinvoice_link'), + url(r'^(?P\d+)/buy$', views.buy_tariff, name='abonapp_buy_tariff'), + url(r'^(?P\d+)/chpriority$', views.chpriority, name='abonapp_chpriority_tariff'), + url(r'^(?P\d+)/complete_service_(?P\d+)$', views.complete_service, name='abonapp_compl_srv'), +] diff --git a/abonapp/views.py b/abonapp/views.py new file mode 100644 index 0000000..1b34a4c --- /dev/null +++ b/abonapp/views.py @@ -0,0 +1,439 @@ +# -*- coding: utf-8 -*- +from json import dumps +from django.db import IntegrityError +from django.db.models import Count +from django.shortcuts import render, redirect, get_object_or_404 +from django.contrib.auth.decorators import login_required +from django.utils import timezone +from accounts_app.models import UserProfile +from ip_pool.models import IpPoolItem +from tariff_app.models import Tariff +from django.template.context_processors import csrf +from django.http import HttpResponse, Http404 +from agent import get_TransmitterClientKlass, NetExcept +import forms +import models +import mydefs + + +@login_required +def peoples(request, gid): + peopleslist = models.Abon.objects.filter(group=gid) + + peopleslist = mydefs.pag_mn(request, peopleslist) + + return render(request, 'abonapp/peoples.html', { + 'peoples': peopleslist, + 'gid': gid + }) + + +@login_required +# @permission_required('abonapp.add_abongroup') +def addgroup(request): + warntext = '' + frm = forms.AbonGroupForm() + if request.method == 'POST': + frm = forms.AbonGroupForm(request.POST) + if frm.is_valid(): + frm.save() + return redirect('abongroup_list_link') + else: + warntext = u'Исправьте ошибки' + return render(request, 'abonapp/addGroup.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'form': frm, + 'warntext': warntext + }) + + +@login_required +def grouplist(request): + groups = models.AbonGroup.objects.annotate(usercount=Count('abon')) + + groups = mydefs.pag_mn(request, groups) + + return render(request, 'abonapp/group_list.html', { + 'groups': groups + }) + + +@login_required +def delgroup(request): + agd = mydefs.safe_int(request.GET.get('id')) + get_object_or_404(models.AbonGroup, id=agd).delete() + return mydefs.res_success(request, 'abongroup_list_link') + + +@login_required +# @permission_required('abonapp.add_abon') +# @permission_required('abonapp.change_abon') +def addabon(request, gid): + warntext = '' + frm = None + try: + grp = get_object_or_404(models.AbonGroup, id=gid) + if request.method == 'POST': + frm = forms.AbonForm(request.POST) + if frm.is_valid(): + prf = models.Abon() + prf.group = grp + prf.save_form(frm) + prf.save() + return redirect('pays_people_list_link', gid) + else: + warntext = u'Некоторые поля заполнены не правильно, проверте ещё раз' + + except IntegrityError, e: + warntext = "%s: %s" % (warntext, e) + + except models.LogicError as e: + warntext = e.value + + if not frm: + frm = forms.AbonForm(initial={ + 'ip_address': IpPoolItem.objects.get_free_ip(), + 'group': grp + }) + + return render(request, 'abonapp/addAbon.html', { + 'warntext': warntext, + 'csrf_token': csrf(request)['csrf_token'], + 'form': frm, + 'gid': gid + }) + + +@login_required +# @permission_required('abonapp.delete_abon') +# @permission_required('abonapp.delete_abongroup') +def delentity(request): + typ = request.GET.get('t') + uid = request.GET.get('id') + + if typ == 'a': + abon = get_object_or_404(models.Abon, id=uid) + abon.delete() + return mydefs.res_success(request, 'pays_people_list_link') + elif typ == 'g': + get_object_or_404(models.AbonGroup, id=uid).delete() + return mydefs.res_success(request, 'pays_people_list_link') + + +@login_required +def abonamount(request, gid, uid): + warntext='' + if request.method == 'POST': + abonid = mydefs.safe_int(request.POST.get('abonid')) + if abonid == int(uid): + amnt = mydefs.safe_float(request.POST.get('amount')) + abon = get_object_or_404(models.Abon, id=abonid) + abon.add_ballance(request.user, amnt) + abon.save() + return redirect('abonhome_link', gid=gid, uid=uid) + else: + warntext = u'Не правильно выбран абонент как цель для пополнения' + return render(request, 'abonapp/abonamount.html', { + 'abon_id': int(uid), + 'gid': gid, + 'warntext': warntext + }) + + +@login_required +def invoice_for_payment(request, gid, uid): + #abon = get_object_or_404(models.Abon, id=uid) + invoices = models.InvoiceForPayment.objects.filter(abon_id=uid) + invoices = mydefs.pag_mn(request, invoices) + return render(request, 'abonapp/invoiceForPayment.html', { + 'invoices': invoices, + 'gid': gid, + 'abon_id': uid + }) + + +@login_required +def pay_history(request, gid, uid): + #abon = get_object_or_404(models.Abon, id=uid) + pay_history = models.AbonLog.objects.filter(abon_id=uid).order_by('-id') + pay_history = mydefs.pag_mn(request, pay_history) + + return render(request, 'abonapp/payHistory.html', { + 'pay_history': pay_history, + 'gid': gid, + 'abon_id': uid + }) + + +@login_required +def abon_services(request, gid, uid): + #abon = get_object_or_404(models.Abon, id=uid) + abon_tarifs = models.AbonTariff.objects.filter(abon_id=uid).order_by('tariff_priority') + + return render(request, 'abonapp/services.html', { + 'abon_id': uid, + 'abon_tarifs': abon_tarifs, + 'active_abontariff_id': abon_tarifs[0].id if abon_tarifs.count() > 0 else None, + 'gid': gid + }) + + +@login_required +def abonhome(request, gid, uid): + abon = get_object_or_404(models.Abon, id=uid) + warntext = '' + ballance = abon.ballance + frm = None + init_frm_dat = { + 'username': abon.username, + 'fio': abon.fio, + 'ip_address': abon.ip_address or u'Не назначен', + 'telephone': abon.telephone, + 'group': abon.group, + 'address': abon.address, + 'is_active': abon.is_active + } + + try: + if request.method == 'POST': + frm = forms.AbonForm(request.POST) + if frm.is_valid(): + cd = frm.cleaned_data + abon.username = cd['username'] + abon.fio = cd['fio'] + + ip_address = abon.ip_address + abon.ip_address = get_object_or_404(IpPoolItem, ip=cd['ip_address']) + + abon.telephone = cd['telephone'] + abon.group = cd['group'] + abon.address = cd['address'] + abisactive = abon.is_active + abon.is_active = 1 if cd['is_active'] else 0 + abon.save() + + # Если включили то шлём событие от этом + if cd['is_active'] and not abisactive: + tc = get_TransmitterClientKlass()() + tc.signal_abon_enable(abon) + + # Если выключили + elif not cd['is_active'] and abisactive: + tc = get_TransmitterClientKlass()() + tc.signal_abon_disable(abon) + + # Если изменили инфу, важную для NAS то говорим NAS'у перечитать инфу об абоненте + if abon.ip_address != ip_address: + tc = get_TransmitterClientKlass()() + tc.signal_abon_refresh_info(abon) + + #return redirect('abonhome_link', gid, uid) + else: + warntext = u'Не правильные значения, проверте поля и попробуйте ещё' + else: + frm = forms.AbonForm(initial=init_frm_dat) + except IntegrityError, e: + warntext = u'Проверте введённые вами значения, скорее всего такой ip уже у кого-то есть. А вообще: %s' % e + frm = forms.AbonForm(initial=init_frm_dat) + + except Http404: + warntext = u'Ip адрес не найден в списке IP адресов' + frm = forms.AbonForm(initial=init_frm_dat) + + except NetExcept as e: + warntext = e.value + + return render(request, 'abonapp/editAbon.html', { + 'warntext': warntext, + 'form': frm or forms.AbonForm(initial=init_frm_dat), + 'abon_id': uid, + 'ballance': ballance, + 'gid': gid + }) + + +def terminal_pay(request): + username = request.GET.get('username') + amount = mydefs.safe_float(request.GET.get('amount')) + + kernel_user = get_object_or_404(UserProfile, username='kernel') + abon = get_object_or_404(models.Abon, username=username) + + abon.add_ballance(kernel_user, amount) + + abon.save() + return HttpResponse('ok') + + +@login_required +# @permission_required('abonapp.add_invoiceforpayment') +def add_invoice(request, gid, uid): + uid = mydefs.safe_int(uid) + abon = get_object_or_404(models.Abon, id=uid) + + if request.method == 'POST': + curr_amount = mydefs.safe_int(request.POST.get('curr_amount')) + comment = request.POST.get('comment') + + newinv = models.InvoiceForPayment() + newinv.abon = abon + newinv.amount = curr_amount + newinv.comment = comment + + if request.POST.get('status') == u'on': + newinv.status = True + + newinv.author = request.user + newinv.save() + return redirect('abonhome_link', gid=gid, uid=uid) + else: + return render(request, 'abonapp/addInvoice.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'abon': abon, + 'invcount': models.InvoiceForPayment.objects.filter(abon=abon).count(), + 'gid': gid + }) + + +@login_required +def buy_tariff(request, gid, uid): + warntext = '' + frm = None + try: + if request.method == 'POST': + frm = forms.BuyTariff(request.POST) + if frm.is_valid(): + cd = frm.cleaned_data + abon = get_object_or_404(models.Abon, id=uid) + abon.buy_tariff(cd['tariff'], request.user) + abon.save() + return redirect('abonhome_link', uid=uid) + else: + warntext = u'Что-то не так при покупке услуги, проверьте и попробуйте ещё' + else: + frm = forms.BuyTariff() + except models.LogicError as e: + warntext = e.value + + except NetExcept as e: + warntext = e.value + + return render(request, 'abonapp/buy_tariff.html', { + 'warntext': warntext, + 'form': frm or forms.BuyTariff(), + 'uid': uid, + 'gid': gid + }) + + +@login_required +def chpriority(request, gid, uid): + t = request.GET.get('t') + act = request.GET.get('a') + + current_abon_tariff = get_object_or_404(models.AbonTariff, id=t) + + if act == 'up': + current_abon_tariff.priority_up() + elif act == 'down': + current_abon_tariff.priority_down() + + return redirect('abonhome_link', gid=gid, uid=uid) + + +@login_required +def complete_service(request, gid, uid, srvid): + abtar = get_object_or_404(models.AbonTariff, id=srvid) + + if abtar.abon.id != int(uid): + return HttpResponse('

uid not equal uid from service

') + + try: + if request.method == 'POST': + # досрочно завершаем услугу + try: + abtar.finish_and_activate_next_tariff(request.user) + # завершаем текущую услугу. + abtar.delete() + + except models.LogicError: + # Значит у абонента нет следующих услуг. Сигналим о закрытии инета в NAS + tc = get_TransmitterClientKlass()() + tc.signal_abon_close_inet(abtar.abon) + + # Переупорядочиваем приоритеты + models.AbonTariff.objects.update_priorities(abtar.abon) + + return redirect('abonhome_link', gid, uid) + + next_tariff = models.AbonTariff.objects.filter( + abon=abtar.abon, + tariff_priority__gt=abtar.tariff_priority + )[:1] + + if not abtar.time_start: + abtar.time_start = timezone.now() + abtar.save() + + time_use = timezone.now() - abtar.time_start + time_use = { + 'days': time_use.days, + 'hours': time_use.seconds / 3600, + 'minutes': time_use.seconds / 60 % 60 + } + return render(request, 'abonapp/complete_service.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'abtar': abtar, + 'uid': uid, + 'next_tariff': next_tariff[0] if next_tariff.count() > 0 else None, + 'time_use': time_use, + 'gid': gid + }) + + except models.LogicError as e: + warntext = e.value + + except NetExcept as e: + warntext = e.value + + return render(request, 'abonapp/complete_service.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'abtar': abtar, + 'uid': uid, + 'warntext': warntext + }) + + +@login_required +def log_page(request): + logs = models.AbonLog.objects.all() + + logs = mydefs.pag_mn(request, logs) + + return render(request, 'abonapp/log.html', { + 'logs': logs + }) + + +# API's + +def abons(request): + ablist = map(lambda abn: { + 'id': abn.id, + 'tarif_id': abn.active_tariff().id if abn.active_tariff() else 0, + 'ip': abn.ip_address.int_ip(), + 'is_active': abn.is_active + }, models.Abon.objects.all()) + + tarlist = map(lambda trf: { + 'id': trf.id, + 'speedIn': trf.speedIn, + 'speedOut': trf.speedOut + }, Tariff.objects.all()) + + data = { + 'subscribers': ablist, + 'tariffs': tarlist + } + del ablist, tarlist + return HttpResponse(dumps(data)) diff --git a/accounts_app/__init__.py b/accounts_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts_app/admin.py b/accounts_app/admin.py new file mode 100644 index 0000000..a98979a --- /dev/null +++ b/accounts_app/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +from models import UserProfile + +admin.site.register(UserProfile) diff --git a/accounts_app/migrations/0001_initial.py b/accounts_app/migrations/0001_initial.py new file mode 100644 index 0000000..a588f8f --- /dev/null +++ b/accounts_app/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0007_alter_validators_add_error_messages'), + ('photo_app', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='UserProfile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(max_length=127, unique=True)), + ('fio', models.CharField(max_length=256)), + ('birth_day', models.DateField(auto_now_add=True)), + ('is_active', models.BooleanField(default=True)), + ('is_admin', models.BooleanField(default=False)), + ('telephone', models.CharField(max_length=16, unique=True, validators=[django.core.validators.RegexValidator(b'^\\+[7,8,9,3]\\d{10,11}$')], verbose_name=b'Telephone number')), + ('skype', models.CharField(blank=True, max_length=20)), + ('avatar', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='photo_app.Photo')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/accounts_app/migrations/__init__.py b/accounts_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts_app/models.py b/accounts_app/models.py new file mode 100644 index 0000000..8c77cd1 --- /dev/null +++ b/accounts_app/models.py @@ -0,0 +1,107 @@ +# -*- coding:utf-8 -*- +from django.db import models +from djing.settings import DEFAULT_PICTURE +from photo_app.models import Photo +from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin +from django.core.validators import RegexValidator + + +class MyUserManager(BaseUserManager): + + def create_user(self, telephone, username, password=None): + """ + Creates and saves a User with the given email, date of + birth and password. + """ + if not telephone: + raise ValueError('Users must have an telephone number') + + user = self.model( + telephone=telephone, + username=username, + ) + + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, telephone, username, password): + """ + Creates and saves a superuser with the given email, date of + birth and password. + """ + user = self.create_user(telephone, + password=password, + username=username + ) + user.is_admin = True + user.is_superuser = True + user.save(using=self._db) + return user + + +class UserProfile(AbstractBaseUser, PermissionsMixin): + username = models.CharField(max_length=127, unique=True) + fio = models.CharField(max_length=256) + birth_day = models.DateField(auto_now_add=True) + is_active = models.BooleanField(default=True) + is_admin = models.BooleanField(default=False) + telephone = models.CharField( + max_length=16, + verbose_name='Telephone number', + unique=True, + validators=[RegexValidator(r'^\+[7,8,9,3]\d{10,11}$')] + ) + skype = models.CharField(max_length=20, blank=True) + avatar = models.ForeignKey(Photo, null=True, blank=True) + + USERNAME_FIELD = 'username' + REQUIRED_FIELDS = ['telephone'] + + def get_full_name(self): + if self.fio: + return "%s: %s" % (self.username, self.fio) + else: + return self.username + + def get_short_name(self): + return self.username or self.telephone + + + # Use UserManager to get the create_user method, etc. + objects = MyUserManager() + + @property + def is_staff(self): + "Is the user a member of staff?" + # Simplest possible answer: All admins are staff + return self.is_admin + + def get_big_ava(self): + if self.avatar: + return self.avatar.big() + else: + return DEFAULT_PICTURE + + def get_min_ava(self): + if self.avatar: + return self.avatar.min() + else: + return DEFAULT_PICTURE + + def __unicode__(self): + return self.username + + +#from django.db.models.signals import post_save + + +'''def create_custom_user(sender, instance, created, **kwargs): + if created: + values = {} + for field in sender._meta.local_fields: + values[field.attname] = getattr(instance, field.attname) + user = UserProfile(**values) + user.save()''' + +#post_save.connect(create_custom_user, User) diff --git a/accounts_app/tests.py b/accounts_app/tests.py new file mode 100644 index 0000000..501deb7 --- /dev/null +++ b/accounts_app/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/accounts_app/urls.py b/accounts_app/urls.py new file mode 100644 index 0000000..f683677 --- /dev/null +++ b/accounts_app/urls.py @@ -0,0 +1,27 @@ +# -*- coding:utf-8 -*- +from django.conf.urls import url +import views + +urlpatterns = [ + + url(r'^login/', views.to_signin, name='login_link'), + url(r'^logout/', views.sign_out, name='logout_link'), + + url(r'^me$', views.profile_show, name='profile'), + + url(r'^$', views.acc_list, name='accounts_list'), + + url(r'^add$', views.create_profile, name='create_profile_link'), + + url(r'^settings$', views.ch_info, name='settings_chinfo_link'), + url(r'^settings/change_ava$', views.ch_ava, name='settings_chava_link'), + + url(r'^(?P\d+)$', views.profile_show, name='other_profile'), + url(r'^(?P\d+)/perms$', views.perms, name='profile_perms_link'), + url(r'^(?P\d+)/chgroup$', views.chgroup, name='profile_chgroup_link'), + url(r'^(?P\d+)/del$', views.delete_profile, name='delete_profile_link'), + + url(r'^group/$', views.groups, name='profile_groups_list'), + url(r'^group/(?P\d+)$', views.group, name='profile_group_link') + +] \ No newline at end of file diff --git a/accounts_app/views.py b/accounts_app/views.py new file mode 100644 index 0000000..17136dc --- /dev/null +++ b/accounts_app/views.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +from django.contrib.auth.decorators import login_required#, permission_required +from django.contrib.auth import authenticate, login, logout +from photo_app.models import Photo +from django.core.urlresolvers import NoReverseMatch +from models import UserProfile +from django.shortcuts import render, redirect, get_object_or_404 +from django.template.context_processors import csrf +from django.http import Http404 +from django.contrib.auth.models import Group, Permission +import mydefs + + +@login_required +def home(request): + return redirect('profile') + + +def to_signin(request): + nextl = request.GET.get('next') + + try: + if request.POST: + auser = authenticate(username=request.POST.get('login'), password=request.POST.get('password')) + if auser: + login(request, auser) + if nextl == 'None' or nextl == None or nextl == '': + return redirect('profile') + else: + return redirect(nextl) + else: + return render(request, 'accounts/login.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'next': nextl, + 'errmsg': u'Неправильный логин или пароль, попробуйте ещё раз' + }) + except NoReverseMatch: + raise Http404(u"Destination page does not exist") + return render(request, 'accounts/login.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'next': nextl + }) + + +def sign_out(request): + logout(request) + return redirect('login_link') + + +@login_required +def profile_show(request, id=0): + id = mydefs.safe_int(id) + + if id == 0: + usr = request.user + else: + usr = get_object_or_404(UserProfile, id=id) + + if request.method == 'POST': + usr.username = request.POST.get('username') + usr.fio = request.POST.get('fio') + usr.telephone = request.POST.get('telephone') + usr.is_active = request.POST.get('stat') + usr.is_admin = request.POST.get('is_admin') + usr.save() + return redirect('other_profile', id=id) + + return render(request, 'accounts/index.html', { + 'uid': id, + 'userprofile': usr + }) + + +@login_required +def chgroup(request, uid): + usr = get_object_or_404(UserProfile, id=uid) + usergroups = usr.groups.all() + othergroups = filter(lambda g: g not in usergroups, Group.objects.all()) + #Group.objects.exclude(user__in=usergroups) + + return render(request, 'accounts/profile_chgroup.html', { + 'uid': uid, + 'userprofile': usr, + 'allgroups': othergroups, + 'usergroups': usergroups + }) + + +@login_required +def ch_ava(request): + if request.method == 'POST': + user = request.user + if user.avatar: + user.avatar.delete() + photo = Photo() + photo.image = request.FILES.get('avatar') + photo.save() + user.avatar = photo + user.save() + request.user = user + + return render(request, 'accounts/settings/ch_info.html', { + 'user': request.user + }) + + +@login_required +def ch_info(request): + warntext='' + if request.method == 'POST': + user = request.user + user.username = request.POST.get('username') + user.fio = request.POST.get('fio') + user.email = request.POST.get('email') + user.telephone = request.POST.get('telephone') + user.skype = request.POST.get('skype') + + psw = request.POST.get('oldpasswd') + if psw != '': + if user.check_password(psw): + newpasswd = request.POST.get('newpasswd') + user.set_password(newpasswd) + else: + warntext = u'Неправильный пароль' + user.save() + request.user = user + + return render(request, 'accounts/settings/ch_info.html', { + 'user': request.user, + 'warntext': warntext + }) + + +@login_required +##@permission_required('accounts_app.add_userprofile') +def create_profile(request): + if request.method == 'POST': + username = request.POST.get('username') + + user = UserProfile() + user.username = username + user.fio = request.POST.get('fio') + user.email = request.POST.get('email') + user.telephone = request.POST.get('telephone') + user.skype = request.POST.get('skype') + user.is_admin = True + + passwd = request.POST.get('passwd') + conpasswd = request.POST.get('conpasswd') + if not passwd: + return render(request, 'accounts/create_acc.html',{ + 'warntext': u'Забыли указать пароль для нового аккаунта', + 'csrf_token': csrf(request)['csrf_token'], + 'newuser': user + }) + if not conpasswd: + return render(request, 'accounts/create_acc.html',{ + 'warntext': u'Забыли повторить пароль для нового аккаунта', + 'csrf_token': csrf(request)['csrf_token'], + 'newuser': user + }) + + if passwd == conpasswd: + user_qs = UserProfile.objects.filter(username=username)[:1] + if user_qs.count() == 0: + user.set_password(passwd) + user.save() + return redirect('accounts_list') + else: + return render(request, 'accounts/create_acc.html',{ + 'warntext': u'Пользователь с таким именем уже есть', + 'csrf_token': csrf(request)['csrf_token'], + 'newuser': user + }) + else: + return render(request, 'accounts/create_acc.html',{ + 'warntext': u'Пароли не совпадают, попробуйте ещё раз', + 'csrf_token': csrf(request)['csrf_token'], + 'newuser': user + }) + return render(request, 'accounts/create_acc.html', {'csrf_token': csrf(request)['csrf_token'],}) + + +@login_required +#@permission_required('accounts_app.del_userprofile') +def delete_profile(request, uid): + prf = get_object_or_404(UserProfile, id=uid) + prf.delete() + return redirect('accounts_list') + + +@login_required +def acc_list(request): + users = UserProfile.objects.filter(is_admin=True) + + users = mydefs.pag_mn(request, users) + + return render(request, 'accounts/acc_list.html', { + 'users': users + }) + + +@login_required +#@permission_required('accounts_app.change_userprofile') +def perms(request, id): + ingroups = filter(lambda x: x[0] == 'ingroups', request.POST.lists())[0][1] + id = mydefs.safe_int(id) + + profile = get_object_or_404(UserProfile, id=id) + profile.groups.clear() + + for group_id in ingroups: + gid = mydefs.safe_int(group_id) + profile.groups.add(gid) + profile.save() + + return redirect('other_profile', id) + + +@login_required +def groups(request): + grps = Group.objects.all() + + grps = mydefs.pag_mn(request, grps) + + return render(request, 'accounts/group_list.html', { + 'groups': grps + }) + + +@login_required +#@permission_required('auth.change_group') +def group(request, id): + id = mydefs.safe_int(id) + grp = get_object_or_404(Group, id=id) + + if request.method == 'POST': + group_rights = filter(lambda x: x[0] == 'group_rights', request.POST.lists())[0][1] + grp.permissions.clear() + for grr in group_rights: + rid = mydefs.safe_int(grr) + grp.permissions.add(rid) + grp.save() + return redirect('profile_group_link', id=id) + + grp_rights = grp.permissions.all() + all_rights = Permission.objects.exclude(group=grp) + + #prms = Permission.objects.all() + #for pr in prms: + # print u"%s | %s" % (pr.name, pr.codename) + + return render(request, 'accounts/group.html', { + 'csrf_token': csrf(request)['csrf_token'], + 'group': grp, + 'all_rights': all_rights, + 'grp_rights': grp_rights + }) diff --git a/agent.py b/agent.py new file mode 100644 index 0000000..82803fd --- /dev/null +++ b/agent.py @@ -0,0 +1,12 @@ +#!/bin/env python + +import os +from agent import main + + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") + + while True: + main(debug=True) + print "Exit from main, reload..." diff --git a/agent/__init__.py b/agent/__init__.py new file mode 100644 index 0000000..380a4e5 --- /dev/null +++ b/agent/__init__.py @@ -0,0 +1,3 @@ +from models import Abonent, Tariff +from main import main +from sslTransmitter import get_TransmitterClientKlass, NetExcept diff --git a/agent/db.py b/agent/db.py new file mode 100644 index 0000000..7416115 --- /dev/null +++ b/agent/db.py @@ -0,0 +1,27 @@ +# -*- coding:utf-8 -*- +import requests +from json import loads +from models import deserialize_tariffs, deserialize_abonents +import settings + + +def load_from_db(): + r = requests.get('%s://%s:%d/abons/api/abons' % ( + 'https' if settings.IS_USE_SSL else 'http', + settings.SERVER_IP, + settings.SERVER_PORT + ), verify=False) + try: + user_data = loads(r.text) + del r + # Получаем тарифы + tariffs = deserialize_tariffs(user_data) + + # Получаем пользователей + abons = deserialize_abonents(user_data, tariffs) + + return abons, tariffs + + except ValueError as e: + print 'Error:', e, r.text + return diff --git a/agent/firewall.py b/agent/firewall.py new file mode 100644 index 0000000..c9b2379 --- /dev/null +++ b/agent/firewall.py @@ -0,0 +1,48 @@ +# -*- coding:utf-8 -*- + + +class FirewallManager(object): + + f = r'/sbin/ipfw -q' + + # вызывает комманду shell + def exec_cmd(self, cmd): + print cmd + #os.execv(cmd, ['']) + + # ставит заглушку на абонента + def set_cap(self, user): + pass + + # Открывает доступ в интернет + def open_inet_door(self, user): + if not user.tariff: + print u'WARNING: User does not have a tariff' + return + cmd = r"%s table 12 add %s/32 %d && %s table 13 add %s/32 %d" % ( + self.f, user.ip_str(), user.tariff.tid, + self.f, user.ip_str(), user.tariff.tid+1000 + ) + self.exec_cmd(cmd) + + # Закрывает доступ в интернет + def close_inet_door(self, user): + cmd = r"%s table 12 del %s/32 && %s table 13 del %s/32" % ( + self.f, user.ip_str(), + self.f, user.ip_str() + ) + self.exec_cmd(cmd) + + # Создаёт тариф (пайпы, режущие скорость + def make_tariff(self, tariff): + cmd = r"make ipfw tariff :)" + self.exec_cmd(cmd) + + # Убирает тариф из фаервола + def destroy_tariff(self, tariff): + cmd = r"destroy ipfw tariff :)" + self.exec_cmd(cmd) + + def reset(self): + cmd = r"%s -f flush && %s table all flush" % (self.f, self.f) + self.exec_cmd(cmd) diff --git a/agent/ipfw.sh b/agent/ipfw.sh new file mode 100644 index 0000000..4e9c550 --- /dev/null +++ b/agent/ipfw.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +######################################################### +# ВАЖНО! Биллинг пока ограничен количеством тарифных планов +# не больше 1000 +######################################################### + + + + +f="/sbin/ipfw -q" + +lan=em1 # Clients +wan=em0 # Inet + + +${f} -f flush +${f} table all flush + +sysctl net.inet.ip.fw.one_pass=0 + +# dns +${f} table 100 add 8.8.8.8 # google public dns +${f} table 100 add 8.8.4.4 # google public dns2 +${f} table 100 add 77.88.8.8 # yandex base dns +${f} table 100 add 77.88.8.1 # yandex base dns2 + + +# ssh access +${f} add 50 allow tcp from any to me 22 +${f} add 51 allow tcp from me 22 to any + + +# loopback +${f} add 100 allow ip from any to any via lo0 + + +# в таблице 100 приоритетный траффик. +# это dns, платёжки.. +${f} add 500 allow ip from table\(100\) to any +${f} add 501 allow ip from any to table\(100\) + + + +# в таблице 10 разрешённые пользователи +# блокируем трафик всем кто не в ней +${f} add 1001 deny ip from not table\(10\) to any via $wan + +# если у абонентов есть внешние адреса (не через NAT) +#${f} add 1101 deny ip from any to not table\(10\) via $wan + + + + +# по 2 пайпа на тарифный план, на вход и выход +#${f} pipe 212 config bw 1152Kbit/s mask src-ip 0xffffffff noerror +#${f} pipe 213 config bw 1152Kbit/s mask dst-ip 0xffffffff noerror + +# добавляем пайпы в таблицу +${f} add 2001 pipe 212 ip from table\(10\) to any via $wan +${f} add 2002 pipe 213 ip from any to table\(11\) via $wan + +#---------------------- +# так добавляем абонентов чтоб резать скорость, надо указать номер их пайпа +#${f} table 10 add 10.0.172.138/32 212 +#${f} table 11 add 10.0.172.138/32 2212 +#---------------------- + + + + +# тут будем поджимать пользователей когда не хватает канала diff --git a/agent/main.py b/agent/main.py new file mode 100644 index 0000000..5d049ea --- /dev/null +++ b/agent/main.py @@ -0,0 +1,120 @@ +# -*- coding:utf-8 -*- +from sys import stdout +from db import load_from_db +from firewall import FirewallManager +from time import sleep +from sslTransmitter import TransmitServer + + +def filter_user_by_id(users, uid): + usrs = filter(lambda usr: usr.uid == uid, users) + if len(usrs) > 0: + return usrs[0] + else: + return + + +def main(debug=False): + users, tariffs = load_from_db() + frw = FirewallManager() + frw.reset() + + # Инициализация абонентов + if debug: + print u'Инициализация...' + # Открываем доступ в инет тем кто активен и у кого подключён тариф + for usr in filter(lambda usr: usr.is_active, users): + + # Доступ в интернет происходит по наличию подключённого тарифа + # если тарифа нет, то и инета нет + if usr.tariff: + # Открываем доступ в инет + frw.open_inet_door(usr) + + # Слушем в отдельном процессе сеть на предмет событий + ts = TransmitServer('127.0.0.1', 2134) + ts.start() + + if debug: + print u"Загружено %d абонентов" % len(users) + + while True: + + # Загружаем события для абонентов из сети (список объектов EventNAS из models) + events = ts.get_data() + # Проходим по появившимся событиям + for event in events: + #event.toa + #event.id + #event.dt + + # Смотрим тип события + toa = int(event.toa) + if toa == 0: continue + + # Включаем абонента + elif toa == 1: + usr = filter_user_by_id(users, event.id) + # Открываем доступ в инет + frw.open_inet_door(usr) + + # Выключаем абонента + elif toa == 2: + usr = filter_user_by_id(users, event.id) + # Выключаем интернет + frw.close_inet_door(usr) + + # Сообщение на заглушку + elif toa == 3: + usr = filter_user_by_id(users, event.id) + # Ставим заглушку + frw.set_cap(usr) + # Выключаем интернет + frw.close_inet_door(usr) + + # Открываем доступ в инет + elif toa == 4: + usr = filter_user_by_id(users, event.id) + frw.close_inet_door(usr) + frw.open_inet_door(usr) + + # Закрываем доступ в инет + elif toa == 5: + usr = filter_user_by_id(users, event.id) + frw.close_inet_door(usr) + + elif toa == 6: + # Сигнал на перезагрузку + # Выходим из main, выше она в цикле запустится ещё раз + return + + elif toa == 7: + # Сигнал о том что инфа об абоненте изменилась, надо перечитать + usr = filter_user_by_id(users, event.id) + usr.deserialize(event.dt, tariffs) + # если абонент активен, и куплен и активирован тариф то можно и в инет + if usr.is_active and usr.tariff is not None: + frw.close_inet_door(usr) + frw.open_inet_door(usr) + + elif toa == 8: + # Сигнал об изменении данных в тарифе + tariff = filter(lambda trf: trf.tid == event.id, tariffs) + if len(tariff) > 0: + tariff = tariff[0] + tariff.deserialize(event.dt) + + # Пересоздаём тариф + frw.destroy_tariff(tariff) + frw.make_tariff(tariff) + else: + print 'WARNING: не найден тариф для которого сигнал на изменение данных, пробуем перезагрузиться' + return + + # Очищаем очередь событий + ts.clear() + + # ждём время между итерациями проверки 10 сек... + sleep(10) + stdout.write('.') + stdout.flush() diff --git a/agent/models.py b/agent/models.py new file mode 100644 index 0000000..6b8d675 --- /dev/null +++ b/agent/models.py @@ -0,0 +1,143 @@ +# -*- coding:utf-8 -*- +import socket +import struct +from json import loads, dumps +from abc import ABCMeta, abstractmethod + + +class Serializer(object): + __metaclass__ = ABCMeta + + @abstractmethod + def _serializable_obj(self): + """Вернуть словарь для сериализации""" + + def serialize(self): + return dumps(self._serializable_obj()) + + @abstractmethod + def deserialize(self, *args): + """Надо обязательно этот метод реализовать, он много где используется. + Из JSON создать объект класса где реализуется метод""" + + +def serialize_tariffs(tariffs): + dt = map(lambda trf: trf._serializable_obj(), tariffs) + return dumps({'tariffs': dt}) + + +def deserialize_tariffs(dat): + dat = loads(dat) if type(dat) == str else dat + # Распаковываем из JSON массива dat['tariffs'] объекты через метод deserialize + return map(lambda tariff: Tariff().deserialize(tariff), dat['tariffs']) + + +def serialize_abonents(abonents): + dt = map(lambda abn: abn._serializable_obj(), abonents) + return dumps({'subscribers': dt}) + + +def deserialize_abonents(dat, tariffs): + dat = loads(dat) if type(dat) == str else dat + # Распаковываем из JSON массива dat['subscribers'] объекты через метод deserialize + return map(lambda abon: Abonent().deserialize(abon, tariffs), dat['subscribers']) + + +class Tariff(Serializer): + tid = 0 + speedIn = 0.0 + speedOut = 0.0 + + def __init__(self, tariff_id=None, speed_in=None, speed_out=None): + self.tid = tariff_id + self.speedOut = speed_out + self.speedIn = speed_in + + def is_active(self): + """возвращает активность тарифа. Если он не активен то пропустить""" + return True + + def _serializable_obj(self): + return { + 'id': self.tid, + 'speedIn': self.speedIn, + 'speedOut': self.speedOut + } + + def deserialize(self, dump): + inf = loads(dump) if type(dump) == str else dump + self.speedIn = float(inf['speedIn']) + self.speedOut = float(inf['speedOut']) + self.tid = int(inf['id']) + return self + + +class Abonent(Serializer): + uid = 0 + tariff = Tariff() + ip = 0xffffffff + + # Включён-ли абонент + is_active = True + + def __init__(self, uid=None, ip=None, tariff=None): + self.ip = ip + self.uid = uid + self.tariff = tariff + + def ip_str(self): + # int2ip, Example out '127.0.0.1' + return socket.inet_ntoa(struct.pack("!I", self.ip)) + + def _serializable_obj(self): + return { + 'id': self.uid, + 'is_active': self.is_active, + 'ip': self.ip, + 'tarif_id': self.tariff.tid if self.tariff else 0 + } + + def deserialize(self, dump, tariffs): + inf = loads(dump) if type(dump) == str else dump + self.uid = int(inf['id']) + self.is_active = bool(inf['is_active']) + self.ip = int(inf['ip']) + + tarif_id = int(inf['tarif_id']) + dbtrf = filter(lambda trf: trf.tid == tarif_id, tariffs) + if len(dbtrf) > 0: + self.tariff = dbtrf[0] + else: + self.tariff = None + return self + + +class EventNAS(Serializer): + + # Type Of Action + toa = 0 + + # id of object + id = 0 + + # extended data + dt = object() + + def __init__(self, type_action=None, obj_id=None, ext_data=None): + self.toa = type_action + self.id = obj_id + self.dt = ext_data + + def _serializable_obj(self): + if self.dt: + return {'toa': self.toa, 'id': self.id, 'dt': self.dt} + else: + return {'toa': self.toa, 'id': self.id} + + def deserialize(self, dump): + print dump + inf = loads(dump) if type(dump) == str else dump + self.toa = int(inf['toa']) + self.id = int(inf['id']) + self.dt = inf.get('dt') + return self diff --git a/agent/netflow/__init__.py b/agent/netflow/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/agent/netflow/netflow_handler.py b/agent/netflow/netflow_handler.py new file mode 100755 index 0000000..a59e00c --- /dev/null +++ b/agent/netflow/netflow_handler.py @@ -0,0 +1,49 @@ +#!/bin/env python2 +import sys +import socket +import struct +from re import sub + + +def ip2int(strip): + return struct.unpack("!I", socket.inet_aton(strip))[0] + + +def convert(query): + dat = sub(r'\s+', ' ', query.strip('\n')).split(' ') + + if len(dat) == 1: + return + + src_ip = ip2int(dat[0]) + dst_ip = ip2int(dat[1]) + proto = int(dat[2]) + src_port = int(dat[3]) + dst_port = int(dat[4]) + octets = int(dat[5]) + packets = int(dat[6]) + + sql = ",(%s,%s,%d,%d,%d,%d,%d)" % ( + hex(src_ip), hex(dst_ip), proto, src_port, dst_port, octets, packets + ) + return sql + + +if __name__=='__main__': + f=sys.stdin + print("INSERT INTO flowstat(`src_ip`, `dst_ip`, `proto`, `src_port`, `dst_port`, `octets`, `packets`) VALUES") + + # always none + f.readline() + + # first line + rs = convert(f.readline()) + # without first comma + print(rs[1:]) + + while True: + rs = convert(f.readline()) + if not rs: + break + print(rs) + f.close() diff --git a/agent/netflow/netflow_handler.sh b/agent/netflow/netflow_handler.sh new file mode 100755 index 0000000..3c1d83f --- /dev/null +++ b/agent/netflow/netflow_handler.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +DUMP_DIR="/var/db/flows" + +DUMP_FILE="$DUMP_DIR/$1" +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin +CUR_DIR=`dirname $0` + + +flow-print -f3 < ${DUMP_FILE} | ${CUR_DIR}/netflow_handler.py \ +| mysql -uroot -p jungagent --password=ps diff --git a/agent/netflow/start_netflow.sh b/agent/netflow/start_netflow.sh new file mode 100755 index 0000000..d7fafba --- /dev/null +++ b/agent/netflow/start_netflow.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/home/dn/bin + +flow-capture -R /home/dn/bin/netflow_handler.py -w /var/db/flows -n1 -N0 0.0.0.0/0.0.0.0/8888 + +softflowd -v 5 -i wlp3s0 -n 127.0.0.1:8888 diff --git a/agent/settings.py b/agent/settings.py new file mode 100644 index 0000000..f09110c --- /dev/null +++ b/agent/settings.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + + +# Agent ip and port +SELF_IP = '127.0.0.1' +SELF_PORT = 2134 + +# Main server ip and port +SERVER_IP = '127.0.0.1' +SERVER_PORT = 8000 #8443 + +# Certificates +CERTFILE = "/etc/ssl/server.crt" +KEYFILE = "/etc/ssl/server.key" + +# Использовать-ли при передаче инфы между NAS и основным сервером SSL +IS_USE_SSL = False diff --git a/agent/sslTransmitter.py b/agent/sslTransmitter.py new file mode 100644 index 0000000..f25c029 --- /dev/null +++ b/agent/sslTransmitter.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- +import ssl +import socket +from multiprocessing import Process, Manager#, Lock +import settings +from models import EventNAS, Abonent, Tariff + + +class NetExcept(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + + +class SSLTransmitterServer(object): + bindsocket = None + + def connect(self, ip, port): + bindsocket = socket.socket() + bindsocket.bind((ip, port)) + bindsocket.listen(5) + self.bindsocket = bindsocket + + def _on_data_recive(self, v, data): + print "do_something:", data + #with lock: + v.append(EventNAS().deserialize(data)) + return False + + def _deal_with_client(self, connstream, v): + data = connstream.read() + while data: + if not self._on_data_recive(v, data): + break + data = connstream.read() + + def process(self, v): + while True: + newsocket, fromaddr = self.bindsocket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=settings.CERTFILE, + keyfile=settings.KEYFILE) + try: + self._deal_with_client(connstream, v) + finally: + connstream.shutdown(socket.SHUT_RDWR) + connstream.close() + + +class PlainTransmitterServer(SSLTransmitterServer): + + def process(self, v): + while True: + newsocket, fromaddr = self.bindsocket.accept() + dat = newsocket.recv(0xffff) + if not dat: + break + self._on_data_recive(v, dat) + + +# Декоратор переводит классы абонента базы к объекту агента если надо. +# abonapp.models.Abon -> agent.Abonent +def agent_abon_typer(fn): + def wrapped(self, abon): + if isinstance(abon, Abonent): + fn(self, abon) + else: + abn = Abonent( + abon.id, + abon.ip_address.int_ip() if abon.ip_address else 0, + abon.active_tariff() + ) + fn(self, abn) + return wrapped + + +# Декоратор переводит классы тарифа базы к объекту агента если надо. +# tariff_app.models.Tariff -> agent.Tariff +def agent_tarif_typer(fn): + def wrapped(self, tariff): + if isinstance(tariff, Tariff): + fn(self, tariff) + else: + trf = Tariff( + tariff.id, + tariff.speedIn, + tariff.speedOut + ) + fn(self, trf) + return wrapped + + +class SSLTransmitterClient(object): + s = None + + def __init__(self, ip=None, port=None): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # Require a certificate from the server. We used a self-signed certificate + # so here ca_certs must be the server certificate itself. + self.s = ssl.wrap_socket(s, + ca_certs=settings.CERTFILE, + cert_reqs=ssl.CERT_REQUIRED) + self.s.connect(( + ip or settings.SELF_IP, + port or settings.SELF_PORT + )) + except socket.error: + raise NetExcept(u'Ошибка подключения к NAS агенту') + + def write(self, d): + self.s.write(d) + + @agent_abon_typer + def signal_abon_enable(self, abon): + self.write( + EventNAS(1, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_abon_disable(self, abon): + self.write( + EventNAS(2, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_abon_set_cap(self, abon): + self.write( + EventNAS(3, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_abon_open_inet(self, abon): + self.write( + EventNAS(4, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_abon_close_inet(self, abon): + self.write( + EventNAS(5, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_agent_reboot(self, abon): + self.write( + EventNAS(6, abon.uid).serialize() + ) + + @agent_abon_typer + def signal_abon_refresh_info(self, abon): + self.write( + EventNAS(7, abon.uid, abon._serializable_obj()).serialize() + ) + + @agent_tarif_typer + def signal_tarif_refresh_info(self, tariff): + self.write( + EventNAS(8, tariff.tid, tariff._serializable_obj()).serialize() + ) + + def __del__(self): + self.s.close() + + +class PlainTransmitterClient(SSLTransmitterClient): + + def __init__(self, ip=None, port=None): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect(( + ip or settings.SELF_IP, + port or settings.SELF_PORT + )) + self.s = s + except socket.error: + raise NetExcept(u'Ошибка подключения к NAS агенту') + + def write(self, d): + self.s.send(d) + + +def get_TransmitterClientKlass(): + if settings.IS_USE_SSL: + return SSLTransmitterClient + else: + return PlainTransmitterClient + + +def get_TransmitterServerKlass(): + if settings.IS_USE_SSL: + return SSLTransmitterServer + else: + return PlainTransmitterServer + + +def proc_entrypoint(obj, v, lock, ip, port): + srv = get_TransmitterServerKlass()() + srv.connect(ip, port) + srv.process(v) + + +class TransmitServer(object): + + def __init__(self, ip, port): + mngr = Manager() + self.v = mngr.list() + #self.lock = Lock() + self.p = Process(target=proc_entrypoint, args=(self, self.v, None, ip, port))#self.lock)) + + def get_data(self): + if len(self.v) > 0: + return list(self.v) + else: + return [] + + def clear(self): + del self.v[:] + + def start(self): + self.p.start() + + def __del__(self): + self.p.terminate() diff --git a/agent/tariff.py b/agent/tariff.py new file mode 100644 index 0000000..380474e --- /dev/null +++ b/agent/tariff.py @@ -0,0 +1 @@ +# -*- coding:utf-8 -*- diff --git a/bugs.txt b/bugs.txt new file mode 100644 index 0000000..1f78199 --- /dev/null +++ b/bugs.txt @@ -0,0 +1,11 @@ +- (GUI) Иконки возле кнопок не настроены, натыканы случайно + +Остановился на управлении купленными услугами(тарифами): + + нужен порядок выполнения очереди тарифов (модель зделана) + + Управление приоритетом тарифов (порядком выполнения) + - удаление ещё не активных купленных тарифов + + отображение и выделение активного тарифа + +Нужно на каждое изменение данных об абоненте слать сигнал об этом на NAS + +Фаервол допилить, там с пайпами не понятно, не знаю принцип действия diff --git a/cron.py b/cron.py new file mode 100644 index 0000000..1645f74 --- /dev/null +++ b/cron.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os +import django + + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") + django.setup() + from abonapp.models import Abon, AbonTariff + + users = Abon.objects.all() + + for usr in users: + + usr.activate_next_tariff() + + AbonTariff.objects.update_priorities(usr) diff --git a/devapp/__init__.py b/devapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/devapp/admin.py b/devapp/admin.py new file mode 100644 index 0000000..19dff8d --- /dev/null +++ b/devapp/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +import models + +admin.site.register(models.Device) +admin.site.register(models.Port) +admin.site.register(models.PortStates) diff --git a/devapp/apps.py b/devapp/apps.py new file mode 100644 index 0000000..1ccacdf --- /dev/null +++ b/devapp/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class DevappConfig(AppConfig): + name = 'devapp' diff --git a/devapp/base_intr.py b/devapp/base_intr.py new file mode 100644 index 0000000..c0e9bac --- /dev/null +++ b/devapp/base_intr.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +from abc import ABCMeta, abstractmethod +from netsnmp import Session, VarList, Varbind + + +class DevBase(object): + __metaclass__ = ABCMeta + + @staticmethod + def description(): + """Возвращает текстовое описание""" + + @abstractmethod + def reboot(self): + """Перезагружает устройство""" + + @abstractmethod + def get_statistics(self): + """Получаем статистику""" + + @abstractmethod + def get_vlan(self): + """Получаем инфу о VLAN""" + + @abstractmethod + def get_ports(self): + """Получаем инфу о портах""" + + @abstractmethod + def toggle_port(self, port_num): + pass + + +class Port(object): + + def __init__(self, num, name, status, mac, speed): + self.num = int(num) + self.nm = name + self.st = status + self._mac = mac + self.sp = speed + + def mac(self): + m = self._mac + return "%x:%x:%x:%x:%x:%x" % (ord(m[0]), ord(m[1]), ord(m[2]), ord(m[3]), ord(m[4]), ord(m[5])) + + +class SNMPBaseWorker(object): + ses = None + + oids = { + 'reboot': '.1.3.6.1.4.1.2021.8.1.101.1', + 'get_ports': { + 'names': 'IF-MIB::ifDescr', + 'stats': 'IF-MIB::ifAdminStatus', + 'macs': 'IF-MIB::ifPhysAddress', + 'speeds': 'IF-MIB::ifHighSpeed' + }, + 'name': 'SNMPv2-SMI::mib-2.47.1.1.1.1.7.1', + 'toggle_port': '.1.3.6.1.2.1.2.2.1.7' + } + + def __init__(self, ip, passw='public', ver=2): + self.ses = Session(DestHost=ip, Version=ver, Community=passw) + + def _get_vars(self, oid): + vs = VarList(Varbind(oid)) + return self.ses.walk(vs) + + def _get_var(self, oid): + var = VarList(Varbind(oid)) + return self.ses.get(var) + + # Enable/Disable port + def toggle_port(self, port_num, status=True): + vs = VarList(Varbind( + tag="%s.%d" % (self.oids['toggle_port'], port_num), + val=1 if status else 2, + type='INTEGER' + )) + return self.ses.set(vs) + + def get_ports(self): + nams = self._get_vars(self.oids['get_ports']['names']) + stats = self._get_vars(self.oids['get_ports']['stats']) + macs = self._get_vars(self.oids['get_ports']['macs']) + speeds = self._get_vars(self.oids['get_ports']['speeds']) + res = [] + ln = len(nams) + for n in range(0, ln): + res.append(Port(n, nams[n], bool(stats[n]), macs[n], int(speeds[n]))) + return res + + def get_name(self): + return self._get_var(self.oids['name']) + + +# Example usage +if __name__ == '__main__': + wrk = SNMPBaseWorker('10.115.1.104', 'private', 2) + print(wrk.get_name()) + for pr in wrk.get_ports(): + assert isinstance(pr, Port) + print(pr.nm, pr.st, pr.mac(), pr.sp) + + # Enable 2 port + print wrk.toggle_port(2, True) + # Disable 2 port + print wrk.toggle_port(2, False) diff --git a/devapp/dev_types.py b/devapp/dev_types.py new file mode 100644 index 0000000..f80d7b2 --- /dev/null +++ b/devapp/dev_types.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from base_intr import DevBase, SNMPBaseWorker + + +class DLinkDevice(DevBase): + + @staticmethod + def description(): + return u"Свич D'Link" + + def reboot(self): + pass + + +DEVICE_TYPES = ( + ('Dl', DLinkDevice), +) + + +class SNMPDlinkWorker(SNMPBaseWorker): + oids = { + 'reboot': '.1.3.6.1.4.1.2021.8.1.101.1', + 'get_ports': { + 'names': 'IF-MIB::ifDescr', + 'stats': 'IF-MIB::ifAdminStatus', + 'macs': 'IF-MIB::ifPhysAddress', + 'speeds': 'IF-MIB::ifHighSpeed' + }, + 'name': 'SNMPv2-SMI::mib-2.47.1.1.1.1.7.1' + } diff --git a/devapp/forms.py b/devapp/forms.py new file mode 100644 index 0000000..36e857b --- /dev/null +++ b/devapp/forms.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from django import forms +import models +from mydefs import ip_addr_regex + + +class DeviceForm(forms.ModelForm): + class Meta: + model = models.Device + fields = '__all__' + widgets = { + 'ip_address': forms.TextInput(attrs={ + 'pattern': ip_addr_regex, + 'placeholder': '192.168.0.100', + 'required': True, + 'class': 'form-control', + 'id': 'ip_address' + }), + 'comment': forms.Textarea(attrs={ + 'required': True, + 'class': 'form-control', + 'id': 'comment' + }), + 'devtype': forms.Select(attrs={ + 'class': 'form-control', + 'id': 'devtype' + }), + 'man_passw': forms.PasswordInput(attrs={ + 'class': 'form-control', + 'id': 'man_passw' + }) + } diff --git a/devapp/migrations/0001_initial.py b/devapp/migrations/0001_initial.py new file mode 100644 index 0000000..143d4b4 --- /dev/null +++ b/devapp/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import mydefs + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Device', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ip_address', mydefs.MyGenericIPAddressField(max_length=8, protocol=b'IPv4')), + ('comment', models.CharField(max_length=256)), + ('devtype', models.CharField(choices=[(b'Dl', "\u0421\u0432\u0438\u0447 D'Link")], default=b'Dl', max_length=2)), + ('man_passw', models.CharField(blank=True, max_length=16, null=True)), + ], + ), + migrations.CreateModel( + name='Port', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('num', models.PositiveSmallIntegerField(default=0)), + ('speed', models.CharField(choices=[(b'h', b'100Mbps'), (b'k', b'1Gbps'), (b'd', b'10Gbps')], default=b'h', max_length=1)), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')), + ], + ), + migrations.CreateModel( + name='PortStates', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('state_json_info', models.TextField()), + ('port', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Port')), + ], + ), + migrations.AlterUniqueTogether( + name='port', + unique_together=set([('device', 'num')]), + ), + ] diff --git a/devapp/migrations/__init__.py b/devapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/devapp/models.py b/devapp/models.py new file mode 100644 index 0000000..033a893 --- /dev/null +++ b/devapp/models.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +from django.db import models +from base_intr import DevBase +from mydefs import MyGenericIPAddressField, MyChoicesAdapter +from dev_types import DEVICE_TYPES + + +class _DeviceChoicesAdapter(MyChoicesAdapter): + + def __init__(self): + super(_DeviceChoicesAdapter, self).__init__(DEVICE_TYPES) + + +class Device(models.Model): + ip_address = MyGenericIPAddressField() + comment = models.CharField(max_length=256) + devtype = models.CharField(max_length=2, default=DEVICE_TYPES[0][0], choices=_DeviceChoicesAdapter()) + man_passw = models.CharField(max_length=16, null=True, blank=True) + #map_dot = models.ForeignKey() + + def get_abons(self): + pass + + def get_stat(self): + pass + + def get_manager_klass(self): + klasses = filter(lambda kl: kl[0] == self.devtype, DEVICE_TYPES) + if len(klasses) > 0: + res = klasses[0][1] + if issubclass(res, DevBase): + return res + return + + +class Port(models.Model): + PORT_SPEEDS = ( + ('h', '100Mbps'), + ('k', '1Gbps'), + ('d', '10Gbps') + ) + device = models.ForeignKey(Device) + num = models.PositiveSmallIntegerField(default=0) + speed = models.CharField(max_length=1, default=PORT_SPEEDS[0][0], choices=PORT_SPEEDS) + + class Meta: + unique_together = (('device', 'num')) + + +class PortStates(models.Model): + port = models.OneToOneField(Port) + state_json_info = models.TextField() diff --git a/devapp/tests.py b/devapp/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/devapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/devapp/urls.py b/devapp/urls.py new file mode 100644 index 0000000..be7fd11 --- /dev/null +++ b/devapp/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import url +import views + +urlpatterns = [ + url(r'^$', views.devices, name='devs_link'), + url(r'^add$', views.dev, name='devs_add_link'), + url(r'^(?P\d+)$', views.devview, name='devs_view_link'), + url(r'^(?P\d+)/del$', views.devdel, name='devs_del_link'), + url(r'^(?P\d+)/edit$', views.dev, name='devs_edit_link'), +] diff --git a/devapp/views.py b/devapp/views.py new file mode 100644 index 0000000..64d3027 --- /dev/null +++ b/devapp/views.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, redirect, get_object_or_404 +from models import Device +from mydefs import pag_mn, res_success, res_error +from forms import DeviceForm + + +@login_required +def devices(request): + devs = Device.objects.all() + devs = pag_mn(request, devs) + + return render(request, 'devapp/devices.html', { + 'devices': devs + }) + + +@login_required +def devdel(request, did): + try: + get_object_or_404(Device, id=did).delete() + return res_success(request, 'devs_link') + except: + return res_error(request, u'Неизвестная ошибка при удалении :(') + + +@login_required +def dev(request, devid=0): + warntext = '' + devinst = get_object_or_404(Device, id=devid) if devid != 0 else None + + if request.method == 'POST': + frm = DeviceForm(request.POST, instance=devinst) + if frm.is_valid(): + frm.save() + return redirect('devs_link') + else: + warntext = u'Ошибка в данных, проверте их ещё раз' + else: + frm = DeviceForm(instance=devinst) + + return render(request, 'devapp/dev.html', { + 'warntext': warntext, + 'form': frm, + 'devid': devid + }) + + +@login_required +def devview(request, did): + warntext = '' + + dev = get_object_or_404(Device, id=did) + + return render(request, 'devapp/ports.html', { + 'warntext': warntext, + 'dev': dev + }) diff --git a/djing/__init__.py b/djing/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/djing/settings.py b/djing/settings.py new file mode 100644 index 0000000..c03ed57 --- /dev/null +++ b/djing/settings.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -* +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +from django.core.urlresolvers import reverse_lazy + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '$xvppe_5&iu4fgnj2h@eie6+w*n&m=60e7k_6ha5r4rgnfndz1' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ['*'] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'accounts_app', + 'photo_app', + 'privatemessage', + 'abonapp', + 'tariff_app', + 'ip_pool', + 'searchapp', + 'devapp', + 'mapapp', + 'statistics' +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'djing.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'mydefs.context_processor_client_ipaddress' + ], + }, + }, +] + +WSGI_APPLICATION = 'djing.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.9/ref/settings/#databases + +DATABASES = { + 'default': { + #'ENGINE': 'django.db.backends.sqlite3', + #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'jungagent', + 'USER': 'root', + 'PASSWORD': 'ps', + 'HOST': 'localhost' + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.9/topics/i18n/ + +LANGUAGE_CODE = 'ru-RU' + +TIME_ZONE = 'Europe/Simferopol' + +USE_I18N = True + +USE_L10N = False + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.9/howto/static-files/ + +STATIC_URL = '/static/' +if DEBUG: + STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),) + + +# Пример вывода: 16 сентября 2012 +DATE_FORMAT = 'd E Y' + + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = '/media/' + +DEFAULT_PICTURE = '/static/images/default-avatar.png' +AUTH_USER_MODEL = 'accounts_app.UserProfile' + +LOGIN_URL = reverse_lazy('login_link') +LOGIN_REDIRECT_URL = reverse_lazy('profile') +LOGOUT_URL = reverse_lazy('logout_link') diff --git a/djing/urls.py b/djing/urls.py new file mode 100644 index 0000000..a47314a --- /dev/null +++ b/djing/urls.py @@ -0,0 +1,26 @@ +from django.conf.urls import url, include +from django.contrib import admin +import settings +from views import home + +urlpatterns = [ + url(r'^$', home), + url(r'^accounts/', include('accounts_app.urls')), + url(r'^im/', include('privatemessage.urls')), + url(r'^abons/', include('abonapp.urls')), + url(r'^tarifs/', include('tariff_app.urls')), + url(r'^ip_pool/', include('ip_pool.urls')), + url(r'^search/', include('searchapp.urls')), + url(r'^dev/', include('devapp.urls')), + url(r'^map/', include('mapapp.urls')), + url(r'^statistic/', include('statistics.urls')), + url(r'^admin/', admin.site.urls), +] + + +if settings.DEBUG: + from django.conf.urls.static import static + from django.contrib.staticfiles.urls import staticfiles_urlpatterns + + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + urlpatterns += staticfiles_urlpatterns() diff --git a/djing/views.py b/djing/views.py new file mode 100644 index 0000000..1dfb701 --- /dev/null +++ b/djing/views.py @@ -0,0 +1,9 @@ +from django.shortcuts import redirect + + +def home(request): + return redirect('profile') + + +def finance_report(request): + pass diff --git a/djing/wsgi.py b/djing/wsgi.py new file mode 100644 index 0000000..fdbbb71 --- /dev/null +++ b/djing/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for djing project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") + +application = get_wsgi_application() diff --git a/install.sql b/install.sql new file mode 100644 index 0000000..5bc979e --- /dev/null +++ b/install.sql @@ -0,0 +1,17 @@ +create table flowstat ( + `id` int(10) AUTO_INCREMENT NOT NULL, + `src_ip` CHAR(8) NOT NULL, + `dst_ip` CHAR(8) NOT NULL, + `proto` smallint(2) unsigned NOT NULL DEFAULT 0, + `src_port` smallint(5) unsigned NOT NULL DEFAULT 0, + `dst_port` smallint(5) unsigned NOT NULL DEFAULT 0, + `octets` INT unsigned NOT NULL DEFAULT 0, + `packets` INT unsigned NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + + +INSERT INTO flowstat(`src_ip`, `dst_ip`, `proto`, `src_port`, `dst_port`, `octets`, `packets`) VALUES +('c0a80201', 'c0a805ba', 6, 49150, 443, 5281, 13), +('c0a80201', 'c0a805ba', 6, 49150, 443, 5281, 13) diff --git a/ip_pool/__init__.py b/ip_pool/__init__.py new file mode 100644 index 0000000..8c4aa32 --- /dev/null +++ b/ip_pool/__init__.py @@ -0,0 +1 @@ +default_app_config = 'ip_pool.apps.IpPoolConfig' diff --git a/ip_pool/admin.py b/ip_pool/admin.py new file mode 100644 index 0000000..65ef72e --- /dev/null +++ b/ip_pool/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +import models + +admin.site.register(models.IpPoolItem) diff --git a/ip_pool/apps.py b/ip_pool/apps.py new file mode 100644 index 0000000..b5b1b03 --- /dev/null +++ b/ip_pool/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class IpPoolConfig(AppConfig): + name = 'ip_pool' + verbose_name = u"Ip pool" diff --git a/ip_pool/forms.py b/ip_pool/forms.py new file mode 100644 index 0000000..5395225 --- /dev/null +++ b/ip_pool/forms.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from django import forms +from mydefs import ip_addr_regex + + +class PoolForm(forms.Form): + start_ip = forms.GenericIPAddressField(protocol='IPv4', widget=forms.TextInput(attrs={ + 'pattern': ip_addr_regex, + 'placeholder': u'127.0.0.1', + 'id': 'start_ip', + 'class': 'form-control', + 'required': '' + }), required=True) + + end_ip = forms.GenericIPAddressField(protocol='IPv4', widget=forms.TextInput(attrs={ + 'pattern': ip_addr_regex, + 'placeholder': u'127.0.0.1', + 'id': 'end_ip', + 'class': 'form-control', + 'required': '' + }), required=True) diff --git a/ip_pool/migrations/0001_initial.py b/ip_pool/migrations/0001_initial.py new file mode 100644 index 0000000..05336f6 --- /dev/null +++ b/ip_pool/migrations/0001_initial.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import mydefs + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='IpPoolItem', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ip', mydefs.MyGenericIPAddressField(max_length=8, protocol=b'IPv4')), + ], + ), + ] diff --git a/ip_pool/migrations/__init__.py b/ip_pool/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ip_pool/models.py b/ip_pool/models.py new file mode 100644 index 0000000..b1342e4 --- /dev/null +++ b/ip_pool/models.py @@ -0,0 +1,60 @@ +from django.db import models, connection +from mydefs import ip2int, MyGenericIPAddressField + + +class IpPoolItemManager(models.Manager): + + def get_pools(self): + ips = self.raw(r'SELECT id, ip FROM ip_pool_ippoolitem ORDER BY id') + ips_len = len(list(ips)) + if ips_len < 1: + return + last_dg = ip2int(ips[0].ip) + start_pool = last_dg + res = list() + cnt = 0 + for ip in ips: + ipnt = ip2int(ip.ip) + if ipnt > last_dg + 1 or ipnt < last_dg - 1: + res.append((start_pool, last_dg, cnt)) + start_pool = ipnt + cnt = 0 + last_dg = ipnt + cnt += 1 + res.append((start_pool, last_dg, cnt)) + return res + + def add_pool(self, start_ip, end_ip): + start_ip = ip2int(start_ip) + end_ip = ip2int(end_ip) + + if (end_ip - start_ip) > 5000: + raise Exception(u'Not add over 5000 ip\'s') + + sql_strs = map(lambda tip: r"(%d)" % tip, range(start_ip, end_ip+1)) + sql = r'INSERT INTO ip_pool_ippoolitem (ip) VALUES %s' % r",".join(sql_strs) + print sql + + cursor = connection.cursor() + cursor.execute(sql) + + def get_free_ip(self): + sql = r'SELECT ip_pool_ippoolitem.id as id, ip_pool_ippoolitem.ip as ip FROM ip_pool_ippoolitem ' \ + r'LEFT JOIN abonent ON abonent.ip_address_id = ip_pool_ippoolitem.id WHERE ' \ + r'abonent.ip_address_id IS NULL LIMIT 1' + + rs = self.raw(sql) + rs_len = len(list(rs)) + return None if rs_len is 0 else rs[0] + + +class IpPoolItem(models.Model): + ip = MyGenericIPAddressField() + + objects = IpPoolItemManager() + + def int_ip(self): + return ip2int(self.ip) + + def __unicode__(self): + return self.ip diff --git a/ip_pool/tests.py b/ip_pool/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/ip_pool/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/ip_pool/urls.py b/ip_pool/urls.py new file mode 100644 index 0000000..5bfb07c --- /dev/null +++ b/ip_pool/urls.py @@ -0,0 +1,13 @@ +# -*- coding:utf-8 -*- +from django.conf.urls import url +import views + +urlpatterns = [ + + url(r'^$', views.home, name='pool_home_link'), + url(r'^range$', views.ips, name='pool_ips_link'), + url(r'^del$', views.del_pool, name='pool_ips_del_link'), + url(r'^add$', views.add_pool, name='pool_add_link'), + + url(r'^delip$', views.delip, name='pool_del_ip_link') +] \ No newline at end of file diff --git a/ip_pool/views.py b/ip_pool/views.py new file mode 100644 index 0000000..938fa19 --- /dev/null +++ b/ip_pool/views.py @@ -0,0 +1,76 @@ +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, redirect, get_object_or_404 +from forms import PoolForm +from models import IpPoolItem +import mydefs + + +@login_required +def home(request): + pools = IpPoolItem.objects.get_pools() + print pools + + if pools: + pools = map(lambda ip: (mydefs.int2ip(ip[0]), mydefs.int2ip(ip[1]), ip[2]), pools) + pools = mydefs.pag_mn(request, pools) + + return render(request, 'ip_pool/index.html', { + 'pools': pools + }) + + +@login_required +def ips(request): + ip_start = request.GET.get('ips') + ip_end = request.GET.get('ipe') + + pool_ips = IpPoolItem.objects.filter(ip__gte=ip_start) + pool_ips = pool_ips.filter(ip__lte=ip_end) + + pool_ips = mydefs.pag_mn(request, pool_ips) + + return render(request, 'ip_pool/ips.html', { + 'pool_ips': pool_ips, + 'ips': ip_start, + 'ipe': ip_end + }) + + +@login_required +def del_pool(request): + ip_start = request.GET.get('ips') + ip_end = request.GET.get('ipe') + + pool_ips = IpPoolItem.objects.filter(ip__gte=ip_start) + pool_ips = pool_ips.filter(ip__lte=ip_end) + pool_ips = pool_ips.filter() + + pool_ips.delete() + + return mydefs.res_success(request, 'pool_home_link') + + +@login_required +def add_pool(request): + if request.method == 'POST': + frm = PoolForm(request.POST) + if frm.is_valid(): + cd = frm.cleaned_data + IpPoolItem.objects.add_pool(cd['start_ip'], cd['end_ip']) + return redirect('pool_home_link') + else: + warntext = u'Form is not valid' + else: + frm = PoolForm() + warntext = '' + return render(request, 'ip_pool/add_pool.html', { + 'form': frm, + 'warntext': warntext + }) + + +@login_required +def delip(request): + ipid = request.GET.get('id') + get_object_or_404(IpPoolItem, id=ipid).delete() + return mydefs.res_success(request, 'pool_home_link') diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..b3fc4dd --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/mapapp/__init__.py b/mapapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mapapp/admin.py b/mapapp/admin.py new file mode 100644 index 0000000..06bdd54 --- /dev/null +++ b/mapapp/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +import models + +admin.site.register(models.Dot) diff --git a/mapapp/apps.py b/mapapp/apps.py new file mode 100644 index 0000000..6bdb84f --- /dev/null +++ b/mapapp/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class MapappConfig(AppConfig): + name = 'mapapp' diff --git a/mapapp/migrations/0001_initial.py b/mapapp/migrations/0001_initial.py new file mode 100644 index 0000000..b42a6c3 --- /dev/null +++ b/mapapp/migrations/0001_initial.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Dot', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=64)), + ('posX', models.FloatField()), + ('posY', models.FloatField()), + ], + ), + ] diff --git a/mapapp/migrations/__init__.py b/mapapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mapapp/models.py b/mapapp/models.py new file mode 100644 index 0000000..925f2f6 --- /dev/null +++ b/mapapp/models.py @@ -0,0 +1,10 @@ +from django.db import models + + +class Dot(models.Model): + title = models.CharField(max_length=64) + posX = models.FloatField() + posY = models.FloatField() + + def __unicode__(self): + return self.title diff --git a/mapapp/tests.py b/mapapp/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/mapapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/mapapp/urls.py b/mapapp/urls.py new file mode 100644 index 0000000..2309fbc --- /dev/null +++ b/mapapp/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import url +import views + +urlpatterns = [ + url(r'^$', views.home, name='maps_home_link'), + url(r'^get_dots$', views.get_dots, name='maps_get_dots') +] diff --git a/mapapp/views.py b/mapapp/views.py new file mode 100644 index 0000000..d050cbd --- /dev/null +++ b/mapapp/views.py @@ -0,0 +1,18 @@ +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +from django.shortcuts import render +from models import Dot +from json import dumps + + +@login_required +def home(request): + return render(request, 'maps/index.html') + + + +def get_dots(r): + dots = Dot.objects.all() + return HttpResponse(dumps({ + 'dots': map(lambda d: (d.id, d.posX, d.posY, d.title), dots) + })) diff --git a/mydefs.py b/mydefs.py new file mode 100644 index 0000000..9660064 --- /dev/null +++ b/mydefs.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +from django.http import HttpResponse, Http404 +from json import dumps +from django.shortcuts import redirect +from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage +import socket +import struct +from django.db import models +from collections import Iterator + + +ip_addr_regex = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' + + +def ip2int(addr): + return struct.unpack("!I", socket.inet_aton(addr))[0] + + +def int2ip(addr): + return socket.inet_ntoa(struct.pack("!I", addr)) + + +def safe_float(fl): + return 0.0 if fl is None or fl == '' else float(fl) + + +def safe_int(i): + return 0 if i is None or i == '' else int(i) + + +def res_success(request, redirect_to='/'): + if request.is_ajax(): + return HttpResponse(dumps({'errnum': 0})) + else: + return redirect(redirect_to) + + +def res_error(request, text): + if request.is_ajax(): + return HttpResponse(dumps({'errnum':1, 'errtext':text})) + else: + raise Http404(text) + + +# Pagination +def pag_mn(request, objs, count_per_page=10): + page = request.GET.get('p') + pgn = Paginator(objs, count_per_page) + try: + objs = pgn.page(page) + except PageNotAnInteger: + objs = pgn.page(1) + except EmptyPage: + objs = pgn.page(pgn.num_pages) + return objs + + +def context_processor_client_ipaddress(request): + ip = request.META.get('REMOTE_ADDR', '') or request.META.get('HTTP_X_FORWARDED_FOR', '') + return { + 'client_ipaddress': ip + } + #logmodels.debug('%s %s %s'%(request.user, request.path, ip)) + + +class MyGenericIPAddressField(models.GenericIPAddressField): + + description = "Int32 notation ip address" + + def __init__(self, protocol='IPv4', *args, **kwargs): + super(MyGenericIPAddressField, self).__init__(protocol=protocol, *args, **kwargs) + self.max_length = 8 + + def get_prep_value(self, value): + # strIp to Int + value = super(models.GenericIPAddressField, self).get_prep_value(value) + return ip2int(value) + + def to_python(self, addr): + return addr + + def get_internal_type(self): + return 'PositiveIntegerField' + + @staticmethod + def from_db_value(value, expression, connection, context): + return int2ip(value) + + +# Предназначен для Django CHOICES чтоб можно было передавать классы вместо просто описания поля, +# классы передавать для того чтоб по значению кода из базы понять какой класс нужно взять для нужной функциональности. +# Например по коду в базе вам нужно определять как считать тариф абонента, что реализовано в возвращаемом классе. +class MyChoicesAdapter(Iterator): + chs = tuple() + current_index = 0 + _max_index = 0 + + # На вход принимает кортеж кортежей, вложенный из 2х элементов: кода и класса, как: TARIFF_CHOICES + def __init__(self, choices): + self._max_index = len(choices) + self.chs = choices + + def next(self): + if self.current_index >= self._max_index: + raise StopIteration + else: + e = self.chs + ci = self.current_index + res = e[ci][0], e[ci][1].description() + self.current_index += 1 + return res diff --git a/photo_app/__init__.py b/photo_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/photo_app/admin.py b/photo_app/admin.py new file mode 100644 index 0000000..9d30a59 --- /dev/null +++ b/photo_app/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +import models + +admin.site.register(models.Photo) \ No newline at end of file diff --git a/photo_app/migrations/0001_initial.py b/photo_app/migrations/0001_initial.py new file mode 100644 index 0000000..00258c1 --- /dev/null +++ b/photo_app/migrations/0001_initial.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Photo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(height_field=b'heigt', upload_to=b'', width_field=b'wdth')), + ('wdth', models.PositiveSmallIntegerField(blank=True, default=b'759', editable=False, null=True)), + ('heigt', models.PositiveSmallIntegerField(blank=True, editable=False, null=True)), + ], + ), + ] diff --git a/photo_app/migrations/__init__.py b/photo_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/photo_app/models.py b/photo_app/models.py new file mode 100644 index 0000000..9251c23 --- /dev/null +++ b/photo_app/models.py @@ -0,0 +1,69 @@ +# -*- coding:utf-8 -*- +from django.db import models +from djing.settings import BASE_DIR +import os +from PIL import Image +import time +import hashlib + + +class Photo(models.Model): + image = models.ImageField(width_field='wdth', height_field='heigt') + wdth = models.PositiveSmallIntegerField(null=True, blank=True, editable=False, default="759") + heigt = models.PositiveSmallIntegerField(null=True, blank=True, editable=False) + + def __unicode__(self): + return "{0}".format(self.image) + + def big(self): + return self.image.url + + def min(self): + pth = self.image.url.split('/')[-1:][0] + return "/media/min/%s" % pth + + def save(self, *args, **kwargs): + if not self.image: + return + + super(Photo, self).save() + + im = Image.open(self.image.path) + im.thumbnail((759, 759), Image.ANTIALIAS) + + hs = hashlib.md5(str(time.time())).hexdigest() + ext = self.image.path.split('.')[1:][0] + fname = "%s/media/%s.%s" % (BASE_DIR, hs, ext) + + im.save(fname) + os.remove(self.image.path) + self.image = "%s.%s" % (hs, ext) + super(Photo, self).save() + + + #class Meta: + # unique_together = (('image',),) + + +def resize_image(sender, instance, **kwargs): + if not kwargs['created']: + im = Image.open(instance.image.path) + im.thumbnail((200, 121), Image.ANTIALIAS) + pth = instance.image.path.split('/')[-1:][0] + fullpath = "%s/media/min/%s" % (BASE_DIR, pth) + im.save(fullpath) + + + +def post_delete_photo(sender, instance, **kwargs): + min_fname = instance.image.path.split('/')[-1:][0] + try: + os.remove('%s/media/min/%s' % (BASE_DIR, min_fname)) + os.remove(instance.image.path) + except OSError: + pass + + + +models.signals.post_save.connect(resize_image, sender=Photo) +models.signals.post_delete.connect(post_delete_photo, sender=Photo) diff --git a/photo_app/tests.py b/photo_app/tests.py new file mode 100644 index 0000000..501deb7 --- /dev/null +++ b/photo_app/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/photo_app/urls.py b/photo_app/urls.py new file mode 100644 index 0000000..3fa1f7b --- /dev/null +++ b/photo_app/urls.py @@ -0,0 +1,12 @@ +# -*- coding:utf-8 -*- +from django.conf.urls import patterns, url + +urlpatterns = [ + #url(r'^$', 'photo_albums', name='media_home_link'), + #url(r'^(?P\d+)$', 'photo_albums', name='media_home_link_by_id'), + #url(r'^album(?P\d+)$', 'photos', name='media_photos_link'), + + + #url(r'^newalbum/$', 'add_album', name='add_media_album_link'), + #url(r'^newphoto/$', 'add_photo_to_album', name='add_media_photo_link') +] diff --git a/photo_app/views.py b/photo_app/views.py new file mode 100644 index 0000000..380474e --- /dev/null +++ b/photo_app/views.py @@ -0,0 +1 @@ +# -*- coding:utf-8 -*- diff --git a/privatemessage/__init__.py b/privatemessage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/privatemessage/admin.py b/privatemessage/admin.py new file mode 100644 index 0000000..5e0689c --- /dev/null +++ b/privatemessage/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from models import PrivateMessages, Dialog + +admin.site.register(PrivateMessages) +admin.site.register(Dialog) diff --git a/privatemessage/context_processors.py b/privatemessage/context_processors.py new file mode 100644 index 0000000..25b8c81 --- /dev/null +++ b/privatemessage/context_processors.py @@ -0,0 +1,7 @@ +from models import PrivateMessages + + +def avail_messages(request): + return { + 'avail_messages_num': PrivateMessages.objects.get_my_messages(request) + } diff --git a/privatemessage/migrations/0001_initial.py b/privatemessage/migrations/0001_initial.py new file mode 100644 index 0000000..4efa2d2 --- /dev/null +++ b/privatemessage/migrations/0001_initial.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-28 23:51 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Dialog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=127)), + ('date_create', models.DateTimeField(auto_now_add=True)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ('recepient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='PrivateMessages', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_send', models.DateTimeField(auto_now_add=True)), + ('text', models.TextField()), + ('is_viewed', models.BooleanField(default=False)), + ('dialog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='privatemessage.Dialog')), + ], + ), + ] diff --git a/privatemessage/migrations/__init__.py b/privatemessage/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/privatemessage/models.py b/privatemessage/models.py new file mode 100644 index 0000000..d90b378 --- /dev/null +++ b/privatemessage/models.py @@ -0,0 +1,34 @@ +from django.db import models +from djing import settings + + +class MessagesManager(models.Manager): + + def get_my_messages(self, request): + if request.user.is_authenticated(): + num = self.filter(recepient=request.user, is_viewed=False).count() + else: + num = 0 + return int(num) + + +class Dialog(models.Model): + title = models.CharField(max_length=127) + owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+') + recepient = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+') + date_create = models.DateTimeField(auto_now_add=True) + + def __unicode__(self): + return self.title + + +class PrivateMessages(models.Model): + dialog = models.ForeignKey(Dialog) + date_send = models.DateTimeField(auto_now_add=True) + text = models.TextField() + is_viewed = models.BooleanField(default=False) + + objects = MessagesManager() + + def __unicode__(self): + return self.text diff --git a/privatemessage/tests.py b/privatemessage/tests.py new file mode 100644 index 0000000..04c4a6f --- /dev/null +++ b/privatemessage/tests.py @@ -0,0 +1,22 @@ +from django.test import TestCase +import models +from django.contrib.auth.models import User + + +class PaysTest(TestCase): + + def setUp(self): + self.msg = models.PrivateMessages.objects.create( + sender=User.objects.all()[0], + recepient=User.objects.all()[0], + text='test init text' + ) + + def tearDown(self): + models.PrivateMessages.objects.all().delete() + + def check_ret_msgs(self): + """check return messages""" + request = self.factory.get('/message/') + self.assertIsInstance(models.PrivateMessages.objects.get_my_messages(request), int, 'checking ret type') + self.assertGreater(models.PrivateMessages.objects.get_my_messages(request), 0, 'checking msg count') diff --git a/privatemessage/urls.py b/privatemessage/urls.py new file mode 100644 index 0000000..fbab5aa --- /dev/null +++ b/privatemessage/urls.py @@ -0,0 +1,8 @@ +from django.conf.urls import url +import views + +urlpatterns = [ + url(r'^$', views.home, name='privmsg_home'), + url(r'^delitem_(?P\d+)$', views.delitem, name='privmsg_delitem'), + url(r'^write', views.send_message, name='privmsg_send_message') +] diff --git a/privatemessage/views.py b/privatemessage/views.py new file mode 100644 index 0000000..67eee3c --- /dev/null +++ b/privatemessage/views.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, redirect +from django.template.loader import render_to_string +from models import PrivateMessages +from django.http import HttpResponse +from json import dumps +from django.template.context_processors import csrf +import mydefs +from accounts_app.models import UserProfile + + +@login_required +def home(request): + msgs = PrivateMessages.objects.all() + return render(request, 'private_messages/index.html', { + 'msgs': msgs + }) + + +@login_required +def delitem(request, id=0): + r = {'errnum': 0,'errtext': u''} + try: + PrivateMessages.objects.get(id=id).delete() + except PrivateMessages.DoesNotExist: + r = { + 'errnum': 1, + 'errtext': u'Error while deleting, item does not exist' + } + return HttpResponse(dumps(r)) + + +@login_required +def send_message(request): + if request.method == 'GET': + return HttpResponse(render_to_string('private_messages/send_form.html',{ + 'csrf_token': csrf(request)['csrf_token'], + 'a': request.GET.get('a') + })) + elif request.method == 'POST': + try: + a = request.GET.get('a') + a = 0 if a is None or a == '' else int(a) + msg = PrivateMessages() + msg.sender = request.user + msg.recepient = UserProfile.objects.get(id=a) + msg.text = request.POST.get('msg_text') + msg.save() + return redirect('privmsg_home') + except UserProfile.DoesNotExist: + return mydefs.res_error(request, u'Адресат не найден') + else: + return mydefs.res_error(request, u'Ошибка типа запроса') diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d1c9c2b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +Django==1.9 +requests +Pillow +MySQL-python diff --git a/searchapp/__init__.py b/searchapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/searchapp/admin.py b/searchapp/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/searchapp/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/searchapp/apps.py b/searchapp/apps.py new file mode 100644 index 0000000..6cc6464 --- /dev/null +++ b/searchapp/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class SearchappConfig(AppConfig): + name = 'searchapp' diff --git a/searchapp/migrations/__init__.py b/searchapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/searchapp/models.py b/searchapp/models.py new file mode 100644 index 0000000..bd4b2ab --- /dev/null +++ b/searchapp/models.py @@ -0,0 +1,5 @@ +from __future__ import unicode_literals + +from django.db import models + +# Create your models here. diff --git a/searchapp/tests.py b/searchapp/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/searchapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/searchapp/urls.py b/searchapp/urls.py new file mode 100644 index 0000000..0838048 --- /dev/null +++ b/searchapp/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import url +import views + +urlpatterns = [ + url(r'^$', views.home, name='search_home_link'), + +] diff --git a/searchapp/views.py b/searchapp/views.py new file mode 100644 index 0000000..0756bd3 --- /dev/null +++ b/searchapp/views.py @@ -0,0 +1,32 @@ +from django.db.models import Q +from django.shortcuts import render +from abonapp.models import Abon +from django.utils.html import escape +import re + + +def replace_without_case(orig, old, new): + return re.sub(old, new, orig, flags=re.IGNORECASE) + + +def home(request): + s = request.GET.get('s') + + if s: + abons = Abon.objects.filter( + Q(fio__icontains=s) | + Q(username__icontains=s) | + Q(telephone__icontains=s) + ) + else: + abons = [] + + for abn in abons: + abn.fio = replace_without_case(escape(abn.fio), s, "%s" % s) + abn.username = replace_without_case(escape(abn.username), s, "%s" % s) + abn.telephone = replace_without_case(escape(abn.telephone), s, "%s" % s) + + return render(request, 'searchapp/index.html', { + 'abons': abons, + 's': s + }) diff --git a/static/bad_ie.html b/static/bad_ie.html new file mode 100644 index 0000000..ca33cf1 --- /dev/null +++ b/static/bad_ie.html @@ -0,0 +1,11 @@ + + + + Старый браузер + + + + +

У вас старый ослик, обновитесь хотяб до IE10

+ + diff --git a/static/css/bootstrap-theme.min.css b/static/css/bootstrap-theme.min.css new file mode 100644 index 0000000..ac8dd55 --- /dev/null +++ b/static/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/static/css/bootstrap.min.css b/static/css/bootstrap.min.css new file mode 100644 index 0000000..28f154d --- /dev/null +++ b/static/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/static/css/custom.css b/static/css/custom.css new file mode 100644 index 0000000..8365c48 --- /dev/null +++ b/static/css/custom.css @@ -0,0 +1,145 @@ +/* + * Base structure + */ + +/* Move down content because we have a fixed navbar that is 50px tall */ +body { + padding-top: 50px; +} + + +/* + * Global add-ons + */ + +.sub-header { + padding-bottom: 10px; + border-bottom: 1px solid #eee; +} + +/* + * Navbar + */ +.navbar-inverse { + background-image: none; +} + + +/* + * Sidebar + */ + +/* Hide for mobile, show later */ +.sidebar { + display: none; +} +@media (min-width: 768px) { + .sidebar { + position: fixed; + top: 39px; + bottom: 0; + left: 0; + z-index: 1000; + display: block; + padding: 20px; + overflow-x: hidden; + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + background-color: #303840; + border-right: 1px solid #eee; + } +} + +/* Sidebar navigation */ +.nav-sidebar { + margin-right: -21px; /* 20px padding + 1px border */ + margin-bottom: 20px; + margin-left: -20px; + border-top: 1px solid #576a7d; +} +.nav-sidebar > li > a { + padding-right: 20px; + padding-left: 20px; + color: #b3c3d2; +} +.nav>li>a:focus, .nav>li>a:hover { + background-color: #1f2429; + color: #b2bfcc; +} +.nav-sidebar > .active > a { + background-color: #44596b; +} + + + +.profile_img{ + color: aliceblue; + padding-bottom: 9px; +} +.main{ + margin-top: 10px; +} +.table-responsive thead{ + background-color: gainsboro; +} +td.btn-group{ + display: table-cell; +} +.table > tbody > tr > td { + vertical-align: middle; +} + +.modal-header.warning{ + background-color: #d2322d; + border-radius: 4px 4px 0 0; +} + + +.tab-pane { + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; + border-bottom: 1px solid #ddd; + border-radius: 0px 0px 5px 5px; + padding: 10px; +} + + +/* search form */ +.stylish-input-group .input-group-addon{ + background: white !important; +} +.stylish-input-group .form-control{ + border-right:0; + box-shadow:0 0 0; + border-color:#ccc; +} +.stylish-input-group button{ + border:0; + background:transparent; +} + + +/*---------Switch----------*/ +.switch_ports { + border: 2px solid #636363; + border-radius: 7px; + box-shadow: 3px 3px 8px #2B2B2B; +} +.switch_ports h4 { + margin: 10px 0 3px 10px; +} +.port { + display: inline-block; + margin: 10px; + border: 1px solid #7B7B7B; + border-radius: 3px; + background-image: url(/static/img/icon-port-64x64-grey.png); + width: 64px; + height: 64px; +} +.port.giga { + background-color: #B5FFB5; +} +.port.kilo { + background-color: #FBEB79; +} +/*-------END-Switch--------*/ diff --git a/static/css/custom_login.css b/static/css/custom_login.css new file mode 100644 index 0000000..78e16fd --- /dev/null +++ b/static/css/custom_login.css @@ -0,0 +1,40 @@ +body { + padding-top: 40px; + padding-bottom: 40px; + background-color: #eee; +} + +.form-signin { + max-width: 330px; + padding: 15px; + margin: 0 auto; +} +.form-signin .form-signin-heading, +.form-signin .checkbox { + margin-bottom: 10px; +} +.form-signin .checkbox { + font-weight: normal; +} +.form-signin .form-control { + position: relative; + height: auto; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px; + font-size: 16px; +} +.form-signin .form-control:focus { + z-index: 2; +} +.form-signin input[type="email"] { + margin-bottom: -1px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.form-signin input[type="password"] { + margin-bottom: 10px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} \ No newline at end of file diff --git a/static/fonts/glyphicons-halflings-regular.eot b/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/fonts/glyphicons-halflings-regular.ttf b/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/static/fonts/glyphicons-halflings-regular.woff2 b/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/static/img/0ZKOa52wPuc.jpg b/static/img/0ZKOa52wPuc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e26edb4c6eeb72024f06c09fb419d71fb80503f GIT binary patch literal 43610 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 M*Zk*oDgK=MKY>hD)c^nh literal 0 HcmV?d00001 diff --git a/static/img/favicon.ico b/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b751e751e3dae9203b5d728a2cc65e2efacbc322 GIT binary patch literal 2918 zcmc&$%TE(Q9G*6@P!Xj&Gqo+{u`}C((SzaS*`p^8p5#D`3L2F@cUg;Qjl{%@F+J!F zFzSJme}IYc?!gnr7*q~OIC?TZXxDGHG%1yW^r4geW!~R6zsJmP3Gomw35N;lK{9%f zkT@YE6!N0)Az#t9FgA=DOUMXBt*ciGkt6QZ^{Ccq8;qp|3pOj$24@pPhkXiotgFMt z$5_~u?5QdFx+(ZZ(<1qrCD|i;fNF{$rBlBp`BFwQCnZ`Z8DM24D_lI*?E`KoCE2%D z;wvoJ+rimaz@w#f76s?`R&yvkOYl`&GMd&|ZyPy2Pw&E!k-V6eyp)!#RBo4R_^pUD zsT*D@Qeu$Vu;mi=zDNpYL*G{ko!(CfI)}J>Go{ljh{cVBV6%vu zXV~L%R&&+k0G^76qKdhj@!%M6CRH0c-!&!eKOfP8IU_i)#&R*fd?(uHOA9)Rxc^y= zuiATXl*R`<{+T$xU>fY|T>PjP_wyb&#AHugwkB=eR9HhtfjZH;2oEI|+X}@cFnpGxV6XB$c&#G{aG`ZBl3JXfH#zx28e+ z+ra@nTz$at5&j>!+!r{Wiv<@d{%D0B6@BnF{K!iF9&z`kpy_y?Qk9 zpdbW-`d<)YLb#|GW4sutCSGidQqgqx>zk=HrELU!oA18NoB6z%dHa?zA3d$DjNUzL zw1qK0W2~P^!u7l>>`+zLbF-PBeoQ4mLXn~UhSYaw08BDsTr5SH0N@gVGQhu*_B#M)n8iu`mW z?2_S0bO@zl0gtbqM`@#onUNtBKIgEQ9z*`qIu@)L5?u#D{OWezbU`*3A65>tqZhS* zIzEh_o8R%=nZVY!4LrM%LL$(}-#p&yzJIxlhZoMlbIX{C4p#Ws72=A-C-8&LwUlkb z8$6%tZF9%{`!IdNtZ-wO{_vL@_;~&KiKn`|s`ggMk9(&EK=si4eBv6ms1CLJ|BF{S z;$4R@Wp-j^_7NVOJ%eAR%{}od2i*rFM_b_Zb>eG|>Yj?CRLEn=NjBE6=KPAS*Hm8s zPJck(=f!Os@xX!Y-;er-m~uT=9VfewP+bHTlGkznbOdT#+dtI5Io-bo_lRjKn)hPu z`@MVZY{7Cw+gVt&7TU)k;6(2jp(t`iuWZ GAoe$3JDv>y literal 0 HcmV?d00001 diff --git a/static/img/gmarkers/dev.png b/static/img/gmarkers/dev.png new file mode 100644 index 0000000000000000000000000000000000000000..81ebf83717c69d13fef970c5bd87b1f3181f48cd GIT binary patch literal 3943 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 literal 0 HcmV?d00001 diff --git a/static/img/gmarkers/dev_bug.png b/static/img/gmarkers/dev_bug.png new file mode 100644 index 0000000000000000000000000000000000000000..1c1e86750359d96184dce0e832837bf0cbdc0de0 GIT binary patch literal 4190 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 literal 0 HcmV?d00001 diff --git a/static/img/gmarkers/dev_ok.png b/static/img/gmarkers/dev_ok.png new file mode 100644 index 0000000000000000000000000000000000000000..b2639cff87f35427f8781d4b8fc28698e1ae3fde GIT binary patch literal 4284 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 literal 0 HcmV?d00001 diff --git a/static/img/icon-port-64x64-grey.png b/static/img/icon-port-64x64-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..3da81828d84c4d7aa33850e10284938222067fe3 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X_IbKEhE&{obJLOQuz~=CgYM56`q$^*lqt$s7_`NAL+Lk( z9v$KE8@_9{woO%L0&0MP2bw`%^{SJL`_|99f9MfoLTSU=|{jm$bY}a3yIb8^%uZmF}W&o6)!QON1@QgTe~DWM4f^f_Kx literal 0 HcmV?d00001 diff --git a/static/img/kpkLhcH5R4E.jpg b/static/img/kpkLhcH5R4E.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f45991abb7d03577f8bad35586926736487c4247 GIT binary patch literal 4474 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 auspcs%4vNmx{UncwJLFe9l*_WKJh<|LOL}7 literal 0 HcmV?d00001 diff --git a/static/img/user_ava.gif b/static/img/user_ava.gif new file mode 100644 index 0000000000000000000000000000000000000000..cc2079cb77e090e9a655250f5f2ddc7d4c57a0dd GIT binary patch literal 7656 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.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.2",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.2",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('