From 4255a4e5c2c962e8e19012758bd3eb4428fa2b07 Mon Sep 17 00:00:00 2001 From: jssmk Date: Thu, 12 Aug 2021 01:01:19 +0300 Subject: [PATCH 01/15] reject student and workplace email addresses in applications --- project/members/forms.py | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/project/members/forms.py b/project/members/forms.py index f294f63..e696b0f 100644 --- a/project/members/forms.py +++ b/project/members/forms.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- from creditor.models import RecurringTransaction from django import forms +from re import compile, match from django.conf import settings from django.utils.functional import keep_lazy from django.utils.translation import gettext_lazy as _ +from django.core.exceptions import ValidationError from .models import MembershipApplication @@ -14,8 +16,22 @@ def rules_accepted_proxy(msg): class ApplicationForm(forms.ModelForm): - rules_accepted = forms.BooleanField(required=True, label=rules_accepted_proxy(_("I have read and accept the rules"))) + field_order = [ + 'fname', + 'lname', + 'city', + 'email', + 'confirm_email', + 'phone', + 'nick', + 'rules_accepted', + ] required_css_class = 'required' + rules_accepted = forms.BooleanField(required=True, + label=rules_accepted_proxy(_("I have read and accept the rules"))) + confirm_email = forms.BooleanField(required=False, + label=(_("I am sure this is not a student or a work address, let me continue")), + widget=forms.HiddenInput()) class Meta: model = MembershipApplication @@ -28,6 +44,38 @@ class Meta: 'nick', ] + def clean_email(self): + """ + Try to avoid receiving email addresses in applications that probably stop responding + or eventually need to be changed (work, university etc.) due to graduation and such + 1. if the address is in domain blacklist, require a different address + 2. if the address is in domain whitelist, accept the address, no further questions asked (gmail, iki.fi and such) + 3. if neither above, ask the applicant if they are sure they want to give this address and accept then + """ + data = self.cleaned_data['email'] + + blacklist = '|'.join(['aalto.fi', '.*\.aalto.fi', 'metropolia.fi', '.*\.metropolia.fi', 'helsinki.fi', '.*\.helsinki.fi', + 'haaga-helia.fi', '.*\.haaga-helia.fi', 'hel.fi', '.*\.hel.fi', '.*\.edu']) + + + whitelist = '|'.join(['gmail.com', 'iki.fi', 'yahoo.com', 'hotmail.com', 'outlook.com', 'kolumbus.fi', 'windowslive.com', + 'hotmail.co.uk', 'pp.inet.fi', 'mac.com', 'wippies.com', 'welho.com', 'kapsi.fi', 'fastmail.fm', 'live.fi', 'protonmail.com', + 'yahoo.co.uk', 'suomi24.fi']) + + domain_regex_blacklist = compile('^.*@(' + blacklist + ')$') + domain_regex_whitelist = compile('^.*@(' + whitelist + ')$') + + # Is in blacklist = student email -> instant reject + if domain_regex_blacklist.match(data): + self.fields['confirm_email'].widget = forms.HiddenInput() + raise ValidationError(_("This very much looks like a student or workplace email address, please provide another address.")) + + # Is not on whitelist -> ask if the applicant wants to use this + if not domain_regex_whitelist.match(data): + self.fields['confirm_email'].widget = forms.CheckboxInput() # not hidden anymore + if not self.data.get('confirm_email') == 'on': + raise ValidationError(_("Please recheck your email address and confirm this is not a student or work address provided by your university, workplace etc., or give a different address.")) + return data class RTInlineForm(forms.ModelForm): amount = forms.DecimalField(max_value=0) From 2be834b24b9ce98c63fe5de3c372a2215708656c Mon Sep 17 00:00:00 2001 From: jssmk Date: Thu, 12 Aug 2021 11:51:41 +0300 Subject: [PATCH 02/15] templates, config and error handling --- project/config/settings/common.py | 2 + project/members/forms.py | 9 +++- .../templates/members/application_form.html | 47 ++++++++++++++++--- .../members/application_received.html | 2 + project/members/views.py | 3 +- 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/project/config/settings/common.py b/project/config/settings/common.py index b61660c..22d9c56 100644 --- a/project/config/settings/common.py +++ b/project/config/settings/common.py @@ -267,6 +267,7 @@ # Your common stuff: Below this line define 3rd party library settings APPLICATION_RULES_URL = env('APPLICATION_RULES_URL', default='http://hacklab.fi/') +MEMBER_REGISTER_WRITEUP_URL = env('MEMBER_REGISTER_WRITEUP_URL', default='http://hacklab.fi/') # Give path to a class implementing the api outlined in member.handers baseclasses MEMBERAPPLICATION_CALLBACKS_HANDLER = env('MEMBERAPPLICATION_CALLBACKS_HANDLER', default=None) @@ -314,6 +315,7 @@ SETTINGS_EXPORT = [ 'ORGANIZATION_NAME', 'APPLICATION_RULES_URL', + 'MEMBER_REGISTER_WRITEUP_URL', ] # Required by Django 3.2 if no explicit primary key is defined diff --git a/project/members/forms.py b/project/members/forms.py index e696b0f..b191cac 100644 --- a/project/members/forms.py +++ b/project/members/forms.py @@ -16,6 +16,11 @@ def rules_accepted_proxy(msg): class ApplicationForm(forms.ModelForm): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.member_register_writeup = [settings.MEMBER_REGISTER_WRITEUP_URL] # "Rekisteriseloste" + field_order = [ 'fname', 'lname', @@ -30,7 +35,7 @@ class ApplicationForm(forms.ModelForm): rules_accepted = forms.BooleanField(required=True, label=rules_accepted_proxy(_("I have read and accept the rules"))) confirm_email = forms.BooleanField(required=False, - label=(_("I am sure this is not a student or a work address, let me continue")), + label=(_("I am sure this is address is not provided by an education institution or a workplace, let me continue")), widget=forms.HiddenInput()) class Meta: @@ -70,7 +75,7 @@ def clean_email(self): self.fields['confirm_email'].widget = forms.HiddenInput() raise ValidationError(_("This very much looks like a student or workplace email address, please provide another address.")) - # Is not on whitelist -> ask if the applicant wants to use this + # Is not on whitelist -> ask if the applicant really wants to use this if not domain_regex_whitelist.match(data): self.fields['confirm_email'].widget = forms.CheckboxInput() # not hidden anymore if not self.data.get('confirm_email') == 'on': diff --git a/project/members/templates/members/application_form.html b/project/members/templates/members/application_form.html index dfcebbd..ee79765 100644 --- a/project/members/templates/members/application_form.html +++ b/project/members/templates/members/application_form.html @@ -1,16 +1,51 @@ {% extends "base.html" %} {% load bootstrap3 static i18n %} +{% block extralink %}{% endblock extralink %} + {% block page_title %}{% trans "Apply for membership" %}{% endblock page_title %} {% block main_title %}{% trans "Apply for membership" %}{% endblock main_title %} {% block content %} +{% if form.errors %} +
+
+

{% trans "Please fix some errors found in your application form." %}

+
+
+
+ {% csrf_token %} + {% bootstrap_form form required_css_class='required' %} + {% trans "Submit" as submittext %} + {% buttons submit=submittext %}{% endbuttons %} +
+
+
+

{% trans "Read the terms of collected data in Helsinki Hacklab ry. member register description:" %} info

+
+
+{% else %}
-
- {% csrf_token %} - {% bootstrap_form form required_css_class='required' %} - {% trans "Submit" as submittext %} - {% buttons submit=submittext %}{% endbuttons %} -
+
+

{% trans "Apply for membership in Helsinki Hacklab. Association act requires us to register your first and last name and city (municipality) of residence. We also need a working email address for contacting you." %}

+

{% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only." %}

+

{% trans "You can also give a nickname you use or are about to use in IRC or in Helsinki Hacklab chat service. Phone number helps us contacting you in urgent or important situations when no other way succeeds." %}

+

{% trans "Every new applicant must accept the rules of the organisation." %}

+

{% trans "If the applicant is under 18 years old, please be in contact with board members first for instructions. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

+ +
+
+
+ {% csrf_token %} + {% bootstrap_form form required_css_class='required' %} + {% trans "Submit" as submittext %} + {% buttons submit=submittext %}{% endbuttons %} +
+
+
+

{% trans "Read the terms of collected data in Helsinki Hacklab ry. member register description:" %} info

+
+{% endif %} {% endblock %} diff --git a/project/members/templates/members/application_received.html b/project/members/templates/members/application_received.html index 899cf40..071a29f 100644 --- a/project/members/templates/members/application_received.html +++ b/project/members/templates/members/application_received.html @@ -1,6 +1,8 @@ {% extends "base.html" %} {% load bootstrap3 static i18n %} +{% block extralink %}{% endblock extralink %} + {% block page_title %}{% trans "Received. Thank you" %}{% endblock page_title %} {% block main_title %}{% trans "Application received. Thank you" %}{% endblock main_title %} diff --git a/project/members/views.py b/project/members/views.py index f36de0a..a8d3f6c 100644 --- a/project/members/views.py +++ b/project/members/views.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.urls import reverse from django.http import HttpResponseRedirect -from django.shortcuts import get_object_or_404, render +from django.shortcuts import get_object_or_404, render, redirect from django.views import generic from .forms import ApplicationForm @@ -16,7 +16,6 @@ class ApplyView(generic.CreateView): def get_success_url(self): return reverse('members-application_received') - class ApplicationReceivedView(generic.TemplateView): template_name = "members/application_received.html" From a0ba7b1cd3e329da1bf4c9931f82a8fbcda675cd Mon Sep 17 00:00:00 2001 From: jssmk Date: Thu, 12 Aug 2021 12:45:39 +0300 Subject: [PATCH 03/15] logo + validation --- project/asylum/static/images/logo_icon.png | Bin 0 -> 22762 bytes project/asylum/templates/base.html | 1 + project/members/forms.py | 12 ++++++++++++ .../templates/members/application_form.html | 2 ++ .../templates/members/application_received.html | 2 ++ 5 files changed, 17 insertions(+) create mode 100644 project/asylum/static/images/logo_icon.png diff --git a/project/asylum/static/images/logo_icon.png b/project/asylum/static/images/logo_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..65534ba8393c8c493e08c786f384dd7322a4b801 GIT binary patch literal 22762 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 WnqJ}hyTGq>r;PN?FqPL_;{F53b}+mE literal 0 HcmV?d00001 diff --git a/project/asylum/templates/base.html b/project/asylum/templates/base.html index efe2748..afde117 100644 --- a/project/asylum/templates/base.html +++ b/project/asylum/templates/base.html @@ -34,6 +34,7 @@
+ Logo

{% block main_title %}Hello world!{% endblock main_title %}

{{ settings.ORGANIZATION_NAME }}

diff --git a/project/members/forms.py b/project/members/forms.py index b191cac..1aadfe3 100644 --- a/project/members/forms.py +++ b/project/members/forms.py @@ -49,6 +49,18 @@ class Meta: 'nick', ] + def clean_city(self): + """Make sure users don't skip this part with unprovided information such as a single hyphen""" + data = self.cleaned_data['city'] + + # This should be enough in most cases, includes extra letters from some European languages + city_name_regex = compile('^[A-Za-zÄÖÅÜÉÆØäöåüõæøéèîêâëâß \-\']{2,}$') + print(data) + print(city_name_regex.match(data)) + if not city_name_regex.match(data): + raise ValidationError(_("Please only provide the city or municipality name of your residence, no detailed addresses, street names or anything extra. We are required by Association Act to register your place of residence.")) + return data + def clean_email(self): """ Try to avoid receiving email addresses in applications that probably stop responding diff --git a/project/members/templates/members/application_form.html b/project/members/templates/members/application_form.html index ee79765..b41901b 100644 --- a/project/members/templates/members/application_form.html +++ b/project/members/templates/members/application_form.html @@ -6,6 +6,8 @@ {% block page_title %}{% trans "Apply for membership" %}{% endblock page_title %} {% block main_title %}{% trans "Apply for membership" %}{% endblock main_title %} + + {% block content %} {% if form.errors %}
diff --git a/project/members/templates/members/application_received.html b/project/members/templates/members/application_received.html index 071a29f..255637c 100644 --- a/project/members/templates/members/application_received.html +++ b/project/members/templates/members/application_received.html @@ -6,6 +6,8 @@ {% block page_title %}{% trans "Received. Thank you" %}{% endblock page_title %} {% block main_title %}{% trans "Application received. Thank you" %}{% endblock main_title %} + + {% block content %}

{% blocktrans %}We'll get back to you{% endblocktrans %}

