diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f61f0cfa --- /dev/null +++ b/.gitignore @@ -0,0 +1,168 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +*.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +env.py +collectstatic +migrations/* +media/* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e91283a3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +#dockerfile for django app +FROM python:3.10-slim + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + libatlas-base-dev gfortran supervisor \ + nano + + +WORKDIR /app + +COPY . . + +RUN pip install -r requirements.txt + +RUN python3 manage.py makemigrations + +RUN python3 manage.py migrate + +RUN python manage.py collectstatic --noinput + +# CMD ["gunicorn", "--bind", "0.0.0.0:8000", "myproject.wsgi:application"] +CMD ["gunicorn", "-c", "gunicorn_config.py", "myproject.wsgi:application"] + +# CMD ["python", "manage.py", "runserver"] diff --git a/PREVIEW/IMG1.png b/PREVIEW/IMG1.png deleted file mode 100644 index 0f382653..00000000 Binary files a/PREVIEW/IMG1.png and /dev/null differ diff --git a/PREVIEW/IMG2.png b/PREVIEW/IMG2.png deleted file mode 100644 index 351d8a73..00000000 Binary files a/PREVIEW/IMG2.png and /dev/null differ diff --git a/PREVIEW/IMG3.png b/PREVIEW/IMG3.png deleted file mode 100644 index 647983d7..00000000 Binary files a/PREVIEW/IMG3.png and /dev/null differ diff --git a/PREVIEW/IMG4.png b/PREVIEW/IMG4.png deleted file mode 100644 index e5162ea8..00000000 Binary files a/PREVIEW/IMG4.png and /dev/null differ diff --git a/PREVIEW/IMG5.png b/PREVIEW/IMG5.png deleted file mode 100644 index d34f5079..00000000 Binary files a/PREVIEW/IMG5.png and /dev/null differ diff --git a/db.sqlite3 b/db.sqlite3 deleted file mode 100644 index e1bb57c0..00000000 Binary files a/db.sqlite3 and /dev/null differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..8f285522 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.3' + +services: + bizz2goo: + build: + context: ./ + dockerfile: Dockerfile + ports: + - "3080:8000" + volumes: + - ./:/app + - /var/www/html/blogStatic/:/var/www/html/blogStatic/ \ No newline at end of file diff --git a/gunicorn_config.py b/gunicorn_config.py new file mode 100644 index 00000000..45279114 --- /dev/null +++ b/gunicorn_config.py @@ -0,0 +1,7 @@ +bind = "0.0.0.0:8000" +workers = 3 # Adjust the number of workers based on your needs +worker_class = "sync" # You can change this to "gevent" or "eventlet" if needed +timeout = 30 # Timeout for workers +loglevel = "info" # Logging level +accesslog = "./access.log" # Log to stdout +errorlog = "./error.log" # Log to stderr \ No newline at end of file diff --git a/links.txt b/links.txt new file mode 100644 index 00000000..7b3c6b2a --- /dev/null +++ b/links.txt @@ -0,0 +1,16 @@ +#UI + +https://demos.creative-tim.com/paper-kit-pro-react/#/profile-page + +https://demos.creative-tim.com/paper-kit-pro-react/#/presentation + +https://demos.creative-tim.com/nextjs-tailwind-blog-posts-page/?_ga=2.127420553.582448555.1730303848-180642451.1724699074# + +https://demos.creative-tim.com/material-kit/index.html?_ga=2.72870167.582448555.1730303848-180642451.1724699074 + +For Articles : +https://demos.creative-tim.com/paper-kit-pro-react/#/blog-post + +#Django + +https://django-ckeditor.readthedocs.io/en/latest/ \ No newline at end of file diff --git a/media/author_pictures/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg b/media/author_pictures/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg new file mode 100644 index 00000000..e161fdb5 Binary files /dev/null and b/media/author_pictures/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg differ diff --git a/media/author_pictures/image_2024-11-22_151016045.png b/media/author_pictures/image_2024-11-22_151016045.png new file mode 100644 index 00000000..f7c59b36 Binary files /dev/null and b/media/author_pictures/image_2024-11-22_151016045.png differ diff --git a/media/images/posts/Florence-840x276.jpg b/media/images/posts/Florence-840x276.jpg new file mode 100644 index 00000000..dafce182 Binary files /dev/null and b/media/images/posts/Florence-840x276.jpg differ diff --git a/media/images/posts/Florence-840x276_BG6nSu8.jpg b/media/images/posts/Florence-840x276_BG6nSu8.jpg new file mode 100644 index 00000000..dafce182 Binary files /dev/null and b/media/images/posts/Florence-840x276_BG6nSu8.jpg differ diff --git a/media/images/posts/Florence-840x276_LqtNbqV.jpg b/media/images/posts/Florence-840x276_LqtNbqV.jpg new file mode 100644 index 00000000..dafce182 Binary files /dev/null and b/media/images/posts/Florence-840x276_LqtNbqV.jpg differ diff --git a/media/images/posts/Florence-840x276_RherTCi.jpg b/media/images/posts/Florence-840x276_RherTCi.jpg new file mode 100644 index 00000000..dafce182 Binary files /dev/null and b/media/images/posts/Florence-840x276_RherTCi.jpg differ diff --git a/media/images/posts/dsd-ecarteur.png b/media/images/posts/dsd-ecarteur.png new file mode 100644 index 00000000..e6921ca9 Binary files /dev/null and b/media/images/posts/dsd-ecarteur.png differ diff --git a/media/images/posts/foto-6-jpg.webp b/media/images/posts/foto-6-jpg.webp new file mode 100644 index 00000000..9efda96b Binary files /dev/null and b/media/images/posts/foto-6-jpg.webp differ diff --git a/media/images/posts/foto-6-jpg_gehcJdW.webp b/media/images/posts/foto-6-jpg_gehcJdW.webp new file mode 100644 index 00000000..9efda96b Binary files /dev/null and b/media/images/posts/foto-6-jpg_gehcJdW.webp differ diff --git a/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg b/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg new file mode 100644 index 00000000..e161fdb5 Binary files /dev/null and b/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567.jpg differ diff --git a/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567_v8SnSAW.jpg b/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567_v8SnSAW.jpg new file mode 100644 index 00000000..e161fdb5 Binary files /dev/null and b/media/images/posts/grand-mec-fait-emotions-face-au-fou_144627-3567_v8SnSAW.jpg differ diff --git "a/media/images/posts/t\303\251l\303\251chargement.jpg" "b/media/images/posts/t\303\251l\303\251chargement.jpg" new file mode 100644 index 00000000..393e5835 Binary files /dev/null and "b/media/images/posts/t\303\251l\303\251chargement.jpg" differ diff --git "a/media/images/posts/t\303\251l\303\251chargement_QKjuVw6.jpg" "b/media/images/posts/t\303\251l\303\251chargement_QKjuVw6.jpg" new file mode 100644 index 00000000..393e5835 Binary files /dev/null and "b/media/images/posts/t\303\251l\303\251chargement_QKjuVw6.jpg" differ diff --git a/myapp/__pycache__/__init__.cpython-311.pyc b/myapp/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index bb0e41b2..00000000 Binary files a/myapp/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/__init__.cpython-38.pyc b/myapp/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index f6147ae2..00000000 Binary files a/myapp/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/myapp/__pycache__/admin.cpython-311.pyc b/myapp/__pycache__/admin.cpython-311.pyc deleted file mode 100644 index 2fc5de95..00000000 Binary files a/myapp/__pycache__/admin.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/admin.cpython-38.pyc b/myapp/__pycache__/admin.cpython-38.pyc deleted file mode 100644 index 52b9f8ed..00000000 Binary files a/myapp/__pycache__/admin.cpython-38.pyc and /dev/null differ diff --git a/myapp/__pycache__/apps.cpython-311.pyc b/myapp/__pycache__/apps.cpython-311.pyc deleted file mode 100644 index a8b9ad73..00000000 Binary files a/myapp/__pycache__/apps.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/apps.cpython-38.pyc b/myapp/__pycache__/apps.cpython-38.pyc deleted file mode 100644 index fb2fecef..00000000 Binary files a/myapp/__pycache__/apps.cpython-38.pyc and /dev/null differ diff --git a/myapp/__pycache__/models.cpython-311.pyc b/myapp/__pycache__/models.cpython-311.pyc deleted file mode 100644 index d012c10c..00000000 Binary files a/myapp/__pycache__/models.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/models.cpython-38.pyc b/myapp/__pycache__/models.cpython-38.pyc deleted file mode 100644 index cfc6b774..00000000 Binary files a/myapp/__pycache__/models.cpython-38.pyc and /dev/null differ diff --git a/myapp/__pycache__/urls.cpython-311.pyc b/myapp/__pycache__/urls.cpython-311.pyc deleted file mode 100644 index 535c35ff..00000000 Binary files a/myapp/__pycache__/urls.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/urls.cpython-38.pyc b/myapp/__pycache__/urls.cpython-38.pyc deleted file mode 100644 index 0c3f805f..00000000 Binary files a/myapp/__pycache__/urls.cpython-38.pyc and /dev/null differ diff --git a/myapp/__pycache__/views.cpython-311.pyc b/myapp/__pycache__/views.cpython-311.pyc deleted file mode 100644 index e50f9bb1..00000000 Binary files a/myapp/__pycache__/views.cpython-311.pyc and /dev/null differ diff --git a/myapp/__pycache__/views.cpython-38.pyc b/myapp/__pycache__/views.cpython-38.pyc deleted file mode 100644 index 89ce8976..00000000 Binary files a/myapp/__pycache__/views.cpython-38.pyc and /dev/null differ diff --git a/myapp/admin.py b/myapp/admin.py index 9f0b1a08..7c5eeeff 100644 --- a/myapp/admin.py +++ b/myapp/admin.py @@ -1,13 +1,122 @@ +# blog/admin.py + from django.contrib import admin -from .models import Post,Comment,Contact -# Register your models here. +from django import forms +from .models import Post, Comment, Contact, AuthorProfile, CKPost, SubCategory, Category, Advertisement +from ckeditor.widgets import CKEditorWidget +from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.models import User +from django.utils.html import format_html # For custom JS in admin form -admin.site.register(Post) -admin.site.register(Comment) -admin.site.register(Contact) +class PostAdminForm(forms.ModelForm): + content = forms.CharField(widget=CKEditorWidget()) + + class Meta: + model = CKPost + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['title'].widget.attrs.update({'class': 'form-control'}) + self.fields['category'].widget.attrs.update({'class': 'form-control'}) + self.fields['sub_category'].widget.attrs.update({'class': 'form-control'}) + self.fields['content'].widget.attrs.update({'class': 'form-control'}) # content already uses CKEditorWidget + self.fields['image'].widget.attrs.update({'class': 'form-control-file'}) + self.fields['slug'].widget.attrs.update({'class': 'form-control'}) + +class PostAdmin(admin.ModelAdmin): + form = PostAdminForm + list_display = ('title', 'user', 'category', 'time') + list_filter = ('category', 'time', 'user') + search_fields = ('title', 'content', 'user__username', 'user__email') + prepopulated_fields = {'slug': ('title',)} # Auto-populate slug from title + +class AuthorProfileInline(admin.StackedInline): + model = AuthorProfile + can_delete = False + verbose_name_plural = 'Author Profile' + fk_name = 'user' + +class AdvertisementAdminForm(forms.ModelForm): + class Meta: + model = Advertisement + fields = '__all__' + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # JavaScript to show/hide category based on position + # This makes 'category' field more prominent when needed + self.fields['position'].widget.attrs['onchange'] = ( + "var categoryRow = document.querySelector('.field-category');" + "if (this.value === 'bottom_banner_category' || this.value === 'sidebar') {" + " categoryRow.style.display = '';" + "} else {" + " categoryRow.style.display = 'none';" + "}" + ) + + # Include the script in the form's media + class Media: + js = ('admin/js/jquery.init.js', 'admin/js/dynamic_form_fields.js') # Example, ensure these paths are correct or provide inline script +@admin.register(Advertisement) +class AdvertisementAdmin(admin.ModelAdmin): + form = AdvertisementAdminForm + list_display = ('title', 'position', 'link_type', 'category', 'is_active', 'display_order', 'created_at') + list_filter = ('is_active', 'position', 'category', 'link_type') + search_fields = ('title',) + fieldsets = ( + (None, { + 'fields': ('title', 'image', 'is_active', 'position', 'display_order') + }), + ('Lien de l\'annonce', { + 'fields': ('link_type', 'external_url'), + 'description': ("Si un type de 'Formulaire Interne' est choisi, l'URL externe sera ignorée. " # Updated description + "Si 'Lien Externe' est choisi, l'URL externe est requise.") + }), + ('Ciblage par Catégorie', { + 'fields': ('category',), + 'description': ("Requis pour 'Bottom Banner Category'. Optionnel pour 'Sidebar Ad' " + "pour cibler une catégorie spécifique. Laisser vide pour les 'Sidebar Ad' généraux.") + }), + ) + list_editable = ('is_active', 'display_order') + +class CustomUserAdmin(UserAdmin): + inlines = (AuthorProfileInline,) + list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active', 'get_is_author') # Renamed for consistency + list_filter = ('is_staff', 'is_active', 'authorprofile__is_author') + fieldsets = UserAdmin.fieldsets # Use default UserAdmin fieldsets + add_fieldsets = UserAdmin.add_fieldsets # Use default UserAdmin add_fieldsets + + + def get_is_author(self, obj): + if hasattr(obj, 'authorprofile'): + return obj.authorprofile.is_author + return False + get_is_author.boolean = True + get_is_author.short_description = 'Is Author' + +@admin.register(Category) +class CategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'slug', 'description') + prepopulated_fields = {'slug': ('name',)} + +@admin.register(SubCategory) +class SubCategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'category') + list_filter = ('category',) + +# --- Registration --- +admin.site.unregister(User) # Unregister default User admin +admin.site.register(User, CustomUserAdmin) # Register with custom admin + +admin.site.register(CKPost, PostAdmin) +admin.site.register(Post) # Assuming this is your old Post model, keep if needed, otherwise remove +admin.site.register(Comment) +admin.site.register(Contact) +# admin.site.register(AuthorProfile) # This is handled by the inline in CustomUserAdmin -admin.site.site_header = 'BLOGSPOT | ADMIN PANEL' -admin.site.site_title = 'BLOGSPOT | BLOGGING WEBSITE' -admin.site.index_title= 'BlogSpot Site Administration' +admin.site.site_header = 'GOZONE | ADMIN PANEL' # Updated name +admin.site.site_title = 'GOZONE | Content Management' # Updated name +admin.site.index_title = 'GoZone Site Administration' # Updated name \ No newline at end of file diff --git a/myapp/forms.py b/myapp/forms.py new file mode 100644 index 00000000..322f1e87 --- /dev/null +++ b/myapp/forms.py @@ -0,0 +1,251 @@ +from django import forms + +from ckeditor.fields import RichTextFormField +from ckeditor.widgets import CKEditorWidget +from ckeditor_uploader.fields import RichTextUploadingFormField +from ckeditor_uploader.widgets import CKEditorUploadingWidget + +from .models import CKPost , Category, SubCategory +from .models import CKPost, Category, SubCategory + + +from django.forms import MultiWidget + + +class CkEditorMultiWidget(MultiWidget): + def decompress(self, value): + return [value for _ in self.widgets] + + +class CkEditorForm(forms.Form): + ckeditor_standard_example = RichTextFormField() + # ckeditor_upload_example = RichTextUploadingFormField( + # config_name="my-custom-toolbar" + # ) + + +class CkEditorMultiWidgetForm(forms.Form): + SUBWIDGET_SUFFIXES = ["0", "1"] + + ckeditor_standard_multi_widget_example = forms.CharField( + widget=CkEditorMultiWidget( + widgets={suffix: CKEditorWidget for suffix in SUBWIDGET_SUFFIXES}, + ), + ) + # ckeditor_upload_multi_widget_example = forms.CharField( + # widget=CkEditorMultiWidget( + # widgets={ + # suffix: CKEditorUploadingWidget(config_name="my-custom-toolbar") + # for suffix in SUBWIDGET_SUFFIXES + # }, + # ), + # ) + + +class CKPostForm(forms.ModelForm): + class Meta: + model = CKPost + fields = '__all__' + exclude = ['slug'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Filtrage dynamique des sous-catégories + if 'category' in self.data: + try: + category_id = int(self.data.get('category')) + self.fields['sub_category'].queryset = SubCategory.objects.filter(category_id=category_id).order_by('name') + except (ValueError, TypeError): + self.fields['sub_category'].queryset = SubCategory.objects.none() + elif self.instance.pk and self.instance.category: + self.fields['sub_category'].queryset = self.instance.category.subcategories.order_by('name') + else: + self.fields['sub_category'].queryset = SubCategory.objects.none() + + # Option par défaut pour les sous-catégories + self.fields['sub_category'].empty_label = "Sélectionnez une sous-catégorie" + + def clean(self): + cleaned_data = super().clean() + category = cleaned_data.get("category") + sub_category = cleaned_data.get("sub_category") + + # Validation que la sous-catégorie appartient bien à la catégorie + if sub_category and sub_category.category != category: + self.add_error('sub_category', "La sous-catégorie ne correspond pas à la catégorie sélectionnée.") + + return cleaned_data + + +# class CKPostOverriddenWidgetForm(forms.ModelForm): +# class Meta: +# model = CKPost +# fields = "__all__" + +# def __init__(self, *args, **kwargs): +# super().__init__(*args, **kwargs) + +# self.fields["content"].widget = CKEditorUploadingWidget( +# config_name="my-custom-toolbar", +# extra_plugins=["someplugin", "anotherplugin"], +# external_plugin_resources=[ +# ( +# "someplugin", +# "/static/path/to/someplugin/", +# "plugin.js", +# ) +# ], +# ) + +class CategoryForm(forms.ModelForm): + class Meta: + model = Category + fields = '__all__' + # You can specify fields to exclude if needed + + +# blog/forms.py +from django import forms + +PROFILE_CHOICES = [ + ('porteur_projet', 'Porteur de projet'), + ('structure_accompagnement', "Structure d'accompagnement (Incubateur, Pépinière, Technopole...)"), + ('organisme_financement', 'Organisme de financement (Banque, Micro-Finance, SICAR...)'), +] + +class LeadGenerationForm(forms.Form): + profil = forms.ChoiceField( + choices=PROFILE_CHOICES, + widget=forms.RadioSelect(attrs={'class': 'form-check-input'}), # For radio buttons + label="Profil" + ) + email = forms.EmailField( + label="Email *", + widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email *'}) + ) + nom_prenom = forms.CharField( + label="Nom et prénom", + required=False, # Assuming this is optional based on screenshot (no asterisk) + widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Nom et prénom'}) + ) + telephone = forms.CharField( + label="Téléphone", + required=False, # Assuming optional + widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Téléphone'}) + ) + gouvernorat = forms.CharField( + label="Gouvernorat", + required=False, # Assuming optional + widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Gouvernorat'}) + ) + # You might want to add a hidden field for the source of the lead, e.g., which ad they clicked + # source_ad_id = forms.IntegerField(widget=forms.HiddenInput(), required=False) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # Optional: if you want to style the radio select label differently or add a general class + # self.fields['profil'].widget.attrs.update({'class': 'profile-radio-group'}) + # For individual radio buttons, you might need custom widget rendering or JS. + # The default rendering of RadioSelect will create
tags around each input and label.
+ # You'll style these in your CSS.
+
+# --- New Form for GOZONE Contact ---
+GOZONE_PROFILE_CHOICES = [
+ ('porteur_projet', 'Porteur de projet'),
+ ('chef_entreprise', 'Chef d’entreprise / dirigeant'),
+ ('organisme_accompagnement', 'Organisme d’accompagnement (incubateur, centre de formation , etc.)'),
+ ('organisme_financement', 'Organisme de financement (banque, micro-finance, SICAR , etc.)'),
+ ('ong', 'Organisation Non Gouvernementale (ONG)'),
+ ('professionnel', 'Professionnel (manager, ingénieur, technicien, etc.)'),
+ ('expert_consultant', 'Expert / consultant / formateur'),
+ ('etudiant', 'Etudiant'),
+ ('autre_profil', 'Autre'),
+]
+
+GOZONE_NEEDS_CHOICES = [
+ ('creation_entreprise', 'Appui à la création d’entreprise ou au montage de projet'),
+ ('etudes_techniques', 'Études techniques (étude d’impact environnemental, Étude de sécurité,)'),
+ ('conseil_organisationnel', 'Conseil ou accompagnement organisationnel (systèmes de management, restructuration, etc.)'),
+ ('formation_professionnelle', 'Formation professionnelle sur mesure'),
+ ('digitalisation_processus', 'Digitalisation de processus internes'),
+ ('organisation_evenement', 'Organisation d’un événement ou atelier sur mesure'),
+ ('collaboration_partenariat', 'Collaboration ou partenariat avec GOZONE'),
+ ('autre_besoin', 'Autre'),
+]
+
+class GozoneContactForm(forms.Form):
+ # Standard contact fields (can be shared or duplicated if styling differs greatly)
+ nom_prenom = forms.CharField(
+ label="Nom et Prénom*",
+ max_length=100,
+ widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Votre nom complet'})
+ )
+ email = forms.EmailField(
+ label="Adresse Email*",
+ widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'exemple@domaine.com'})
+ )
+ telephone = forms.CharField(
+ label="Numéro de Téléphone (Optionnel)",
+ max_length=20,
+ required=False,
+ widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '+216 XX XXX XXX'})
+ )
+ organisation = forms.CharField(
+ label="Organisation / Société (Optionnel)",
+ max_length=150,
+ required=False,
+ widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Nom de votre organisation'})
+ )
+
+ # GOZONE specific fields
+ profil_gozone = forms.ChoiceField(
+ choices=GOZONE_PROFILE_CHOICES,
+ widget=forms.RadioSelect, # Using RadioSelect as per your description
+ label="Votre profil*",
+ required=True
+ )
+ profil_gozone_autre_details = forms.CharField(
+ label="Si autre profil, veuillez préciser :",
+ required=False,
+ widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Précisez votre profil'})
+ )
+
+ besoins_gozone = forms.MultipleChoiceField(
+ choices=GOZONE_NEEDS_CHOICES,
+ widget=forms.CheckboxSelectMultiple, # Using CheckboxSelectMultiple for "Cochez ou précisez"
+ label="Vous êtes à la recherche de...*",
+ help_text="Cochez ou précisez votre demande (Votre besoin / prestation souhaitée)",
+ required=True
+ )
+ besoins_gozone_autre_details = forms.CharField(
+ label="Si autre besoin, veuillez préciser :",
+ required=False,
+ widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Décrivez votre besoin spécifique'})
+ )
+ message_complementaire = forms.CharField(
+ label="Message complémentaire (Optionnel)",
+ required=False,
+ widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'placeholder': 'Ajoutez des détails ou un message ici'})
+ )
+
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ # You can add common classes or tweaks here if needed
+ # For radio/checkbox, styling is often template/CSS driven
+
+ def clean(self):
+ cleaned_data = super().clean()
+ profil = cleaned_data.get("profil_gozone")
+ profil_autre_details = cleaned_data.get("profil_gozone_autre_details")
+ besoins = cleaned_data.get("besoins_gozone")
+ besoins_autre_details = cleaned_data.get("besoins_gozone_autre_details")
+
+ if profil == 'autre_profil' and not profil_autre_details:
+ self.add_error('profil_gozone_autre_details', "Veuillez préciser votre profil si vous avez sélectionné 'Autre'.")
+
+ if besoins and 'autre_besoin' in besoins and not besoins_autre_details:
+ self.add_error('besoins_gozone_autre_details', "Veuillez préciser votre besoin si vous avez coché 'Autre'.")
+
+ return cleaned_data
\ No newline at end of file
diff --git a/myapp/migrations/0001_initial.py b/myapp/migrations/0001_initial.py
index db3ebb2c..daa148ff 100644
--- a/myapp/migrations/0001_initial.py
+++ b/myapp/migrations/0001_initial.py
@@ -1,92 +1,105 @@
-# Generated by Django 4.1.7 on 2023-04-22 11:52
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name="UserInfo",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("image", models.ImageField(blank=True, null=True, upload_to="images")),
- (
- "username",
- models.OneToOneField(
- on_delete=django.db.models.deletion.CASCADE,
- to=settings.AUTH_USER_MODEL,
- ),
- ),
- ],
- ),
- migrations.CreateModel(
- name="Post",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("postname", models.CharField(max_length=600)),
- ("category", models.CharField(max_length=600)),
- (
- "image",
- models.ImageField(blank=True, null=True, upload_to="images/posts"),
- ),
- ("content", models.CharField(max_length=10000000)),
- ("time", models.CharField(max_length=30)),
- ("likes", models.IntegerField()),
- (
- "username",
- models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE,
- to=settings.AUTH_USER_MODEL,
- ),
- ),
- ],
- ),
- migrations.CreateModel(
- name="Comment",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("content", models.CharField(max_length=200)),
- ("time", models.CharField(max_length=30)),
- (
- "username",
- models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE,
- to=settings.AUTH_USER_MODEL,
- ),
- ),
- ],
- ),
- ]
+# Generated by Django 4.1.8 on 2025-02-13 18:25
+
+import ckeditor.fields
+from django.conf import settings
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Category',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(blank=True, choices=[('Technology', 'Technology'), ('Science', 'Science'), ('Business', 'Business'), ('Entertainment', 'Entertainment'), ('Sports', 'Sports'), ('Politics', 'Politics'), ('Health', 'Health')], max_length=600, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='CKPost',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=600)),
+ ('content', ckeditor.fields.RichTextField()),
+ ('slug', models.SlugField(blank=True, default='', max_length=200, unique=True)),
+ ('image', models.ImageField(blank=True, null=True, upload_to='images/posts')),
+ ('likes', models.IntegerField(blank=True, default=0, null=True)),
+ ('time', models.DateTimeField(auto_now_add=True)),
+ ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='posts', to='myapp.category')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Contact',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=600)),
+ ('email', models.EmailField(max_length=600)),
+ ('subject', models.CharField(max_length=1000)),
+ ('message', models.CharField(blank=True, max_length=10000)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='SubCategory',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=600)),
+ ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subcategories', to='myapp.category')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Post',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('postname', models.CharField(max_length=600)),
+ ('category', models.CharField(max_length=600)),
+ ('image', models.ImageField(blank=True, null=True, upload_to='images/posts')),
+ ('content', models.CharField(max_length=100000)),
+ ('time', models.CharField(blank=True, default='13 February 2025', max_length=100)),
+ ('likes', models.IntegerField(blank=True, default=0, null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Comment',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('user', models.CharField(max_length=100)),
+ ('content', models.TextField()),
+ ('time', models.DateTimeField(auto_now_add=True)),
+ ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='myapp.comment')),
+ ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='myapp.ckpost')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='ckpost',
+ name='sub_category',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='myapp.subcategory'),
+ ),
+ migrations.AddField(
+ model_name='ckpost',
+ name='user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.CreateModel(
+ name='AuthorProfile',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('bio', models.TextField(blank=True, null=True)),
+ ('profile_picture', models.ImageField(blank=True, null=True, upload_to='author_pictures/')),
+ ('website', models.URLField(blank=True, null=True)),
+ ('metier', models.TextField(blank=True, null=True)),
+ ('facebook', models.URLField(blank=True, null=True, validators=[django.core.validators.URLValidator()])),
+ ('twitter', models.URLField(blank=True, null=True, validators=[django.core.validators.URLValidator()])),
+ ('gmail', models.EmailField(blank=True, max_length=254, null=True)),
+ ('user', models.OneToOneField(limit_choices_to={'is_staff': True}, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ ]
diff --git a/myapp/migrations/0002_authorprofile_is_author_alter_authorprofile_user_and_more.py b/myapp/migrations/0002_authorprofile_is_author_alter_authorprofile_user_and_more.py
new file mode 100644
index 00000000..8f5d809d
--- /dev/null
+++ b/myapp/migrations/0002_authorprofile_is_author_alter_authorprofile_user_and_more.py
@@ -0,0 +1,31 @@
+# Generated by Django 5.1.6 on 2025-02-14 08:40
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0001_initial'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='authorprofile',
+ name='is_author',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='authorprofile',
+ name='user',
+ field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='14 February 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0002_rename_username_post_post_remove_comment_username_and_more.py b/myapp/migrations/0002_rename_username_post_post_remove_comment_username_and_more.py
deleted file mode 100644
index ef9bd0a6..00000000
--- a/myapp/migrations/0002_rename_username_post_post_remove_comment_username_and_more.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:08
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0001_initial"),
- ]
-
- operations = [
- migrations.RenameField(
- model_name="post", old_name="username", new_name="post",
- ),
- migrations.RemoveField(model_name="comment", name="username",),
- migrations.AddField(
- model_name="comment",
- name="comment",
- field=models.ForeignKey(
- default=1, on_delete=django.db.models.deletion.CASCADE, to="myapp.post"
- ),
- preserve_default=False,
- ),
- migrations.AlterField(
- model_name="post",
- name="content",
- field=models.CharField(max_length=100000),
- ),
- ]
diff --git a/myapp/migrations/0003_category_description_category_image_category_slug_and_more.py b/myapp/migrations/0003_category_description_category_image_category_slug_and_more.py
new file mode 100644
index 00000000..42f105b4
--- /dev/null
+++ b/myapp/migrations/0003_category_description_category_image_category_slug_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 5.1.6 on 2025-02-19 09:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0002_authorprofile_is_author_alter_authorprofile_user_and_more'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='category',
+ name='description',
+ field=models.TextField(blank=True, null=True),
+ ),
+ migrations.AddField(
+ model_name='category',
+ name='image',
+ field=models.ImageField(blank=True, null=True, upload_to='category_images/'),
+ ),
+ migrations.AddField(
+ model_name='category',
+ name='slug',
+ field=models.SlugField(blank=True, null=True, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='19 February 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0003_rename_comment_comment_postcomment_and_more.py b/myapp/migrations/0003_rename_comment_comment_postcomment_and_more.py
deleted file mode 100644
index 743b4375..00000000
--- a/myapp/migrations/0003_rename_comment_comment_postcomment_and_more.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:09
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0002_rename_username_post_post_remove_comment_username_and_more"),
- ]
-
- operations = [
- migrations.RenameField(
- model_name="comment", old_name="comment", new_name="postcomment",
- ),
- migrations.RenameField(
- model_name="post", old_name="post", new_name="userpost",
- ),
- ]
diff --git a/myapp/migrations/0004_advertisement_alter_category_name_alter_post_time.py b/myapp/migrations/0004_advertisement_alter_category_name_alter_post_time.py
new file mode 100644
index 00000000..3706c9b6
--- /dev/null
+++ b/myapp/migrations/0004_advertisement_alter_category_name_alter_post_time.py
@@ -0,0 +1,34 @@
+# Generated by Django 5.1.6 on 2025-04-24 15:26
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0003_category_description_category_image_category_slug_and_more'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Advertisement',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=200)),
+ ('image', models.ImageField(upload_to='ads/')),
+ ('url', models.URLField()),
+ ('is_active', models.BooleanField(default=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ migrations.AlterField(
+ model_name='category',
+ name='name',
+ field=models.CharField(blank=True, max_length=600, null=True),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='24 April 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.py b/myapp/migrations/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.py
deleted file mode 100644
index 858110f3..00000000
--- a/myapp/migrations/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:14
-
-import datetime
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0003_rename_comment_comment_postcomment_and_more"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="userinfo",
- name="address",
- field=models.CharField(default=1, max_length=200),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name="userinfo",
- name="dob",
- field=models.CharField(default=django.utils.timezone.now, max_length=200),
- preserve_default=False,
- ),
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 43, 44, 866459)
- ),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 43, 44, 865459)
- ),
- ),
- ]
diff --git a/myapp/migrations/0005_alter_advertisement_options_advertisement_category_and_more.py b/myapp/migrations/0005_alter_advertisement_options_advertisement_category_and_more.py
new file mode 100644
index 00000000..7f2a482a
--- /dev/null
+++ b/myapp/migrations/0005_alter_advertisement_options_advertisement_category_and_more.py
@@ -0,0 +1,58 @@
+# Generated by Django 5.1.6 on 2025-05-07 07:50
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0004_advertisement_alter_category_name_alter_post_time'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='advertisement',
+ options={'ordering': ['position', 'category', 'display_order', '-created_at']},
+ ),
+ migrations.AddField(
+ model_name='advertisement',
+ name='category',
+ field=models.ForeignKey(blank=True, help_text='Optional: Show this ad ONLY when this category is active (for sidebar ads).', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='advertisements', to='myapp.category'),
+ ),
+ migrations.AddField(
+ model_name='advertisement',
+ name='display_order',
+ field=models.IntegerField(default=0, help_text='Order of display for multiple ads in the same position/category (lower numbers first).'),
+ ),
+ migrations.AddField(
+ model_name='advertisement',
+ name='position',
+ field=models.CharField(choices=[('sidebar', 'Sidebar Ad (Vertical)'), ('bottom_banner_home', 'Bottom Banner Home (Horizontal)')], default='sidebar', help_text='Where this ad will be displayed.', max_length=50),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='image',
+ field=models.ImageField(help_text='Image for the advertisement.', upload_to='ads/'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='is_active',
+ field=models.BooleanField(default=True, help_text='Is this ad currently active and should be displayed?'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='title',
+ field=models.CharField(help_text="Internal title for the ad (e.g., 'Sidebar Ad for Tech Category').", max_length=200),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='url',
+ field=models.URLField(blank=True, help_text='Optional: URL the ad links to if clickable.', null=True),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='07 May 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0005_alter_comment_time_alter_post_likes_alter_post_time.py b/myapp/migrations/0005_alter_comment_time_alter_post_likes_alter_post_time.py
deleted file mode 100644
index c2b1a656..00000000
--- a/myapp/migrations/0005_alter_comment_time_alter_post_likes_alter_post_time.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:16
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0004_userinfo_address_userinfo_dob_alter_comment_time_and_more"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 46, 13, 961428)
- ),
- ),
- migrations.AlterField(
- model_name="post",
- name="likes",
- field=models.IntegerField(blank=True, default=0, null=True),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 46, 13, 961428)
- ),
- ),
- ]
diff --git a/myapp/migrations/0006_alter_comment_time_alter_post_time.py b/myapp/migrations/0006_alter_comment_time_alter_post_time.py
deleted file mode 100644
index 04e6784a..00000000
--- a/myapp/migrations/0006_alter_comment_time_alter_post_time.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:17
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0005_alter_comment_time_alter_post_likes_alter_post_time"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 47, 53, 666251)
- ),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 47, 53, 666251)
- ),
- ),
- ]
diff --git a/myapp/migrations/0006_remove_advertisement_url_advertisement_external_url_and_more.py b/myapp/migrations/0006_remove_advertisement_url_advertisement_external_url_and_more.py
new file mode 100644
index 00000000..0aa0e87f
--- /dev/null
+++ b/myapp/migrations/0006_remove_advertisement_url_advertisement_external_url_and_more.py
@@ -0,0 +1,42 @@
+# Generated by Django 5.1.6 on 2025-05-07 09:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0005_alter_advertisement_options_advertisement_category_and_more'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='advertisement',
+ name='url',
+ ),
+ migrations.AddField(
+ model_name='advertisement',
+ name='external_url',
+ field=models.URLField(blank=True, help_text="URL externe (si 'Lien Externe Personnalisé' est choisi).", null=True),
+ ),
+ migrations.AddField(
+ model_name='advertisement',
+ name='link_type',
+ field=models.CharField(choices=[('external', 'Lien Externe Personnalisé'), ('internal_form', 'Formulaire Interne (Création Société)')], default='external', help_text="Choisir si l'annonce redirige vers un lien externe ou le formulaire interne.", max_length=20),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='display_order',
+ field=models.IntegerField(default=0, help_text='Order of display (lower numbers first).'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='is_active',
+ field=models.BooleanField(default=True, help_text='Is this ad currently active?'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='title',
+ field=models.CharField(help_text='Internal title for the ad.', max_length=200),
+ ),
+ ]
diff --git a/myapp/migrations/0007_alter_advertisement_category_and_more.py b/myapp/migrations/0007_alter_advertisement_category_and_more.py
new file mode 100644
index 00000000..95af90bc
--- /dev/null
+++ b/myapp/migrations/0007_alter_advertisement_category_and_more.py
@@ -0,0 +1,29 @@
+# Generated by Django 5.1.6 on 2025-05-15 09:29
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0006_remove_advertisement_url_advertisement_external_url_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='advertisement',
+ name='category',
+ field=models.ForeignKey(blank=True, help_text="Required for 'Bottom Banner Category' & optional for 'Sidebar Ad'. Specifies which category this ad is tied to.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='advertisements', to='myapp.category'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='position',
+ field=models.CharField(choices=[('sidebar', 'Sidebar Ad (Vertical)'), ('bottom_banner_home', 'Bottom Banner Home (Horizontal)'), ('bottom_banner_category', 'Bottom Banner Category (Horizontal)')], default='sidebar', help_text='Where this ad will be displayed.', max_length=50),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='15 May 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0007_rename_postcomment_comment_post_and_more.py b/myapp/migrations/0007_rename_postcomment_comment_post_and_more.py
deleted file mode 100644
index ad1125c4..00000000
--- a/myapp/migrations/0007_rename_postcomment_comment_post_and_more.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:19
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0006_alter_comment_time_alter_post_time"),
- ]
-
- operations = [
- migrations.RenameField(
- model_name="comment", old_name="postcomment", new_name="post",
- ),
- migrations.RenameField(
- model_name="post", old_name="userpost", new_name="user",
- ),
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 49, 13, 782667)
- ),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 49, 13, 782667)
- ),
- ),
- ]
diff --git a/myapp/migrations/0008_alter_advertisement_category_and_more.py b/myapp/migrations/0008_alter_advertisement_category_and_more.py
new file mode 100644
index 00000000..0c2f198c
--- /dev/null
+++ b/myapp/migrations/0008_alter_advertisement_category_and_more.py
@@ -0,0 +1,29 @@
+# Generated by Django 5.1.6 on 2025-06-18 08:44
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0007_alter_advertisement_category_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='advertisement',
+ name='category',
+ field=models.ForeignKey(blank=True, help_text="Required for 'Bottom Banner Category' & optional for 'Sidebar Ad'.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='advertisements', to='myapp.category'),
+ ),
+ migrations.AlterField(
+ model_name='advertisement',
+ name='link_type',
+ field=models.CharField(choices=[('external', 'Lien Externe Personnalisé'), ('internal_form_livre', 'Formulaire Interne (Livre Création Société)'), ('internal_form_gozone', 'Formulaire Interne (Contact GOZONE)')], default='external', help_text="Choisir si l'annonce redirige vers un lien externe ou un formulaire interne.", max_length=30),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='18 June 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0008_alter_comment_time_alter_post_time.py b/myapp/migrations/0008_alter_comment_time_alter_post_time.py
deleted file mode 100644
index ab37c314..00000000
--- a/myapp/migrations/0008_alter_comment_time_alter_post_time.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 12:19
-
-import datetime
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0007_rename_postcomment_comment_post_and_more"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 49, 35, 13510)
- ),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.DateTimeField(
- blank=True, default=datetime.datetime(2023, 4, 22, 17, 49, 35, 12510)
- ),
- ),
- ]
diff --git a/myapp/migrations/0009_alter_ckpost_time_alter_post_time.py b/myapp/migrations/0009_alter_ckpost_time_alter_post_time.py
new file mode 100644
index 00000000..e5e0018e
--- /dev/null
+++ b/myapp/migrations/0009_alter_ckpost_time_alter_post_time.py
@@ -0,0 +1,24 @@
+# Generated by Django 5.1.6 on 2025-07-12 09:11
+
+import django.utils.timezone
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('myapp', '0008_alter_advertisement_category_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='ckpost',
+ name='time',
+ field=models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True),
+ ),
+ migrations.AlterField(
+ model_name='post',
+ name='time',
+ field=models.CharField(blank=True, default='12 July 2025', max_length=100),
+ ),
+ ]
diff --git a/myapp/migrations/0009_alter_comment_time_alter_post_time.py b/myapp/migrations/0009_alter_comment_time_alter_post_time.py
deleted file mode 100644
index 3052a4cd..00000000
--- a/myapp/migrations/0009_alter_comment_time_alter_post_time.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-22 13:35
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0008_alter_comment_time_alter_post_time"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.CharField(blank=True, default="22 April 2023", max_length=100),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.CharField(blank=True, default="22 April 2023", max_length=100),
- ),
- ]
diff --git a/myapp/migrations/0010_comment_user_alter_comment_time_alter_post_time_and_more.py b/myapp/migrations/0010_comment_user_alter_comment_time_alter_post_time_and_more.py
deleted file mode 100644
index 07f46bc9..00000000
--- a/myapp/migrations/0010_comment_user_alter_comment_time_alter_post_time_and_more.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-23 13:53
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ("myapp", "0009_alter_comment_time_alter_post_time"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="comment",
- name="user",
- field=models.ForeignKey(
- default=1,
- on_delete=django.db.models.deletion.CASCADE,
- to=settings.AUTH_USER_MODEL,
- ),
- preserve_default=False,
- ),
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.CharField(blank=True, default="23 April 2023", max_length=100),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.CharField(blank=True, default="23 April 2023", max_length=100),
- ),
- migrations.AlterField(
- model_name="userinfo",
- name="image",
- field=models.ImageField(blank=True, null=True, upload_to="images/profile"),
- ),
- ]
diff --git a/myapp/migrations/0011_delete_userinfo.py b/myapp/migrations/0011_delete_userinfo.py
deleted file mode 100644
index 85e1e079..00000000
--- a/myapp/migrations/0011_delete_userinfo.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated by Django 4.1.7 on 2023-04-23 14:23
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0010_comment_user_alter_comment_time_alter_post_time_and_more"),
- ]
-
- operations = [
- migrations.DeleteModel(name="UserInfo",),
- ]
diff --git a/myapp/migrations/0012_alter_comment_time_alter_post_time.py b/myapp/migrations/0012_alter_comment_time_alter_post_time.py
deleted file mode 100644
index 5b0b8d8f..00000000
--- a/myapp/migrations/0012_alter_comment_time_alter_post_time.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.1.7 on 2023-05-09 16:18
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("myapp", "0011_delete_userinfo"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="comment",
- name="time",
- field=models.CharField(blank=True, default="09 May 2023", max_length=100),
- ),
- migrations.AlterField(
- model_name="post",
- name="time",
- field=models.CharField(blank=True, default="09 May 2023", max_length=100),
- ),
- ]
diff --git a/myapp/migrations/0013_alter_comment_time_alter_post_time.py b/myapp/migrations/0013_alter_comment_time_alter_post_time.py
deleted file mode 100644
index 1a805185..00000000
--- a/myapp/migrations/0013_alter_comment_time_alter_post_time.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.2.4 on 2023-09-03 11:43
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('myapp', '0012_alter_comment_time_alter_post_time'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='comment',
- name='time',
- field=models.CharField(blank=True, default='03 September 2023', max_length=100),
- ),
- migrations.AlterField(
- model_name='post',
- name='time',
- field=models.CharField(blank=True, default='03 September 2023', max_length=100),
- ),
- ]
diff --git a/myapp/migrations/0014_contact.py b/myapp/migrations/0014_contact.py
deleted file mode 100644
index 21f38175..00000000
--- a/myapp/migrations/0014_contact.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.2.4 on 2023-09-03 17:00
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('myapp', '0013_alter_comment_time_alter_post_time'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Contact',
- fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=600)),
- ('email', models.EmailField(max_length=600)),
- ('subject', models.CharField(max_length=1000)),
- ('message', models.CharField(blank=True, max_length=10000)),
- ],
- ),
- ]
diff --git a/myapp/migrations/__pycache__/0001_initial.cpython-311.pyc b/myapp/migrations/__pycache__/0001_initial.cpython-311.pyc
deleted file mode 100644
index 6d451d5a..00000000
Binary files a/myapp/migrations/__pycache__/0001_initial.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0001_initial.cpython-38.pyc b/myapp/migrations/__pycache__/0001_initial.cpython-38.pyc
deleted file mode 100644
index 49dc7994..00000000
Binary files a/myapp/migrations/__pycache__/0001_initial.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-311.pyc b/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-311.pyc
deleted file mode 100644
index 68e2ca3d..00000000
Binary files a/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-38.pyc b/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-38.pyc
deleted file mode 100644
index 55ce905e..00000000
Binary files a/myapp/migrations/__pycache__/0002_rename_username_post_post_remove_comment_username_and_more.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-311.pyc b/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-311.pyc
deleted file mode 100644
index f0660253..00000000
Binary files a/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-38.pyc b/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-38.pyc
deleted file mode 100644
index 64550bf3..00000000
Binary files a/myapp/migrations/__pycache__/0003_rename_comment_comment_postcomment_and_more.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-311.pyc b/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-311.pyc
deleted file mode 100644
index 67138cd0..00000000
Binary files a/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-38.pyc b/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-38.pyc
deleted file mode 100644
index 1a84f326..00000000
Binary files a/myapp/migrations/__pycache__/0004_userinfo_address_userinfo_dob_alter_comment_time_and_more.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-311.pyc
deleted file mode 100644
index ac0df95e..00000000
Binary files a/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-38.pyc b/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-38.pyc
deleted file mode 100644
index 1851181a..00000000
Binary files a/myapp/migrations/__pycache__/0005_alter_comment_time_alter_post_likes_alter_post_time.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-311.pyc
deleted file mode 100644
index c65f85e0..00000000
Binary files a/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-38.pyc b/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-38.pyc
deleted file mode 100644
index 1b1964a4..00000000
Binary files a/myapp/migrations/__pycache__/0006_alter_comment_time_alter_post_time.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-311.pyc b/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-311.pyc
deleted file mode 100644
index 1296a8e5..00000000
Binary files a/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-38.pyc b/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-38.pyc
deleted file mode 100644
index cee2d84f..00000000
Binary files a/myapp/migrations/__pycache__/0007_rename_postcomment_comment_post_and_more.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-311.pyc
deleted file mode 100644
index ed987c2d..00000000
Binary files a/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-38.pyc b/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-38.pyc
deleted file mode 100644
index d38ca495..00000000
Binary files a/myapp/migrations/__pycache__/0008_alter_comment_time_alter_post_time.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-311.pyc
deleted file mode 100644
index 86dcb9ce..00000000
Binary files a/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-38.pyc b/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-38.pyc
deleted file mode 100644
index d691bbbe..00000000
Binary files a/myapp/migrations/__pycache__/0009_alter_comment_time_alter_post_time.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-311.pyc b/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-311.pyc
deleted file mode 100644
index 27b739c9..00000000
Binary files a/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-38.pyc b/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-38.pyc
deleted file mode 100644
index f5518a1e..00000000
Binary files a/myapp/migrations/__pycache__/0010_comment_user_alter_comment_time_alter_post_time_and_more.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-311.pyc b/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-311.pyc
deleted file mode 100644
index 316411d5..00000000
Binary files a/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-38.pyc b/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-38.pyc
deleted file mode 100644
index a8823b90..00000000
Binary files a/myapp/migrations/__pycache__/0011_delete_userinfo.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-311.pyc
deleted file mode 100644
index 298c045d..00000000
Binary files a/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-38.pyc b/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-38.pyc
deleted file mode 100644
index b38ad3c3..00000000
Binary files a/myapp/migrations/__pycache__/0012_alter_comment_time_alter_post_time.cpython-38.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0013_alter_comment_time_alter_post_time.cpython-311.pyc b/myapp/migrations/__pycache__/0013_alter_comment_time_alter_post_time.cpython-311.pyc
deleted file mode 100644
index 0a7a8827..00000000
Binary files a/myapp/migrations/__pycache__/0013_alter_comment_time_alter_post_time.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/0014_contact.cpython-311.pyc b/myapp/migrations/__pycache__/0014_contact.cpython-311.pyc
deleted file mode 100644
index 29cbe371..00000000
Binary files a/myapp/migrations/__pycache__/0014_contact.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/__init__.cpython-311.pyc b/myapp/migrations/__pycache__/__init__.cpython-311.pyc
deleted file mode 100644
index 9ae77c32..00000000
Binary files a/myapp/migrations/__pycache__/__init__.cpython-311.pyc and /dev/null differ
diff --git a/myapp/migrations/__pycache__/__init__.cpython-38.pyc b/myapp/migrations/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index c67c4dc3..00000000
Binary files a/myapp/migrations/__pycache__/__init__.cpython-38.pyc and /dev/null differ
diff --git a/myapp/models.py b/myapp/models.py
index 9d5c2a3d..726e214a 100644
--- a/myapp/models.py
+++ b/myapp/models.py
@@ -1,37 +1,211 @@
from django.db import models
from django.contrib.auth.models import User
-from datetime import datetime
+from datetime import datetime
+from ckeditor.fields import RichTextField
+from django.utils.text import slugify
+from django.core.validators import URLValidator
+from django.urls import reverse # Import reverse
-now = datetime.now()
+
+now = datetime.now()
time = now.strftime("%d %B %Y")
-# Create your models here.
+
+choices = (
+ ('Technology', 'Technology'),
+ ('Science', 'Science'),
+ ('Business', 'Business'),
+ ('Entertainment', 'Entertainment'),
+ ('Sports', 'Sports'),
+ ('Politics', 'Politics'),
+ ('Health', 'Health'),
+)
class Post(models.Model):
postname = models.CharField(max_length=600)
category = models.CharField(max_length=600)
- image = models.ImageField(upload_to='images/posts',blank=True,null=True)
+ image = models.ImageField(upload_to='images/posts', blank=True, null=True)
content = models.CharField(max_length=100000)
- time = models.CharField(default=time,max_length=100, blank=True)
- likes = models.IntegerField(null=True,blank=True,default=0)
- user = models.ForeignKey(User,on_delete=models.CASCADE)
-
+ time = models.CharField(default=time, max_length=100, blank=True)
+ likes = models.IntegerField(null=True, blank=True, default=0)
+ user = models.ForeignKey(User, on_delete=models.CASCADE)
+
+ def __str__(self):
+ return str(self.postname)
+
+# blog/models.py
+# class Advertisement(models.Model):
+# title = models.CharField(max_length=200)
+# image = models.ImageField(upload_to='ads/')
+# url = models.URLField()
+# is_active = models.BooleanField(default=True)
+# created_at = models.DateTimeField(auto_now_add=True)
+
+# def __str__(self):
+# return self.title
+
+class Category(models.Model):
+ name = models.CharField( # Removed 'choices' parameter
+ max_length=600,
+ blank=True,
+ null=True
+ )
+ slug = models.SlugField(unique=True, blank=True, null=True)
+ description = models.TextField(blank=True, null=True)
+ image = models.ImageField(
+ upload_to='category_images/',
+ blank=True,
+ null=True
+ )
+
+ def __str__(self):
+ return self.name
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+ super().save(*args, **kwargs)
+
+
+class SubCategory(models.Model):
+ category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="subcategories", blank=True,
+ null=True)
+ name = models.CharField(max_length=600)
+
+ def __str__(self):
+ return self.name
+
+
+class Advertisement(models.Model):
+ LINK_TYPE_CHOICES = [
+ ('external', 'Lien Externe Personnalisé'),
+ ('internal_form_livre', 'Formulaire Interne (Livre Création Société)'), # Renamed for clarity
+ ('internal_form_gozone', 'Formulaire Interne (Contact GOZONE)'), # <<< NEW CHOICE
+ ]
+ POSITION_CHOICES = [
+ ('sidebar', 'Sidebar Ad (Vertical)'),
+ ('bottom_banner_home', 'Bottom Banner Home (Horizontal)'),
+ ('bottom_banner_category', 'Bottom Banner Category (Horizontal)'),
+ ]
+
+ title = models.CharField(max_length=200, help_text="Internal title for the ad.")
+ image = models.ImageField(upload_to='ads/', help_text="Image for the advertisement.")
+
+ link_type = models.CharField(
+ max_length=30, # Increased length to accommodate longer choice values
+ choices=LINK_TYPE_CHOICES,
+ default='external',
+ help_text="Choisir si l'annonce redirige vers un lien externe ou un formulaire interne."
+ )
+ external_url = models.URLField(
+ blank=True, null=True,
+ help_text="URL externe (si 'Lien Externe Personnalisé' est choisi)."
+ )
+
+ is_active = models.BooleanField(default=True, help_text="Is this ad currently active?")
+ position = models.CharField(
+ max_length=50,
+ choices=POSITION_CHOICES,
+ default='sidebar',
+ help_text="Where this ad will be displayed."
+ )
+ category = models.ForeignKey(
+ 'Category',
+ on_delete=models.SET_NULL,
+ blank=True, null=True,
+ related_name="advertisements",
+ help_text="Required for 'Bottom Banner Category' & optional for 'Sidebar Ad'."
+ )
+ display_order = models.IntegerField(default=0, help_text="Order of display (lower numbers first).")
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return f"{self.title} ({self.get_position_display()})"
+
+ def get_absolute_url(self):
+ if self.link_type == 'internal_form_livre': # Updated value
+ return reverse('lead_generation_form')
+ elif self.link_type == 'internal_form_gozone': # <<< NEW
+ return reverse('gozone_contact_form') # <<< New URL name we will create
+ elif self.link_type == 'external' and self.external_url:
+ return self.external_url
+ return None
+
+ class Meta:
+ ordering = ['position', 'category', 'display_order', '-created_at']
+
+ def clean(self):
+ from django.core.exceptions import ValidationError
+ if self.link_type == 'external' and not self.external_url:
+ raise ValidationError({'external_url': "L'URL externe est requise lorsque le type de lien est 'Lien Externe Personnalisé'."})
+
+ if self.position == 'bottom_banner_category' and not self.category:
+ raise ValidationError({'category': "Une catégorie doit être associée pour les 'Bottom Banner Category'."})
+
+from django.utils import timezone
+
+class CKPost(models.Model):
+ title = models.CharField(max_length=600)
+ category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="posts", blank=True, null=True,
+ )
+ sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, blank=True, null=True)
+ content = RichTextField()
+ slug = models.SlugField(default="", max_length=200, unique=True, blank=True, null=False)
+ image = models.ImageField(upload_to='images/posts', blank=True, null=True)
+ likes = models.IntegerField(null=True, blank=True, default=0)
+ user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
+ time = models.DateTimeField(default=timezone.now, blank=True, null=True)
+
def __str__(self):
- return str( self.postname)
-
-
+ return self.title
+
+ def save(self, *args, **kwargs):
+ self.slug = slugify(self.title) if self.title else self.slug
+ original_slug = self.slug
+ slug = original_slug
+ counter = 1
+
+ while CKPost.objects.filter(slug=slug).exclude(pk=self.pk).exists():
+ slug = f"{original_slug}-{counter}"
+ counter += 1
+
+ self.slug = slug
+ super().save(*args, **kwargs)
+
+
class Comment(models.Model):
- content = models.CharField(max_length=200)
- time = models.CharField(default=time,max_length=100, blank=True)
- post = models.ForeignKey(Post,on_delete=models.CASCADE)
- user = models.ForeignKey(User,on_delete=models.CASCADE)
+ user = models.CharField(max_length=100)
+ content = models.TextField()
+ post = models.ForeignKey(CKPost, related_name="comments", on_delete=models.CASCADE)
+ parent = models.ForeignKey(
+ 'self', null=True, blank=True, related_name="children", on_delete=models.CASCADE
+ )
+ time = models.DateTimeField(auto_now_add=True)
+
def __str__(self):
- return f"{self.id}.{self.content[:20]}..."
-
-
+ return f"Comment by {self.user} on {self.post.title}"
+
class Contact(models.Model):
name = models.CharField(max_length=600)
email = models.EmailField(max_length=600)
subject = models.CharField(max_length=1000)
- message = models.CharField(max_length=10000, blank=True)
\ No newline at end of file
+ message = models.CharField(max_length=10000, blank=True)
+
+
+class AuthorProfile(models.Model):
+ user = models.OneToOneField(
+ User,
+ on_delete=models.CASCADE,
+ )
+ is_author = models.BooleanField(default=False) # Add this field
+ bio = models.TextField(blank=True, null=True)
+ profile_picture = models.ImageField(upload_to='author_pictures/', blank=True, null=True)
+ website = models.URLField(blank=True, null=True)
+ metier = models.TextField(blank=True, null=True)
+ facebook = models.URLField(validators=[URLValidator()], blank=True, null=True)
+ twitter = models.URLField(validators=[URLValidator()], blank=True, null=True)
+ gmail = models.EmailField(blank=True, null=True)
+
+ def __str__(self):
+ return f"Author Profile: {self.user.username}"
\ No newline at end of file
diff --git a/myapp/permissions.py b/myapp/permissions.py
new file mode 100644
index 00000000..01703a7e
--- /dev/null
+++ b/myapp/permissions.py
@@ -0,0 +1,22 @@
+from rest_framework import permissions
+from .models import AuthorProfile
+
+class IsAuthor(permissions.BasePermission):
+ """
+ Allows access only to authors.
+ """
+
+ def has_permission(self, request, view):
+ # Check if user is authenticated first
+ if not request.user.is_authenticated:
+ return False
+
+ # Check if user is staff (admin)
+ if request.user.is_staff:
+ return True
+
+ try:
+ author_profile = request.user.authorprofile
+ return author_profile.is_author
+ except AuthorProfile.DoesNotExist:
+ return False
\ No newline at end of file
diff --git a/myapp/serializers.py b/myapp/serializers.py
new file mode 100644
index 00000000..0dde43a8
--- /dev/null
+++ b/myapp/serializers.py
@@ -0,0 +1,9 @@
+# serializers.py
+from rest_framework import serializers
+from .models import AuthorProfile
+
+class AuthorProfileSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = AuthorProfile
+ fields = ['bio', 'profile_picture', 'website', 'metier', 'facebook', 'twitter', 'gmail', 'is_author'] # Include fields you want to be editable
+ read_only_fields = ('user',) # User should not be editable through the serializer
\ No newline at end of file
diff --git a/myapp/signals.py b/myapp/signals.py
new file mode 100644
index 00000000..1d6cbbae
--- /dev/null
+++ b/myapp/signals.py
@@ -0,0 +1,14 @@
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+from django.contrib.auth.models import User
+from .models import AuthorProfile
+
+@receiver(post_save, sender=User)
+def create_author_profile(sender, instance, created, **kwargs):
+ if created and instance.is_staff: # Vérifie si l'utilisateur est un administrateur
+ AuthorProfile.objects.get_or_create(user=instance)
+
+@receiver(post_save, sender=User)
+def save_author_profile(sender, instance, **kwargs):
+ if instance.is_staff and hasattr(instance, 'authorprofile'):
+ instance.authorprofile.save()
diff --git a/myapp/templatetags/__init__.py b/myapp/templatetags/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/myapp/templatetags/custom_filters.py b/myapp/templatetags/custom_filters.py
new file mode 100644
index 00000000..f329c343
--- /dev/null
+++ b/myapp/templatetags/custom_filters.py
@@ -0,0 +1,15 @@
+from django import template
+
+register = template.Library()
+
+@register.filter
+def first_words(value, num_words=50):
+ """
+ Returns the first 'num_words' words from the string.
+ """
+ words = value.split() # Divise le texte en mots
+ return ' '.join(words[:num_words]) + ('...' if len(words) > num_words else '')
+
+@register.filter(name='has_author_profile')
+def has_author_profile(user):
+ return hasattr(user, 'authorprofile') and user.authorprofile.is_author
\ No newline at end of file
diff --git a/myapp/urls.py b/myapp/urls.py
index fc7474f9..0f778b87 100644
--- a/myapp/urls.py
+++ b/myapp/urls.py
@@ -1,20 +1,45 @@
from . import views
from django.urls import path
+# from .views import AuthorProfileCreateView
urlpatterns = [
- path("",views.index,name="index"),
+ path("",views.new_index,name="index"),
+ path("old_index",views.index,name="old_index"),
+
+ path("ckeditor" , views.create_post, name="ckeditor-form"),
+ path('posts/', views.post_list, name='post_list'), # This is the URL for listing posts
+ path('edit_post/Python Django Blog Website
+# Installation
+```
+python -m venv venv
-A Blog application in Django contains all the features of a Blog site like login/register into the system, add blog post with title, description and image and edit or delete the blog post.
+# linux
+source venv/bin/activate
+#windows
+venv\Scripts\activate
- ➥ Live Demo
+pip install -r requirements.txt
-
+python manage.py migrate
-## 📃 Description
+python manage.py runserver
+```
+# Usefull
-Creating A Blog In Django has interactive UI design using which users can see what others are posting. It also has an admin panel through which all the blog posts and users can be managed.
+Please always create new branch, and never push on main !!!
-
-
+```
+# new branch
+git checkout -b {branch_name}
-
-
-
-
-
-
+# change branch
+git checkout {branch_name}
+# pull from remote
+git pull origin {branch_name}
-## Features
+# push to remote
+git push origin {branch_name}
-- **Manage Blog** :– In this feature includes the CRUD operation in a blog or content you create like adding, editing and deleting content of the blog
-- **Login System** :- In this feature the admin can login to the system and manage all the feature of the system.
-- **Blog** :- In this method which is the main method of the system.
-- **Media** :- In this method which you can found all the media that you are upload in the system.
-- **Template** :- In this method which is the design of the system that consist of HTML,CSS and JavaScript.
-
-
-
-## 🚀 Setup/Installation Requirements
-
-To view the website,
-* click [Python Django Blog Website](https://github.com/keerti1924/Python-Django-Blog-Website.git)
-or
-* copy the link https://github.com/keerti1924/Python-Django-Blog-Website.git paste it to your browser and load it.
-
-## 🛠 Built With
-
-* HTML
-* CSS
-* JAVASCRIPT
-* PYTHON
-* DJANGO
-* DATABASE
-
-The system is built fully in Django Framework in back-end and HTML, CSS in front-end. It has full-featured user interface with all the functionalities
-
-
-## ⭐️ Show your support
-
-Give a ⭐️ if you like this project!
+# delete branch
+git branch -D {branch_name}
+```
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 60bc2751..0b50daea 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,11 @@
-asgiref
-django
-Pillow
-sqlparse
-tzdata
+asgiref==3.8.1
+Django==4.1.8
+django-ckeditor==6.7.1
+django-js-asset==2.2.0
+pillow==10.0.0
+sqlparse==0.5.1
+typing_extensions==4.12.2
+tzdata==2024.2
+gunicorn==23.0.0
+packaging==24.2
+python-dotenv==1.0.1
diff --git a/static/assets/css/flex-slider.css b/static/assets/css/flex-slider.css
index f2b67ac6..3bad2b32 100644
--- a/static/assets/css/flex-slider.css
+++ b/static/assets/css/flex-slider.css
@@ -1,281 +1,281 @@
-/*
- * jQuery FlexSlider v2.7.1
- * http://www.woothemes.com/flexslider/
- *
- * Copyright 2012 WooThemes
- * Free to use under the GPLv2 and later license.
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Contributing author: Tyler Smith (@mbmufffin)
- *
- */
-/* ====================================================================================================================
- * FONT-FACE
- * ====================================================================================================================*/
-@font-face {
- font-family: 'flexslider-icon';
- src: url('../fonts/flexslider-icon.eot');
- src: url('../fonts/flexslider-icon.eot?#iefix') format('embedded-opentype'), url('../fonts/flexslider-icon.woff') format('woff'), url('../fonts/flexslider-icon.ttf') format('truetype'), url('../fonts/flexslider-icon.svg#flexslider-icon') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-/* ====================================================================================================================
- * RESETS
- * ====================================================================================================================*/
-.flex-container a:hover,
-.flex-slider a:hover {
- outline: none;
-}
-.slides,
-.slides > li,
-.flex-control-nav,
-.flex-direction-nav {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-.flex-pauseplay span {
- text-transform: capitalize;
-}
-/* ====================================================================================================================
- * BASE STYLES
- * ====================================================================================================================*/
-.flexslider {
- margin: 0;
- padding: 0;
-}
-.flexslider .slides > li {
- display: none;
- -webkit-backface-visibility: hidden;
-}
-.flexslider .slides img {
- width: 100%;
- display: block;
-}
-.flexslider .slides:after {
- content: "\0020";
- display: block;
- clear: both;
- visibility: hidden;
- line-height: 0;
- height: 0;
-}
-html[xmlns] .flexslider .slides {
- display: block;
-}
-* html .flexslider .slides {
- height: 1%;
-}
-.no-js .flexslider .slides > li:first-child {
- display: block;
-}
-/* ====================================================================================================================
- * DEFAULT THEME
- * ====================================================================================================================*/
-.flexslider {
- margin: 0;
- background: #fff;
- border: 4px solid #fff;
- position: relative;
- zoom: 1;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -webkit-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
- -o-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
- box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
-}
-.flexslider .slides {
- zoom: 1;
-}
-.flexslider .slides img {
- height: auto;
- -moz-user-select: none;
-}
-.flex-viewport {
- max-height: 2000px;
- -webkit-transition: all 1s ease;
- -moz-transition: all 1s ease;
- -ms-transition: all 1s ease;
- -o-transition: all 1s ease;
- transition: all 1s ease;
-}
-.loading .flex-viewport {
- max-height: 300px;
-}
-@-moz-document url-prefix() {
- .loading .flex-viewport {
- max-height: none;
- }
-}
-.carousel li {
- margin-right: 5px;
-}
-.flex-direction-nav {
- *height: 0;
-}
-.flex-direction-nav a {
- text-decoration: none;
- display: block;
- width: 40px;
- height: 40px;
- line-height: 40px;
- margin: -20px 0 0;
- position: absolute;
- top: 50%;
- z-index: 10;
- overflow: hidden;
- opacity: 0;
- cursor: pointer;
- color: rgba(0, 0, 0, 0.8);
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
- -webkit-transition: all 0.3s ease-in-out;
- -moz-transition: all 0.3s ease-in-out;
- -ms-transition: all 0.3s ease-in-out;
- -o-transition: all 0.3s ease-in-out;
- transition: all 0.3s ease-in-out;
-}
-.flex-direction-nav a:before {
- font-family: "flexslider-icon";
- font-size: 26px;
- display: inline-block;
- content: '\f001';
- color: rgba(0, 0, 0, 0.8);
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
-}
-.flex-direction-nav a.flex-next:before {
- content: '\f002';
-}
-.flex-direction-nav .flex-prev {
- left: -50px;
-}
-.flex-direction-nav .flex-next {
- right: -50px;
- text-align: right;
-}
-.flexslider:hover .flex-direction-nav .flex-prev {
- opacity: 0.7;
- left: 10px;
-}
-.flexslider:hover .flex-direction-nav .flex-prev:hover {
- opacity: 1;
-}
-.flexslider:hover .flex-direction-nav .flex-next {
- opacity: 0.7;
- right: 10px;
-}
-.flexslider:hover .flex-direction-nav .flex-next:hover {
- opacity: 1;
-}
-.flex-direction-nav .flex-disabled {
- opacity: 0!important;
- filter: alpha(opacity=0);
- cursor: default;
- z-index: -1;
-}
-.flex-pauseplay a {
- display: block;
- width: 20px;
- height: 20px;
- position: absolute;
- bottom: 5px;
- left: 10px;
- opacity: 0.8;
- z-index: 10;
- overflow: hidden;
- cursor: pointer;
- color: #000;
-}
-.flex-pauseplay a:before {
- font-family: "flexslider-icon";
- font-size: 20px;
- display: inline-block;
- content: '\f004';
-}
-.flex-pauseplay a:hover {
- opacity: 1;
-}
-.flex-pauseplay a.flex-play:before {
- content: '\f003';
-}
-.flex-control-nav {
- width: 100%;
- position: absolute;
- bottom: -40px;
- text-align: center;
-}
-.flex-control-nav li {
- margin: 0 6px;
- display: inline-block;
- zoom: 1;
- *display: inline;
-}
-.flex-control-paging li a {
- width: 11px;
- height: 11px;
- display: block;
- background: #666;
- background: rgba(0, 0, 0, 0.5);
- cursor: pointer;
- text-indent: -9999px;
- -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
- -o-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
- box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
- -webkit-border-radius: 20px;
- -moz-border-radius: 20px;
- border-radius: 20px;
-}
-.flex-control-paging li a:hover {
- background: #333;
- background: rgba(0, 0, 0, 0.7);
-}
-.flex-control-paging li a.flex-active {
- background: #000;
- background: rgba(0, 0, 0, 0.9);
- cursor: default;
-}
-.flex-control-thumbs {
- margin: 5px 0 0;
- position: static;
- overflow: hidden;
-}
-.flex-control-thumbs li {
- width: 25%;
- float: left;
- margin: 0;
-}
-.flex-control-thumbs img {
- width: 100%;
- height: auto;
- display: block;
- opacity: .7;
- cursor: pointer;
- -moz-user-select: none;
- -webkit-transition: all 1s ease;
- -moz-transition: all 1s ease;
- -ms-transition: all 1s ease;
- -o-transition: all 1s ease;
- transition: all 1s ease;
-}
-.flex-control-thumbs img:hover {
- opacity: 1;
-}
-.flex-control-thumbs .flex-active {
- opacity: 1;
- cursor: default;
-}
-/* ====================================================================================================================
- * RESPONSIVE
- * ====================================================================================================================*/
-@media screen and (max-width: 860px) {
- .flex-direction-nav .flex-prev {
- opacity: 1;
- left: 10px;
- }
- .flex-direction-nav .flex-next {
- opacity: 1;
- right: 10px;
- }
-}
+/*
+ * jQuery FlexSlider v2.7.1
+ * http://www.woothemes.com/flexslider/
+ *
+ * Copyright 2012 WooThemes
+ * Free to use under the GPLv2 and later license.
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Contributing author: Tyler Smith (@mbmufffin)
+ *
+ */
+/* ====================================================================================================================
+ * FONT-FACE
+ * ====================================================================================================================*/
+@font-face {
+ font-family: 'flexslider-icon';
+ src: url('../fonts/flexslider-icon.eot');
+ src: url('../fonts/flexslider-icon.eot?#iefix') format('embedded-opentype'), url('../fonts/flexslider-icon.woff') format('woff'), url('../fonts/flexslider-icon.ttf') format('truetype'), url('../fonts/flexslider-icon.svg#flexslider-icon') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+/* ====================================================================================================================
+ * RESETS
+ * ====================================================================================================================*/
+.flex-container a:hover,
+.flex-slider a:hover {
+ outline: none;
+}
+.slides,
+.slides > li,
+.flex-control-nav,
+.flex-direction-nav {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+.flex-pauseplay span {
+ text-transform: capitalize;
+}
+/* ====================================================================================================================
+ * BASE STYLES
+ * ====================================================================================================================*/
+.flexslider {
+ margin: 0;
+ padding: 0;
+}
+.flexslider .slides > li {
+ display: none;
+ -webkit-backface-visibility: hidden;
+}
+.flexslider .slides img {
+ width: 100%;
+ display: block;
+}
+.flexslider .slides:after {
+ content: "\0020";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
+}
+html[xmlns] .flexslider .slides {
+ display: block;
+}
+* html .flexslider .slides {
+ height: 1%;
+}
+.no-js .flexslider .slides > li:first-child {
+ display: block;
+}
+/* ====================================================================================================================
+ * DEFAULT THEME
+ * ====================================================================================================================*/
+.flexslider {
+ margin: 0;
+ background: #fff;
+ border: 4px solid #fff;
+ position: relative;
+ zoom: 1;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
+ -o-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
+ box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
+}
+.flexslider .slides {
+ zoom: 1;
+}
+.flexslider .slides img {
+ height: auto;
+ -moz-user-select: none;
+}
+.flex-viewport {
+ max-height: 2000px;
+ -webkit-transition: all 1s ease;
+ -moz-transition: all 1s ease;
+ -ms-transition: all 1s ease;
+ -o-transition: all 1s ease;
+ transition: all 1s ease;
+}
+.loading .flex-viewport {
+ max-height: 300px;
+}
+@-moz-document url-prefix() {
+ .loading .flex-viewport {
+ max-height: none;
+ }
+}
+.carousel li {
+ margin-right: 5px;
+}
+.flex-direction-nav {
+ *height: 0;
+}
+.flex-direction-nav a {
+ text-decoration: none;
+ display: block;
+ width: 40px;
+ height: 40px;
+ line-height: 40px;
+ margin: -20px 0 0;
+ position: absolute;
+ top: 50%;
+ z-index: 10;
+ overflow: hidden;
+ opacity: 0;
+ cursor: pointer;
+ color: rgba(0, 0, 0, 0.8);
+ text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
+ -webkit-transition: all 0.3s ease-in-out;
+ -moz-transition: all 0.3s ease-in-out;
+ -ms-transition: all 0.3s ease-in-out;
+ -o-transition: all 0.3s ease-in-out;
+ transition: all 0.3s ease-in-out;
+}
+.flex-direction-nav a:before {
+ font-family: "flexslider-icon";
+ font-size: 26px;
+ display: inline-block;
+ content: '\f001';
+ color: rgba(0, 0, 0, 0.8);
+ text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
+}
+.flex-direction-nav a.flex-next:before {
+ content: '\f002';
+}
+.flex-direction-nav .flex-prev {
+ left: -50px;
+}
+.flex-direction-nav .flex-next {
+ right: -50px;
+ text-align: right;
+}
+.flexslider:hover .flex-direction-nav .flex-prev {
+ opacity: 0.7;
+ left: 10px;
+}
+.flexslider:hover .flex-direction-nav .flex-prev:hover {
+ opacity: 1;
+}
+.flexslider:hover .flex-direction-nav .flex-next {
+ opacity: 0.7;
+ right: 10px;
+}
+.flexslider:hover .flex-direction-nav .flex-next:hover {
+ opacity: 1;
+}
+.flex-direction-nav .flex-disabled {
+ opacity: 0!important;
+ filter: alpha(opacity=0);
+ cursor: default;
+ z-index: -1;
+}
+.flex-pauseplay a {
+ display: block;
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ bottom: 5px;
+ left: 10px;
+ opacity: 0.8;
+ z-index: 10;
+ overflow: hidden;
+ cursor: pointer;
+ color: #000;
+}
+.flex-pauseplay a:before {
+ font-family: "flexslider-icon";
+ font-size: 20px;
+ display: inline-block;
+ content: '\f004';
+}
+.flex-pauseplay a:hover {
+ opacity: 1;
+}
+.flex-pauseplay a.flex-play:before {
+ content: '\f003';
+}
+.flex-control-nav {
+ width: 100%;
+ position: absolute;
+ bottom: -40px;
+ text-align: center;
+}
+.flex-control-nav li {
+ margin: 0 6px;
+ display: inline-block;
+ zoom: 1;
+ *display: inline;
+}
+.flex-control-paging li a {
+ width: 11px;
+ height: 11px;
+ display: block;
+ background: #666;
+ background: rgba(0, 0, 0, 0.5);
+ cursor: pointer;
+ text-indent: -9999px;
+ -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
+ -o-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
+ -webkit-border-radius: 20px;
+ -moz-border-radius: 20px;
+ border-radius: 20px;
+}
+.flex-control-paging li a:hover {
+ background: #333;
+ background: rgba(0, 0, 0, 0.7);
+}
+.flex-control-paging li a.flex-active {
+ background: #000;
+ background: rgba(0, 0, 0, 0.9);
+ cursor: default;
+}
+.flex-control-thumbs {
+ margin: 5px 0 0;
+ position: static;
+ overflow: hidden;
+}
+.flex-control-thumbs li {
+ width: 25%;
+ float: left;
+ margin: 0;
+}
+.flex-control-thumbs img {
+ width: 100%;
+ height: auto;
+ display: block;
+ opacity: .7;
+ cursor: pointer;
+ -moz-user-select: none;
+ -webkit-transition: all 1s ease;
+ -moz-transition: all 1s ease;
+ -ms-transition: all 1s ease;
+ -o-transition: all 1s ease;
+ transition: all 1s ease;
+}
+.flex-control-thumbs img:hover {
+ opacity: 1;
+}
+.flex-control-thumbs .flex-active {
+ opacity: 1;
+ cursor: default;
+}
+/* ====================================================================================================================
+ * RESPONSIVE
+ * ====================================================================================================================*/
+@media screen and (max-width: 860px) {
+ .flex-direction-nav .flex-prev {
+ opacity: 1;
+ left: 10px;
+ }
+ .flex-direction-nav .flex-next {
+ opacity: 1;
+ right: 10px;
+ }
+}
diff --git a/static/assets/css/fontawesome.css b/static/assets/css/fontawesome.css
index 1ab861b5..24fcc04c 100644
--- a/static/assets/css/fontawesome.css
+++ b/static/assets/css/fontawesome.css
@@ -1,4 +1,4 @@
-/*!
- * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+/*!
+ * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.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;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.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:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.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}.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-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-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-genderless:before,.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-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-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"}
\ No newline at end of file
diff --git a/static/assets/css/owl.css b/static/assets/css/owl.css
index e92c0655..b78c8418 100644
--- a/static/assets/css/owl.css
+++ b/static/assets/css/owl.css
@@ -1,186 +1,186 @@
-/**
- * Owl Carousel v2.3.4
- * Copyright 2013-2018 David Deutsch
- * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
- */
-/*
- * Owl Carousel - Core
- */
-.owl-carousel {
- display: none;
- width: 100%;
- -webkit-tap-highlight-color: transparent;
- /* position relative and z-index fix webkit rendering fonts issue */
- position: relative;
- z-index: 1; }
- .owl-carousel .owl-stage {
- position: relative;
- -ms-touch-action: pan-Y;
- touch-action: manipulation;
- -moz-backface-visibility: hidden;
- /* fix firefox animation glitch */ }
- .owl-carousel .owl-stage:after {
- content: ".";
- display: block;
- clear: both;
- visibility: hidden;
- line-height: 0;
- height: 0; }
- .owl-carousel .owl-stage-outer {
- position: relative;
- overflow: hidden;
- /* fix for flashing background */
- -webkit-transform: translate3d(0px, 0px, 0px); }
- .owl-carousel .owl-wrapper,
- .owl-carousel .owl-item {
- -webkit-backface-visibility: hidden;
- -moz-backface-visibility: hidden;
- -ms-backface-visibility: hidden;
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- -ms-transform: translate3d(0, 0, 0); }
- .owl-carousel .owl-item {
- position: relative;
- min-height: 1px;
- float: left;
- -webkit-backface-visibility: hidden;
- -webkit-tap-highlight-color: transparent;
- -webkit-touch-callout: none; }
- .owl-carousel .owl-item img {
- display: block;
- width: 100%; }
- .owl-carousel .owl-nav.disabled,
- .owl-carousel .owl-dots.disabled {
- display: none; }
- .owl-carousel .owl-nav .owl-prev,
- .owl-carousel .owl-nav .owl-next,
- .owl-carousel .owl-dot {
- cursor: pointer;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none; }
- .owl-carousel .owl-nav button.owl-prev,
- .owl-carousel .owl-nav button.owl-next,
- .owl-carousel button.owl-dot {
- background: none;
- color: inherit;
- border: none;
- padding: 0 !important;
- font: inherit; }
- .owl-carousel.owl-loaded {
- display: block; }
- .owl-carousel.owl-loading {
- opacity: 0;
- display: block; }
- .owl-carousel.owl-hidden {
- opacity: 0; }
- .owl-carousel.owl-refresh .owl-item {
- visibility: hidden; }
- .owl-carousel.owl-drag .owl-item {
- -ms-touch-action: pan-y;
- touch-action: pan-y;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none; }
- .owl-carousel.owl-grab {
- cursor: move;
- cursor: grab; }
- .owl-carousel.owl-rtl {
- direction: rtl; }
- .owl-carousel.owl-rtl .owl-item {
- float: right; }
-
-/* No Js */
-.no-js .owl-carousel {
- display: block; }
-
-/*
- * Owl Carousel - Animate Plugin
- */
-.owl-carousel .animated {
- animation-duration: 1000ms;
- animation-fill-mode: both; }
-
-.owl-carousel .owl-animated-in {
- z-index: 0; }
-
-.owl-carousel .owl-animated-out {
- z-index: 1; }
-
-.owl-carousel .fadeOut {
- animation-name: fadeOut; }
-
-@keyframes fadeOut {
- 0% {
- opacity: 1; }
- 100% {
- opacity: 0; } }
-
-/*
- * Owl Carousel - Auto Height Plugin
- */
-.owl-height {
- transition: height 500ms ease-in-out; }
-
-/*
- * Owl Carousel - Lazy Load Plugin
- */
-.owl-carousel .owl-item {
- /**
- This is introduced due to a bug in IE11 where lazy loading combined with autoheight plugin causes a wrong
- calculation of the height of the owl-item that breaks page layouts
- */ }
- .owl-carousel .owl-item .owl-lazy {
- opacity: 0;
- transition: opacity 400ms ease; }
- .owl-carousel .owl-item .owl-lazy[src^=""], .owl-carousel .owl-item .owl-lazy:not([src]) {
- max-height: 0; }
- .owl-carousel .owl-item img.owl-lazy {
- transform-style: preserve-3d; }
-
-/*
- * Owl Carousel - Video Plugin
- */
-.owl-carousel .owl-video-wrapper {
- position: relative;
- height: 100%;
- background: #000; }
-
-.owl-carousel .owl-video-play-icon {
- position: absolute;
- height: 80px;
- width: 80px;
- left: 50%;
- top: 50%;
- margin-left: -40px;
- margin-top: -40px;
- background: url("owl.video.play.png") no-repeat;
- cursor: pointer;
- z-index: 1;
- -webkit-backface-visibility: hidden;
- transition: transform 100ms ease; }
-
-.owl-carousel .owl-video-play-icon:hover {
- -ms-transform: scale(1.3, 1.3);
- transform: scale(1.3, 1.3); }
-
-.owl-carousel .owl-video-playing .owl-video-tn,
-.owl-carousel .owl-video-playing .owl-video-play-icon {
- display: none; }
-
-.owl-carousel .owl-video-tn {
- opacity: 0;
- height: 100%;
- background-position: center center;
- background-repeat: no-repeat;
- background-size: contain;
- transition: opacity 400ms ease; }
-
-.owl-carousel .owl-video-frame {
- position: relative;
- z-index: 1;
- height: 100%;
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/*
+ * Owl Carousel - Core
+ */
+.owl-carousel {
+ display: none;
+ width: 100%;
+ -webkit-tap-highlight-color: transparent;
+ /* position relative and z-index fix webkit rendering fonts issue */
+ position: relative;
+ z-index: 1; }
+ .owl-carousel .owl-stage {
+ position: relative;
+ -ms-touch-action: pan-Y;
+ touch-action: manipulation;
+ -moz-backface-visibility: hidden;
+ /* fix firefox animation glitch */ }
+ .owl-carousel .owl-stage:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0; }
+ .owl-carousel .owl-stage-outer {
+ position: relative;
+ overflow: hidden;
+ /* fix for flashing background */
+ -webkit-transform: translate3d(0px, 0px, 0px); }
+ .owl-carousel .owl-wrapper,
+ .owl-carousel .owl-item {
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ -webkit-transform: translate3d(0, 0, 0);
+ -moz-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0); }
+ .owl-carousel .owl-item {
+ position: relative;
+ min-height: 1px;
+ float: left;
+ -webkit-backface-visibility: hidden;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none; }
+ .owl-carousel .owl-item img {
+ display: block;
+ width: 100%; }
+ .owl-carousel .owl-nav.disabled,
+ .owl-carousel .owl-dots.disabled {
+ display: none; }
+ .owl-carousel .owl-nav .owl-prev,
+ .owl-carousel .owl-nav .owl-next,
+ .owl-carousel .owl-dot {
+ cursor: pointer;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel .owl-nav button.owl-prev,
+ .owl-carousel .owl-nav button.owl-next,
+ .owl-carousel button.owl-dot {
+ background: none;
+ color: inherit;
+ border: none;
+ padding: 0 !important;
+ font: inherit; }
+ .owl-carousel.owl-loaded {
+ display: block; }
+ .owl-carousel.owl-loading {
+ opacity: 0;
+ display: block; }
+ .owl-carousel.owl-hidden {
+ opacity: 0; }
+ .owl-carousel.owl-refresh .owl-item {
+ visibility: hidden; }
+ .owl-carousel.owl-drag .owl-item {
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel.owl-grab {
+ cursor: move;
+ cursor: grab; }
+ .owl-carousel.owl-rtl {
+ direction: rtl; }
+ .owl-carousel.owl-rtl .owl-item {
+ float: right; }
+
+/* No Js */
+.no-js .owl-carousel {
+ display: block; }
+
+/*
+ * Owl Carousel - Animate Plugin
+ */
+.owl-carousel .animated {
+ animation-duration: 1000ms;
+ animation-fill-mode: both; }
+
+.owl-carousel .owl-animated-in {
+ z-index: 0; }
+
+.owl-carousel .owl-animated-out {
+ z-index: 1; }
+
+.owl-carousel .fadeOut {
+ animation-name: fadeOut; }
+
+@keyframes fadeOut {
+ 0% {
+ opacity: 1; }
+ 100% {
+ opacity: 0; } }
+
+/*
+ * Owl Carousel - Auto Height Plugin
+ */
+.owl-height {
+ transition: height 500ms ease-in-out; }
+
+/*
+ * Owl Carousel - Lazy Load Plugin
+ */
+.owl-carousel .owl-item {
+ /**
+ This is introduced due to a bug in IE11 where lazy loading combined with autoheight plugin causes a wrong
+ calculation of the height of the owl-item that breaks page layouts
+ */ }
+ .owl-carousel .owl-item .owl-lazy {
+ opacity: 0;
+ transition: opacity 400ms ease; }
+ .owl-carousel .owl-item .owl-lazy[src^=""], .owl-carousel .owl-item .owl-lazy:not([src]) {
+ max-height: 0; }
+ .owl-carousel .owl-item img.owl-lazy {
+ transform-style: preserve-3d; }
+
+/*
+ * Owl Carousel - Video Plugin
+ */
+.owl-carousel .owl-video-wrapper {
+ position: relative;
+ height: 100%;
+ background: #000; }
+
+.owl-carousel .owl-video-play-icon {
+ position: absolute;
+ height: 80px;
+ width: 80px;
+ left: 50%;
+ top: 50%;
+ margin-left: -40px;
+ margin-top: -40px;
+ background: url("owl.video.play.png") no-repeat;
+ cursor: pointer;
+ z-index: 1;
+ -webkit-backface-visibility: hidden;
+ transition: transform 100ms ease; }
+
+.owl-carousel .owl-video-play-icon:hover {
+ -ms-transform: scale(1.3, 1.3);
+ transform: scale(1.3, 1.3); }
+
+.owl-carousel .owl-video-playing .owl-video-tn,
+.owl-carousel .owl-video-playing .owl-video-play-icon {
+ display: none; }
+
+.owl-carousel .owl-video-tn {
+ opacity: 0;
+ height: 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ transition: opacity 400ms ease; }
+
+.owl-carousel .owl-video-frame {
+ position: relative;
+ z-index: 1;
+ height: 100%;
width: 100%; }
\ No newline at end of file
diff --git a/static/assets/css/styles.css b/static/assets/css/styles.css
index 0b587c5b..00c8bf02 100644
--- a/static/assets/css/styles.css
+++ b/static/assets/css/styles.css
@@ -1,9 +1,10 @@
-.carousel img {
- width: 100%;
- height: 700px;
-}
-
-.blog-posts .blog-post img,
-.blog-post img {
- height: 300px;
-}
\ No newline at end of file
+.carousel img {
+ width: 100%;
+ height: 700px;
+}
+
+.blog-posts .blog-post img,
+.blog-post img {
+ height: 300px;
+}
+
diff --git a/static/assets/css/templatemo-stand-blog.css b/static/assets/css/templatemo-stand-blog.css
index c0a8ad93..e24bfbba 100644
--- a/static/assets/css/templatemo-stand-blog.css
+++ b/static/assets/css/templatemo-stand-blog.css
@@ -1,1093 +1,1096 @@
-/*
-
-TemplateMo 551 Stand Blog
-
-https://templatemo.com/tm-551-stand-blog
-
-*/
-
-body {
- font-family: 'Roboto', sans-serif;
- overflow-x: hidden;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-p {
- margin-bottom: 0px;
- font-size: 15px;
- font-weight: 400;
- color: #7a7a7a;
- line-height: 30px;
-}
-a {
- text-decoration: none!important;
-}
-ul {
- padding: 0;
- margin: 0;
- list-style: none;
-}
-
-h1,h2,h3,h4,h5,h6 {
- margin: 0px;
-}
-
-.main-button a {
- display: inline-block;
- background-color: #f48840;
- color: #fff;
- font-size: 13px;
- font-weight: 500;
- padding: 12px 20px;
- text-transform: uppercase;
- transition: all .3s;
-}
-
-.main-button a:hover {
- background-color: #fb9857;
-}
-
-.heading-page {
- padding-top: 110px;
-}
-
-.page-heading {
- margin: 0px 10px;
- padding: 120px 0px;
- text-align: left;
- background-position: center center;
- background-repeat: no-repeat;
- background-size: cover;
- background-image: url(../images/heading-bg.jpg);
-}
-
-.page-heading .text-content h4 {
- color: #f48840;
- font-size: 18px;
- text-transform: uppercase;
- font-weight: 900;
- letter-spacing: 0.5px;
- margin-bottom: 15px;
-}
-
-.page-heading .text-content h2 {
- color: #fff;
- font-size: 36px;
- font-weight: 700;
- text-transform: uppercase;
- letter-spacing: 0.5px;
-}
-
-#preloader {
- overflow: hidden;
- background: #f48840;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- position: fixed;
- z-index: 9999999;
- color: #fff;
-}
-
-#preloader .jumper {
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
- display: block;
- position: absolute;
- margin: auto;
- width: 50px;
- height: 50px;
-}
-
-#preloader .jumper > div {
- background-color: #fff;
- width: 10px;
- height: 10px;
- border-radius: 100%;
- -webkit-animation-fill-mode: both;
- animation-fill-mode: both;
- position: absolute;
- opacity: 0;
- width: 50px;
- height: 50px;
- -webkit-animation: jumper 1s 0s linear infinite;
- animation: jumper 1s 0s linear infinite;
-}
-
-#preloader .jumper > div:nth-child(2) {
- -webkit-animation-delay: 0.33333s;
- animation-delay: 0.33333s;
-}
-
-#preloader .jumper > div:nth-child(3) {
- -webkit-animation-delay: 0.66666s;
- animation-delay: 0.66666s;
-}
-
-@-webkit-keyframes jumper {
- 0% {
- opacity: 0;
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 5% {
- opacity: 1;
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
-}
-
-@keyframes jumper {
- 0% {
- opacity: 0;
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 5% {
- opacity: 1;
- }
- 100% {
- opacity: 0;
- }
-}
-
-
-/* Header Style */
-header {
- position: absolute;
- z-index: 99999;
- width: 100%;
- height: 100px;
- background-color: #f7f7f7;
- -webkit-transition: all 0.3s ease-in-out 0s;
- -moz-transition: all 0.3s ease-in-out 0s;
- -o-transition: all 0.3s ease-in-out 0s;
- transition: all 0.3s ease-in-out 0s;
-}
-header .navbar {
- padding: 25px 0px;
-}
-.background-header .navbar {
- padding: 17px 0px;
-}
-.background-header {
- top: 0;
- height: 80px;
- position: fixed;
- box-shadow: 0px 1px 10px rgba(0,0,0,0.1);
-}
-.background-header .navbar-brand h2 {
- color: #121212!important;
-}
-.background-header .navbar-nav a.nav-link {
- color: #1e1e1e!important;
-}
-.background-header .navbar-nav .nav-link:hover,
-.background-header .navbar-nav .active>.nav-link,
-.background-header .navbar-nav .nav-link.active,
-.background-header .navbar-nav .nav-link.show,
-.background-header .navbar-nav .show>.nav-link {
- color: #f48840!important;
-}
-.navbar .navbar-brand {
- float: left;
- margin-top: -12px;
- outline: none;
-}
-.navbar .navbar-brand h2 {
- color: #1e1e1e;
- text-transform: uppercase;
- font-size: 24px;
- font-weight: 900;
- -webkit-transition: all .3s ease 0s;
- -moz-transition: all .3s ease 0s;
- -o-transition: all .3s ease 0s;
- transition: all .3s ease 0s;
-}
-.navbar .navbar-brand h2 em {
- font-size: 44px;
- font-style: normal;
- color: #f48840;
-}
-#navbarResponsive {
- z-index: 999;
-}
-.navbar-collapse {
- text-align: center;
-}
-.navbar .navbar-nav .nav-item {
- margin: 0px 15px;
-}
-.navbar .navbar-nav a.nav-link {
- text-transform: capitalize;
- font-size: 15px;
- font-weight: 800;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- color: #1e1e1e;
- transition: all 0.3s;
-}
-.navbar .navbar-nav .nav-link:hover,
-.navbar .navbar-nav .active>.nav-link,
-.navbar .navbar-nav .nav-link.active,
-.navbar .navbar-nav .nav-link.show,
-.navbar .navbar-nav .show>.nav-link {
- color: #f48840;
-}
-.navbar .navbar-toggler-icon {
- background-image: none;
-}
-.navbar .navbar-toggler {
- border-color: #fff;
- background-color: #f48840;
- height: 46px;
- outline: none;
- border-radius: 0px;
- position: absolute;
- right: 30px;
- top: 25px;
-}
-.navbar .navbar-toggler-icon:after {
- content: '\f0c9';
- color: #fff;
- font-size: 18px;
- line-height: 30px;
- font-family: 'FontAwesome';
-}
-
-
-
-/* Banner Style */
-.main-banner .container-fluid {
- padding: 0px 10px;
- margin-bottom: -24px;
-}
-.owl-banner {
- padding-top: 110px;
-}
-
-.owl-banner .item {
- position: relative;
-}
-
-.owl-banner .item .item-content {
- position: absolute;
- bottom: 40px;
- left: 40px;
-}
-
-.owl-banner .item .item-content .meta-category span {
- color: #f48840;
- font-size: 18px;
- text-transform: uppercase;
- font-weight: 900;
- letter-spacing: 0.25px;
-}
-
-.owl-banner .item .item-content h4 {
- font-size: 24px;
- font-weight: 900;
- color: #fff;
- letter-spacing: 0.5px;
- text-transform: capitalize;
- margin: 10px 0px 12px 0px;
-}
-
-.owl-banner .item .item-content ul li {
- display: inline-block;
- margin-right: 8px;
-}
-
-.owl-banner .item .item-content ul li:after {
- content: '|';
- color: #fff;
- margin-left: 8px;
-}
-
-.owl-banner .item .item-content ul li:last-child::after {
- display: none;
-}
-
-.owl-banner .item .item-content ul li a {
- font-size: 14px;
- color: #fff;
- font-weight: 500;
- transition: all .3s;
-}
-
-.owl-banner .item .item-content ul li a:hover {
- color: #f48840;
-}
-
-.owl-banner .owl-nav {
- position: absolute;
- top: 50%;
- width: 100%;
-}
-
-.owl-banner .owl-nav .owl-prev {
- position: absolute;
- left: 40px;
-}
-
-.owl-banner .owl-nav .owl-next {
- position: absolute;
- right: 40px;
-}
-
-.owl-banner .owl-nav button {
- outline: none;
-}
-
-.owl-banner .owl-nav button span {
- color: #fff;
- font-size: 36px;
- width: 60px;
- height: 60px;
- display: inline-block;
- text-align: center;
- line-height: 60px;
- background-color: rgba(250,250,250,0.3);
-}
-
-
-/* Call To Action */
-
-.call-to-action {
- margin-top: 100px;
-}
-
-.call-to-action .main-content {
- padding: 40px;
- background-image: url(../images/cta-bg.jpg);
- background-position: center center;
- background-repeat: no-repeat;
- background-size: cover;
-}
-
-.call-to-action .main-content span {
- color: #f48840;
- font-size: 18px;
- font-weight: 900;
- letter-spacing: 0.5px;
-}
-
-.call-to-action .main-content h4 {
- margin-bottom: 0px;
- margin-top: 12px;
- color: #fff;
- font-size: 26px;
- font-weight: 900;
- letter-spacing: 0.25px;
-}
-
-.call-to-action .main-content .main-button {
- text-align: right;
- margin-top: 12px;
-}
-
-
-
-/* Blog Posts */
-
-.blog-posts {
- margin-top: 100px;
-}
-
-.blog-posts .blog-post {
- margin-bottom: 30px;
-}
-
-.blog-posts .blog-thumb img {
- width: 100%;
- overflow: hidden;
-}
-
-.blog-posts .down-content {
- padding: 40px;
- border-right: 1px solid #eee;
- border-left: 1px solid #eee;
- border-bottom: 1px solid #eee;
-}
-
-.blog-posts .down-content span {
- font-size: 18px;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- font-weight: 900;
- color: #f48840;
-}
-
-.blog-posts .down-content h4 {
- font-size: 24px;
- text-transform: capitalize;
- letter-spacing: 0.5px;
- font-weight: 900;
- color: #20232e;
- margin: 10px 0px 12px 0px;
-}
-
-.blog-posts .down-content ul.post-info li {
- display: inline-block;
- margin-right: 8px;
-}
-
-.blog-posts .down-content ul.post-info li:after {
- content: '|';
- color: #aaa;
- margin-left: 8px;
-}
-
-.blog-posts .down-content h4 {
- font-size: 20px;
- letter-spacing: 0.25px;
-}
-
-.grid-system .down-content ul.post-info li {
- margin-right: 3px;
-}
-
-.grid-system .down-content ul.post-info li:after {
- margin-left: 5px;
-}
-
-.blog-posts .down-content ul.post-info li:last-child::after {
- display: none;
-}
-
-.blog-posts .down-content ul.post-info li a {
- font-size: 14px;
- color: #aaa;
- font-weight: 400;
- transition: all .3s;
-}
-
-.blog-posts .down-content ul.post-info li a:hover {
- color: #f48840;
-}
-
-.blog-posts .down-content p {
- padding: 25px 0px;
- margin: 25px 0px;
- border-top: 1px solid #eee;
- border-bottom: 1px solid #eee;
-}
-
-.blog-posts .down-content ul.post-share {
- text-align: right;
-}
-
-.blog-posts .down-content ul.post-tags li,
-.blog-posts .down-content ul.post-share li {
- display: inline-block;
-}
-
-.blog-posts .down-content ul.post-tags li:first-child i,
-.blog-posts .down-content ul.post-share li:first-child i {
- color: #f48840;
- margin-right: 5px;
-}
-
-.blog-posts .down-content ul.post-tags li,
-.blog-posts .down-content ul.post-share li {
- color: #aaa;
-}
-
-.blog-posts .down-content ul.post-tags li a,
-.blog-posts .down-content ul.post-share li a {
- font-size: 14px;
- color: #aaa;
- font-weight: 400;
- transition: all .3s;
-}
-
-.blog-posts .down-content ul.post-tags li a:hover,
-.blog-posts .down-content ul.post-share li a:hover {
- color: #f48840;
-}
-
-.blog-posts .main-button a {
- height: 60px;
- line-height: 60px;
- padding: 0px;
- width: 100%;
- text-align: center;
-}
-
-ul.page-numbers {
- text-align: center;
-}
-
-ul.page-numbers li {
- display: inline-block;
- margin: 0px 5px;
-}
-
-ul.page-numbers li a {
- width: 50px;
- height: 50px;
- display: inline-block;
- text-align: center;
- line-height: 50px;
- font-size: 15px;
- color: #7a7a7a;
- border: 1px solid #eee;
- font-weight: 500;
- transition: all 0.3s;
-}
-
-ul.page-numbers li.active a {
- background-color: #f48840;
- border-color: #f48840;
- color: #fff;
-}
-
-ul.page-numbers li a:hover {
- color: #f48840;
-}
-
-.blog-posts .sidebar-heading h2 {
- font-size: 18px;
- text-transform: uppercase;
- font-weight: 900;
- letter-spacing: 0.5px;
- color: #20232e;
- border-bottom: 1px solid #eee;
- padding-bottom: 15px;
- margin-bottom: 25px;
-}
-
-.blog-posts .comments {
- margin-top: 30px;
-}
-
-.blog-posts .comments ul li {
- display: inline-block;
- margin-bottom: 20px;
- padding-bottom: 20px;
- border-bottom: 1px solid #eee;
-}
-
-.blog-posts .comments ul li.replied {
- padding-left: 130px;
-}
-
-.blog-posts .comments ul li:last-child {
- margin-bottom: 0px;
- padding-bottom: 0px;
- border-bottom: none;
-}
-
-.blog-posts .comments ul li .author-thumb {
- display: inline;
- float: left;
-}
-
-.blog-posts .comments ul li .author-thumb img {
- max-width: 100px;
- display: inline;
-}
-
-.blog-posts .comments ul li .right-content {
- margin-left: 130px;
-}
-
-.blog-posts .comments ul li .right-content h4 {
- color: #20232e;
- font-size: 19px;
- font-weight: 900;
- letter-spacing: 0.5px;
-}
-
-.blog-posts .comments ul li .right-content h4 span {
- font-size: 14px;
- color: #aaa;
- font-weight: 400;
- letter-spacing: 0.25px;
- margin-left: 20px;
-}
-
-.blog-posts .submit-comment {
- margin-top: 60px;
-}
-
-.blog-posts .submit-comment input {
- width: 100%;
- height: 46px;
- border: 1px solid #eee;
- font-size: 13px;
- text-transform: uppercase;
- font-weight: 500;
- color: #7a7a7a;
- outline: none;
- padding: 0px 15px;
- margin-bottom: 30px;
-}
-
-.blog-posts .submit-comment textarea {
- width: 100%;
- height: 46px;
- border: 1px solid #eee;
- font-size: 13px;
- text-transform: uppercase;
- font-weight: 500;
- color: #7a7a7a;
- outline: none;
- padding: 10px 15px;
- margin-bottom: 30px;
- height: 180px;
- max-height: 220px;
- max-width: 100%;
- min-width: 160px;
-}
-
-.blog-posts .submit-comment input::placeholder,
-.blog-posts .submit-comment textarea::placeholder {
- color: #aaa;
-}
-
-.blog-posts .submit-comment button {
- display: inline-block;
- background-color: #f48840;
- color: #fff;
- font-size: 13px;
- font-weight: 500;
- padding: 12px 20px;
- text-transform: uppercase;
- transition: all .3s;
- border: none;
- outline: none;
-}
-
-.blog-posts .submit-comment button:hover {
- background-color: #fb9857;
-}
-
-/* Sidebar */
-
-.sidebar {
- margin-left: 30px;
-}
-
-.sidebar .sidebar-item {
- margin-top: 50px;
-}
-
-.sidebar .search {
- margin-top: 0px;
-}
-
-.sidebar .sidebar-heading h2 {
- font-size: 18px;
- text-transform: uppercase;
- font-weight: 900;
- letter-spacing: 0.5px;
- color: #20232e;
- border-bottom: 1px solid #eee;
- padding-bottom: 15px;
- margin-bottom: 25px;
-}
-
-.sidebar .search input {
- width: 100%;
- height: 50px;
- border: 1px solid #eee;
- font-size: 13px;
- text-transform: uppercase;
- font-weight: 500;
- color: #7a7a7a;
- outline: none;
- padding: 0px 15px;
-}
-
-.sidebar .search input::placeholder {
- color: #aaa;
-}
-
-.sidebar .recent-posts ul li {
- margin-bottom: 15px;
- padding-bottom: 15px;
- border-bottom: 1px solid #eee;
-}
-
-.sidebar .recent-posts ul li:last-child {
- margin-bottom: 0px;
- padding-bottom: 0px;
- border-bottom: none;
-}
-
-.sidebar .recent-posts ul li h5 {
- font-size: 19px;
- font-weight: 900;
- color: #20232e;
- line-height: 30px;
- transition: all 0.3s;
-}
-
-.sidebar .recent-posts ul li h5:hover {
- color: #f48840;
-}
-
-.sidebar .recent-posts ul li span {
- display: block;
- font-size: 14px;
- color: #aaa;
- margin-top: 8px;
-}
-
-.sidebar .categories ul li {
- margin-bottom: 15px;
-}
-
-.sidebar .categories ul li:last-child {
- margin-bottom: 0px;
-}
-
-.sidebar .categories ul li a {
- font-size: 15px;
- font-weight: 700;
- color: #20232e;
- transition: all .3s;
-}
-
-.sidebar .categories ul li a:hover {
- color: #f48840;
-}
-
-.sidebar .tags ul li {
- margin-right: 6px;
- display: inline-block;
-}
-
-.sidebar .tags ul li {
- margin-bottom: 10px;
-}
-
-.sidebar .tags ul li a {
- font-size: 15px;
- font-weight: 500;
- color: #aaa;
- display: inline-block;
- border: 1px solid #eee;
- padding: 10px 18px;
- transition: all .3s;
-}
-
-.sidebar .tags ul li a:hover {
- background-color: #f48840;
- border-color: #f48840;
- color: #fff;
-}
-
-
-/* Footer */
-
-footer {
- margin-top: 100px;
- text-align: center;
- background-color: #20232e;
- padding: 60px 0px;
-}
-
-footer ul.social-icons {
- padding-bottom: 60px;
- margin-bottom: 60px;
- border-bottom: 1px solid rgba(250,250,250,0.15);
-}
-
-footer ul.social-icons li {
- display: inline-block;
- margin-right: 30px;
-}
-
-footer ul.social-icons li:after {
- content: "|";
- color: #fff;
- margin-left: 30px;
-}
-
-footer ul.social-icons li:last-child {
- margin-right: 0px;
-}
-
-footer ul.social-icons li:last-child::after {
- display: none;
-}
-
-footer ul.social-icons li a {
- font-size: 14px;
- text-transform: uppercase;
- color: #fff;
- font-weight: 500;
- letter-spacing: 0.25px;
- transition: all .3s;
-}
-
-footer ul.social-icons li a:hover {
- color: #f48840;
-}
-
-footer p {
- font-size: 13px;
- text-transform: uppercase;
- color: #fff;
-}
-
-footer p a {
- color: #f48840;
-}
-
-footer p a:hover {
- color: #f48840;
-}
-
-
-/* Contact Form */
-
-.contact-us .down-contact,
-.contact-us #map {
- margin-top: 80px;
-}
-
-.contact-us .sidebar-heading h2 {
- font-size: 18px;
- text-transform: uppercase;
- font-weight: 900;
- letter-spacing: 0.5px;
- color: #20232e;
- border-bottom: 1px solid #eee;
- padding-bottom: 15px;
- margin-bottom: 25px;
-}
-
-.contact-us .contact-form input {
- width: 100%;
- height: 46px;
- border: 1px solid #eee;
- font-size: 13px;
- text-transform: uppercase;
- font-weight: 500;
- color: #7a7a7a;
- outline: none;
- padding: 0px 15px;
- margin-bottom: 30px;
-}
-
-.contact-us .contact-form textarea {
- width: 100%;
- height: 46px;
- border: 1px solid #eee;
- font-size: 13px;
- text-transform: uppercase;
- font-weight: 500;
- color: #7a7a7a;
- outline: none;
- padding: 10px 15px;
- margin-bottom: 30px;
- height: 180px;
- max-height: 220px;
- max-width: 100%;
- min-width: 160px;
-}
-
-.contact-us .contact-form input::placeholder,
-.contact-us .contact-form textarea::placeholder {
- color: #aaa;
-}
-
-.contact-us .contact-form button {
- display: inline-block;
- background-color: #f48840;
- color: #fff;
- font-size: 13px;
- font-weight: 500;
- padding: 12px 20px;
- text-transform: uppercase;
- transition: all .3s;
- border: none;
- outline: none;
-}
-
-.contact-us .contact-form button:hover {
- background-color: #fb9857;
-}
-
-.contact-us .contact-information {
- margin-left: 30px;
-}
-
-.contact-us .contact-information ul li {
- margin-bottom: 15px;
- padding-bottom: 15px;
- border-bottom: 1px solid #eee;
-}
-
-.contact-us .contact-information ul li:last-child {
- margin-bottom: 0px;
- padding-bottom: 0px;
- border-bottom: none;
-}
-
-.contact-us .contact-information ul li h5 {
- font-size: 19px;
- font-weight: 900;
- color: #20232e;
- line-height: 30px;
-}
-
-.contact-us .contact-information ul li span {
- display: block;
- font-size: 14px;
- color: #aaa;
- margin-top: 8px;
-}
-
-
-/* About Us */
-
-.about-us {
- margin-top: 100px;
- text-align: center;
-}
-
-.about-us img {
- width: 100%;
- overflow: hidden;
-}
-
-.about-us p {
- margin: 40px 0px;
- border-bottom: 1px solid #eee;
- padding-bottom: 40px;
-}
-
-.about-us ul li {
- display: inline-block;
- margin: 0px 5px;
-}
-
-.about-us ul li a {
- width: 40px;
- height: 40px;
- text-align: center;
- line-height: 40px;
- display: inline-block;
- background-color: #212931;
- color: #fff;
- border-radius: 50%;
- transition: all .3s;
-}
-
-.about-us ul li a:hover {
- background-color: #f48840;
-}
-
-
-/* Responsive Style */
-@media (max-width: 1250px) {
- .owl-banner .owl-nav .owl-prev {
- left: 0px;
- }
- .owl-banner .owl-nav .owl-next {
- right: 0px;
- }
- .owl-banner .owl-nav button span {
- width: 35px;
- }
- .owl-banner .item .item-content .meta-category span {
- font-size: 16px;
- }
- .owl-banner .item .item-content h4 {
- font-size: 20px;
- }
-}
-@media (max-width: 768px) {
- .owl-banner .owl-nav {
- display: none;
- }
-}
-
-@media (max-width: 992px) {
- .navbar .navbar-brand {
- position: absolute;
- left: 30px;
- top: 25px;
- }
- .background-header .navbar-brand,
- .background-header .navbar-toggler {
- top: 15px;
- }
- .navbar .navbar-brand {
- width: auto;
- }
- .navbar:after {
- display: none;
- }
- #navbarResponsive {
- z-index: 99999;
- position: absolute;
- top: 80px;
- left: 0;
- width: 100%;
- text-align: center;
- background-color: #fff;
- box-shadow: 0px 10px 10px rgba(0,0,0,0.1);
- }
- .navbar .navbar-nav .nav-item {
- border-bottom: 1px solid #eee;
- }
- .navbar .navbar-nav .nav-item:last-child {
- border-bottom: none;
- }
- .navbar .navbar-nav a.nav-link {
- padding: 15px 0px;
- color: #1e1e1e!important;
- }
- .navbar .navbar-nav .nav-link:hover,
- .navbar .navbar-nav .active>.nav-link,
- .navbar .navbar-nav .nav-link.active,
- .navbar .navbar-nav .nav-link.show,
- .navbar .navbar-nav .show>.nav-link {
- color: #f48840!important;
- border-bottom: none!important;
- padding-bottom: 15px;
- }
- .owl-banner .item .item-content .meta-category span {
- font-size: 18px;
- }
- .owl-banner .item .item-content {
- text-align: center;
- width: 80%;
- left: 50%;
- top: 50%;
- bottom: auto;
- transform: translate(-50%,-50%);
- }
- .owl-banner .item .item-content h4 {
- font-size: 24px;
- }
- .call-to-action {
- text-align: center;
- }
- .call-to-action .main-content .main-button {
- text-align: center;
- margin-top: 30px;
- }
- .sidebar {
- margin-left: 0px;
- margin-top: 60px;
- padding-top: 60px;
- border-top: 3px solid #f7f7f7;
- }
- .contact-us .contact-information {
- margin-left: 0px;
- margin-top: 60px;
- }
+/*
+
+TemplateMo 551 Stand Blog
+
+https://templatemo.com/tm-551-stand-blog
+
+*/
+
+body {
+ font-family: 'Roboto', sans-serif;
+ overflow-x: hidden;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+p {
+ margin-bottom: 0px;
+ font-size: 18px;
+ font-weight: 400;
+ color: #7a7a7a;
+ line-height: 30px;
+}
+
+
+
+a {
+ text-decoration: none!important;
+}
+ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+h1,h2,h3,h4,h5,h6 {
+ margin: 0px;
+}
+
+.main-button a {
+ display: inline-block;
+ background-color: #f48840;
+ color: #fff;
+ font-size: 13px;
+ font-weight: 500;
+ padding: 12px 20px;
+ text-transform: uppercase;
+ transition: all .3s;
+}
+
+.main-button a:hover {
+ background-color: #fb9857;
+}
+
+.heading-page {
+ padding-top: 110px;
+}
+
+.page-heading {
+ margin: 0px 10px;
+ padding: 120px 0px;
+ text-align: left;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-image: url(../images/heading-bg.jpg);
+}
+
+.page-heading .text-content h4 {
+ color: #f48840;
+ font-size: 18px;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+ margin-bottom: 15px;
+}
+
+.page-heading .text-content h2 {
+ color: #fff;
+ font-size: 36px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+#preloader {
+ overflow: hidden;
+ background: #f48840;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ position: fixed;
+ z-index: 9999999;
+ color: #fff;
+}
+
+#preloader .jumper {
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ display: block;
+ position: absolute;
+ margin: auto;
+ width: 50px;
+ height: 50px;
+}
+
+#preloader .jumper > div {
+ background-color: #fff;
+ width: 10px;
+ height: 10px;
+ border-radius: 100%;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+ position: absolute;
+ opacity: 0;
+ width: 50px;
+ height: 50px;
+ -webkit-animation: jumper 1s 0s linear infinite;
+ animation: jumper 1s 0s linear infinite;
+}
+
+#preloader .jumper > div:nth-child(2) {
+ -webkit-animation-delay: 0.33333s;
+ animation-delay: 0.33333s;
+}
+
+#preloader .jumper > div:nth-child(3) {
+ -webkit-animation-delay: 0.66666s;
+ animation-delay: 0.66666s;
+}
+
+@-webkit-keyframes jumper {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 5% {
+ opacity: 1;
+ }
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 0;
+ }
+}
+
+@keyframes jumper {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 5% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+
+
+/* Header Style */
+header {
+ position: absolute;
+ z-index: 99999;
+ width: 100%;
+ height: 100px;
+ background-color: #f7f7f7;
+ -webkit-transition: all 0.3s ease-in-out 0s;
+ -moz-transition: all 0.3s ease-in-out 0s;
+ -o-transition: all 0.3s ease-in-out 0s;
+ transition: all 0.3s ease-in-out 0s;
+}
+header .navbar {
+ padding: 25px 0px;
+}
+.background-header .navbar {
+ padding: 17px 0px;
+}
+.background-header {
+ top: 0;
+ height: 80px;
+ position: fixed;
+ box-shadow: 0px 1px 10px rgba(0,0,0,0.1);
+}
+.background-header .navbar-brand h2 {
+ color: #121212!important;
+}
+.background-header .navbar-nav a.nav-link {
+ color: #1e1e1e!important;
+}
+.background-header .navbar-nav .nav-link:hover,
+.background-header .navbar-nav .active>.nav-link,
+.background-header .navbar-nav .nav-link.active,
+.background-header .navbar-nav .nav-link.show,
+.background-header .navbar-nav .show>.nav-link {
+ color: #f48840!important;
+}
+.navbar .navbar-brand {
+ float: left;
+ margin-top: -12px;
+ outline: none;
+}
+.navbar .navbar-brand h2 {
+ color: #1e1e1e;
+ text-transform: uppercase;
+ font-size: 24px;
+ font-weight: 900;
+ -webkit-transition: all .3s ease 0s;
+ -moz-transition: all .3s ease 0s;
+ -o-transition: all .3s ease 0s;
+ transition: all .3s ease 0s;
+}
+.navbar .navbar-brand h2 em {
+ font-size: 44px;
+ font-style: normal;
+ color: #f48840;
+}
+#navbarResponsive {
+ z-index: 999;
+}
+.navbar-collapse {
+ text-align: center;
+}
+.navbar .navbar-nav .nav-item {
+ margin: 0px 15px;
+}
+.navbar .navbar-nav a.nav-link {
+ text-transform: capitalize;
+ font-size: 15px;
+ font-weight: 800;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: #1e1e1e;
+ transition: all 0.3s;
+}
+.navbar .navbar-nav .nav-link:hover,
+.navbar .navbar-nav .active>.nav-link,
+.navbar .navbar-nav .nav-link.active,
+.navbar .navbar-nav .nav-link.show,
+.navbar .navbar-nav .show>.nav-link {
+ color: #f48840;
+}
+.navbar .navbar-toggler-icon {
+ background-image: none;
+}
+.navbar .navbar-toggler {
+ border-color: #fff;
+ background-color: #f48840;
+ height: 46px;
+ outline: none;
+ border-radius: 0px;
+ position: absolute;
+ right: 30px;
+ top: 25px;
+}
+.navbar .navbar-toggler-icon:after {
+ content: '\f0c9';
+ color: #fff;
+ font-size: 18px;
+ line-height: 30px;
+ font-family: 'FontAwesome';
+}
+
+
+
+/* Banner Style */
+.main-banner .container-fluid {
+ padding: 0px 10px;
+ margin-bottom: -24px;
+}
+.owl-banner {
+ padding-top: 110px;
+}
+
+.owl-banner .item {
+ position: relative;
+}
+
+.owl-banner .item .item-content {
+ position: absolute;
+ bottom: 40px;
+ left: 40px;
+}
+
+.owl-banner .item .item-content .meta-category span {
+ color: #f48840;
+ font-size: 18px;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: 0.25px;
+}
+
+.owl-banner .item .item-content h4 {
+ font-size: 24px;
+ font-weight: 900;
+ color: #fff;
+ letter-spacing: 0.5px;
+ text-transform: capitalize;
+ margin: 10px 0px 12px 0px;
+}
+
+.owl-banner .item .item-content ul li {
+ display: inline-block;
+ margin-right: 8px;
+}
+
+.owl-banner .item .item-content ul li:after {
+ content: '|';
+ color: #fff;
+ margin-left: 8px;
+}
+
+.owl-banner .item .item-content ul li:last-child::after {
+ display: none;
+}
+
+.owl-banner .item .item-content ul li a {
+ font-size: 14px;
+ color: #fff;
+ font-weight: 500;
+ transition: all .3s;
+}
+
+.owl-banner .item .item-content ul li a:hover {
+ color: #f48840;
+}
+
+.owl-banner .owl-nav {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+}
+
+.owl-banner .owl-nav .owl-prev {
+ position: absolute;
+ left: 40px;
+}
+
+.owl-banner .owl-nav .owl-next {
+ position: absolute;
+ right: 40px;
+}
+
+.owl-banner .owl-nav button {
+ outline: none;
+}
+
+.owl-banner .owl-nav button span {
+ color: #fff;
+ font-size: 36px;
+ width: 60px;
+ height: 60px;
+ display: inline-block;
+ text-align: center;
+ line-height: 60px;
+ background-color: rgba(250,250,250,0.3);
+}
+
+
+/* Call To Action */
+
+.call-to-action {
+ margin-top: 100px;
+}
+
+.call-to-action .main-content {
+ padding: 40px;
+ background-image: url(../images/cta-bg.jpg);
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: cover;
+}
+
+.call-to-action .main-content span {
+ color: #f48840;
+ font-size: 18px;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+}
+
+.call-to-action .main-content h4 {
+ margin-bottom: 0px;
+ margin-top: 12px;
+ color: #fff;
+ font-size: 26px;
+ font-weight: 900;
+ letter-spacing: 0.25px;
+}
+
+.call-to-action .main-content .main-button {
+ text-align: right;
+ margin-top: 12px;
+}
+
+
+
+/* Blog Posts */
+
+.blog-posts {
+ margin-top: 100px;
+}
+
+.blog-posts .blog-post {
+ margin-bottom: 30px;
+}
+
+.blog-posts .blog-thumb img {
+ width: 100%;
+ overflow: hidden;
+}
+
+.blog-posts .down-content {
+ padding: 40px;
+ border-right: 1px solid #eee;
+ border-left: 1px solid #eee;
+ border-bottom: 1px solid #eee;
+}
+
+.blog-posts .down-content span {
+ font-size: 18px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ font-weight: 900;
+ color: #f48840;
+}
+
+.blog-posts .down-content h4 {
+ font-size: 24px;
+ text-transform: capitalize;
+ letter-spacing: 0.5px;
+ font-weight: 900;
+ color: #20232e;
+ margin: 10px 0px 12px 0px;
+}
+
+.blog-posts .down-content ul.post-info li {
+ display: inline-block;
+ margin-right: 8px;
+}
+
+.blog-posts .down-content ul.post-info li:after {
+ content: '|';
+ color: #aaa;
+ margin-left: 8px;
+}
+
+.blog-posts .down-content h4 {
+ font-size: 20px;
+ letter-spacing: 0.25px;
+}
+
+.grid-system .down-content ul.post-info li {
+ margin-right: 3px;
+}
+
+.grid-system .down-content ul.post-info li:after {
+ margin-left: 5px;
+}
+
+.blog-posts .down-content ul.post-info li:last-child::after {
+ display: none;
+}
+
+.blog-posts .down-content ul.post-info li a {
+ font-size: 14px;
+ color: #aaa;
+ font-weight: 400;
+ transition: all .3s;
+}
+
+.blog-posts .down-content ul.post-info li a:hover {
+ color: #f48840;
+}
+
+.blog-posts .down-content p {
+ padding: 25px 0px;
+ margin: 25px 0px;
+ border-top: 1px solid #eee;
+ border-bottom: 1px solid #eee;
+}
+
+.blog-posts .down-content ul.post-share {
+ text-align: right;
+}
+
+.blog-posts .down-content ul.post-tags li,
+.blog-posts .down-content ul.post-share li {
+ display: inline-block;
+}
+
+.blog-posts .down-content ul.post-tags li:first-child i,
+.blog-posts .down-content ul.post-share li:first-child i {
+ color: #f48840;
+ margin-right: 5px;
+}
+
+.blog-posts .down-content ul.post-tags li,
+.blog-posts .down-content ul.post-share li {
+ color: #aaa;
+}
+
+.blog-posts .down-content ul.post-tags li a,
+.blog-posts .down-content ul.post-share li a {
+ font-size: 14px;
+ color: #aaa;
+ font-weight: 400;
+ transition: all .3s;
+}
+
+.blog-posts .down-content ul.post-tags li a:hover,
+.blog-posts .down-content ul.post-share li a:hover {
+ color: #f48840;
+}
+
+.blog-posts .main-button a {
+ height: 60px;
+ line-height: 60px;
+ padding: 0px;
+ width: 100%;
+ text-align: center;
+}
+
+ul.page-numbers {
+ text-align: center;
+}
+
+ul.page-numbers li {
+ display: inline-block;
+ margin: 0px 5px;
+}
+
+ul.page-numbers li a {
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+ text-align: center;
+ line-height: 50px;
+ font-size: 15px;
+ color: #7a7a7a;
+ border: 1px solid #eee;
+ font-weight: 500;
+ transition: all 0.3s;
+}
+
+ul.page-numbers li.active a {
+ background-color: #f48840;
+ border-color: #f48840;
+ color: #fff;
+}
+
+ul.page-numbers li a:hover {
+ color: #f48840;
+}
+
+.blog-posts .sidebar-heading h2 {
+ font-size: 18px;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+ color: #20232e;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 15px;
+ margin-bottom: 25px;
+}
+
+.blog-posts .comments {
+ margin-top: 30px;
+}
+
+.blog-posts .comments ul li {
+ display: inline-block;
+ margin-bottom: 20px;
+ padding-bottom: 20px;
+ border-bottom: 1px solid #eee;
+}
+
+.blog-posts .comments ul li.replied {
+ padding-left: 130px;
+}
+
+.blog-posts .comments ul li:last-child {
+ margin-bottom: 0px;
+ padding-bottom: 0px;
+ border-bottom: none;
+}
+
+.blog-posts .comments ul li .author-thumb {
+ display: inline;
+ float: left;
+}
+
+.blog-posts .comments ul li .author-thumb img {
+ max-width: 100px;
+ display: inline;
+}
+
+.blog-posts .comments ul li .right-content {
+ margin-left: 130px;
+}
+
+.blog-posts .comments ul li .right-content h4 {
+ color: #20232e;
+ font-size: 19px;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+}
+
+.blog-posts .comments ul li .right-content h4 span {
+ font-size: 14px;
+ color: #aaa;
+ font-weight: 400;
+ letter-spacing: 0.25px;
+ margin-left: 20px;
+}
+
+.blog-posts .submit-comment {
+ margin-top: 60px;
+}
+
+.blog-posts .submit-comment input {
+ width: 100%;
+ height: 46px;
+ border: 1px solid #eee;
+ font-size: 13px;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: #7a7a7a;
+ outline: none;
+ padding: 0px 15px;
+ margin-bottom: 30px;
+}
+
+.blog-posts .submit-comment textarea {
+ width: 100%;
+ height: 46px;
+ border: 1px solid #eee;
+ font-size: 13px;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: #7a7a7a;
+ outline: none;
+ padding: 10px 15px;
+ margin-bottom: 30px;
+ height: 180px;
+ max-height: 220px;
+ max-width: 100%;
+ min-width: 160px;
+}
+
+.blog-posts .submit-comment input::placeholder,
+.blog-posts .submit-comment textarea::placeholder {
+ color: #aaa;
+}
+
+.blog-posts .submit-comment button {
+ display: inline-block;
+ background-color: #f48840;
+ color: #fff;
+ font-size: 13px;
+ font-weight: 500;
+ padding: 12px 20px;
+ text-transform: uppercase;
+ transition: all .3s;
+ border: none;
+ outline: none;
+}
+
+.blog-posts .submit-comment button:hover {
+ background-color: #fb9857;
+}
+
+/* Sidebar */
+
+.sidebar {
+ margin-left: 30px;
+}
+
+.sidebar .sidebar-item {
+ margin-top: 50px;
+}
+
+.sidebar .search {
+ margin-top: 0px;
+}
+
+.sidebar .sidebar-heading h2 {
+ font-size: 18px;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+ color: #20232e;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 15px;
+ margin-bottom: 25px;
+}
+
+.sidebar .search input {
+ width: 100%;
+ height: 50px;
+ border: 1px solid #eee;
+ font-size: 13px;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: #7a7a7a;
+ outline: none;
+ padding: 0px 15px;
+}
+
+.sidebar .search input::placeholder {
+ color: #aaa;
+}
+
+.sidebar .recent-posts ul li {
+ margin-bottom: 15px;
+ padding-bottom: 15px;
+ border-bottom: 1px solid #eee;
+}
+
+.sidebar .recent-posts ul li:last-child {
+ margin-bottom: 0px;
+ padding-bottom: 0px;
+ border-bottom: none;
+}
+
+.sidebar .recent-posts ul li h5 {
+ font-size: 19px;
+ font-weight: 900;
+ color: #20232e;
+ line-height: 30px;
+ transition: all 0.3s;
+}
+
+.sidebar .recent-posts ul li h5:hover {
+ color: #f48840;
+}
+
+.sidebar .recent-posts ul li span {
+ display: block;
+ font-size: 14px;
+ color: #aaa;
+ margin-top: 8px;
+}
+
+.sidebar .categories ul li {
+ margin-bottom: 15px;
+}
+
+.sidebar .categories ul li:last-child {
+ margin-bottom: 0px;
+}
+
+.sidebar .categories ul li a {
+ font-size: 15px;
+ font-weight: 700;
+ color: #20232e;
+ transition: all .3s;
+}
+
+.sidebar .categories ul li a:hover {
+ color: #f48840;
+}
+
+.sidebar .tags ul li {
+ margin-right: 6px;
+ display: inline-block;
+}
+
+.sidebar .tags ul li {
+ margin-bottom: 10px;
+}
+
+.sidebar .tags ul li a {
+ font-size: 15px;
+ font-weight: 500;
+ color: #aaa;
+ display: inline-block;
+ border: 1px solid #eee;
+ padding: 10px 18px;
+ transition: all .3s;
+}
+
+.sidebar .tags ul li a:hover {
+ background-color: #f48840;
+ border-color: #f48840;
+ color: #fff;
+}
+
+
+/* Footer */
+
+footer {
+ margin-top: 100px;
+ text-align: center;
+ background-color: #20232e;
+ padding: 60px 0px;
+}
+
+footer ul.social-icons {
+ padding-bottom: 60px;
+ margin-bottom: 60px;
+ border-bottom: 1px solid rgba(250,250,250,0.15);
+}
+
+footer ul.social-icons li {
+ display: inline-block;
+ margin-right: 30px;
+}
+
+footer ul.social-icons li:after {
+ content: "|";
+ color: #fff;
+ margin-left: 30px;
+}
+
+footer ul.social-icons li:last-child {
+ margin-right: 0px;
+}
+
+footer ul.social-icons li:last-child::after {
+ display: none;
+}
+
+footer ul.social-icons li a {
+ font-size: 14px;
+ text-transform: uppercase;
+ color: #fff;
+ font-weight: 500;
+ letter-spacing: 0.25px;
+ transition: all .3s;
+}
+
+footer ul.social-icons li a:hover {
+ color: #f48840;
+}
+
+footer p {
+ font-size: 13px;
+ text-transform: uppercase;
+ color: #fff;
+}
+
+footer p a {
+ color: #f48840;
+}
+
+footer p a:hover {
+ color: #f48840;
+}
+
+
+/* Contact Form */
+
+.contact-us .down-contact,
+.contact-us #map {
+ margin-top: 80px;
+}
+
+.contact-us .sidebar-heading h2 {
+ font-size: 18px;
+ text-transform: uppercase;
+ font-weight: 900;
+ letter-spacing: 0.5px;
+ color: #20232e;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 15px;
+ margin-bottom: 25px;
+}
+
+.contact-us .contact-form input {
+ width: 100%;
+ height: 46px;
+ border: 1px solid #eee;
+ font-size: 13px;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: #7a7a7a;
+ outline: none;
+ padding: 0px 15px;
+ margin-bottom: 30px;
+}
+
+.contact-us .contact-form textarea {
+ width: 100%;
+ height: 46px;
+ border: 1px solid #eee;
+ font-size: 13px;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: #7a7a7a;
+ outline: none;
+ padding: 10px 15px;
+ margin-bottom: 30px;
+ height: 180px;
+ max-height: 220px;
+ max-width: 100%;
+ min-width: 160px;
+}
+
+.contact-us .contact-form input::placeholder,
+.contact-us .contact-form textarea::placeholder {
+ color: #aaa;
+}
+
+.contact-us .contact-form button {
+ display: inline-block;
+ background-color: #f48840;
+ color: #fff;
+ font-size: 13px;
+ font-weight: 500;
+ padding: 12px 20px;
+ text-transform: uppercase;
+ transition: all .3s;
+ border: none;
+ outline: none;
+}
+
+.contact-us .contact-form button:hover {
+ background-color: #fb9857;
+}
+
+.contact-us .contact-information {
+ margin-left: 30px;
+}
+
+.contact-us .contact-information ul li {
+ margin-bottom: 15px;
+ padding-bottom: 15px;
+ border-bottom: 1px solid #eee;
+}
+
+.contact-us .contact-information ul li:last-child {
+ margin-bottom: 0px;
+ padding-bottom: 0px;
+ border-bottom: none;
+}
+
+.contact-us .contact-information ul li h5 {
+ font-size: 19px;
+ font-weight: 900;
+ color: #20232e;
+ line-height: 30px;
+}
+
+.contact-us .contact-information ul li span {
+ display: block;
+ font-size: 14px;
+ color: #aaa;
+ margin-top: 8px;
+}
+
+
+/* About Us */
+
+.about-us {
+ margin-top: 100px;
+ text-align: center;
+}
+
+.about-us img {
+ width: 100%;
+ overflow: hidden;
+}
+
+.about-us p {
+ margin: 40px 0px;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 40px;
+}
+
+.about-us ul li {
+ display: inline-block;
+ margin: 0px 5px;
+}
+
+.about-us ul li a {
+ width: 40px;
+ height: 40px;
+ text-align: center;
+ line-height: 40px;
+ display: inline-block;
+ background-color: #212931;
+ color: #fff;
+ border-radius: 50%;
+ transition: all .3s;
+}
+
+.about-us ul li a:hover {
+ background-color: #f48840;
+}
+
+
+/* Responsive Style */
+@media (max-width: 1250px) {
+ .owl-banner .owl-nav .owl-prev {
+ left: 0px;
+ }
+ .owl-banner .owl-nav .owl-next {
+ right: 0px;
+ }
+ .owl-banner .owl-nav button span {
+ width: 35px;
+ }
+ .owl-banner .item .item-content .meta-category span {
+ font-size: 16px;
+ }
+ .owl-banner .item .item-content h4 {
+ font-size: 20px;
+ }
+}
+@media (max-width: 768px) {
+ .owl-banner .owl-nav {
+ display: none;
+ }
+}
+
+@media (max-width: 992px) {
+ .navbar .navbar-brand {
+ position: absolute;
+ left: 30px;
+ top: 25px;
+ }
+ .background-header .navbar-brand,
+ .background-header .navbar-toggler {
+ top: 15px;
+ }
+ .navbar .navbar-brand {
+ width: auto;
+ }
+ .navbar:after {
+ display: none;
+ }
+ #navbarResponsive {
+ z-index: 99999;
+ position: absolute;
+ top: 80px;
+ left: 0;
+ width: 100%;
+ text-align: center;
+ background-color: #fff;
+ box-shadow: 0px 10px 10px rgba(0,0,0,0.1);
+ }
+ .navbar .navbar-nav .nav-item {
+ border-bottom: 1px solid #eee;
+ }
+ .navbar .navbar-nav .nav-item:last-child {
+ border-bottom: none;
+ }
+ .navbar .navbar-nav a.nav-link {
+ padding: 15px 0px;
+ color: #1e1e1e!important;
+ }
+ .navbar .navbar-nav .nav-link:hover,
+ .navbar .navbar-nav .active>.nav-link,
+ .navbar .navbar-nav .nav-link.active,
+ .navbar .navbar-nav .nav-link.show,
+ .navbar .navbar-nav .show>.nav-link {
+ color: #f48840!important;
+ border-bottom: none!important;
+ padding-bottom: 15px;
+ }
+ .owl-banner .item .item-content .meta-category span {
+ font-size: 18px;
+ }
+ .owl-banner .item .item-content {
+ text-align: center;
+ width: 80%;
+ left: 50%;
+ top: 50%;
+ bottom: auto;
+ transform: translate(-50%,-50%);
+ }
+ .owl-banner .item .item-content h4 {
+ font-size: 24px;
+ }
+ .call-to-action {
+ text-align: center;
+ }
+ .call-to-action .main-content .main-button {
+ text-align: center;
+ margin-top: 30px;
+ }
+ .sidebar {
+ margin-left: 0px;
+ margin-top: 60px;
+ padding-top: 60px;
+ border-top: 3px solid #f7f7f7;
+ }
+ .contact-us .contact-information {
+ margin-left: 0px;
+ margin-top: 60px;
+ }
}
\ No newline at end of file
diff --git a/static/assets/js/accordions.js b/static/assets/js/accordions.js
index 5fec5e09..ce8731b0 100644
--- a/static/assets/js/accordions.js
+++ b/static/assets/js/accordions.js
@@ -1,16582 +1,16582 @@
-/*! jQuery UI - v1.11.2 - 2014-10-16
-* http://jqueryui.com
-* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
-* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
-
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "jquery" ], factory );
- } else {
-
- // Browser globals
- factory( jQuery );
- }
-}(function( $ ) {
-/*!
- * jQuery UI Core 1.11.2
- * http://jqueryui.com
- *
- * Copyright 2014 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/category/ui-core/
- */
-
-
-// $.ui might exist from components with no dependencies, e.g., $.ui.position
-$.ui = $.ui || {};
-
-$.extend( $.ui, {
- version: "1.11.2",
-
- keyCode: {
- BACKSPACE: 8,
- COMMA: 188,
- DELETE: 46,
- DOWN: 40,
- END: 35,
- ENTER: 13,
- ESCAPE: 27,
- HOME: 36,
- LEFT: 37,
- PAGE_DOWN: 34,
- PAGE_UP: 33,
- PERIOD: 190,
- RIGHT: 39,
- SPACE: 32,
- TAB: 9,
- UP: 38
- }
-});
-
-// plugins
-$.fn.extend({
- scrollParent: function( includeHidden ) {
- var position = this.css( "position" ),
- excludeStaticParent = position === "absolute",
- overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
- scrollParent = this.parents().filter( function() {
- var parent = $( this );
- if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
- return false;
- }
- return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
- }).eq( 0 );
-
- return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
- },
-
- uniqueId: (function() {
- var uuid = 0;
-
- return function() {
- return this.each(function() {
- if ( !this.id ) {
- this.id = "ui-id-" + ( ++uuid );
- }
- });
- };
- })(),
-
- removeUniqueId: function() {
- return this.each(function() {
- if ( /^ui-id-\d+$/.test( this.id ) ) {
- $( this ).removeAttr( "id" );
- }
- });
- }
-});
-
-// selectors
-function focusable( element, isTabIndexNotNaN ) {
- var map, mapName, img,
- nodeName = element.nodeName.toLowerCase();
- if ( "area" === nodeName ) {
- map = element.parentNode;
- mapName = map.name;
- if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
- return false;
- }
- img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
- return !!img && visible( img );
- }
- return ( /input|select|textarea|button|object/.test( nodeName ) ?
- !element.disabled :
- "a" === nodeName ?
- element.href || isTabIndexNotNaN :
- isTabIndexNotNaN) &&
- // the element and all of its ancestors must be visible
- visible( element );
-}
-
-function visible( element ) {
- return $.expr.filters.visible( element ) &&
- !$( element ).parents().addBack().filter(function() {
- return $.css( this, "visibility" ) === "hidden";
- }).length;
-}
-
-$.extend( $.expr[ ":" ], {
- data: $.expr.createPseudo ?
- $.expr.createPseudo(function( dataName ) {
- return function( elem ) {
- return !!$.data( elem, dataName );
- };
- }) :
- // support: jQuery <1.8
- function( elem, i, match ) {
- return !!$.data( elem, match[ 3 ] );
- },
-
- focusable: function( element ) {
- return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
- },
-
- tabbable: function( element ) {
- var tabIndex = $.attr( element, "tabindex" ),
- isTabIndexNaN = isNaN( tabIndex );
- return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
- }
-});
-
-// support: jQuery <1.8
-if ( !$( "" ).outerWidth( 1 ).jquery ) {
- $.each( [ "Width", "Height" ], function( i, name ) {
- var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
- type = name.toLowerCase(),
- orig = {
- innerWidth: $.fn.innerWidth,
- innerHeight: $.fn.innerHeight,
- outerWidth: $.fn.outerWidth,
- outerHeight: $.fn.outerHeight
- };
-
- function reduce( elem, size, border, margin ) {
- $.each( side, function() {
- size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
- if ( border ) {
- size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
- }
- if ( margin ) {
- size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
- }
- });
- return size;
- }
-
- $.fn[ "inner" + name ] = function( size ) {
- if ( size === undefined ) {
- return orig[ "inner" + name ].call( this );
- }
-
- return this.each(function() {
- $( this ).css( type, reduce( this, size ) + "px" );
- });
- };
-
- $.fn[ "outer" + name] = function( size, margin ) {
- if ( typeof size !== "number" ) {
- return orig[ "outer" + name ].call( this, size );
- }
-
- return this.each(function() {
- $( this).css( type, reduce( this, size, true, margin ) + "px" );
- });
- };
- });
-}
-
-// support: jQuery <1.8
-if ( !$.fn.addBack ) {
- $.fn.addBack = function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter( selector )
- );
- };
-}
-
-// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
-if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
- $.fn.removeData = (function( removeData ) {
- return function( key ) {
- if ( arguments.length ) {
- return removeData.call( this, $.camelCase( key ) );
- } else {
- return removeData.call( this );
- }
- };
- })( $.fn.removeData );
-}
-
-// deprecated
-$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
-
-$.fn.extend({
- focus: (function( orig ) {
- return function( delay, fn ) {
- return typeof delay === "number" ?
- this.each(function() {
- var elem = this;
- setTimeout(function() {
- $( elem ).focus();
- if ( fn ) {
- fn.call( elem );
- }
- }, delay );
- }) :
- orig.apply( this, arguments );
- };
- })( $.fn.focus ),
-
- disableSelection: (function() {
- var eventType = "onselectstart" in document.createElement( "div" ) ?
- "selectstart" :
- "mousedown";
-
- return function() {
- return this.bind( eventType + ".ui-disableSelection", function( event ) {
- event.preventDefault();
- });
- };
- })(),
-
- enableSelection: function() {
- return this.unbind( ".ui-disableSelection" );
- },
-
- zIndex: function( zIndex ) {
- if ( zIndex !== undefined ) {
- return this.css( "zIndex", zIndex );
- }
-
- if ( this.length ) {
- var elem = $( this[ 0 ] ), position, value;
- while ( elem.length && elem[ 0 ] !== document ) {
- // Ignore z-index if position is set to a value where z-index is ignored by the browser
- // This makes behavior of this function consistent across browsers
- // WebKit always returns auto if the element is positioned
- position = elem.css( "position" );
- if ( position === "absolute" || position === "relative" || position === "fixed" ) {
- // IE returns 0 when zIndex is not specified
- // other browsers return a string
- // we ignore the case of nested elements with an explicit value of 0
- // ",
- delay: 300,
- options: {
- icons: {
- submenu: "ui-icon-carat-1-e"
- },
- items: "> *",
- menus: "ul",
- position: {
- my: "left-1 top",
- at: "right top"
- },
- role: "menu",
-
- // callbacks
- blur: null,
- focus: null,
- select: null
- },
-
- _create: function() {
- this.activeMenu = this.element;
-
- // Flag used to prevent firing of the click handler
- // as the event bubbles up through nested menus
- this.mouseHandled = false;
- this.element
- .uniqueId()
- .addClass( "ui-menu ui-widget ui-widget-content" )
- .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
- .attr({
- role: this.options.role,
- tabIndex: 0
- });
-
- if ( this.options.disabled ) {
- this.element
- .addClass( "ui-state-disabled" )
- .attr( "aria-disabled", "true" );
- }
-
- this._on({
- // Prevent focus from sticking to links inside menu after clicking
- // them (focus should always stay on UL during navigation).
- "mousedown .ui-menu-item": function( event ) {
- event.preventDefault();
- },
- "click .ui-menu-item": function( event ) {
- var target = $( event.target );
- if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
- this.select( event );
-
- // Only set the mouseHandled flag if the event will bubble, see #9469.
- if ( !event.isPropagationStopped() ) {
- this.mouseHandled = true;
- }
-
- // Open submenu on click
- if ( target.has( ".ui-menu" ).length ) {
- this.expand( event );
- } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
-
- // Redirect focus to the menu
- this.element.trigger( "focus", [ true ] );
-
- // If the active item is on the top level, let it stay active.
- // Otherwise, blur the active item since it is no longer visible.
- if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
- clearTimeout( this.timer );
- }
- }
- }
- },
- "mouseenter .ui-menu-item": function( event ) {
- // Ignore mouse events while typeahead is active, see #10458.
- // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
- // is over an item in the menu
- if ( this.previousFilter ) {
- return;
- }
- var target = $( event.currentTarget );
- // Remove ui-state-active class from siblings of the newly focused menu item
- // to avoid a jump caused by adjacent elements both having a class with a border
- target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
- this.focus( event, target );
- },
- mouseleave: "collapseAll",
- "mouseleave .ui-menu": "collapseAll",
- focus: function( event, keepActiveItem ) {
- // If there's already an active item, keep it active
- // If not, activate the first item
- var item = this.active || this.element.find( this.options.items ).eq( 0 );
-
- if ( !keepActiveItem ) {
- this.focus( event, item );
- }
- },
- blur: function( event ) {
- this._delay(function() {
- if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
- this.collapseAll( event );
- }
- });
- },
- keydown: "_keydown"
- });
-
- this.refresh();
-
- // Clicks outside of a menu collapse any open menus
- this._on( this.document, {
- click: function( event ) {
- if ( this._closeOnDocumentClick( event ) ) {
- this.collapseAll( event );
- }
-
- // Reset the mouseHandled flag
- this.mouseHandled = false;
- }
- });
- },
-
- _destroy: function() {
- // Destroy (sub)menus
- this.element
- .removeAttr( "aria-activedescendant" )
- .find( ".ui-menu" ).addBack()
- .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
- .removeAttr( "role" )
- .removeAttr( "tabIndex" )
- .removeAttr( "aria-labelledby" )
- .removeAttr( "aria-expanded" )
- .removeAttr( "aria-hidden" )
- .removeAttr( "aria-disabled" )
- .removeUniqueId()
- .show();
-
- // Destroy menu items
- this.element.find( ".ui-menu-item" )
- .removeClass( "ui-menu-item" )
- .removeAttr( "role" )
- .removeAttr( "aria-disabled" )
- .removeUniqueId()
- .removeClass( "ui-state-hover" )
- .removeAttr( "tabIndex" )
- .removeAttr( "role" )
- .removeAttr( "aria-haspopup" )
- .children().each( function() {
- var elem = $( this );
- if ( elem.data( "ui-menu-submenu-carat" ) ) {
- elem.remove();
- }
- });
-
- // Destroy menu dividers
- this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
- },
-
- _keydown: function( event ) {
- var match, prev, character, skip,
- preventDefault = true;
-
- switch ( event.keyCode ) {
- case $.ui.keyCode.PAGE_UP:
- this.previousPage( event );
- break;
- case $.ui.keyCode.PAGE_DOWN:
- this.nextPage( event );
- break;
- case $.ui.keyCode.HOME:
- this._move( "first", "first", event );
- break;
- case $.ui.keyCode.END:
- this._move( "last", "last", event );
- break;
- case $.ui.keyCode.UP:
- this.previous( event );
- break;
- case $.ui.keyCode.DOWN:
- this.next( event );
- break;
- case $.ui.keyCode.LEFT:
- this.collapse( event );
- break;
- case $.ui.keyCode.RIGHT:
- if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
- this.expand( event );
- }
- break;
- case $.ui.keyCode.ENTER:
- case $.ui.keyCode.SPACE:
- this._activate( event );
- break;
- case $.ui.keyCode.ESCAPE:
- this.collapse( event );
- break;
- default:
- preventDefault = false;
- prev = this.previousFilter || "";
- character = String.fromCharCode( event.keyCode );
- skip = false;
-
- clearTimeout( this.filterTimer );
-
- if ( character === prev ) {
- skip = true;
- } else {
- character = prev + character;
- }
-
- match = this._filterMenuItems( character );
- match = skip && match.index( this.active.next() ) !== -1 ?
- this.active.nextAll( ".ui-menu-item" ) :
- match;
-
- // If no matches on the current filter, reset to the last character pressed
- // to move down the menu to the first item that starts with that character
- if ( !match.length ) {
- character = String.fromCharCode( event.keyCode );
- match = this._filterMenuItems( character );
- }
-
- if ( match.length ) {
- this.focus( event, match );
- this.previousFilter = character;
- this.filterTimer = this._delay(function() {
- delete this.previousFilter;
- }, 1000 );
- } else {
- delete this.previousFilter;
- }
- }
-
- if ( preventDefault ) {
- event.preventDefault();
- }
- },
-
- _activate: function( event ) {
- if ( !this.active.is( ".ui-state-disabled" ) ) {
- if ( this.active.is( "[aria-haspopup='true']" ) ) {
- this.expand( event );
- } else {
- this.select( event );
- }
- }
- },
-
- refresh: function() {
- var menus, items,
- that = this,
- icon = this.options.icons.submenu,
- submenus = this.element.find( this.options.menus );
-
- this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
-
- // Initialize nested menus
- submenus.filter( ":not(.ui-menu)" )
- .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
- .hide()
- .attr({
- role: this.options.role,
- "aria-hidden": "true",
- "aria-expanded": "false"
- })
- .each(function() {
- var menu = $( this ),
- item = menu.parent(),
- submenuCarat = $( "" )
- .addClass( "ui-menu-icon ui-icon " + icon )
- .data( "ui-menu-submenu-carat", true );
-
- item
- .attr( "aria-haspopup", "true" )
- .prepend( submenuCarat );
- menu.attr( "aria-labelledby", item.attr( "id" ) );
- });
-
- menus = submenus.add( this.element );
- items = menus.find( this.options.items );
-
- // Initialize menu-items containing spaces and/or dashes only as dividers
- items.not( ".ui-menu-item" ).each(function() {
- var item = $( this );
- if ( that._isDivider( item ) ) {
- item.addClass( "ui-widget-content ui-menu-divider" );
- }
- });
-
- // Don't refresh list items that are already adapted
- items.not( ".ui-menu-item, .ui-menu-divider" )
- .addClass( "ui-menu-item" )
- .uniqueId()
- .attr({
- tabIndex: -1,
- role: this._itemRole()
- });
-
- // Add aria-disabled attribute to any disabled menu item
- items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
-
- // If the active item has been removed, blur the menu
- if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
- this.blur();
- }
- },
-
- _itemRole: function() {
- return {
- menu: "menuitem",
- listbox: "option"
- }[ this.options.role ];
- },
-
- _setOption: function( key, value ) {
- if ( key === "icons" ) {
- this.element.find( ".ui-menu-icon" )
- .removeClass( this.options.icons.submenu )
- .addClass( value.submenu );
- }
- if ( key === "disabled" ) {
- this.element
- .toggleClass( "ui-state-disabled", !!value )
- .attr( "aria-disabled", value );
- }
- this._super( key, value );
- },
-
- focus: function( event, item ) {
- var nested, focused;
- this.blur( event, event && event.type === "focus" );
-
- this._scrollIntoView( item );
-
- this.active = item.first();
- focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
- // Only update aria-activedescendant if there's a role
- // otherwise we assume focus is managed elsewhere
- if ( this.options.role ) {
- this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
- }
-
- // Highlight active parent menu item, if any
- this.active
- .parent()
- .closest( ".ui-menu-item" )
- .addClass( "ui-state-active" );
-
- if ( event && event.type === "keydown" ) {
- this._close();
- } else {
- this.timer = this._delay(function() {
- this._close();
- }, this.delay );
- }
-
- nested = item.children( ".ui-menu" );
- if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
- this._startOpening(nested);
- }
- this.activeMenu = item.parent();
-
- this._trigger( "focus", event, { item: item } );
- },
-
- _scrollIntoView: function( item ) {
- var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
- if ( this._hasScroll() ) {
- borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
- paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
- offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
- scroll = this.activeMenu.scrollTop();
- elementHeight = this.activeMenu.height();
- itemHeight = item.outerHeight();
-
- if ( offset < 0 ) {
- this.activeMenu.scrollTop( scroll + offset );
- } else if ( offset + itemHeight > elementHeight ) {
- this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
- }
- }
- },
-
- blur: function( event, fromFocus ) {
- if ( !fromFocus ) {
- clearTimeout( this.timer );
- }
-
- if ( !this.active ) {
- return;
- }
-
- this.active.removeClass( "ui-state-focus" );
- this.active = null;
-
- this._trigger( "blur", event, { item: this.active } );
- },
-
- _startOpening: function( submenu ) {
- clearTimeout( this.timer );
-
- // Don't open if already open fixes a Firefox bug that caused a .5 pixel
- // shift in the submenu position when mousing over the carat icon
- if ( submenu.attr( "aria-hidden" ) !== "true" ) {
- return;
- }
-
- this.timer = this._delay(function() {
- this._close();
- this._open( submenu );
- }, this.delay );
- },
-
- _open: function( submenu ) {
- var position = $.extend({
- of: this.active
- }, this.options.position );
-
- clearTimeout( this.timer );
- this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
- .hide()
- .attr( "aria-hidden", "true" );
-
- submenu
- .show()
- .removeAttr( "aria-hidden" )
- .attr( "aria-expanded", "true" )
- .position( position );
- },
-
- collapseAll: function( event, all ) {
- clearTimeout( this.timer );
- this.timer = this._delay(function() {
- // If we were passed an event, look for the submenu that contains the event
- var currentMenu = all ? this.element :
- $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
-
- // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
- if ( !currentMenu.length ) {
- currentMenu = this.element;
- }
-
- this._close( currentMenu );
-
- this.blur( event );
- this.activeMenu = currentMenu;
- }, this.delay );
- },
-
- // With no arguments, closes the currently active menu - if nothing is active
- // it closes all menus. If passed an argument, it will search for menus BELOW
- _close: function( startMenu ) {
- if ( !startMenu ) {
- startMenu = this.active ? this.active.parent() : this.element;
- }
-
- startMenu
- .find( ".ui-menu" )
- .hide()
- .attr( "aria-hidden", "true" )
- .attr( "aria-expanded", "false" )
- .end()
- .find( ".ui-state-active" ).not( ".ui-state-focus" )
- .removeClass( "ui-state-active" );
- },
-
- _closeOnDocumentClick: function( event ) {
- return !$( event.target ).closest( ".ui-menu" ).length;
- },
-
- _isDivider: function( item ) {
-
- // Match hyphen, em dash, en dash
- return !/[^\-\u2014\u2013\s]/.test( item.text() );
- },
-
- collapse: function( event ) {
- var newItem = this.active &&
- this.active.parent().closest( ".ui-menu-item", this.element );
- if ( newItem && newItem.length ) {
- this._close();
- this.focus( event, newItem );
- }
- },
-
- expand: function( event ) {
- var newItem = this.active &&
- this.active
- .children( ".ui-menu " )
- .find( this.options.items )
- .first();
-
- if ( newItem && newItem.length ) {
- this._open( newItem.parent() );
-
- // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
- this._delay(function() {
- this.focus( event, newItem );
- });
- }
- },
-
- next: function( event ) {
- this._move( "next", "first", event );
- },
-
- previous: function( event ) {
- this._move( "prev", "last", event );
- },
-
- isFirstItem: function() {
- return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
- },
-
- isLastItem: function() {
- return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
- },
-
- _move: function( direction, filter, event ) {
- var next;
- if ( this.active ) {
- if ( direction === "first" || direction === "last" ) {
- next = this.active
- [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
- .eq( -1 );
- } else {
- next = this.active
- [ direction + "All" ]( ".ui-menu-item" )
- .eq( 0 );
- }
- }
- if ( !next || !next.length || !this.active ) {
- next = this.activeMenu.find( this.options.items )[ filter ]();
- }
-
- this.focus( event, next );
- },
-
- nextPage: function( event ) {
- var item, base, height;
-
- if ( !this.active ) {
- this.next( event );
- return;
- }
- if ( this.isLastItem() ) {
- return;
- }
- if ( this._hasScroll() ) {
- base = this.active.offset().top;
- height = this.element.height();
- this.active.nextAll( ".ui-menu-item" ).each(function() {
- item = $( this );
- return item.offset().top - base - height < 0;
- });
-
- this.focus( event, item );
- } else {
- this.focus( event, this.activeMenu.find( this.options.items )
- [ !this.active ? "first" : "last" ]() );
- }
- },
-
- previousPage: function( event ) {
- var item, base, height;
- if ( !this.active ) {
- this.next( event );
- return;
- }
- if ( this.isFirstItem() ) {
- return;
- }
- if ( this._hasScroll() ) {
- base = this.active.offset().top;
- height = this.element.height();
- this.active.prevAll( ".ui-menu-item" ).each(function() {
- item = $( this );
- return item.offset().top - base + height > 0;
- });
-
- this.focus( event, item );
- } else {
- this.focus( event, this.activeMenu.find( this.options.items ).first() );
- }
- },
-
- _hasScroll: function() {
- return this.element.outerHeight() < this.element.prop( "scrollHeight" );
- },
-
- select: function( event ) {
- // TODO: It should never be possible to not have an active item at this
- // point, but the tests don't trigger mouseenter before click.
- this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
- var ui = { item: this.active };
- if ( !this.active.has( ".ui-menu" ).length ) {
- this.collapseAll( event, true );
- }
- this._trigger( "select", event, ui );
- },
-
- _filterMenuItems: function(character) {
- var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
- regex = new RegExp( "^" + escapedCharacter, "i" );
-
- return this.activeMenu
- .find( this.options.items )
-
- // Only match on items, not dividers or other content (#10571)
- .filter( ".ui-menu-item" )
- .filter(function() {
- return regex.test( $.trim( $( this ).text() ) );
- });
- }
-});
-
-
-/*!
- * jQuery UI Autocomplete 1.11.2
- * http://jqueryui.com
- *
- * Copyright 2014 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/autocomplete/
- */
-
-
-$.widget( "ui.autocomplete", {
- version: "1.11.2",
- defaultElement: "",
- options: {
- appendTo: null,
- autoFocus: false,
- delay: 300,
- minLength: 1,
- position: {
- my: "left top",
- at: "left bottom",
- collision: "none"
- },
- source: null,
-
- // callbacks
- change: null,
- close: null,
- focus: null,
- open: null,
- response: null,
- search: null,
- select: null
- },
-
- requestIndex: 0,
- pending: 0,
-
- _create: function() {
- // Some browsers only repeat keydown events, not keypress events,
- // so we use the suppressKeyPress flag to determine if we've already
- // handled the keydown event. #7269
- // Unfortunately the code for & in keypress is the same as the up arrow,
- // so we use the suppressKeyPressRepeat flag to avoid handling keypress
- // events when we know the keydown event was used to modify the
- // search term. #7799
- var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
- nodeName = this.element[ 0 ].nodeName.toLowerCase(),
- isTextarea = nodeName === "textarea",
- isInput = nodeName === "input";
-
- this.isMultiLine =
- // Textareas are always multi-line
- isTextarea ? true :
- // Inputs are always single-line, even if inside a contentEditable element
- // IE also treats inputs as contentEditable
- isInput ? false :
- // All other element types are determined by whether or not they're contentEditable
- this.element.prop( "isContentEditable" );
-
- this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
- this.isNewMenu = true;
-
- this.element
- .addClass( "ui-autocomplete-input" )
- .attr( "autocomplete", "off" );
-
- this._on( this.element, {
- keydown: function( event ) {
- if ( this.element.prop( "readOnly" ) ) {
- suppressKeyPress = true;
- suppressInput = true;
- suppressKeyPressRepeat = true;
- return;
- }
-
- suppressKeyPress = false;
- suppressInput = false;
- suppressKeyPressRepeat = false;
- var keyCode = $.ui.keyCode;
- switch ( event.keyCode ) {
- case keyCode.PAGE_UP:
- suppressKeyPress = true;
- this._move( "previousPage", event );
- break;
- case keyCode.PAGE_DOWN:
- suppressKeyPress = true;
- this._move( "nextPage", event );
- break;
- case keyCode.UP:
- suppressKeyPress = true;
- this._keyEvent( "previous", event );
- break;
- case keyCode.DOWN:
- suppressKeyPress = true;
- this._keyEvent( "next", event );
- break;
- case keyCode.ENTER:
- // when menu is open and has focus
- if ( this.menu.active ) {
- // #6055 - Opera still allows the keypress to occur
- // which causes forms to submit
- suppressKeyPress = true;
- event.preventDefault();
- this.menu.select( event );
- }
- break;
- case keyCode.TAB:
- if ( this.menu.active ) {
- this.menu.select( event );
- }
- break;
- case keyCode.ESCAPE:
- if ( this.menu.element.is( ":visible" ) ) {
- if ( !this.isMultiLine ) {
- this._value( this.term );
- }
- this.close( event );
- // Different browsers have different default behavior for escape
- // Single press can mean undo or clear
- // Double press in IE means clear the whole form
- event.preventDefault();
- }
- break;
- default:
- suppressKeyPressRepeat = true;
- // search timeout should be triggered before the input value is changed
- this._searchTimeout( event );
- break;
- }
- },
- keypress: function( event ) {
- if ( suppressKeyPress ) {
- suppressKeyPress = false;
- if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
- event.preventDefault();
- }
- return;
- }
- if ( suppressKeyPressRepeat ) {
- return;
- }
-
- // replicate some key handlers to allow them to repeat in Firefox and Opera
- var keyCode = $.ui.keyCode;
- switch ( event.keyCode ) {
- case keyCode.PAGE_UP:
- this._move( "previousPage", event );
- break;
- case keyCode.PAGE_DOWN:
- this._move( "nextPage", event );
- break;
- case keyCode.UP:
- this._keyEvent( "previous", event );
- break;
- case keyCode.DOWN:
- this._keyEvent( "next", event );
- break;
- }
- },
- input: function( event ) {
- if ( suppressInput ) {
- suppressInput = false;
- event.preventDefault();
- return;
- }
- this._searchTimeout( event );
- },
- focus: function() {
- this.selectedItem = null;
- this.previous = this._value();
- },
- blur: function( event ) {
- if ( this.cancelBlur ) {
- delete this.cancelBlur;
- return;
- }
-
- clearTimeout( this.searching );
- this.close( event );
- this._change( event );
- }
- });
-
- this._initSource();
- this.menu = $( "
" )
- .addClass( "ui-autocomplete ui-front" )
- .appendTo( this._appendTo() )
- .menu({
- // disable ARIA support, the live region takes care of that
- role: null
- })
- .hide()
- .menu( "instance" );
-
- this._on( this.menu.element, {
- mousedown: function( event ) {
- // prevent moving focus out of the text field
- event.preventDefault();
-
- // IE doesn't prevent moving focus even with event.preventDefault()
- // so we set a flag to know when we should ignore the blur event
- this.cancelBlur = true;
- this._delay(function() {
- delete this.cancelBlur;
- });
-
- // clicking on the scrollbar causes focus to shift to the body
- // but we can't detect a mouseup or a click immediately afterward
- // so we have to track the next mousedown and close the menu if
- // the user clicks somewhere outside of the autocomplete
- var menuElement = this.menu.element[ 0 ];
- if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
- this._delay(function() {
- var that = this;
- this.document.one( "mousedown", function( event ) {
- if ( event.target !== that.element[ 0 ] &&
- event.target !== menuElement &&
- !$.contains( menuElement, event.target ) ) {
- that.close();
- }
- });
- });
- }
- },
- menufocus: function( event, ui ) {
- var label, item;
- // support: Firefox
- // Prevent accidental activation of menu items in Firefox (#7024 #9118)
- if ( this.isNewMenu ) {
- this.isNewMenu = false;
- if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
- this.menu.blur();
-
- this.document.one( "mousemove", function() {
- $( event.target ).trigger( event.originalEvent );
- });
-
- return;
- }
- }
-
- item = ui.item.data( "ui-autocomplete-item" );
- if ( false !== this._trigger( "focus", event, { item: item } ) ) {
- // use value to match what will end up in the input, if it was a key event
- if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
- this._value( item.value );
- }
- }
-
- // Announce the value in the liveRegion
- label = ui.item.attr( "aria-label" ) || item.value;
- if ( label && $.trim( label ).length ) {
- this.liveRegion.children().hide();
- $( "