From 2c7f6ae895ab72fd01fecbd5850ff4a90ff49096 Mon Sep 17 00:00:00 2001 From: jssmk Date: Thu, 12 Aug 2021 12:51:08 +0300 Subject: [PATCH 04/15] form styles --- project/.gitignore | 2 +- .../asylum/static/css/application_form.css | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 project/asylum/static/css/application_form.css diff --git a/project/.gitignore b/project/.gitignore index 961ede2..bb10cda 100644 --- a/project/.gitignore +++ b/project/.gitignore @@ -3,7 +3,7 @@ reload staticfiles/ media/ bower_components/ -asylum/static/css/ +asylym/static/css/asylym.css asylum/static/js/ asylum/static/fonts/ diff --git a/project/asylum/static/css/application_form.css b/project/asylum/static/css/application_form.css new file mode 100644 index 0000000..b220c94 --- /dev/null +++ b/project/asylum/static/css/application_form.css @@ -0,0 +1,43 @@ +.container-fluid { + max-width: 800px; + margin: 0px auto +} + +.form-logo { + width: 200px; +} + +.form-group { +} + +.applicationintro { + padding: 19px; + background: #fff2dd; + border-radius: 20px; + margin: 10px; +} + + +.applicationform { + padding: 19px; + background: #fff2dd; + border-radius: 20px; + margin: 10px; + transition:all 1.0s ease-in; + opacity: 0.0; + height: 0px; +} +.showform { + opacity: 1.0; + height: auto; +} + + +.applicationfooter { + margin: 20px 10px 50px; +} + +body { + background-color: #ffa000; +} + From 3ee4c3c7546b54a82ecaf2b683ef12816a39a7b4 Mon Sep 17 00:00:00 2001 From: jssmk Date: Fri, 13 Aug 2021 20:40:56 +0300 Subject: [PATCH 05/15] templates and styles --- .../asylum/static/css/application_form.css | 10 +- project/asylum/static/css/asylum.css | 8884 +++++++++++++++++ project/asylum/static/css/stats.css | 49 + project/asylum/templates/base.html | 2 +- .../templates/members/application_form.html | 14 +- .../members/application_received.html | 6 +- .../members/email_confirmation_error.html | 17 + .../templates/members/email_confirmed.html | 13 + 8 files changed, 8975 insertions(+), 20 deletions(-) create mode 100644 project/asylum/static/css/asylum.css create mode 100644 project/asylum/static/css/stats.css create mode 100644 project/members/templates/members/email_confirmation_error.html create mode 100644 project/members/templates/members/email_confirmed.html diff --git a/project/asylum/static/css/application_form.css b/project/asylum/static/css/application_form.css index b220c94..45ad14a 100644 --- a/project/asylum/static/css/application_form.css +++ b/project/asylum/static/css/application_form.css @@ -10,19 +10,14 @@ .form-group { } -.applicationintro { +.applicationsection { padding: 19px; background: #fff2dd; border-radius: 20px; margin: 10px; } - -.applicationform { - padding: 19px; - background: #fff2dd; - border-radius: 20px; - margin: 10px; +.formsection { transition:all 1.0s ease-in; opacity: 0.0; height: 0px; @@ -32,7 +27,6 @@ height: auto; } - .applicationfooter { margin: 20px 10px 50px; } diff --git a/project/asylum/static/css/asylum.css b/project/asylum/static/css/asylum.css new file mode 100644 index 0000000..bb07ffd --- /dev/null +++ b/project/asylum/static/css/asylum.css @@ -0,0 +1,8884 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-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: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +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 { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + 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-appearance: textfield; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + box-shadow: none !important; + text-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .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 th, + .table-bordered td { + 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: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before, +.glyphicon-eur: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-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub: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; +} +*:before, +*:after { + -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: "proxima-nova", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + 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; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + 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; +} +[role="button"] { + cursor: pointer; +} +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, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777777; +} +h1, +.h1, +h2, +.h2, +h3, +.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, +.h4, +h5, +.h5, +h6, +.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 { + background-color: #fcf8e3; + padding: 0.2em; +} +.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: #777777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eeeeee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; + text-align: right; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small: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; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + word-break: break-all; + word-wrap: break-word; + color: #333333; + 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 { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, +.col-sm-1, +.col-md-1, +.col-lg-1, +.col-xs-2, +.col-sm-2, +.col-md-2, +.col-lg-2, +.col-xs-3, +.col-sm-3, +.col-md-3, +.col-lg-3, +.col-xs-4, +.col-sm-4, +.col-md-4, +.col-lg-4, +.col-xs-5, +.col-sm-5, +.col-md-5, +.col-lg-5, +.col-xs-6, +.col-sm-6, +.col-md-6, +.col-lg-6, +.col-xs-7, +.col-sm-7, +.col-md-7, +.col-lg-7, +.col-xs-8, +.col-sm-8, +.col-md-8, +.col-lg-8, +.col-xs-9, +.col-sm-9, +.col-md-9, +.col-lg-9, +.col-xs-10, +.col-sm-10, +.col-md-10, +.col-lg-10, +.col-xs-11, +.col-sm-11, +.col-md-11, +.col-lg-11, +.col-xs-12, +.col-sm-12, +.col-md-12, +.col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11, +.col-xs-12 { + 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-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-10, + .col-sm-11, + .col-sm-12 { + 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-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-10, + .col-md-11, + .col-md-12 { + 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-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-10, + .col-lg-11, + .col-lg-12 { + 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: #777777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + 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 > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + 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; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +@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 > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + 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="radio"]:focus, +input[type="checkbox"]: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: #555555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, 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, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.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 { + background-color: #eeeeee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .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"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .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"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + min-height: 34px; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 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; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 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; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 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, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; +} +.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 .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.333333px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + 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:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + 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:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + 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:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + 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:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + 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:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + color: #337ab7; + font-weight: normal; + 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:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + 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="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-property: height, visibility; + transition-property: height, visibility; + -webkit-transition-duration: 0.35s; + transition-duration: 0.35s; + -webkit-transition-timing-function: ease; + transition-timing-function: ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + 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; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.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: normal; + line-height: 1.42857143; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + outline: 0; + background-color: #337ab7; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + 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-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-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-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 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-bottom-left-radius: 4px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.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-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + 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="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + 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-left: 0; + padding-right: 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; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].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; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control: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: normal; + line-height: 1; + color: #555555; + text-align: center; + background-color: #eeeeee; + 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="radio"], +.input-group-addon input[type="checkbox"] { + 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:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-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:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-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:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + 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 { + z-index: 2; + margin-left: -1px; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li.disabled > a { + color: #777777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777777; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + 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: #eeeeee #eeeeee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.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:hover, +.nav-tabs.nav-justified > .active > a:focus { + 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:hover, + .nav-tabs.nav-justified > .active > a:focus { + 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:hover, +.nav-pills > li.active > a:focus { + 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 { + text-align: center; + margin-bottom: 5px; +} +.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:hover, +.nav-tabs-justified > .active > a:focus { + 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:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-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 { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + 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-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + 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; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + height: 50px; +} +.navbar-brand:hover, +.navbar-brand:focus { + 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; + margin-right: 15px; + padding: 9px 10px; + margin-top: 8px; + 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; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + 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 { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 8px; + margin-bottom: 8px; +} +@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 .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + 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; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-right-radius: 4px; + border-top-left-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-left: 15px; + margin-right: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + float: left; + } + .navbar-right { + float: right !important; + float: right; + 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:hover, +.navbar-default .navbar-brand:focus { + 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:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + 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:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #e7e7e7; + color: #555; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + 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:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + 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:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + 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:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: #080808; + color: #fff; +} +@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:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + 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:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + 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 { + content: "/\00a0"; + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #777777; +} +.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; + line-height: 1.42857143; + text-decoration: none; + color: #337ab7; + background-color: #fff; + border: 1px solid #ddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 3; + color: #23527c; + background-color: #eeeeee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777777; + background-color: #fff; + border-color: #ddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 6px; + border-top-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + list-style: none; + text-align: center; +} +.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:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777777; + background-color: #fff; + cursor: not-allowed; +} +.label { + display: inline; + padding: 0.2em 0.6em 0.3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + color: #fff; + line-height: 1; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: #777777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + 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-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eeeeee; +} +.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-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-left: 60px; + padding-right: 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 0.2s ease-in-out; + -o-transition: border 0.2s ease-in-out; + transition: border 0.2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333333; +} +.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: bold; +} +.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 { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.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; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 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, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -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, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + zoom: 1; + overflow: hidden; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + 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 { + margin-bottom: 20px; + padding-left: 0; +} +.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-right-radius: 4px; + border-top-left-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + text-decoration: none; + color: #555; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #eeeeee; + color: #777777; + cursor: not-allowed; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + 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, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.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-right-radius: 3px; + border-top-left-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 > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-left: 15px; + padding-right: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead: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-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .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 td:first-child, +.panel > .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 td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .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 td:last-child, +.panel > .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 td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} +.panel > .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 td:first-child, +.panel > .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 td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .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 td:last-child, +.panel > .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 td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .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 th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 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 > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + 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: #333333; + 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: #333333; +} +.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 iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.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, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.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; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.42857143px; +} +.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-left: 5px; + margin-bottom: 0; +} +.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, 0.5); + box-shadow: 0 5px 15px rgba(0, 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: "proxima-nova", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 12px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + 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 { + bottom: 0; + right: 5px; + 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: "proxima-nova", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 14px; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 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 { + margin: 0; + padding: 8px 14px; + 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 { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + 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: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform 0.6s ease-in-out; + -moz-transition: -moz-transform 0.6s ease-in-out; + -o-transition: -o-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + -moz-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + left: 0; + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + left: 0; + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + left: 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; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: 0; + color: #fff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + margin-top: -10px; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + line-height: 1; + font-family: serif; +} +.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%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #fff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 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-prev, + .carousel-control .icon-next { + 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 { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: 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; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.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 !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.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 !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.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 !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.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 !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.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; + } +} +/*! + * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.4.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: 0.2em 0.25em 0.15em; + border: solid 0.08em #eee; + border-radius: 0.1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: 0.3em; +} +.fa.fa-pull-right { + margin-left: 0.3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: 0.3em; +} +.fa.pull-right { + margin-left: 0.3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #fff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.form-group.required .control-label:after { + content: " *"; + color: red; +} diff --git a/project/asylum/static/css/stats.css b/project/asylum/static/css/stats.css new file mode 100644 index 0000000..41eba8a --- /dev/null +++ b/project/asylum/static/css/stats.css @@ -0,0 +1,49 @@ +.stats_table { + margin: 10px; +} + +.stats_table th { + padding: 5px; + border-color: #cecece; + border-width: 0px 0px 1px 0px; + border-style: solid; +} + +.stats_table td { + padding: 5px; + border-color: #cecece; + border-width: 0px 0px 1px 0px; + border-style: solid; +} + +.stats_main { + max-width: 1000px; + margin: 0px auto; +} + +.stats_right { + float: right; + max-width: 400px; +} + +.stats_left { + clear: left; +} + + +.stats_months_sel_table th { + padding: 5px; +} + +.stats_months_sel_table td { + padding: 5px; +} + +.stats_tag_options { + display: inline-block; + margin-right: 10px; +} + +.stats_tag_selected a { + text-decoration: underline; +} \ No newline at end of file diff --git a/project/asylum/templates/base.html b/project/asylum/templates/base.html index afde117..2856efb 100644 --- a/project/asylum/templates/base.html +++ b/project/asylum/templates/base.html @@ -34,7 +34,7 @@
- Logo +

{% block main_title %}Hello world!{% endblock main_title %}

{{ settings.ORGANIZATION_NAME }}

diff --git a/project/members/templates/members/application_form.html b/project/members/templates/members/application_form.html index b41901b..01211f0 100644 --- a/project/members/templates/members/application_form.html +++ b/project/members/templates/members/application_form.html @@ -6,15 +6,13 @@ {% block page_title %}{% trans "Apply for membership" %}{% endblock page_title %} {% block main_title %}{% trans "Apply for membership" %}{% endblock main_title %} - - {% block content %} {% if form.errors %}
-
+

{% trans "Please fix some errors found in your application form." %}

-
+
{% csrf_token %} {% bootstrap_form form required_css_class='required' %} @@ -28,16 +26,16 @@
{% else %}
-
+

{% trans "Apply for membership in Helsinki Hacklab. Association act requires us to register your first and last name and city (municipality) of residence. We also need a working email address for contacting you." %}

{% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only." %}

{% trans "You can also give a nickname you use or are about to use in IRC or in Helsinki Hacklab chat service. Phone number helps us contacting you in urgent or important situations when no other way succeeds." %}

{% trans "Every new applicant must accept the rules of the organisation." %}

-

{% trans "If the applicant is under 18 years old, please be in contact with board members first for instructions. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

+

{% trans "If the applicant is under 18 years old, please be in contact with board members for instructions first. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

+ onclick="document.querySelector('.formsection').classList.add('showform');">{% trans "I understand, continue" %}
-
+
{% csrf_token %} {% bootstrap_form form required_css_class='required' %} diff --git a/project/members/templates/members/application_received.html b/project/members/templates/members/application_received.html index 255637c..5df9d70 100644 --- a/project/members/templates/members/application_received.html +++ b/project/members/templates/members/application_received.html @@ -6,10 +6,10 @@ {% block page_title %}{% trans "Received. Thank you" %}{% endblock page_title %} {% block main_title %}{% trans "Application received. Thank you" %}{% endblock main_title %} - - {% block content %}
-

{% blocktrans %}We'll get back to you{% endblocktrans %}

+
+

{% blocktrans %}We'll get back to you{% endblocktrans %}

+
{% endblock content %} diff --git a/project/members/templates/members/email_confirmation_error.html b/project/members/templates/members/email_confirmation_error.html new file mode 100644 index 0000000..ac6c76c --- /dev/null +++ b/project/members/templates/members/email_confirmation_error.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% load bootstrap3 static i18n %} + +{% block page_title %}{% trans "Error confirming email" %}{% endblock page_title %} +{% block main_title %}{% trans "There was an error confirming your email" %}{% endblock main_title %} + +{% block content %} +
+
+
    +
  • {% trans "Check that you entered the URL correclty" %}
  • +
  • {% trans "Maybe the link was already used?" %}
  • +
  • {% trans "Confirmation URL already expired?" %}
  • +
+
+
+{% endblock content %} \ No newline at end of file diff --git a/project/members/templates/members/email_confirmed.html b/project/members/templates/members/email_confirmed.html new file mode 100644 index 0000000..9285796 --- /dev/null +++ b/project/members/templates/members/email_confirmed.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% load bootstrap3 static i18n %} + +{% block page_title %}{% trans "Confirmed. Thank you" %}{% endblock page_title %} +{% block main_title %}{% trans "Email confirmation received. Thank you" %}{% endblock main_title %} + +{% block content %} +
+
+

{% trans "Email address successfully confirmed" %}

+
+
+{% endblock content %} \ No newline at end of file From 3361c8ce67bb9e00fa63413275a2fb4e4c5d322a Mon Sep 17 00:00:00 2001 From: jssmk Date: Fri, 13 Aug 2021 20:41:45 +0300 Subject: [PATCH 06/15] email confirmation link for new applications --- project/hhlcallback/handlers.py | 43 ++++++++++++-- project/members/admin.py | 14 ++++- project/members/handlers.py | 4 ++ .../migrations/0005_emailconfirmation.py | 32 ++++++++++ project/members/models.py | 59 ++++++++++++++++++- project/members/urls.py | 1 + project/members/views.py | 40 ++++++++++++- 7 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 project/members/migrations/0005_emailconfirmation.py diff --git a/project/hhlcallback/handlers.py b/project/hhlcallback/handlers.py index 7f584d9..78e0a66 100644 --- a/project/hhlcallback/handlers.py +++ b/project/hhlcallback/handlers.py @@ -35,12 +35,43 @@ def on_saved(self, instance, *args, **kwargs): if instance.email in self.fresh_emails: # Just created del(self.fresh_emails[instance.email]) - mail = EmailMessage() - mail.from_email = '"%s" <%s>' % (instance.name, instance.email) - mail.to = ["hallitus@helsinki.hacklab.fi", ] - mail.subject = "Jäsenhakemus: %s" % instance.name - mail.body = "Uusi hakemus Asylumissa: https://lataamo.hacklab.fi/admin/members/membershipapplication/%d/" % instance.pk - mail.send() + + print(self) + print(dir(instance)) + #print(args) + #print(confirmation_code) + + # Notification mail for admins that there is a new application + admin_mail = EmailMessage() + admin_mail.from_email = '"%s" <%s>' % (instance.name, instance.email) + admin_mail.to = ["hallitus@helsinki.hacklab.fi", ] + admin_mail.subject = "Jäsenhakemus: %s" % instance.name + admin_mail.body = "Uusi hakemus Asylumissa: https://lataamo.helsinki.hacklab.fi/admin/members/membershipapplication/%d/" % instance.pk + admin_mail.send() + + # This mail checks that applicant can receive mail in the provided address + address_check_mail = EmailMessage() + address_check_mail.from_email = "hallitus@helsinki.hacklab.fi" + address_check_mail.to = [instance.email] + address_check_mail.subject = "Helsinki Hacklab ry: Vahvista sähköpostiosoitteesi | Confirm your email address" + address_check_mail.body = """Hei, + +Joku (toivottavasti sinä) on lähettänyt uuden jäsenhakemuksen yhdistykselle Helsinki Hacklab ry. +Vahvista lähetetty hakemus alla olevassa osoitteessa. +Mikäli et ole lähettänyt hakemusta ja olet silti saanut tämän viestin, sinun ei tarvitse tehdä mitään, tai voit olla yhteydessä osoitteeseen hallitus@helsinki.hacklab.fi selvittääksesi asiaa. +Vahvistamattomat hakemukset hylätään. + +Someone (hopefully you) has sent a new membership application application to Helsinki Hacklab ry. +Please confirm the sent application form the address below. +If you haven't sent the application and have still received this message, you don't have to do anything, or you can be in contact with hallitus@helsinki.hacklab.fi for resolving the issue. +Applications that are not confirmed are not approved. + +https://lataamo.helsinki.hacklab.fi/members/confirm_email/%s""" % instance.confirmation_code + + try: + address_check_mail.send() + except Exception as e: + logger.exception("Failed to send email confirmation code to {}".format(instance.email)) pass def on_approved(self, application, member): diff --git a/project/members/admin.py b/project/members/admin.py index 412d0a5..8e52eb1 100644 --- a/project/members/admin.py +++ b/project/members/admin.py @@ -12,7 +12,7 @@ from reversion.admin import VersionAdmin from .forms import RTInlineForm -from .models import Member, MemberNote, MembershipApplication, MembershipApplicationTag, MemberType +from .models import Member, MemberNote, MembershipApplication, MembershipApplicationTag, MemberType, EmailConfirmation class MemberTypeAdmin(VersionAdmin): @@ -182,6 +182,7 @@ class MembershipApplicationAdmin(VersionAdmin): 'email', 'nick', 'tags_formatted', + 'confirmation_status', ) list_filter = (TagListFilter,) actions = ['approve_selected'] @@ -210,8 +211,19 @@ class MemberNoteAdmin(VersionAdmin): pass +class EmailConfirmationAdmin(VersionAdmin): + list_display = ( + 'email', + 'window_start', + 'window_end', + 'status', + 'confirmation_code' + ) + + admin.site.register(MemberType, MemberTypeAdmin) admin.site.register(Member, MemberAdmin) admin.site.register(MembershipApplication, MembershipApplicationAdmin) admin.site.register(MembershipApplicationTag, MembershipApplicationTagAdmin) admin.site.register(MemberNote, MemberNoteAdmin) +admin.site.register(EmailConfirmation, EmailConfirmationAdmin) diff --git a/project/members/handlers.py b/project/members/handlers.py index 0147e0c..89131bd 100644 --- a/project/members/handlers.py +++ b/project/members/handlers.py @@ -21,6 +21,10 @@ def on_saved(self, instance, *args, **kwargs): class BaseApplicationHandler(BaseHandler): """Baseclass for callback handlers for MembershipApplication processing""" + # def on_saved(self, instance, confirmation_code, *args, **kwargs): + # """Called after save() returns""" + # pass + def on_approving(self, application, member): """Called just before member.save()""" pass diff --git a/project/members/migrations/0005_emailconfirmation.py b/project/members/migrations/0005_emailconfirmation.py new file mode 100644 index 0000000..e94c004 --- /dev/null +++ b/project/members/migrations/0005_emailconfirmation.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2 on 2021-08-13 16:10 + +import asylum.mixins +from django.db import migrations, models +import django.utils.timezone +import members.models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0004_auto_20151229_2055'), + ] + + operations = [ + migrations.CreateModel( + name='EmailConfirmation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254, verbose_name='Email address')), + ('window_start', models.DateTimeField(db_index=True, default=django.utils.timezone.now, verbose_name='Confirmation window start')), + ('window_end', models.DateTimeField(db_index=True, default=members.models.now_plus_one, verbose_name='Confirmation window end')), + ('confirmed', models.DateTimeField(blank=True, default=None, null=True, verbose_name='Confirmation received')), + ('confirmation_code', models.UUIDField(default=uuid.uuid4, editable=False)), + ], + options={ + 'abstract': False, + }, + bases=(asylum.mixins.AtomicVersionMixin, asylum.mixins.CleanSaveMixin, models.Model), + ), + ] diff --git a/project/members/models.py b/project/members/models.py index 4480116..74a5748 100644 --- a/project/members/models.py +++ b/project/members/models.py @@ -7,9 +7,11 @@ from django.core.exceptions import ValidationError from django.db import models, transaction from django.utils import timezone +from datetime import timedelta from django.utils.translation import gettext_lazy as _ from markdownx.models import MarkdownxField from reversion import revisions +from uuid import uuid4 from asylum.models import AsylumModel @@ -125,7 +127,20 @@ class MembershipApplication(MemberCommon): @call_saves('MEMBERAPPLICATION_CALLBACKS_HANDLER') def save(self, *args, **kwargs): - return super().save(*args, **kwargs) + #h = get_handler_instance('MEMBERAPPLICATION_CALLBACKS_HANDLER') + #if h: + # h.on_saving(self) + #e = EmailConfirmation() + #self.confirmation_code = e.confirmation_code + #a = super().save(*args, **kwargs) + #if h: + # h.on_saved(self, e.confirmation_code) + #e.save() + #return a + e = EmailConfirmation(email=self.email) + e.save() + self.confirmation_code = e.confirmation_code + return super().save(*args, **kwargs) def validate_unique(self, exclude=None): if exclude and 'email' in exclude: @@ -164,6 +179,10 @@ class Meta: verbose_name = _('Membership Application') verbose_name_plural = _('Membership Applications') + def confirmation_status(self): + e = EmailConfirmation.objects.get(email=self.email) + return e.status + revisions.register(MembershipApplication) @@ -183,3 +202,41 @@ def __str__(self): revisions.register(MemberNote) + +def now_plus_one(): + return timezone.now() + timedelta(days=1) + +class EmailConfirmation(AsylumModel): + """Confirmation that a member or applicant can receive email in provided address """ + email = models.EmailField(_("Email address"), blank=False) + window_start = models.DateTimeField(_("Confirmation window start"), default=timezone.now, db_index=True) + window_end = models.DateTimeField(_("Confirmation window end"), default=now_plus_one, db_index=True) + confirmed = models.DateTimeField(_("Confirmation received"), null=True, blank=True, default=None) + confirmation_code = models.UUIDField(default=uuid4, editable=False) + + def confirm(self, user_code): + print(user_code) + print(self.confirmation_code) + print(self.confirmed) + print(self.status) + print("---------") + if self.status == 'waiting confirmation' and str(self.confirmation_code) == str(user_code): + self.confirmed = timezone.now() + self.save() + return True + else: + return ValidationError + + @property + def status(self): + if self.confirmed: + if self.window_start < self.confirmed and self.window_end > self.confirmed: + return 'confirmed' + else: + # This should not ever happen + return 'error' + else: + if self.window_end < timezone.now(): + return 'expired' + else: + return 'waiting confirmation' diff --git a/project/members/urls.py b/project/members/urls.py index 49f2463..2e80c18 100644 --- a/project/members/urls.py +++ b/project/members/urls.py @@ -7,4 +7,5 @@ re_path(r'^$', views.HomeView.as_view(), name="members-home"), re_path(r'^apply/?$', views.ApplyView.as_view(), name="members-apply"), re_path(r'^apply/done/?$', views.ApplicationReceivedView.as_view(), name="members-application_received"), + re_path(r'^confirm_email/(?P[a-z0-9\-]+)$', views.EmailConfirmationView.as_view(), name="members-email-confirmation"), ] diff --git a/project/members/views.py b/project/members/views.py index a8d3f6c..55bdaea 100644 --- a/project/members/views.py +++ b/project/members/views.py @@ -3,9 +3,11 @@ from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render, redirect from django.views import generic +from django.utils import timezone +from uuid import UUID from .forms import ApplicationForm -from .models import MembershipApplication +from .models import MembershipApplication, EmailConfirmation class ApplyView(generic.CreateView): @@ -25,3 +27,39 @@ class HomeView(generic.base.RedirectView): def get_redirect_url(self, *args, **kwargs): return reverse('members-apply') + + +class EmailConfirmationView(generic.TemplateView): + template_name = "members/email_confirmation_error.html" + + def is_uuid(self, val): + try: + UUID(str(val)) + return True + except ValueError: + return False + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + ctx_code = ctx.get('confirmation_code') + + if not self.is_uuid(ctx_code): + return + + email_c = EmailConfirmation.objects.get(confirmation_code=ctx_code) + + confirmed = False + try: + confirmed = email_c.confirm(ctx_code) + except ValidationError: + return + + if confirmed == True: + self.template_name = "members/email_confirmed.html" + + +class EmailConfirmationSuccessView(generic.TemplateView): + template_name = "members/email_confirmed.html" + +class EmailConfirmationErrorView(generic.TemplateView): + template_name = "members/email_error.html" From 45664026d20cf89ac6f654662a37036d81b6a859 Mon Sep 17 00:00:00 2001 From: jssmk Date: Fri, 13 Aug 2021 21:14:05 +0300 Subject: [PATCH 07/15] remove extra file --- project/asylum/static/css/stats.css | 49 ----------------------------- 1 file changed, 49 deletions(-) delete mode 100644 project/asylum/static/css/stats.css diff --git a/project/asylum/static/css/stats.css b/project/asylum/static/css/stats.css deleted file mode 100644 index 41eba8a..0000000 --- a/project/asylum/static/css/stats.css +++ /dev/null @@ -1,49 +0,0 @@ -.stats_table { - margin: 10px; -} - -.stats_table th { - padding: 5px; - border-color: #cecece; - border-width: 0px 0px 1px 0px; - border-style: solid; -} - -.stats_table td { - padding: 5px; - border-color: #cecece; - border-width: 0px 0px 1px 0px; - border-style: solid; -} - -.stats_main { - max-width: 1000px; - margin: 0px auto; -} - -.stats_right { - float: right; - max-width: 400px; -} - -.stats_left { - clear: left; -} - - -.stats_months_sel_table th { - padding: 5px; -} - -.stats_months_sel_table td { - padding: 5px; -} - -.stats_tag_options { - display: inline-block; - margin-right: 10px; -} - -.stats_tag_selected a { - text-decoration: underline; -} \ No newline at end of file From 51577de2db7ccdc2177d88b6ae0eaa0972cbd4a6 Mon Sep 17 00:00:00 2001 From: jssmk Date: Fri, 13 Aug 2021 21:46:55 +0300 Subject: [PATCH 08/15] visible error sign --- project/asylum/static/css/application_form.css | 5 +++++ project/asylum/static/images/warning.png | Bin 0 -> 21842 bytes .../templates/members/application_received.html | 4 +++- .../members/email_confirmation_error.html | 9 ++++++--- .../templates/members/email_confirmed.html | 2 ++ 5 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 project/asylum/static/images/warning.png diff --git a/project/asylum/static/css/application_form.css b/project/asylum/static/css/application_form.css index 45ad14a..662cc46 100644 --- a/project/asylum/static/css/application_form.css +++ b/project/asylum/static/css/application_form.css @@ -35,3 +35,8 @@ body { background-color: #ffa000; } +.warning-sign { + float: right; + width: 150px; + margin: 10px; +} \ No newline at end of file diff --git a/project/asylum/static/images/warning.png b/project/asylum/static/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..c63bcfdb6707caefab44c331cba0b8021e0509cd GIT binary patch literal 21842 zcmcG#bySp5_b^I>NGj5eA|XS!ba#uiFmw$ubcsrXh=3>^(gM;9FkrwSC@>O|L*oqH zUH2K^-}~MB$G5(9*InzfV3?V6_CCAMKKtw^!BAg=oRpCi2M32-OHL;V3ym9Guv-yzE_^jGgQqLwx(49^>HP`@5Mwg+A5O zl>tM%K=#-vp)`&0T6gOLG9Uty*$1BWrF26|KXJZ-ebQOKU@DK>VE8#X%ARU|~@ac1dZFu(-5{l-MJ75g}m-K_M|gVQB$jQ5oP@Oo;t| zemH^E{2ZNSj8)bDXD#599H%Q3>LVj47!(u)3K9iD{9FK7X=yBUO-w}#7RI{Tu4OP z$q8)l;4JcAJpVg*31w9YbtP3*X%%r1VPQ21WnncjDKSw=b!8Q4VF?k5|H5i{`$O%$ z!A}2O+YMOze_&PqkFYW-eoppKh@UA0;`v`IFm#1LA^xrqA9fWLb{;)@u$wpbGcQ(0 z|6y6x$G??$TDvK8v_2{G5;TU$N#Uw69kA7#9GS#!*c%n6=06oxBtrz zfDix6lbpN(_wfV#M2K1c0}hT+fR?I~Y4G$Wia6J7^@GALx&}QfOCCGdL8D|y^VzT$ z?}fHesD@(i3sO!^mbdRw8Bq;d62kr7>t!Ai+4=7sC8zWP(}Caj@1F`!`nZbvU&!s; zL<|=iy%hT16t;5~apEslO%jw3yv;-BwhDpCaB*-HeV2KFe>iw7zzY=yczLc!47?J^ z{Qv$X@_6OzOX4-O!i_W^t|5VLFuis*;)bP>SoUmK!!Vvy%W50MR)7hUdBlE5%~@` zop~(hHp&Hb-QvA|H$NS)=M=HIBmR8S=c3!CZGKmq_WEbm^&J8Oi8p7927a)DE53q@ zUW0?FyCIzqaAFuRJh+OBz9&B(>Wr`Af$H9a#&hM94G!p!v_4FD!*X`t1$*?z_1Q)B znJ(XKP9@amkN1GA%H=HW4-ev!&;C&Qeb9)?8&)_@50{7zBE^ZOz$r)O_*-(q`$bDF z=hF9J*+z9uHzjRBhsW$gl=pGj*Nc^az zC(eb<>>oGlFm38cdfd3MC1hTqpq1?lD|i49kA?TsvjF3hGt17U<&EZ>h?zls10!Fe zv&t9nKY^ReuV&Acx;I^ppCa=XY4EWC!rRB^aSl#N?w6;-o*G?UPi6Nyv4k$C_v!zUct!cEyJ%*7iirP2|`2#e2&v^xkZN zSUP&XHwIwESMPVwkJgsk&a=IY%XU>sBn|s)rGM6dTdjd>V_Tp^;M4+ef-Aunc&#XQf#t{Mal zG8@RuaIvepx(s1nMo!I73C%~~RhQ)%OOOTlqr%|8oOHg|i8$;?TvGmD3?-DOdqMi| z{P@3J>K1Lw1WH`U*C8WR-iRPfA^ zh=@lc>9f$-%Tv$F>od~I_Tqm82L4VEZa42c_E9%qF?{`G5tK;qdp9U_kMi(4$O}ut zu}|yk!Cb!a zDa0j=SYQdGL3%Ia>kcnEX##l2Or>PmjK1J;zC81U?!RH5j@N^%ygls%-p#GNtshe0 zuGy_ReOYd*GFb75+dME^wXU4odGbO9(FD(^IiTU47uT!Ut{}n=o3(*_;rp#Rh#@7& zT%?F(A?(LfdaIsglwuYl%#b*m*Mvqexzrmsx+2gmu0@n0a|yP z(dSlMEPP(6Nioy1dR2U;_&{JmJ{n;4$Y@Pq@&_$-f??;$tIbh3Q+>VxWB|M_+Vv|$dX=sDcE3bszYez1^{Bygo z#FlRil}eT;*TW{!okFm+m*dGcFze6*!+)^6De z|3SO)gdZ;8q6?Yz6s!Wl%eO{a|6>VA?yVHY2R+5M z4(m2G?OAVkvT+{UqZYI7p{~@IQhg4J*ukZ^8y4GeC&K!K$&Jpo)qcZ!^#>lEr!v+b zaPe5!9Y9%C2d*6322_aVEW8u>*Z2JT#40}*Q2^>FRyJ(QnMO&g;2WikP}8rcxOrj` zQqA;|vpihc;)S9gJaC&IK7h>zCmr|wBZbG;J9|39))O*dNLXbQDx$jgU|?qc_UI&F z7KYRB+#!kNM`{)TAg{~(1Sr|2_34^L1re~8wkZU0c4Ry;#>6Ge*barc#UEq@Em(sd zo8kise4uXJ*0b@J4^j3k+tST{2jYSNP5$luqn&{rEp@6gHIw9v3X(gPN!8BUCi=0} zM$l0YuvZA>@$0Az$uV&pQW7ubdNwxEwPQu7jSI+gM988Fce!o$t#S}6@Ag$b`^q4& zi-=WW$2ietm0Q2}F1&)~2*=~|KML;=8t?2R{9~WTJ1H}NGPBW)o`g>&(PIHWlBIOF}1USb}hGO@*jSyF$=ysku||| zx1jFu+WS3%2w?GBi&EG!HwjEWVVhZ>Lt}9>?o5&|;@&^@@m6UmVYZ>-0f^IJZBj@d z`5UXUPW-zWBS5o-@Mfu7c!0RSSo3{sHC@Xlnstxk z4qR(dnHM(tQTtE9q_1Z5JmANFdKqLD6r~GqF$!Kh?FJHyX1xCx2R(?oVJ1d->kFp{ zau#$Y!U3_V>`eOyD)TgRt5#wX^fT~p1Qi;|Tq~$xuRDcTdGe%0hZvATpJmOZ(cPF% zLX>naxnxSsL$u_hw{xrifsMCfcFZ>ov&o9NCLMYL7xt{7D6h9Smj~nyef2=wZZ72@ zMmht}@(cOLLx!9t{WE?;a$u~f5tLkgHXyrj+^#NOSUSs zqQCDy;>54vV2-x`^<{9nqnZ?d1sne4L3gVTdRua|i)fJ9HtllUw_qU&`>{n>Uv(w+ z@T7C{l#KD+LT2mhgR3no4(IeSBe(!ui??YgCK%+c5=7zkmHhMO;OSEDNKT?VHdd!V z>upB8WLh4wS1AL-r9cHG^|zNz>f_0pz*+K+Df`?1L8%S8 z*WmCXBkb<0hiGJ%&ADpP_R~+DU;jzf@+;#O%6quxJD`p^fI}Gwa&CL*KbG~*qO=p2 z&M(0H4oVvOyy-C)PFq0?N-#r3hWAs7 z`i)VI${|-qSbd8vs=zEmn6~DJ)Wi#sEAdrcg*!d}yfgP}jPh~*{V{kg6CRHk!v$>f z=UG*Vv4J9%pIr$c>W0B5haP?Kt{|c*M!0z*tcp9cIo|hTz0Aa_;*by@_B2P0xA08| zH0<#2T10^36)9-7GwI?~uM?vRqht z9L3Z!;Q)*52>re?^-0rJL9nEL$l{88YjTQhNoPuTKYA{Xnhmhv&mbz17UeK;k^^S~ zZ5cf!kP7D$b*E*7ac^&W#ri%24U@zpGQaJM!Sk#AfB=cff})k>sKVvctN8V(z1!N? zd$&j%+?J*vmeC|$)84uW$>SJr$sD*?DsNn)!>UnbrQ@J^po7;yjMhf~F5|wV$mRf; zE7k<<;cRkr8Dbi^7|hh(?zE$#Mwpo*C-}G>WTAR?9$Iy?V>gmk7oPGu{J<(h{*>9b zG9iQ!@{Q?Z%3A%?kdrG93I7@4M=uCSpz#g2V>UzT4Ntg*^tKL_^0lX0W(|9L62>CF z%T#p*g8J9jTRM<@g5_0fqu)w~i?$Be>AF+}qm~MI&U)D5!|HcKWT{}dx%g6cQSgz1 zOH+v}CQ||#QX*I7xGLvlir_sjX%V>|Iz_1AEu@)adByOD*K5eP6LtK#JqpIFbT*?_CmpY#&49^`G@EwA`Mi_gFokp6fb4)~II`m50Qz^SiByW$ z&{n9;^NL{wzikEMq*1$ zlqTJ%jvteXk`|ws7oJE!ZO%iiLr-x42jo2Z+A))4gL=6a68}QdzjYEN)-)I7U1T(W z#+{kkUC3@%9u_+XnP+9ZT+sM_!*XO8#HHvNB=24GXJe0-2;c~Dro4Wp&Gsd93v!E) zX$8bg9D#W$wtKbXc0AVj8X0k<&A8uBoIpS+s9yZ&cN^2p>!eqk(FUUINRB&y_#i1M z`+M;R6Vo>8N-}z#pORxEj!nk=M`Mda&ur)fi=%f!43p|8 z=@U;t7U|T{9o`*{plfr`FE#qV1!e0Y6LhP?$b)w&$88_>`_DDIv%K?8x^m|q8@PGi z+y;Pb%vwCAc6xVwWequp3<3jS%)-2`Kl&8Z^U%LQ>jkAZvhEd^#R-d;OCBADyLO!L z2-bEeV8NA^6`g5tsrg(bUj3H8N^P$;o)gch*?2!SJXCmX<>kFF-<{L8qZTS-)yBlM zd=P}0%shPqh*w+RsVygaE=R14Y}|Fl+aPG(=k8H^g#TLSut~XL>%E`61&PPsMBPL- zWlB8|J_%~Oz_wB96g?(-?%PE*I;JmyP9OmE5KnZC>d@YH*?=E;8>2$s^s5JrbucmV zByfKkpW_Rk2B02*nX~*}9#e|ZzZ_;3-?kW97G^xXK6zVF#Rn@GW|PTi7qC%Q;+`HJ zL5a2SDsOk1{%{Xp#{$~t9X~M@3KXWjB{u~x-Kgw~B{!8mYj}Ib&@tbX?^wR>^8m&Z zw03-7)~A)OTlRIT96PdTGUZ;wfs^r;`xmihM0z;4-gRNo7y=cuSJ&~-*K#&0jA7FNeTh|bw;C0>a;{0+Rb{_(1-hp7&AQQfQUZ+7<(t$Lt zbMw5Sw`!V5GU#muP6vk20k5Dg&5$sCdXtz{aYjNIO@LKblg)|9j;8k)yYW>~o*&#? zH*+(j@%*J#481X5Byj;KQ(A2~n8LD-u-=wqQ2x)fs%_f2*w=5X7)0Y?m6O!nI?F^q zLVCFC#;=XTnSd~@2L43l(0EKa#`MyArCD+KW93qVPCpxKO}$ZOy5NIxxXVY4j&5$H zSZ9*vzQ8rJQ*~h5PyEKXD%gVhk%3cs>QR{UT*fZIY$eiryzybCos@iMVM2R)(jXaZ z^k9dF>v22~F=*NjUR3~x)Hwos_Sp@4?+z1-se}Q+eER-^?(lDF$1jLj+DD&t(~Z9B zT9zpV4yVr*<6f*DKkw4%^G3(Uat_UZA!?uKX6sc?iT{gsSRz=8wD@?U9hI{2b0ekF zwyM)+brPEf8dm((lEd67YAKYBYGltTI-RWVkyCi95EZ@|^06Jt@luh}Y4Ze3h5lKW zb?$)8LkxX@ol++wC@ODD9vRg6p(wn~&(aj;7FwUi^-V1Rs6Yzug9M-WgUYapJL#Zu zbJ+pM+5CS?UY)VkX{^`kF_=SCT zg2~Yg6tlXzaKOnI;$TW^U86D6vD=qoEHbN_C+i6dBiWs} zSN$v07)YjsH)GCIxZ>L0KjKj^H+PSW?(ahDiBbwSg-ph%_7bXh+cSOF_xKTc4LXvD zZk-EpE-7cMIH#wWEBh!{!u1$YXKo|2lj-6Qr|s;z&z)WbW7Y zreNKuW9_GOjbUii+aG=XXfhOCR@&6fWpcE9Vbn_Bo!r-9P;ry0>_zJyZ0e*kL!2SE zZCt-W(LZfTOEh=VDuCyLJpfdyZWO^84CDTyV`dH zMRND>eh|I?^huS&x-e)Xmg0(xar4Ce-N?zHNjves*(SAN$mA5Y)bR|WE5|rnqiBbx z#huBH4}YmCm}Ge?NXl)Uc!n`&{Q{)j(xADPZ?4r0$8FWknJcS#9z7!7zGz+*Q5f0pXqqL1^$dqr~74*cQ@PDHvfW z$=&kg?BYT+w+x7THJ-0Wz_C8{xJ=I^1b=^!_)C}%)911KUK7vV#nPF^w1a21mmnoa{5&d5R1I-ijkpf{YR;za@aiCAI~IFzusp=ID1kS(lryI0d~}&85`Bvq*Kx7f2AwSV$SCx)VL8>-~Jz zhr|2BgK-k9BO^V1XUHFAo&(3?2*Z>{FC@9|OwsbY3#Ozy3!LajACr0KKVC+>+_eD0 zk=TT|aVoQW2Oilg4>z5}-52lt=fC6T3R;(6{`_Y<>Ez2VBzPg+Tcn>kNfkM)>5QdP zQtWum2B|Lqr^+uXkdssl=o;zx%ZIv!J@n-MVce?QXUK^! zRj`cPK-P;)Gp(oTmyif#2stCQSG|7o5CYQJvSwF3T2-DaP{e5-k^B{i;bnR@2|6Ta z37tMhOC2?-0+c2RG?uddJD^?1T0Lq(B$G%V{<+`y_ zLcCABH$C%G8=&?Y(QI5G`X*_{m`81+9(HfVFGIl>uh}Ogzq#4f^>e`2%5w4cLw|a^ zPMbdNe=%Azg6f?I1Tt-VRKi$87JWUTIPA#dTG1NvngT99nFN6;uHnCwdXj?+aM$!R z$$;h8Y0CSuKLh0LOso0BTu1}b28MwN$!DvbPu`aMFwSI*57@nM$LTUt{4Pc3Un=vg z?pV0FS)kn*ih-;nzgw~+t@K_BLz_)I1Zf)Xj00ZYQ)6^3Qc(YMpGVEA3FFvcF~EUj zl0A$iBE55KQ+^^_yjdf8Qd$;1>BV?(L5-oZ0TM2^GI)ERShK{YHh$1gI7Q6o28~ql z+FarqKBd^9MTehe#^j3PR2V9yE_inLL=tL|n(2j`yVqpV-Tb0%?w~{0<$(|k(#i&5 zn3Xv_6VvOAo!eN-`1n`ZKjDWA(`;;Qzr29{df?`>4({ATIwFWua?#*3C2LcxV> zvVkIjg*9!swG*0fNTMmQ!2s#ptoAC3{-Fd5{^In8RbYckACW+YLSXLa0QVWv@_J#3 z^}yBnr4nXrrYTxl)n-`*2XvM%5V|Z1)tzWyIp15B+G@gYo%}_@u?@3ckNk)9&DMZh z<340GIq#)yJ5SgXPrP*MteBZn4For zhZc(7%E!=*NxtGosL2eY8tS$gWZp%1(eYl$u?h6F3ru(8U^RVf&9iRA+#RBkUBO>F zG1G11XP;kJoeE`m0hQ@A`AUV^`cpc=v}_}AbRBKI;E}2rXY88=oMBfS%otH2#JLtz z{p6O#asf5eA`dXdjkr3=KPyH|irT*OhEM6T76vz(v{ZaeOR$)D7mV zO~Xm^pBQB6M#p5@p|SaJ8ry5w?;v=o@T2U8xH11d{&_=_@K zDw0Gmm;5H(YE)ncUwAkqtjiDSP4R)uu4gNuQ~OMI(=0^Nv}Bo~l|OW>ps2%Y8&~F# zVrwKN0Ww-2aYf(a3n2X6rWAsvL_4swAK7hB@Y5c-fAOq zAdicVwnowlJ^|Mu>LpchBgTub$>f4IdGw_T*>e$Prg{*B9CmF&@6!Fh)AzfH4ES$X zYouO2J_Jv`FQsY=yYE|kdw#9YTqgsV6;rK%uAed<2a2cBz0!?e+dtWnx0kPg>(%#> zKoOj>DjLXx#%!7-hJDaJGlk~Mn_p{8_Cgx3&?8gaH##>Y}wKdrL(Aq3c|%I-K@ z_H`|-F3D>#?lcZBy=4!VC6HV)l(L$ojOax!mh_zh|4lI6xf; z2uR%7t9s(j(`l*S!N4WLAyHmTG%bn(MHKp`m$=AKP+}`h(s_Yz)$8j6IsoODd&U7w z4|;~~Ya5ZJvF=g8-+jyJz#wn8>#zYu_0br{M68#vz+7yqn_9(PbnQ$_c=mH&giAEM zTx#&%Fjam}7n+qXT(%Axo*zx(U<3&8cGed6Bg<+9^jl9Lv}+ea>pXLmzCELZ4$o!Pmf z0YVtV5>4UdmAUUiu@H{?ZjGla-H8TY&S#^I?W@eTn*VRDSQ$|Xr@Uj@MHZDp6{hv? zFuyQ{35KO$PK$86Rvx1Een;M@6%yg-*t(}<3@ZE?tuF1RnOJR2KbK|kHk=zEMR2d) zlAKA}+ju9-`jtX1&6OFIYPGHQzzdT*KF~p)We=n}_&{j1{nUA}Q6H~sL@Mc;@GLH0 zHuQdOL!8of?*q4-Sm4?vEYT3(5OA9&&er&3t3wVqSN1BSPxCG5t+RSf?{NK+1_&gO z^{>PBv=~OuQzJ1 z|6zU6)zUb#coDWa?g!jz{0bTR7J@OFQ5UoBlS}XA^X)zT(5wL$4$U7Cm-}7Hg)CZq zrv-7RM9|sSRW0oxzpvVHwY2HdV~C<{n|2E1WP~OB(~s#KqRaq-71@S*oB3w-$mdJn zk{s%;yo(xax7rRiH662QpBeP6-#@nDHk0Oip%~X#xM{xjWL2=n(bJE0l_x=wQiOUF znaWyU;0W9$fz+JG+*iGfc?j`XvLRI&d9*wb$zvHo7Nc3;LGnZoYc(@1Zv{Pq}_V74b?H)M^VuLPZ zZD@iA;-Bp*Rb@1A71GpV7{C(x<|q5GPKK9UXsy{b+$s1aHD&j$lbCe44e-o|RLDSw;|IX7WRB}lHOdP}*hK4Ejxs^4=Bn=7$ z0;+HURB@=e(JK|yQJE*CUczXk3DsBPQ#*@|btO2j_6F1DI&0_6KpbFOBM)z_6#=t< zSQZ~1+0b{8j*b=I!FV4vxqd=#Z!0^dPEy!B(~2=h(|+XxZ@xI1wu>`VD%2Qp~-=j#VY6a<`E6!a5o4hqsisKih;#0^(xjt#z>|ztUp`qa6|^TnXEA zvRGm$>3~{|f|GstTWAp)mWf;7l>< zUg|K{Bezs7<*jTUM>;@MwtjzHcetH@N%csF9$wau>>wNKx)M!vU%?KnpXuJrG)D!w z%$6z@X1)FSYSTCE%}J>tX%FnG+nUB3)}iL)lb8^maDvsP^1g@W~D-La;Yb1wnKkJ5o5x(`p3C4=2HQ)zq zm_?cGI#%^U6{(aOx@E~}P=pL%s)GC5xufBwCo|P!Qndy}^klXB=rletNpoBQrN3Y6o>1GuI2^$(-4-#`fL)}Ayh;2GaeirIXH zojk<2RWroUPUTAhAwM(*r1el1`sjkRPBG-GgBe=fk~w4#kF{-QYHBlE@@bDX(V97MFhFF1 zGUl+y0C-_Q z)$(KKPp=BWAH}k9qPb)HeL8I_3YUEEB4S!^!Y2>FltX2xa&XcvuTml1M|G0oht7N^qu>)D>aPOn~28!!QtVdb^B!cTm0pQN^$Qyu)$6uMz4C z+7D-CX$71xuKqi?5rUf!x0}!yr3wNufuWH8Kukz$g)SdUiye;3Tk*2c%KbpIe^x-{ zId+XqD(#d@cwk%9KmWLO+0qR-w`8`lXZA2dUGKE289|23f2D_V0yef|=q=gIR63U~ zQARrcysQ;ddO?Qr`gP~N$!O>KCR$g@encqmN2+6vK4ZeIMdusRrE@6hpGg&l9Va`MofKajBxPhL3(xXxMYTH z;l!V}!XZGlqFN^iKT(j{Z~jdAT?r@2Vc@Da*;IA^0~_gr7x1A)PZ_95v1~0&8bjtU zSNLI;U%+|UxM>V%Ltd$jiap4g@YKx9lECYy4PZGEQDHBSjc(rF( znY+~q0vtl{o+M<+X^#D|$iN*Y$spx(}ibeIM z9@a0+YkYn*HLCHx(@sL;=W z@?bQpBeF=P8fcEe7%lg0hO4nWLs9L#^c`DV2khQJ0cM)gz9`WMWtgm=` zGSOcN)Ga z{`7t1#zy~&w#%IAacP#26Zy320Bd8Wybo&@cAtl|z-=$jS(9y2)Eo=F_H&KiXd88H zt7=_7-u^~V-J@i6izocO|Fz{-4YtlO=okHFkN;zp7SKiDJTD(9g51zv>g#8d(>^2m zbcfihk6btZ(aN!#ai9t?Td(Cw2$PquIx!DnlT8vUQK(O`7#>Q1?{1r#6Cg1r;gq8B zpmMtIRx&Vlwr{2>97K(698t>o3)?_?;rxA_g%CJ-^d#YB;F}f=HiV>r;kh-iCq-Ij z9y>zo=w|EON9djf>u@#k1)uhlm{uiR-ZZ}gs~gRC`@VHSB}B1 zK%KXc1rJ4FF_8IVta)?syW{@T2Nctbjn1i&$-{MfOXk>+Yf|N!Th^jrPZoF*eXJcY z(6z7amg{I29!x5+$9KX&lV`WJc*8bEqCOu!i{cP@FjS4`Y>SaJAOb@jdOUrBOx3t+&azKR9e!vJrB633)7?xR^&Ci*34YYFNYOUX znZfb~v-nJeG%>6fzm+&ts*N(5V(XF9@XVET_mO3#20M~#Xsax+`nYwy#U(zPVJBN20YLx`4>be&?ygh2w{`eb%i# z29Er~4b9CN)pZ(i6f6g4jp!ZRWWni5@F+EgdOXk9viQh0EWkXrjsU6|=Z!BEb=kJ% zlk^z5wL!VQ{<(q-`aV>|Gkb(s{WkR!N|*~M!_Oz#jAxx*lC}F|zEH?%KIA$0mZWwC zUa^(dRgy@cV3A3dO`5si?by8kjuXk{ocm_Z$#{IST1K}i`t|lG@6n;C+SOf0+b_i; z$i3NXrqP%=IpcVJl0%YubKmOwztu2%ChL{uiL%HWzj&eh#H2+!=wu>P-Lh4& zREogc`7grCfxb!9_v>>QX;h16D6T5YlR8xtUa2`1vVYtRiRgS2^efGs2M^u@TyJy) zY_c+~UQwY9sX{;mPIlo5`+bQ)6U{zkI4W@zgu4+98u)}}KQmf89y!>Au5?9v??wMs zo=bFdHx&9vMwg|Iby$h$NI4>HQo`fBXa1l={r8S zq>>V$H-$1s00zd@oDp(;Rvdl>o3ur zD-K)xkY#)SuH*OL=QuGvVzIN*JG)CcKe=|#l2r>+?-U=1aRh<08EH1v%8fH37Gu(H zH_>DrHV#w&1+K+xeI%T}pn$6Bb45YF%;Ty}pwXCuY4s&F+VFEU=z)`Mc=U)`n}hYa zG#v(LjPWT=uC%S~w24fJ($@hjQ(F!w9|Sq?eTc=QTWJ7DpQo`eWb0|EG~Bg0R|Gw& z9iIbsiL}JDoU*@L_2w>SraHh`uZg?tliQAA7_e zjIhwzG(>OD)$2_c%%&ccGK9Y?qMtO>mER)($~=2e`6y|c?Ir|pYq&5gCZQ$f-@H%D ziA?&%13Cptu9MXwxo(A0AmvO_h+R1)>!a+6+{j~#fv!*~W_%n&%Jf|b9XMj>yhs=#5&x9wmMjQ2|TztEiVok-2TvgYd`p)Ft{D6!Zp9z3rWaaXiI%d z2DFw|0L{Dk1VC_1^DUS>zq#Hi4uJ>U>>cb*DJa%!&Vb)jS=FVrv*E$Nz)%63;}g!# zuJlXHiALY+lE5Fsws-BdueVQnG7vdLY7fA=6Zf=tc$$gT9?)SXwB>x*>4L!Q%rvWX z#=P2cXQplPp+(g zzNr&D$m&M!?c6+nb-d@S^t-wh<_jM?v8{#*5`+@_-*uL7-+40VdY?8edc^fN1K}DC z%f)dJX`}4Tx=KdKA{DiIt4e~aP+6bfs+Zs~x>=1416+QErI=bVeU2x~FwPnxWVx6- z@%mhTdp&?Kfq>=u&?Vv4FS)pp#V#kVwn?9qF)%fTrH8!FqO3FT2m$TYxT9UAb#mns z{o(wE?~~cGJ6ouf^>*eNJsEN71N-EtEV^ojUrCa*NixW~%(>Gd>rcRz!~<7#p>Z66 zo|+W!zRy}|(T>=QVEZ!UZur*k7&9;l)U&#YqUVN&7GJakUq=&xeRe3d-|m7j@a??QJ@Ea3f!#<&Rpq?%Plj`U96EMvq0#c@RdeRr z@S12K6;l;K1@;1+S?320nG#QLYOWd{XO*~kcf7Q{?s=Hd_j6BO(ea~KSMtKr-|A9% zy68D|hn^pL*L9L*59R%+9?YKbo(%9G_Pk)i?7GNL{Ee~&a;i0hq^#dbY}Y~w!3=?> zFMnv!-<{v?J*Hgj6|F9*z>9co436`wmw&mqx&c?F3}1G zKi>)PW9XzaZtvXQ+rJTu9qRiL_`DT5G4+Xj2^w5k9d^W77ZtT1N5%o!RW!Egh$$Jh zaoPD3Gt45ZK1F9+xKdE?@lbTw_L47TgkiN?;TAADg4 z(cr-uT3l}i7Ofv?7ReIhJjYvz{qRI6aLsR3K&em?*v%w>76+MD8CrQ292`UTI}%y7 z>Fy_)#`k6q-@G6@%p9;XLQE3;k_JGPH%9J(RsQft=@e~!u=Rhz zQawQ7NONrGa;!chIG^$9sH_>kmOEBE(#QqaDH^yFU|D`;gL=Bye$SYk?Q5?W zaF)fviJ2=+U356(-m-h47?osu%;!>beC(L~mDT{D2RS=>u#EU&VLX0_E@p3NdWLu9 zyk*dcI!oaV*T=yrBx%F-%S;}8T69QGa+pr!%TbrH{srg&E~~`FQLOjDZ-bbI?wA>y zu_J5Dv<3NHHjQ;n@Nu3yEUAZ2>9PTJkXGp7zAp0|XD zVa}Q;!G`GC4;w>pSw94sI+m0A0me~aZ{OaTiXNSm5kuC!3H`ytv8}n>2s|UG2C%Z^ zaAdh^Ll0Bj`6-S1bSdWsmRT$T#(Fnb#3Uk8M#Li+cHZovSZFaD89`HqLs^Abtr#y5 z1qL~6u4hhn$cseFzquu>;|?_0J7hEB;AD`tGR=q^@38#{>0H4_5uP$`3DiFGvvX>ik@)fwIV9=a}_<2YVFD-AH0*G^xWPQwURn5zTRp>+t-@rUjD#D(GXI_6R9s8B zFW(meqgfm`6{vcy=zWK|%EmV0n9|%E9)6c|NrlF~a2&ZtTU^v_*8M)F`eysre~hN^ z-pZy?@8oReK*!%`-Tj;g)R-$N7oCjS`f|pUR{FwBeQWJS*ogKKYw6YeZ z0gbHzR_$$r-yV04WWD7p*DX_GJ7-V1p6WKbxe{L#2%o6$n83ps+#Dl6vZ#UAc%8X4 zxfR-R1Qetxd+JenH{<8(W#vLDO7?Hj{f@6wQ2pM0e6K27z6NC%Ct0X)glbMlTwbJB z49i(1T*woW9|ga}$>wnK_j#1nI#+p>rbdU^mITV)c@`?D-6wcrjr>8w{mo_97so)q z?hWi4>hB+}SN63Z zL5H%s6{}o^i-V`~oQI3k<|AJXAo5*Qt_bEdo{RdxTn~JgP}6o((+P9y(eg$=Cap_7 zHqA&t6S&#bf8pLJ-IogI)JyeGjo_E3Fm!AxF(0=s85yh@kcTJ(Bm2gl`dPL#0; zcz&(LIcu&eT3)Yet^_vu=lQ)wob2Z@EM7ms-6&U=0pCu=I-yLLl>{q~l| z8vd6VovGZ%1xYiWS#$0)39XieeVhGmnft9y3`gIr2z{KDM3nZ7O5A{+Vn*+e#-t8t zvXY{k!&`TpoZgQR`IH$xteQsm2Dbk3_N<}Bw1!=WEWet34?FpEOca$ei!uOJEW1uj4<{dY94*=XJ#EoGrwrlK7m+#-*@8}ua%-{-H8!Tkz{ zZ}-4aM5W--{Iw#eS}1*Cj!p`aSTnKVTN$C zeZ=!U3x_6#O7+cc7!nFv(TJQ1&)Kt-pWpGm%nVSG+mu|+Scy!Oszu9NRM~=KCZo5R z3whmG-^6Db72N3_zb?D0Ympl|A0qpKJr&mvr+kqp!;XFB-Op0S$?a&{e)<}dxuIM* zNuL!i^3`L52bJ!Bb@{r3jXy?igCrk)Y!F7LX_fDB;7HkIdFvjr3PwhyHs&G%|3r6b zUED?74l%i7j>2*Io1b@EA2m_?dNy?%K?=31Pk!;3s1G;ywH2)BE|@=y2jb8{7#f7= zZ8lc$`9`1O=8mKH?RDmwDRo4j&O7$yHVT(M?3%J>VXF}FWvX&{wy3-i0n%mu`NC!NXIR9$6hTKsX2 zp8Fs?U3j%64JImD!O{D5VEwxD`l{0N@>Fx8$bH)MZC-W%iZ6t60czcmD=FsJdVO-U{B4?{+p6oHXta))=c#RaC8msFRnq)%b-AQH?VO(D9}Mq z2gOZ%erI)Xd*Cdf&4LKosYn;e&^shY*Zg@2jG$U3P5Ol+rt~e+fSaT~Fmpfqu(MVx zTHcH&s`QXzY*~i{`RlRdqPttYe{3=R6VH`+1bp5Xge%20k;Ntn+(UO}*Xq6RMda)= z)&8Di)c+eEPKcY$`y+jG_JiX@Z3UsYyau|SexJE8Vb*5PJ9*Hu>M)m<_?)Jws_!<8 z#fl#%S1m4|Qu7G&domMmZ(roCP5Uc4862e8_V%ge)(+fMbLSKOm19t()id2FYeW3p z!PNl8hIUcmQp4Lp-}b`a=E>TxGb;Ks;-8>|ojV7YGhJ9PCZ(I;j)NIw9)9lD|5e4A z$3xY&aeQPevPF?Fl|o6Ph_TE>C0QSm${yMG8HTY;JXxM>6(xxoTX%!Hi*;G4Jtt|9C&|ALp-g-Pe8J=bU>vzw5rfl4^-7OM%6{$5!HmRFzw?_0C=$RDLJBP^ROAWA#?+P-F3O-$#ug{xyV+m#b1#G6RQe+nvR0ER;&jrpmOH`G8cG2EBd=%&O|T zVl9rTYdYowj$aEq1a>v<9OFIW>qViYf-7R8TYuleN`X8&tN0DI$s;L2;bSn262+$4 z1bi^+j~^n1<}>RccfpWnj~^@+W6saCOI*>t$*;96=sKRiJr~)0tf&|Wx@}h|VtBjk za&Erkt`y$O5s;QvVs=RXiG5ctaQ9ETI57_wpoIx%;PS&-K*f>v~=<{YyAP->>$A8YMD;bXX8>ug&_M zbTo~Sp-nfatfxWsZ*(f|o60PYaaTUd)SsARJWa2-?I;3hQ!*3j8-l?lVz6btI?)V0 zmVhj0AWhyO!IjLGn>}R?#93gCt=ROk<{PUA0?K$V6RIVy4LnHz@~R*nA)&$p1O<-TvVJedf(|RlLp@Z zS$yG+=ATdRp?`cvJfAD}-jEc#%L@^$%lo+R6bjuh}jY}AL34Tbq zmIM&?b!~%8gt}&>xN8Hcul1UBiAzkLdIld>s2*Wqz1ayJQpW5Q-(gRvMz0%AVPVM3 zL!d`asU^!t^Z0_UXZjtUF9@oT#md$pW&yQe_wbXm5MU{gM8^#+xgckMy3QgN8mI+^R1|U}A^f75h2Ph#RNYNH z<1ufx=Ap`puYzPWNy@)~>|@#0`n}2{j*m2>T(Z z$T=GX{iTs0qv)M)s$&>2Vo_wcr>K>RPV<-p#RUrF1qPgGz6LNRzP7u&Xw?asVK zhEylGIUl-Km$~L<)U+Q$%Hh=-F2wdEZys#9#Yr_$XTjGQh&3#X*a^U zIV0O>m{H?C-UT~%8l6> zRqS(P@zRy%4GFNubGMLr_mF;Ivh0%8HV`80J9+Q?!Z&+R{8bne1M*W}A0qd_H-s&D zVjKf{1|$Z=YRZo??6{R;oh6(3e8a290#kx+-%v2g=(PfZT~Z^Xz+WT~gs__H7j*f|KPsW7&=S5eHHdo~&u6)AAF7=1 zx*1V>sc5s-L%~E((DJWR}3%lfbZYrJ-as3Djc!wdL2`$wJSEUL?RR3is@99x_w zP4m$;0z@Ar;c8{{hFxusDzE|(L^kPeFF3X$!~p=mB#?V*n=yZy6QD_Oin7M)kbgXB zJbzLHYYH?VuD91}&qjaSvZXVwU{Ycs&8-5BQaBtPKd^RiH{~j7iobS3#F4`x@2C#B z*^i;`<^wVjh__o$4w=@;xsK5Z?t&qsGl-Ga>X5`>pgIYKUZrg)bE261wRDWkvrB|C z#nC_Jp|g382L+8r3i{rn_Yj)wr0e@MU@^-u+atOUVfvF@%mFMEEG9_#TlCdT<~sZa ztXK#!KVUz{gz_uIF6CLX_iBXb$$I+fW}K+^UksJxfqFZF zTt}6q1RJxuSHdTGYTbG3Xm>Q>J9)kzKD>9yI|)4c)akW1P)QyP=bi$4WSsqOhz~U> zhxzdVnx#p1jX@m(fe?vWt_jc=#%q-%?Hn7djs-7sV!nJ)MeYmFU4Wq1A3cF%m?sZp zR%H2+JD*^nB)s3Ce<`@<9Gdp2ld2-mh}ZA}`hiucwOb|fG}%IPjiWAVwc!1%u=RFS zWbrX7)Ge0k`BM_G>8%~`nN8N)dTF{;Jw);jxDO=M32)Y>d01y(l+sB&6AU==Q@(wP z9b@WEDyZ!-F=K9h({Q)N83=4d}bi z&g!q`w8rf2$@^{Vx&XcltJ2JJeu3sVEXJo%vNy<^6-;i9S~_aI_H>w$Odjxr`@LP( zg14BbcP4sE<8c9`$Re{t?8Va-43TMXOE@O1kQVNG@gjl@LCP|BeK{63_DT_CD6%HHFe|#;;gZQMRXX8?ok-(d3OB zdw1*P2gkku&0S~Mo423r);&d`Rx`sp;MLmxi_}iLK;IYp?mkPc7j(-6pIOW=LXab@CVMNw>@`{ zyUI;wo15=BD{PVYhEO=wfFwzl>L|U*E?o$Yx!Uwbpgpy~4p0tDkh8Co8#Yty=YHE+ zZP5sx@bW5-%;bIO_w*aN{&#+|3GBtzO8NH4Zim-_-|zrR?abwE$T&;Kw`Z79D4tF= zJFmZKs!VzuPy<6+G3qELqdfusW*YXi6km63dDKLQUl<6K2zz0Bt&g?KSs{&^Nc;ur z*nnp_BsJ$JUUrTXyMetEaGq|-qj&H0&Y)rcD*E$+NaB7hHsNS%=9=EQm^%^=CEn&c zd{6vw<)0tVeMwnYJCt3R zwt%g2vV)WRWCgr01E+n{@U}~CxQs3B`J2t5AW(_bB9dYf`2vkxn^F;XShzMdJO59P z{f{SyPoRp1$PNwC3E;AhsnOL(80f1~uhD|59kzFC;e*++@&M@edbBaFp9NU&}yQ`PP0CT%P(q>YB`WZp3fhui%b=;N#bnbV@4u zWXd(?O=?88*KXr}@s&z%^JU3~SW*AA^)|v~EJv2$tISI_-IJpVJ|rw_C&+=WWRp|A z-t|FjAlvnsayvU8TN`_|2dIXTSVc`$ay_LDTlH5_nYD9r=?LGpQ07qqoj^rR?&!_O z4TOj1TT#lbb0^MdmNC#ndyRGeI8h%>!7AMokFzjk7hd~%72nECeRD@047wOAKI8TH;B-_hl9E8~{F9nh6V?zdEN|7P20MhH0SB<+maoML+!bGn$k_eW}3 z{OrFU3Yvovh{{R+mF0uds literal 0 HcmV?d00001 diff --git a/project/members/templates/members/application_received.html b/project/members/templates/members/application_received.html index 5df9d70..369413f 100644 --- a/project/members/templates/members/application_received.html +++ b/project/members/templates/members/application_received.html @@ -9,7 +9,9 @@ {% block content %}
-

{% blocktrans %}We'll get back to you{% endblocktrans %}

+

{% blocktrans %}You will soon receive an email message to verify your email address.{% endblocktrans %}

+

{% blocktrans %}Your personal confirmation link is valid for 24 hours, and this check is required before we can process your application. If you do not receive a link in your mail, please be in contact with the board of Helsinki Hacklab.{% endblocktrans %}

+

{% blocktrans %}Further instructions are emailed after we have processed the application, which happens usually once a month. You can now close this page.{% endblocktrans %}

{% endblock content %} diff --git a/project/members/templates/members/email_confirmation_error.html b/project/members/templates/members/email_confirmation_error.html index ac6c76c..d620661 100644 --- a/project/members/templates/members/email_confirmation_error.html +++ b/project/members/templates/members/email_confirmation_error.html @@ -1,16 +1,19 @@ {% extends "base.html" %} {% load bootstrap3 static i18n %} +{% block extralink %}{% endblock extralink %} + {% block page_title %}{% trans "Error confirming email" %}{% endblock page_title %} {% block main_title %}{% trans "There was an error confirming your email" %}{% endblock main_title %} {% block content %}
+ warning sign
    -
  • {% trans "Check that you entered the URL correclty" %}
  • -
  • {% trans "Maybe the link was already used?" %}
  • -
  • {% trans "Confirmation URL already expired?" %}
  • +
  • {% trans "Check that you entered the URL correctly" %}
  • +
  • {% trans "Maybe you have already confirmed the address?" %}
  • +
  • {% trans "Confirmation link not used within 24 hours expiration time?" %}
diff --git a/project/members/templates/members/email_confirmed.html b/project/members/templates/members/email_confirmed.html index 9285796..d5d409a 100644 --- a/project/members/templates/members/email_confirmed.html +++ b/project/members/templates/members/email_confirmed.html @@ -1,6 +1,8 @@ {% extends "base.html" %} {% load bootstrap3 static i18n %} +{% block extralink %}{% endblock extralink %} + {% block page_title %}{% trans "Confirmed. Thank you" %}{% endblock page_title %} {% block main_title %}{% trans "Email confirmation received. Thank you" %}{% endblock main_title %} From 2a871d6b3a231377e59f0bb2035ce8eb899c4768 Mon Sep 17 00:00:00 2001 From: jssmk Date: Fri, 13 Aug 2021 21:47:25 +0300 Subject: [PATCH 09/15] better error handling --- project/hhlcallback/handlers.py | 5 ----- project/members/models.py | 5 ----- project/members/views.py | 9 +++++++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/project/hhlcallback/handlers.py b/project/hhlcallback/handlers.py index 78e0a66..5d38a5a 100644 --- a/project/hhlcallback/handlers.py +++ b/project/hhlcallback/handlers.py @@ -36,11 +36,6 @@ def on_saved(self, instance, *args, **kwargs): # Just created del(self.fresh_emails[instance.email]) - print(self) - print(dir(instance)) - #print(args) - #print(confirmation_code) - # Notification mail for admins that there is a new application admin_mail = EmailMessage() admin_mail.from_email = '"%s" <%s>' % (instance.name, instance.email) diff --git a/project/members/models.py b/project/members/models.py index 74a5748..d9a5a06 100644 --- a/project/members/models.py +++ b/project/members/models.py @@ -215,11 +215,6 @@ class EmailConfirmation(AsylumModel): confirmation_code = models.UUIDField(default=uuid4, editable=False) def confirm(self, user_code): - print(user_code) - print(self.confirmation_code) - print(self.confirmed) - print(self.status) - print("---------") if self.status == 'waiting confirmation' and str(self.confirmation_code) == str(user_code): self.confirmed = timezone.now() self.save() diff --git a/project/members/views.py b/project/members/views.py index 55bdaea..d8de671 100644 --- a/project/members/views.py +++ b/project/members/views.py @@ -5,6 +5,7 @@ from django.views import generic from django.utils import timezone from uuid import UUID +from django.core.exceptions import ObjectDoesNotExist from .forms import ApplicationForm from .models import MembershipApplication, EmailConfirmation @@ -46,9 +47,13 @@ def get_context_data(self, **kwargs): if not self.is_uuid(ctx_code): return - email_c = EmailConfirmation.objects.get(confirmation_code=ctx_code) - confirmed = False + + try: + email_c = EmailConfirmation.objects.get(confirmation_code=ctx_code) + except ObjectDoesNotExist: + return + try: confirmed = email_c.confirm(ctx_code) except ValidationError: From a05eb2b85dde71381fa3fe0b163aad92ee045307 Mon Sep 17 00:00:00 2001 From: jssmk Date: Sat, 14 Aug 2021 00:07:40 +0300 Subject: [PATCH 10/15] cleanup and logic fix --- project/members/handlers.py | 4 ---- project/members/models.py | 21 ++++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/project/members/handlers.py b/project/members/handlers.py index 89131bd..0147e0c 100644 --- a/project/members/handlers.py +++ b/project/members/handlers.py @@ -21,10 +21,6 @@ def on_saved(self, instance, *args, **kwargs): class BaseApplicationHandler(BaseHandler): """Baseclass for callback handlers for MembershipApplication processing""" - # def on_saved(self, instance, confirmation_code, *args, **kwargs): - # """Called after save() returns""" - # pass - def on_approving(self, application, member): """Called just before member.save()""" pass diff --git a/project/members/models.py b/project/members/models.py index d9a5a06..2f1274d 100644 --- a/project/members/models.py +++ b/project/members/models.py @@ -127,16 +127,6 @@ class MembershipApplication(MemberCommon): @call_saves('MEMBERAPPLICATION_CALLBACKS_HANDLER') def save(self, *args, **kwargs): - #h = get_handler_instance('MEMBERAPPLICATION_CALLBACKS_HANDLER') - #if h: - # h.on_saving(self) - #e = EmailConfirmation() - #self.confirmation_code = e.confirmation_code - #a = super().save(*args, **kwargs) - #if h: - # h.on_saved(self, e.confirmation_code) - #e.save() - #return a e = EmailConfirmation(email=self.email) e.save() self.confirmation_code = e.confirmation_code @@ -215,13 +205,22 @@ class EmailConfirmation(AsylumModel): confirmation_code = models.UUIDField(default=uuid4, editable=False) def confirm(self, user_code): - if self.status == 'waiting confirmation' and str(self.confirmation_code) == str(user_code): + if self.status == 'confirmed': + return True + elif self.status == 'waiting confirmation' and str(self.confirmation_code) == str(user_code): self.confirmed = timezone.now() self.save() return True else: return ValidationError + def __str__(self): + return _("%s (%s)") % (self.email, self.confirmation_code) + + class Meta: + verbose_name = _('Email confirmation check') + verbose_name_plural = _('Email confirmation checks') + @property def status(self): if self.confirmed: From 969624a0bd401c1f29858c8e4e9b41c55fd5b15b Mon Sep 17 00:00:00 2001 From: jssmk Date: Sun, 15 Aug 2021 18:05:36 +0300 Subject: [PATCH 11/15] info emphasis, css fix --- project/asylum/static/css/application_form.css | 1 + project/members/forms.py | 4 ---- .../members/templates/members/application_form.html | 10 +++++----- project/members/views.py | 9 +++++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/project/asylum/static/css/application_form.css b/project/asylum/static/css/application_form.css index 662cc46..9af68a2 100644 --- a/project/asylum/static/css/application_form.css +++ b/project/asylum/static/css/application_form.css @@ -21,6 +21,7 @@ transition:all 1.0s ease-in; opacity: 0.0; height: 0px; + overflow: hidden; } .showform { opacity: 1.0; diff --git a/project/members/forms.py b/project/members/forms.py index 1aadfe3..ae12d2a 100644 --- a/project/members/forms.py +++ b/project/members/forms.py @@ -17,10 +17,6 @@ def rules_accepted_proxy(msg): class ApplicationForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.member_register_writeup = [settings.MEMBER_REGISTER_WRITEUP_URL] # "Rekisteriseloste" - field_order = [ 'fname', 'lname', diff --git a/project/members/templates/members/application_form.html b/project/members/templates/members/application_form.html index 01211f0..944a5a5 100644 --- a/project/members/templates/members/application_form.html +++ b/project/members/templates/members/application_form.html @@ -27,11 +27,11 @@ {% else %}
-

{% trans "Apply for membership in Helsinki Hacklab. Association act requires us to register your first and last name and city (municipality) of residence. We also need a working email address for contacting you." %}

-

{% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only." %}

-

{% trans "You can also give a nickname you use or are about to use in IRC or in Helsinki Hacklab chat service. Phone number helps us contacting you in urgent or important situations when no other way succeeds." %}

-

{% trans "Every new applicant must accept the rules of the organisation." %}

-

{% trans "If the applicant is under 18 years old, please be in contact with board members for instructions first. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

+

{% trans "Required information" %}: {% trans "Apply for membership in Helsinki Hacklab. Association act requires us to register your first and last name and city (municipality) of residence. We also need a working email address for contacting you." %}

+

{% trans "Forbidden email addresses" %}: {% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only." %}

+

{% trans "Extra contact info" %}: {% trans "You can also give a nickname you use or are about to use in IRC or in Helsinki Hacklab chat service. Phone number helps us contacting you in urgent or important situations when no other way succeeds." %}

+

{% trans "The rules" %}: {% trans "Every new applicant must accept the rules of the organisation." %} info

+

{% trans "Underage applicants" %}: {% trans "If the applicant is under 18 years old, please be in contact with board members for instructions first. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

diff --git a/project/members/views.py b/project/members/views.py index d8de671..827606d 100644 --- a/project/members/views.py +++ b/project/members/views.py @@ -6,6 +6,7 @@ from django.utils import timezone from uuid import UUID from django.core.exceptions import ObjectDoesNotExist +from django.conf import settings from .forms import ApplicationForm from .models import MembershipApplication, EmailConfirmation @@ -16,6 +17,14 @@ class ApplyView(generic.CreateView): template_name = "members/application_form.html" form_class = ApplicationForm + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["member_register_writeup"] = settings.MEMBER_REGISTER_WRITEUP_URL # "Rekisteriseloste" + context["organisation_rules"] = settings.APPLICATION_RULES_URL + return context + + + def get_success_url(self): return reverse('members-application_received') From bb575fc05c07dc8d84ebfd2519bb958121b543ed Mon Sep 17 00:00:00 2001 From: jssmk Date: Sun, 15 Aug 2021 18:48:19 +0300 Subject: [PATCH 12/15] localisations --- .../members/locale/fi/LC_MESSAGES/django.po | 286 +++++++++++++++--- .../templates/members/application_form.html | 2 +- 2 files changed, 247 insertions(+), 41 deletions(-) diff --git a/project/members/locale/fi/LC_MESSAGES/django.po b/project/members/locale/fi/LC_MESSAGES/django.po index c2791bd..af87f29 100644 --- a/project/members/locale/fi/LC_MESSAGES/django.po +++ b/project/members/locale/fi/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-04-04 19:51+0300\n" +"POT-Creation-Date: 2021-08-15 18:16+0300\n" "PO-Revision-Date: 2015-11-29 02:53+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -15,7 +15,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.8.6\n" -#: admin.py:44 admin.py:142 admin.py:174 models.py:83 +#: admin.py:44 admin.py:142 admin.py:174 models.py:86 msgid "Membership types" msgstr "Jäsentyyppi" @@ -27,15 +27,15 @@ msgstr "Pääsyoikeudet" msgid "Cities" msgstr "Kaupungit" -#: admin.py:88 admin.py:137 +#: admin.py:87 admin.py:137 msgid "Credit" msgstr "Saldo" -#: admin.py:93 +#: admin.py:92 msgid "Negative credit" msgstr "Saldo miinuksella" -#: admin.py:94 +#: admin.py:93 msgid "Positive credit" msgstr "Saldo plussalla" @@ -43,133 +43,339 @@ msgstr "Saldo plussalla" msgid "Name" msgstr "Nimi" -#: admin.py:155 admin.py:193 +#: admin.py:155 admin.py:194 msgid "Tags" msgstr "Tägit" -#: admin.py:202 +#: admin.py:203 msgid "Approve selected applications" msgstr "Hyväksy valitut hakemukset" -#: forms.py:18 +#: forms.py:32 #, python-format msgid "I have read and accept the rules" msgstr "Olen lukenut ja hyväksyn säännöt" -#: models.py:41 +#: forms.py:34 +msgid "" +"I am sure this is address is not provided by an education institution or a " +"workplace, let me continue" +msgstr "" +"Olen varma, että tämä osoite ei ole työpaikan tai oppilaitoksen myöntämä, " +"anna minun jatkaa." + +#: forms.py:57 +msgid "" +"Please only provide the city or municipality name of your residence, no " +"detailed addresses, street names or anything extra. We are required by " +"Association Act to register your place of residence." +msgstr "" +"Ole hyvä ja anna asuinpaikkanuntasi nimi, ei muita lisätietoja, kadunnimiä " +"tai muuta ylimääräistä. Yhdistyslaki vaatii meitä tallentamaan asuinpaikkakuntasi." + +#: forms.py:84 +msgid "" +"This very much looks like a student or workplace email address, please " +"provide another address." +msgstr "" +"Tämä vaikuttaa hyvin vahvasti oppilaitoksen tai työpaikan myöntämältä " +"sähköpostiosoitteelta. Ole hyvä ja anna muu osoite." + +#: forms.py:90 +msgid "" +"Please recheck your email address and confirm this is not a student or work " +"address provided by your university, workplace etc., or give a different " +"address." +msgstr "" +"Vahvista, että syöttämääsi sähköpostiosoitetta ei ole annettu sinulle " +"oppilaitoksesi tai työpaikkasi puolesta, tai anna vaihtoehtoisesti " +"toinen osoite." + +#: models.py:43 msgid "First name" msgstr "Etunimi" -#: models.py:42 +#: models.py:44 msgid "Last name" msgstr "Sukunimi" -#: models.py:43 +#: models.py:45 msgid "City of residence" msgstr "Paikkakunta" -#: models.py:44 +#: models.py:46 models.py:201 msgid "Email address" msgstr "Sähköpostiosoite" -#: models.py:45 +#: models.py:47 msgid "Phone number" msgstr "Puhelinnumero" -#: models.py:46 +#: models.py:48 msgid "Nickname" msgstr "Lempinimi" -#: models.py:69 models.py:106 +#: models.py:71 models.py:110 msgid "Label" msgstr "Nimiö" -#: models.py:75 +#: models.py:77 msgid "Member Type" msgstr "Jäsentyyppi" -#: models.py:76 +#: models.py:78 msgid "Member Types" msgstr "Jäsentyypit" -#: models.py:82 +#: models.py:85 msgid "Date accepted" msgstr "Hyväksymispäivä" -#: models.py:84 +#: models.py:87 msgid "Anonymized id (for use in external databases)" msgstr "Anonymisoitu tunniste (käytettäväksi ulkoisissa tietokannoissa)" -#: models.py:85 +#: models.py:88 msgid "Member id no" msgstr "Jäsennumero" -#: models.py:99 models.py:170 +#: models.py:102 models.py:183 msgid "Member" msgstr "Jäsen" -#: models.py:100 +#: models.py:103 msgid "Members" msgstr "Jäsenet" -#: models.py:112 +#: models.py:116 msgid "Membership Application Tag" msgstr "Jäsenhakemuksen tägi" -#: models.py:113 +#: models.py:117 msgid "Membership Application Tags" msgstr "Jäsenhakemuksen tägit" -#: models.py:120 +#: models.py:125 msgid "Application tags" msgstr "Jäsenhakemuksen tagit" -#: models.py:121 models.py:169 models.py:174 +#: models.py:126 models.py:182 models.py:187 msgid "Notes" msgstr "Muistiinpanot" -#: models.py:132 +#: models.py:140 msgid "Member with this email already exists" msgstr "Tämä sähköpostiosoite on jo jäsenrekisterissä" -#: models.py:161 +#: models.py:169 msgid "Membership Application" msgstr "Jäsenhakemus" -#: models.py:162 +#: models.py:170 msgid "Membership Applications" msgstr "Jäsenhakemukset" -#: models.py:168 +#: models.py:181 msgid "Datetime" msgstr "Päivä ja aika" -#: models.py:173 +#: models.py:186 msgid "Note" msgstr "Muistiinpano" -#: models.py:178 +#: models.py:191 #, python-format msgid "Notes about %s on %s" msgstr "Muistiinpanoja jäsenestä %s ajalla %s" -#: templates/members/application_form.html:4 -#: templates/members/application_form.html:5 +#: models.py:202 +msgid "Confirmation window start" +msgstr "Vahvistusajan alkuhetki" + +#: models.py:203 +msgid "Confirmation window end" +msgstr "Vahvistusajan loppuhetki" + +#: models.py:204 +msgid "Confirmation received" +msgstr "Vahvistus vastaanotettu" + +#: models.py:218 +#, python-format +msgid "%s (%s)" +msgstr "%s (%s)" + +#: models.py:221 +msgid "Email confirmation check" +msgstr "Sähköpostiosoitteen varmistus" + +#: models.py:222 +msgid "Email confirmation checks" +msgstr "Sähköpostiosoitteen varmistukset" + +#: templates/members/application_form.html:6 +#: templates/members/application_form.html:7 msgid "Apply for membership" msgstr "Hae jäseneksi" -#: templates/members/application_form.html:12 +#: templates/members/application_form.html:13 +msgid "Please fix some errors found in your application form." +msgstr "Ole hyvä ja korjaa joitain hakemuksestasi löytyneitä virheitä" + +#: templates/members/application_form.html:19 +#: templates/members/application_form.html:42 msgid "Submit" msgstr "Lähetä" -#: templates/members/application_received.html:4 +#: templates/members/application_form.html:24 +#: templates/members/application_form.html:47 +msgid "" +"Read the terms of collected data in Helsinki Hacklab ry. member register " +"description:" +msgstr "Tutustu Helsinki Hacklab ry.:n rekisterselosteeseen:" + +#: templates/members/application_form.html:30 +msgid "Required information" +msgstr "Vaaditut tiedot" + +#: templates/members/application_form.html:30 +msgid "" +"Apply for membership in Helsinki Hacklab. Association act requires us to " +"register your first and last name and city (municipality) of residence. We " +"also need a working email address for contacting you." +msgstr "" +"Hae jäsenyyttä Helsinki Hacklabissa. Yhdistyslaki vaatii meitä " +"rekisteröimään etu- ja sukunimesi sekä asuinpaikkauntasi. " +"Me tarvitsemme myös toimivan sähköpostiosoitteen yhteydenpitoon." + +#: templates/members/application_form.html:31 +msgid "Forbidden email addresses" +msgstr "Kielletty sähköpostiosoite" + +#: templates/members/application_form.html:31 +msgid "" +"Please do not type an email address that is provided by your education " +"institution or workplace, as these addresses often eventually stop " +"responding. We need a working email address even if you change workplace or " +"graduate! Also your workplace mail admin is pleased if you use your work " +"mail for business only and we don't have to deal with strict in-house " +"filtering rules." +msgstr "" +"Ole hyvä ja älä anna sähköpostiosoitetta, jonka on myöntänyt " +"oppilaitoksesi tai työpaikkasi, koska nämä osoitteet aikanaan lakkaavat " +"aina toimimasta. Me tarvitsemme toimivan sähköpostiosoitteen myös silloin, " +"kun opintosi päättyvät tai vaihdat työpaikkaa! Työpaikkasi email-admin " +"varmastikin haluaa, että työpostia käytettän työhön liittyviin asioihin " +"ja meidän ei tarvitse huolehtia tiukoista talon omista email-flttereistä." + +#: templates/members/application_form.html:32 +msgid "Extra contact info" +msgstr "Lisäyhteystiedot" + +#: templates/members/application_form.html:32 +msgid "" +"You can also give a nickname you use or are about to use in IRC or in " +"Helsinki Hacklab chat service. Phone number helps us contacting you in " +"urgent or important situations when no other way succeeds." +msgstr "" +"Voit myös antaa irkkinimesi tms. tai muun nimen, jota tulet käyttämään " +"Helsinki Hacklabin chat-palvelussa. Puhelinnumero auttaa meitä ottamaan " +"yhteyttä tärkeissä tai poikkeuksellissa tilanteissa, kun muu ei tavoita." + +#: templates/members/application_form.html:33 +msgid "The rules" +msgstr "Säännöt" + +#: templates/members/application_form.html:33 +msgid "Every new applicant must accept the rules of the organisation." +msgstr "Jokaisen uuden hakijan tulee hyväksyä yhdistyksen säännöt." + +#: templates/members/application_form.html:34 +msgid "Underage applicants" +msgstr "Alaikäiset hakijat" + +#: templates/members/application_form.html:34 +msgid "" +"If the applicant is under 18 years old, please be in contact with board " +"members for instructions first. Underage members' applications are handled " +"by individual consideration, depending on age, maturity, caretaker co-" +"opeation and other terms." +msgstr "" +"Jos hakija on alle 18 vuotta vanha, ole hyvä ja ota yhteyttä ensin " +"yhdistyksen hallitukseen. Alaikäisten jäsenten hakemukset käsitellään " +"yksilöllisesti perustuen ikään, kypsyyteen, huoltajayhteistyöhön ja " +"muihin seikkoihin perustuen." + +#: templates/members/application_form.html:36 +msgid "I understand, continue" +msgstr "Ymmärrän, jatka" + +#: templates/members/application_received.html:6 msgid "Received. Thank you" msgstr "Jäsenhakemuksesi on vastaanotettu. Paljon kiitoksia!" -#: templates/members/application_received.html:5 +#: templates/members/application_received.html:7 msgid "Application received. Thank you" msgstr "Jäsenhakemuksesi on vastaanotettu. Paljon kiitoksia!" -#: templates/members/application_received.html:9 -msgid "We'll get back to you" -msgstr "Vastaamme sinulle pian." +#: templates/members/application_received.html:12 +msgid "You will soon receive an email message to verify your email address." +msgstr "Saat kohta sähköpostia, jolla vahvistat sähköpostiosoitteesi." + +#: templates/members/application_received.html:13 +msgid "" +"Your personal confirmation link is valid for 24 hours, and this check is " +"required before we can process your application. If you do not receive a " +"link in your mail, please be in contact with the board of Helsinki Hacklab." +msgstr "" +"Henkilökohtainen vahvistuslinkkisi on voimassa 24 tuntia, ja tämä varmistus " +"edellytetään ennen kuin voimme käsitellä hakemuksesi. Jos et saa linkkiä " +"sähköpostiisi, ole yhteydessä yhdistyksen hallituksen." + +#: templates/members/application_received.html:14 +msgid "" +"Further instructions are emailed after we have processed the application, " +"which happens usually once a month. You can now close this page." +msgstr "" +"Jatko-ohjeet lähetetään sinulle sähköpostitse, kun olemme ensin käsitelleet " +"hakemuksesi, mikä tapahtuu yleensä noin kuukauden aikana. " +"Voit nyt sulkea tämän sivun." + +#: templates/members/email_confirmation_error.html:6 +msgid "Error confirming email" +msgstr "Virhe vahvistettaessa sähköpostiosoitetta" + +#: templates/members/email_confirmation_error.html:7 +msgid "There was an error confirming your email" +msgstr "Sähköpostin vahvistamisessa tapahtui virhe" + +#: templates/members/email_confirmation_error.html:14 +msgid "Check that you entered the URL correctly" +msgstr "Katso että sivun osoite on syötetty oikein" + +#: templates/members/email_confirmation_error.html:15 +msgid "Maybe you have already confirmed the address?" +msgstr "Ehkä olet jo vahvistanut osoitten?" + +#: templates/members/email_confirmation_error.html:16 +msgid "Confirmation link not used within 24 hours expiration time?" +msgstr "Vahvistusta yritetty lähettää 24 tunnin voimassaoloajan jälkeen?" + +#: templates/members/email_confirmed.html:6 +#, fuzzy +#| msgid "Received. Thank you" +msgid "Confirmed. Thank you" +msgstr "Vahvistettu. Paljon kiitoksia!" + +#: templates/members/email_confirmed.html:7 +#, fuzzy +#| msgid "Application received. Thank you" +msgid "Email confirmation received. Thank you" +msgstr "Sähköpostiosoite vahvistettu. Paljon kiitoksia!" + +#: templates/members/email_confirmed.html:12 +msgid "Email address successfully confirmed" +msgstr "Sähköpostiosoite on vahvistettu onnistuneesti" + +#~ msgid "We'll get back to you" +#~ msgstr "Vastaamme sinulle pian." diff --git a/project/members/templates/members/application_form.html b/project/members/templates/members/application_form.html index 944a5a5..9aa8853 100644 --- a/project/members/templates/members/application_form.html +++ b/project/members/templates/members/application_form.html @@ -28,7 +28,7 @@

{% trans "Required information" %}: {% trans "Apply for membership in Helsinki Hacklab. Association act requires us to register your first and last name and city (municipality) of residence. We also need a working email address for contacting you." %}

-

{% trans "Forbidden email addresses" %}: {% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only." %}

+

{% trans "Forbidden email addresses" %}: {% trans "Please do not type an email address that is provided by your education institution or workplace, as these addresses often eventually stop responding. We need a working email address even if you change workplace or graduate! Also your workplace mail admin is pleased if you use your work mail for business only and we don't have to deal with strict in-house filtering rules." %}

{% trans "Extra contact info" %}: {% trans "You can also give a nickname you use or are about to use in IRC or in Helsinki Hacklab chat service. Phone number helps us contacting you in urgent or important situations when no other way succeeds." %}

{% trans "The rules" %}: {% trans "Every new applicant must accept the rules of the organisation." %} info

{% trans "Underage applicants" %}: {% trans "If the applicant is under 18 years old, please be in contact with board members for instructions first. Underage members' applications are handled by individual consideration, depending on age, maturity, caretaker co-opeation and other terms." %}

From 963b7d0f774121089c8bb31abd5bbe70c7571940 Mon Sep 17 00:00:00 2001 From: jssmk Date: Sun, 15 Aug 2021 19:19:58 +0300 Subject: [PATCH 13/15] use config for email checks --- project/config/settings/common.py | 13 +++++++++++++ project/members/forms.py | 12 ++---------- project/members/views.py | 8 +------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/project/config/settings/common.py b/project/config/settings/common.py index 22d9c56..fe77fad 100644 --- a/project/config/settings/common.py +++ b/project/config/settings/common.py @@ -269,6 +269,19 @@ APPLICATION_RULES_URL = env('APPLICATION_RULES_URL', default='http://hacklab.fi/') MEMBER_REGISTER_WRITEUP_URL = env('MEMBER_REGISTER_WRITEUP_URL', default='http://hacklab.fi/') +# Membership application email address domain whitelists and blacklists in regex +# Whitelist: Instantly accepted email domains, commonly used typical personal address such like gmail etc. +# Blacklist: Instantly rejected email domains, such as university addresses or other policies +# Everyting else: greylist - the users themselves have to confirm that the address is according to rules on submit +APPLICATION_EMAIL_DOMAIN_REGEX_WHITELIST = ['gmail.com', 'iki.fi', +'yahoo.com', 'hotmail.com', 'outlook.com', 'kolumbus.fi', 'windowslive.com', +'hotmail.co.uk', 'pp.inet.fi', 'mac.com', 'wippies.com', 'welho.com', +'kapsi.fi', 'fastmail.fm', 'live.fi', 'protonmail.com', 'yahoo.co.uk', +'suomi24.fi'] +APPLICATION_EMAIL_DOMAIN_REGEX_BLACKLIST = [ 'aalto.fi', '.*\.aalto.fi', +'metropolia.fi', '.*\.metropolia.fi','helsinki.fi', '.*\.helsinki.fi', +'haaga-helia.fi', '.*\.haaga-helia.fi','hel.fi', '.*\.hel.fi', '.*\.edu'] + # Give path to a class implementing the api outlined in member.handers baseclasses MEMBERAPPLICATION_CALLBACKS_HANDLER = env('MEMBERAPPLICATION_CALLBACKS_HANDLER', default=None) MEMBER_CALLBACKS_HANDLER = env('MEMBER_CALLBACKS_HANDLER', default=None) diff --git a/project/members/forms.py b/project/members/forms.py index ae12d2a..50503dc 100644 --- a/project/members/forms.py +++ b/project/members/forms.py @@ -67,16 +67,8 @@ def clean_email(self): """ data = self.cleaned_data['email'] - blacklist = '|'.join(['aalto.fi', '.*\.aalto.fi', 'metropolia.fi', '.*\.metropolia.fi', 'helsinki.fi', '.*\.helsinki.fi', - 'haaga-helia.fi', '.*\.haaga-helia.fi', 'hel.fi', '.*\.hel.fi', '.*\.edu']) - - - whitelist = '|'.join(['gmail.com', 'iki.fi', 'yahoo.com', 'hotmail.com', 'outlook.com', 'kolumbus.fi', 'windowslive.com', - 'hotmail.co.uk', 'pp.inet.fi', 'mac.com', 'wippies.com', 'welho.com', 'kapsi.fi', 'fastmail.fm', 'live.fi', 'protonmail.com', - 'yahoo.co.uk', 'suomi24.fi']) - - domain_regex_blacklist = compile('^.*@(' + blacklist + ')$') - domain_regex_whitelist = compile('^.*@(' + whitelist + ')$') + domain_regex_blacklist = compile('^.*@(' + '|'.join(settings.APPLICATION_EMAIL_DOMAIN_REGEX_BLACKLIST) + ')$') + domain_regex_whitelist = compile('^.*@(' + '|'.join(settings.APPLICATION_EMAIL_DOMAIN_REGEX_WHITELIST) + ')$') # Is in blacklist = student email -> instant reject if domain_regex_blacklist.match(data): diff --git a/project/members/views.py b/project/members/views.py index 827606d..00fea90 100644 --- a/project/members/views.py +++ b/project/members/views.py @@ -23,11 +23,10 @@ def get_context_data(self, **kwargs): context["organisation_rules"] = settings.APPLICATION_RULES_URL return context - - def get_success_url(self): return reverse('members-application_received') + class ApplicationReceivedView(generic.TemplateView): template_name = "members/application_received.html" @@ -72,8 +71,3 @@ def get_context_data(self, **kwargs): self.template_name = "members/email_confirmed.html" -class EmailConfirmationSuccessView(generic.TemplateView): - template_name = "members/email_confirmed.html" - -class EmailConfirmationErrorView(generic.TemplateView): - template_name = "members/email_error.html" From 87eae44880e182ad05b12a27565dbde0e0eb16f5 Mon Sep 17 00:00:00 2001 From: jssmk Date: Sun, 15 Aug 2021 21:21:46 +0300 Subject: [PATCH 14/15] small meta igration --- .../0006_alter_emailconfirmation_options.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 project/members/migrations/0006_alter_emailconfirmation_options.py diff --git a/project/members/migrations/0006_alter_emailconfirmation_options.py b/project/members/migrations/0006_alter_emailconfirmation_options.py new file mode 100644 index 0000000..ddfd9be --- /dev/null +++ b/project/members/migrations/0006_alter_emailconfirmation_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2 on 2021-08-15 18:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0005_emailconfirmation'), + ] + + operations = [ + migrations.AlterModelOptions( + name='emailconfirmation', + options={'verbose_name': 'Email confirmation check', 'verbose_name_plural': 'Email confirmation checks'}, + ), + ] From 15a25269a1558dc0d3d4fcc710587bd58f7712c5 Mon Sep 17 00:00:00 2001 From: jssmk Date: Sun, 15 Aug 2021 21:54:52 +0300 Subject: [PATCH 15/15] exceptions handling in email confirmation --- .../members/locale/fi/LC_MESSAGES/django.po | 83 ++++++++++++------- project/members/models.py | 23 +++-- 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/project/members/locale/fi/LC_MESSAGES/django.po b/project/members/locale/fi/LC_MESSAGES/django.po index af87f29..eb15e71 100644 --- a/project/members/locale/fi/LC_MESSAGES/django.po +++ b/project/members/locale/fi/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-15 18:16+0300\n" +"POT-Creation-Date: 2021-08-15 21:51+0300\n" "PO-Revision-Date: 2015-11-29 02:53+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -71,9 +71,10 @@ msgid "" "Association Act to register your place of residence." msgstr "" "Ole hyvä ja anna asuinpaikkanuntasi nimi, ei muita lisätietoja, kadunnimiä " -"tai muuta ylimääräistä. Yhdistyslaki vaatii meitä tallentamaan asuinpaikkakuntasi." +"tai muuta ylimääräistä. Yhdistyslaki vaatii meitä tallentamaan " +"asuinpaikkakuntasi." -#: forms.py:84 +#: forms.py:76 msgid "" "This very much looks like a student or workplace email address, please " "provide another address." @@ -81,15 +82,15 @@ msgstr "" "Tämä vaikuttaa hyvin vahvasti oppilaitoksen tai työpaikan myöntämältä " "sähköpostiosoitteelta. Ole hyvä ja anna muu osoite." -#: forms.py:90 +#: forms.py:82 msgid "" "Please recheck your email address and confirm this is not a student or work " "address provided by your university, workplace etc., or give a different " "address." msgstr "" "Vahvista, että syöttämääsi sähköpostiosoitetta ei ole annettu sinulle " -"oppilaitoksesi tai työpaikkasi puolesta, tai anna vaihtoehtoisesti " -"toinen osoite." +"oppilaitoksesi tai työpaikkasi puolesta, tai anna vaihtoehtoisesti toinen " +"osoite." #: models.py:43 msgid "First name" @@ -103,7 +104,7 @@ msgstr "Sukunimi" msgid "City of residence" msgstr "Paikkakunta" -#: models.py:46 models.py:201 +#: models.py:46 models.py:214 msgid "Email address" msgstr "Sähköpostiosoite" @@ -139,7 +140,7 @@ msgstr "Anonymisoitu tunniste (käytettäväksi ulkoisissa tietokannoissa)" msgid "Member id no" msgstr "Jäsennumero" -#: models.py:102 models.py:183 +#: models.py:102 models.py:196 msgid "Member" msgstr "Jäsen" @@ -159,7 +160,7 @@ msgstr "Jäsenhakemuksen tägit" msgid "Application tags" msgstr "Jäsenhakemuksen tagit" -#: models.py:126 models.py:182 models.py:187 +#: models.py:126 models.py:195 models.py:200 msgid "Notes" msgstr "Muistiinpanot" @@ -175,41 +176,65 @@ msgstr "Jäsenhakemus" msgid "Membership Applications" msgstr "Jäsenhakemukset" +#: models.py:176 +msgid "Not found" +msgstr "Ei löytynyt" + +#: models.py:178 +msgid "Undefined error" +msgstr "Määrittelemätön virhe" + #: models.py:181 +msgid "Email confirmed" +msgstr "Sähköpostiosoite vahvistettu" + +#: models.py:183 +msgid "Expired" +msgstr "Vanhentunut" + +#: models.py:185 +msgid "Waiting confirmation" +msgstr "Odottaa vahvistusta" + +#: models.py:187 +msgid "Error in confirmation" +msgstr "Virhe vahvistuksessa" + +#: models.py:194 msgid "Datetime" msgstr "Päivä ja aika" -#: models.py:186 +#: models.py:199 msgid "Note" msgstr "Muistiinpano" -#: models.py:191 +#: models.py:204 #, python-format msgid "Notes about %s on %s" msgstr "Muistiinpanoja jäsenestä %s ajalla %s" -#: models.py:202 +#: models.py:215 msgid "Confirmation window start" msgstr "Vahvistusajan alkuhetki" -#: models.py:203 +#: models.py:216 msgid "Confirmation window end" msgstr "Vahvistusajan loppuhetki" -#: models.py:204 +#: models.py:217 msgid "Confirmation received" msgstr "Vahvistus vastaanotettu" -#: models.py:218 +#: models.py:231 #, python-format msgid "%s (%s)" msgstr "%s (%s)" -#: models.py:221 +#: models.py:234 msgid "Email confirmation check" msgstr "Sähköpostiosoitteen varmistus" -#: models.py:222 +#: models.py:235 msgid "Email confirmation checks" msgstr "Sähköpostiosoitteen varmistukset" @@ -245,8 +270,8 @@ msgid "" "also need a working email address for contacting you." msgstr "" "Hae jäsenyyttä Helsinki Hacklabissa. Yhdistyslaki vaatii meitä " -"rekisteröimään etu- ja sukunimesi sekä asuinpaikkauntasi. " -"Me tarvitsemme myös toimivan sähköpostiosoitteen yhteydenpitoon." +"rekisteröimään etu- ja sukunimesi sekä asuinpaikkauntasi. Me tarvitsemme " +"myös toimivan sähköpostiosoitteen yhteydenpitoon." #: templates/members/application_form.html:31 msgid "Forbidden email addresses" @@ -261,12 +286,12 @@ msgid "" "mail for business only and we don't have to deal with strict in-house " "filtering rules." msgstr "" -"Ole hyvä ja älä anna sähköpostiosoitetta, jonka on myöntänyt " -"oppilaitoksesi tai työpaikkasi, koska nämä osoitteet aikanaan lakkaavat " -"aina toimimasta. Me tarvitsemme toimivan sähköpostiosoitteen myös silloin, " -"kun opintosi päättyvät tai vaihdat työpaikkaa! Työpaikkasi email-admin " -"varmastikin haluaa, että työpostia käytettän työhön liittyviin asioihin " -"ja meidän ei tarvitse huolehtia tiukoista talon omista email-flttereistä." +"Ole hyvä ja älä anna sähköpostiosoitetta, jonka on myöntänyt oppilaitoksesi " +"tai työpaikkasi, koska nämä osoitteet aikanaan lakkaavat aina toimimasta. Me " +"tarvitsemme toimivan sähköpostiosoitteen myös silloin, kun opintosi " +"päättyvät tai vaihdat työpaikkaa! Työpaikkasi email-admin varmastikin " +"haluaa, että työpostia käytettän työhön liittyviin asioihin ja meidän ei " +"tarvitse huolehtia tiukoista talon omista email-flttereistä." #: templates/members/application_form.html:32 msgid "Extra contact info" @@ -303,8 +328,8 @@ msgid "" msgstr "" "Jos hakija on alle 18 vuotta vanha, ole hyvä ja ota yhteyttä ensin " "yhdistyksen hallitukseen. Alaikäisten jäsenten hakemukset käsitellään " -"yksilöllisesti perustuen ikään, kypsyyteen, huoltajayhteistyöhön ja " -"muihin seikkoihin perustuen." +"yksilöllisesti perustuen ikään, kypsyyteen, huoltajayhteistyöhön ja muihin " +"seikkoihin perustuen." #: templates/members/application_form.html:36 msgid "I understand, continue" @@ -338,8 +363,8 @@ msgid "" "which happens usually once a month. You can now close this page." msgstr "" "Jatko-ohjeet lähetetään sinulle sähköpostitse, kun olemme ensin käsitelleet " -"hakemuksesi, mikä tapahtuu yleensä noin kuukauden aikana. " -"Voit nyt sulkea tämän sivun." +"hakemuksesi, mikä tapahtuu yleensä noin kuukauden aikana. Voit nyt sulkea " +"tämän sivun." #: templates/members/email_confirmation_error.html:6 msgid "Error confirming email" diff --git a/project/members/models.py b/project/members/models.py index 2f1274d..19b71d0 100644 --- a/project/members/models.py +++ b/project/members/models.py @@ -4,7 +4,7 @@ from access.models import AccessType from access.utils import resolve_acl -from django.core.exceptions import ValidationError +from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.db import models, transaction from django.utils import timezone from datetime import timedelta @@ -170,8 +170,21 @@ class Meta: verbose_name_plural = _('Membership Applications') def confirmation_status(self): - e = EmailConfirmation.objects.get(email=self.email) - return e.status + try: + e = EmailConfirmation.objects.get(email=self.email) + except ObjectDoesNotExist: + return _('Not found') + except: + return _('Undefined error') + + if e.status == 'confirmed': + return _('Email confirmed') + elif e.status == 'expired': + return _('Expired') + elif e.status == 'waiting': + return _('Waiting confirmation') + + return _('Error in confirmation') revisions.register(MembershipApplication) @@ -207,7 +220,7 @@ class EmailConfirmation(AsylumModel): def confirm(self, user_code): if self.status == 'confirmed': return True - elif self.status == 'waiting confirmation' and str(self.confirmation_code) == str(user_code): + elif self.status == 'waiting' and str(self.confirmation_code) == str(user_code): self.confirmed = timezone.now() self.save() return True @@ -233,4 +246,4 @@ def status(self): if self.window_end < timezone.now(): return 'expired' else: - return 'waiting confirmation' + return 'waiting'