commit ec28a2024de979386d43509f71b61ddb7cf9780f Author: Beyhan Oğur Date: Sun Apr 26 22:22:29 2026 +0300 first commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0c2a70a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,68 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +*.egg-info/ +dist/ +*.egg +*.pyc +*.pyo +*.pyd + +# Virtual Environment +venv/ +env/ +ENV/ +.venv + +# Django +*.log +db.sqlite3 +db.sqlite3-journal +/staticfiles/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Git +.git/ +.gitignore + +# Docker +.dockerignore +Dockerfile +docker-compose*.yml + +# Documentation +*.md +!README.md + +# Test +.coverage +htmlcov/ +.pytest_cache/ +.tox/ + +# Environment variables +.env +.env.* +!.env.example + +# Secrets +*.pem +*.key +client_secret*.json + +# OS +Thumbs.db + +# Backup files +*.bak +*~ diff --git a/.env b/.env new file mode 100644 index 0000000..540d63c --- /dev/null +++ b/.env @@ -0,0 +1,40 @@ +# Django Settings +DEBUG=1 +SECRET_KEY='django-insecure-slih+3-7gn0b04-2wm4zq)rp*kz1jnt&bf9o3i3*8jhz*n9=2k' +DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,api.beyhano.net.tr,api.beyhano.com.tr + +# Database Settings (Mevcut PostgreSQL sunucunuz) +USE_POSTGRES=True +POSTGRES_DB=server_dj +POSTGRES_USER=cloud +POSTGRES_PASSWORD=gg7678290 +POSTGRES_HOST=10.80.80.70 +#POSTGRES_HOST=ares-postgresql-bieeud +POSTGRES_PORT=5432 + +# Social Auth (Google) +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY='915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com' # Your Google Client ID +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET='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' # Your Google Client Secret + +# Social Auth (GitHub) +SOCIAL_AUTH_GITHUB_KEY='Ov23liUt9B61O46Mdfm4' # Your GitHub Client ID +SOCIAL_AUTH_GITHUB_SECRET='c7fc8dcb1b2c8f22120608425d07d5efd995baaf' # Your GitHub Client Secret + +# Email Settings (Optional) +EMAIL_HOST=10.80.80.70 +EMAIL_PORT=1025 +EMAIL_HOST_USER='' +EMAIL_HOST_PASSWORD='' +EMAIL_USE_TLS=False +DEFAULT_FROM_EMAIL='noreply@localhost' + +# Additional settings +CSRF_TRUSTED_ORIGINS=https://beyhano.net.tr,https://api.beyhano.net.tr,https://api.beyhano.com.tr +DEBUG=True +REDIS_URL=redis://default:gg7678290@10.80.80.70:6379 +DJOSER_DOMAIN=localhost:3000 +DJOSER_SITE_NAME=Django Auth API +CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173,http://localhost:8080,http://127.0.0.1:8080 +EMAIL_USE_SSL=False +SOCIAL_AUTH_FACEBOOK_KEY= +SOCIAL_AUTH_FACEBOOK_SECRET= diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b17d4a0 --- /dev/null +++ b/.env.example @@ -0,0 +1,39 @@ +# Django Settings +DEBUG=True +SECRET_KEY='your-secret-key-here' +DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.com + +# Database Settings (Mevcut PostgreSQL sunucunuz) +USE_POSTGRES=True +POSTGRES_DB=server_dj +POSTGRES_USER=cloud +POSTGRES_PASSWORD=your-password +POSTGRES_HOST=10.80.80.70 +POSTGRES_PORT=5432 + +# Social Auth (Google) +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY='your-google-client-id' # Your Google Client ID +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET='your-google-client-secret' # Your Google Client Secret + +# Social Auth (GitHub) +SOCIAL_AUTH_GITHUB_KEY='your-github-client-id' # Your GitHub Client ID +SOCIAL_AUTH_GITHUB_SECRET='your-github-client-secret' # Your GitHub Client Secret + +# Email Settings (Optional) +EMAIL_HOST=10.80.80.70 +EMAIL_PORT=1025 +EMAIL_HOST_USER='' +EMAIL_HOST_PASSWORD='' +EMAIL_USE_TLS=False +EMAIL_USE_SSL=False +DEFAULT_FROM_EMAIL='noreply@localhost' + +# Additional settings +CSRF_TRUSTED_ORIGINS=https://yourdomain.com,https://api.yourdomain.com +REDIS_URL=redis://default:your-redis-password@10.80.80.70:6379 +DJOSER_DOMAIN=localhost:3000 +DJOSER_SITE_NAME=Django Auth API +CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173,http://localhost:8080,http://127.0.0.1:8080 + +SOCIAL_AUTH_FACEBOOK_KEY= +SOCIAL_AUTH_FACEBOOK_SECRET= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51c3a6b --- /dev/null +++ b/.gitignore @@ -0,0 +1,177 @@ +### Django template +*.log +*.pot +*.pyc +__pycache__/ +local_settings.py +db.sqlite3 +db.sqlite3-journal +media + +# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ +# in your Git repository. Update and uncomment the following line accordingly. +# /staticfiles/ + +### Python template +# 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 + +# 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 +.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/ + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e273a61 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,12 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Django PowerTools cache (generated) +/djangoPowerTools/ diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 0000000..4ea72a9 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 0000000..7ef04e2 --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 0000000..8648f94 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml new file mode 100644 index 0000000..b9cc2fc --- /dev/null +++ b/.idea/dictionaries/project.xml @@ -0,0 +1,7 @@ + + + + beyhano + + + \ No newline at end of file diff --git a/.idea/dj52.iml b/.idea/dj52.iml new file mode 100644 index 0000000..ace654f --- /dev/null +++ b/.idea/dj52.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..5cb71ef --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..1b39b96 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c919dea --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AUTH.md b/AUTH.md new file mode 100644 index 0000000..1151a4e --- /dev/null +++ b/AUTH.md @@ -0,0 +1,904 @@ +# Authentication API Documentation + +Bu doküman, Django REST API'nin authentication endpoint'lerini ve kullanım örneklerini içerir. + +## 📋 İçindekiler + +1. [Genel Bilgiler](#genel-bilgiler) +2. [Registration (Kayıt)](#registration-kayıt) +3. [Email Activation (Aktivasyon)](#email-activation-aktivasyon) +4. [Login (Giriş)](#login-giriş) +5. [Token Refresh](#token-refresh) +6. [Social Authentication](#social-authentication) +7. [User Profile](#user-profile) +8. [Password Reset](#password-reset) +9. [Frontend Entegrasyonu](#frontend-entegrasyonu) +10. [Error Handling](#error-handling) + +--- + +## Genel Bilgiler + +**Base URL:** `http://localhost:8000/api/v1/` + +**Authentication:** JWT Bearer Token +``` +Authorization: Bearer +``` + +**Content-Type:** `application/json` + +### Rate Limiting +- **Anonymous users:** 100 requests/hour +- **Authenticated users:** 1000 requests/hour + +--- + +## Registration (Kayıt) + +### Endpoint +``` +POST /api/v1/auth/users/ +``` + +### Request Body +```json +{ + "email": "user@example.com", + "password": "StrongP@ssw0rd123", + "re_password": "StrongP@ssw0rd123", + "first_name": "Ali", + "last_name": "Veli" +} +``` + +### Response (201 Created) +```json +{ + "id": 1, + "email": "user@example.com", + "first_name": "Ali", + "last_name": "Veli" +} +``` + +### Önemli Notlar +- Kullanıcı oluşturulur ancak **`is_active=False`** olarak ayarlanır +- Aktivasyon emaili otomatik gönderilir +- Kullanıcı email aktivasyonu yapmadan login olamaz +- Password minimum 8 karakter olmalı ve güçlü olmalı + +### Curl Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/users/ \ + -H "Content-Type: application/json" \ + -d '{ + "email": "user@example.com", + "password": "StrongP@ssw0rd123", + "re_password": "StrongP@ssw0rd123", + "first_name": "Ali", + "last_name": "Veli" + }' +``` + +--- + +## Email Activation (Aktivasyon) + +### Endpoint +``` +POST /api/v1/auth/users/activation/ +``` + +### Request Body +```json +{ + "uid": "MQ", + "token": "c4h7vu-a8f3d2e1c4b5a6d7e8f9g0h1" +} +``` + +### Response (204 No Content) +Başarılı aktivasyon sonrası response body boş döner. + +### Önemli Notlar +- `uid` ve `token` aktivasyon emailindeki linkten alınır +- Token 24 saat geçerlidir +- Başarılı aktivasyon sonrası `is_active=True` olur +- Kullanıcı artık login olabilir + +### Email Link Format +``` +http://localhost:3000/auth/activate/{uid}/{token}/ +``` + +Frontend bu linki yakalayıp backend'e POST request yapmalı. + +### Curl Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/users/activation/ \ + -H "Content-Type: application/json" \ + -d '{ + "uid": "MQ", + "token": "c4h7vu-a8f3d2e1c4b5a6d7e8f9g0h1" + }' +``` + +### Resend Activation Email +``` +POST /api/v1/auth/users/resend_activation/ +``` + +Request Body: +```json +{ + "email": "user@example.com" +} +``` + +--- + +## Login (Giriş) + +### Endpoint +``` +POST /api/v1/auth/jwt/create/ +``` + +### Request Body +```json +{ + "email": "user@example.com", + "password": "StrongP@ssw0rd123" +} +``` + +### Response (200 OK) +```json +{ + "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +} +``` + +### Token Bilgileri +- **Access Token:** 60 dakika geçerli +- **Refresh Token:** 7 gün geçerli +- Token rotation aktif (refresh kullanıldığında yeni refresh token döner) + +### Önemli Notlar +- Kullanıcı `is_active=False` ise login başarısız olur +- Hatalı email/password için 401 Unauthorized döner + +### Curl Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/jwt/create/ \ + -H "Content-Type: application/json" \ + -d '{ + "email": "user@example.com", + "password": "StrongP@ssw0rd123" + }' +``` + +### Error Response (401 Unauthorized) +```json +{ + "detail": "No active account found with the given credentials" +} +``` + +--- + +## Token Refresh + +### Endpoint +``` +POST /api/v1/auth/jwt/refresh/ +``` + +### Request Body +```json +{ + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +} +``` + +### Response (200 OK) +```json +{ + "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +} +``` + +### Önemli Notlar +- Yeni access token ve yeni refresh token döner (rotation) +- Eski refresh token blacklist'e eklenir +- Refresh token expire olduysa 401 döner + +### Curl Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/jwt/refresh/ \ + -H "Content-Type: application/json" \ + -d '{ + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + }' +``` + +--- + +## Social Authentication + +### Supported Providers +- **Google:** `google-oauth2` +- **GitHub:** `github` +- **Facebook:** `facebook` + +### Endpoint +``` +POST /api/v1/auth/social// +``` + +### Request Body +```json +{ + "access_token": "ya29.a0AfH6SMBx..." +} +``` + +### Response (200 OK) +```json +{ + "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": { + "id": 1, + "email": "user@example.com", + "first_name": "Ali", + "last_name": "Veli", + "is_active": true, + "date_joined": "2025-12-12T21:30:00Z" + } +} +``` + +### Önemli Notlar +- Social login ile gelen kullanıcılar **otomatik aktif** (`is_active=True`) +- Email aktivasyon gerekmez +- Kullanıcı yoksa otomatik oluşturulur +- Provider'dan email alınamazsa hata döner + +### Google OAuth2 Example + +#### 1. Frontend'de Google OAuth +```javascript +// Google OAuth2 ile token al +const googleUser = await gapi.auth2.getAuthInstance().signIn(); +const accessToken = googleUser.getAuthResponse().access_token; + +// Backend'e gönder +const response = await fetch('http://localhost:8000/api/v1/auth/social/google-oauth2/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + access_token: accessToken + }) +}); + +const data = await response.json(); +// data.access, data.refresh, data.user +``` + +#### 2. Curl Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/social/google-oauth2/ \ + -H "Content-Type: application/json" \ + -d '{ + "access_token": "ya29.a0AfH6SMBx..." + }' +``` + +### GitHub OAuth2 Example +```bash +curl -X POST http://localhost:8000/api/v1/auth/social/github/ \ + -H "Content-Type: application/json" \ + -d '{ + "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a" + }' +``` + +### Error Responses + +**Invalid Provider (400)** +```json +{ + "error": "Invalid provider. Must be one of: google-oauth2, github, facebook" +} +``` + +**Missing Token (400)** +```json +{ + "error": "access_token is required" +} +``` + +**Authentication Failed (401)** +```json +{ + "error": "Authentication failed. Invalid token." +} +``` + +**Email Not Provided (403)** +```json +{ + "error": "Authentication forbidden. Email not provided by provider or permission denied." +} +``` + +--- + +## User Profile + +### Get Current User +``` +GET /api/v1/auth/users/me/ +``` + +**Headers:** +``` +Authorization: Bearer +``` + +**Response (200 OK):** +```json +{ + "id": 1, + "email": "user@example.com", + "first_name": "Ali", + "last_name": "Veli", + "is_active": true, + "date_joined": "2025-12-12T21:30:00Z" +} +``` + +### Update Current User +``` +PATCH /api/v1/auth/users/me/ +``` + +**Request Body:** +```json +{ + "first_name": "Ahmet", + "last_name": "Yılmaz" +} +``` + +### Curl Example +```bash +curl -X GET http://localhost:8000/api/v1/auth/users/me/ \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +``` + +--- + +## Password Reset + +### 1. Request Password Reset +``` +POST /api/v1/auth/users/reset_password/ +``` + +**Request Body:** +```json +{ + "email": "user@example.com" +} +``` + +**Response (204 No Content)** + +Email gönderilir, link formatı: +``` +http://localhost:3000/auth/password/reset/confirm/{uid}/{token}/ +``` + +### 2. Confirm Password Reset +``` +POST /api/v1/auth/users/reset_password_confirm/ +``` + +**Request Body:** +```json +{ + "uid": "MQ", + "token": "c4h7vu-a8f3d2e1c4b5a6d7e8f9g0h1", + "new_password": "NewStrongP@ssw0rd123", + "re_new_password": "NewStrongP@ssw0rd123" +} +``` + +**Response (204 No Content)** + +--- + +## Frontend Entegrasyonu + +### Nuxt.js 3 Example + +#### 1. Composable: `useAuth.ts` +```typescript +// composables/useAuth.ts +export const useAuth = () => { + const config = useRuntimeConfig(); + const accessToken = useCookie('access_token'); + const refreshToken = useCookie('refresh_token'); + + const register = async (userData: { + email: string; + password: string; + re_password: string; + first_name: string; + last_name: string; + }) => { + const { data, error } = await useFetch(`${config.public.apiBase}/auth/users/`, { + method: 'POST', + body: userData, + }); + return { data, error }; + }; + + const login = async (email: string, password: string) => { + const { data, error } = await useFetch(`${config.public.apiBase}/auth/jwt/create/`, { + method: 'POST', + body: { email, password }, + }); + + if (data.value) { + accessToken.value = data.value.access; + refreshToken.value = data.value.refresh; + } + + return { data, error }; + }; + + const socialLogin = async (provider: string, accessTokenValue: string) => { + const { data, error } = await useFetch( + `${config.public.apiBase}/auth/social/${provider}/`, + { + method: 'POST', + body: { access_token: accessTokenValue }, + } + ); + + if (data.value) { + accessToken.value = data.value.access; + refreshToken.value = data.value.refresh; + } + + return { data, error }; + }; + + const getUser = async () => { + if (!accessToken.value) return null; + + const { data } = await useFetch(`${config.public.apiBase}/auth/users/me/`, { + headers: { + Authorization: `Bearer ${accessToken.value}`, + }, + }); + + return data.value; + }; + + const logout = () => { + accessToken.value = null; + refreshToken.value = null; + }; + + return { + register, + login, + socialLogin, + getUser, + logout, + accessToken, + refreshToken, + }; +}; +``` + +#### 2. Register Page: `pages/auth/register.vue` +```vue + + + +``` + +#### 3. Activation Page: `pages/auth/activate/[uid]/[token].vue` +```vue + + + +``` + +#### 4. Login Page: `pages/auth/login.vue` +```vue + + + +``` + +### Next.js 14 Example + +#### 1. Auth Context: `context/AuthContext.tsx` +```typescript +'use client'; + +import { createContext, useContext, useState, useEffect } from 'react'; + +interface User { + id: number; + email: string; + first_name: string; + last_name: string; +} + +interface AuthContextType { + user: User | null; + login: (email: string, password: string) => Promise; + logout: () => void; + register: (userData: any) => Promise; +} + +const AuthContext = createContext(undefined); + +export function AuthProvider({ children }: { children: React.ReactNode }) { + const [user, setUser] = useState(null); + const [accessToken, setAccessToken] = useState(null); + + useEffect(() => { + // Load token from localStorage + const token = localStorage.getItem('access_token'); + if (token) { + setAccessToken(token); + fetchUser(token); + } + }, []); + + const fetchUser = async (token: string) => { + try { + const response = await fetch('http://localhost:8000/api/v1/auth/users/me/', { + headers: { + 'Authorization': `Bearer ${token}`, + }, + }); + const data = await response.json(); + setUser(data); + } catch (error) { + console.error('Failed to fetch user', error); + } + }; + + const login = async (email: string, password: string) => { + const response = await fetch('http://localhost:8000/api/v1/auth/jwt/create/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email, password }), + }); + + if (!response.ok) { + throw new Error('Login failed'); + } + + const data = await response.json(); + localStorage.setItem('access_token', data.access); + localStorage.setItem('refresh_token', data.refresh); + setAccessToken(data.access); + await fetchUser(data.access); + }; + + const logout = () => { + localStorage.removeItem('access_token'); + localStorage.removeItem('refresh_token'); + setAccessToken(null); + setUser(null); + }; + + const register = async (userData: any) => { + const response = await fetch('http://localhost:8000/api/v1/auth/users/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(userData), + }); + + if (!response.ok) { + throw new Error('Registration failed'); + } + }; + + return ( + + {children} + + ); +} + +export const useAuth = () => { + const context = useContext(AuthContext); + if (context === undefined) { + throw new Error('useAuth must be used within an AuthProvider'); + } + return context; +}; +``` + +--- + +## Error Handling + +### Common Error Codes + +| Status Code | Meaning | Common Causes | +|-------------|---------|---------------| +| 400 | Bad Request | Invalid data, validation errors | +| 401 | Unauthorized | Invalid credentials, expired token | +| 403 | Forbidden | Account not activated, permission denied | +| 404 | Not Found | Endpoint doesn't exist | +| 429 | Too Many Requests | Rate limit exceeded | +| 500 | Internal Server Error | Server-side error | + +### Error Response Format +```json +{ + "detail": "Error message here", + "field_name": ["Field-specific error"] +} +``` + +### Example: Registration Validation Error +```json +{ + "email": ["A user with that email already exists."], + "password": ["This password is too common."] +} +``` + +--- + +## Testing with Postman/Insomnia + +### 1. Register +``` +POST http://localhost:8000/api/v1/auth/users/ +Content-Type: application/json + +{ + "email": "test@example.com", + "password": "TestP@ssw0rd123", + "re_password": "TestP@ssw0rd123", + "first_name": "Test", + "last_name": "User" +} +``` + +### 2. Check Email (MailPit) +Open: `http://localhost:8025` + +### 3. Activate Account +``` +POST http://localhost:8000/api/v1/auth/users/activation/ +Content-Type: application/json + +{ + "uid": "MQ", + "token": "c4h7vu-a8f3d2e1c4b5a6d7e8f9g0h1" +} +``` + +### 4. Login +``` +POST http://localhost:8000/api/v1/auth/jwt/create/ +Content-Type: application/json + +{ + "email": "test@example.com", + "password": "TestP@ssw0rd123" +} +``` + +### 5. Get User Profile +``` +GET http://localhost:8000/api/v1/auth/users/me/ +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... +``` + +--- + +## Environment Variables + +### Development (.env.dev) +```bash +DEBUG=True +SECRET_KEY=your-secret-key-here +ALLOWED_HOSTS=localhost,127.0.0.1 + +# Database +DATABASE_URL=sqlite:///db.sqlite3 + +# Email (MailPit) +EMAIL_HOST=localhost +EMAIL_PORT=1025 +EMAIL_USE_TLS=False + +# CORS +CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173 +``` + +### Production (.env.prod) +```bash +DEBUG=False +SECRET_KEY=your-production-secret-key +ALLOWED_HOSTS=yourdomain.com,api.yourdomain.com + +# Database +DATABASE_URL=postgresql://user:pass@host:5432/dbname + +# Email +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-app-password + +# Social Auth +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your-google-client-id +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your-google-client-secret +SOCIAL_AUTH_GITHUB_KEY=your-github-client-id +SOCIAL_AUTH_GITHUB_SECRET=your-github-client-secret + +# CORS +CORS_ALLOWED_ORIGINS=https://yourdomain.com +``` + +--- + +## Support + +Sorularınız için: +- GitHub Issues: [Your Repo] +- Email: support@yourdomain.com +- Documentation: [Your Docs URL] + +--- + +**Last Updated:** 2025-12-12 +**Version:** 1.0.0 + diff --git a/BACKUP_SYSTEM_GUIDE.md b/BACKUP_SYSTEM_GUIDE.md new file mode 100644 index 0000000..0f18891 --- /dev/null +++ b/BACKUP_SYSTEM_GUIDE.md @@ -0,0 +1,145 @@ +# Veritabanı Yedekleme Sistemi - Kullanım Kılavuzu + +## 🎯 Özellikler + +### 1. 🔄 Yeni Yedek Al +Admin panel listesinde üstte bulunan **"Yeni Yedek Al"** butonuna tıklayarak anında yeni bir veritabanı yedeği oluşturabilirsiniz. + +**Konum:** `/admin/backup/databasebackup/` + +**Özellikler:** +- Tek tıkla yedek oluşturma +- Otomatik dosya adlandırma (ör: `backup_server_dj_20251224_152152.sql`) +- Gerçek zamanlı durum güncellemesi +- Başarı/hata mesajları + +### 2. 📤 Yedek Yükle (YENİ!) +Elinizdeki SQL yedek dosyasını sisteme yükleyebilirsiniz. + +**Konum:** `/admin/backup/databasebackup/` - Mavi "Yedek Yükle" butonu + +**Özellikler:** +- Bilgisayarınızdan SQL dosyası yükleme +- Maksimum 500MB dosya boyutu +- Otomatik dosya validasyonu (.sql kontrolü) +- Timestamp ile dosya adlandırma +- Yüklenen dosyalar hemen kullanılabilir (geri yükleme, indirme) + +**Kullanım:** +1. "Yedek Yükle" butonuna tıklayın +2. Yedek adı girin (opsiyonel) +3. SQL dosyasını seçin +4. "Yükle" butonuna tıklayın + +### 3. 📥 Yedek İndirme + +#### Yöntem 1: İndir Butonu (Önerilen) +Liste görünümünde her yedeğin yanında yeşil **"İndir"** butonu vardır. +- Sadece tamamlanmış yedekler için görünür +- Tek tıkla indirme + +#### Yöntem 2: Admin Action +1. Listeden bir yedek seçin (checkbox) +2. Üstteki "Actions" dropdown menüsünden **"Seçili Yedeği İndir"** seçin +3. "Go" butonuna tıklayın + +#### Yöntem 3: Direkt URL +``` +/admin/backup/databasebackup/{backup_id}/download/ +``` + +### 3. 🔄 Yedek Geri Yükleme + +1. Listeden geri yüklenecek yedeği seçin +2. "Actions" dropdown → **"Seçili Yedeği Geri Yükle"** +3. "Go" butonuna tıklayın + +**⚠️ Uyarı:** Geri yükleme işlemi mevcut veritabanını değiştirecektir. Dikkatli olun! + +### 4. 🗑️ Yedek Silme + +#### Dosyaları Silme (Kayıtları Koruma) +1. Silinecek yedekleri seçin +2. "Actions" dropdown → **"Yedek Dosyalarını Sil"** +3. Veritabanı kaydı kalır ama fiziksel dosya silinir + +#### Tamamen Silme (Kayıt + Dosya) +1. Silinecek yedekleri seçin +2. "Actions" dropdown → **"Seçili veritabanı yedekleri siliniyor"** (varsayılan delete) +3. Hem kayıt hem fiziksel dosya silinir (post_delete signal sayesinde) + +## 📊 Yedek Durumları + +| Durum | Renk | Açıklama | +|-------|------|----------| +| 🟠 Bekliyor | Turuncu | Yedek oluşturulmayı bekliyor | +| 🔵 İşleniyor | Mavi | Yedek şu an oluşturuluyor | +| 🟢 Tamamlandı | Yeşil | Yedek başarıyla oluşturuldu | +| 🔴 Başarısız | Kırmızı | Yedek oluşturulurken hata oluştu | + +## 🔧 Teknik Detaylar + +### Yedek Dosyaları +- **Konum:** `/backups/` klasörü +- **Format:** SQL dump dosyası +- **Adlandırma:** `backup_server_dj_YYYYMMDD_HHMMSS.sql` + +### Otomatik Temizleme +Django'nun `post_delete` sinyali kullanılarak, veritabanı kaydı silindiğinde ilgili SQL dosyası da otomatik olarak silinir. + +### Güvenlik +- Sadece staff/admin kullanıcıları erişebilir +- Her yedek, oluşturan kullanıcı bilgisi ile birlikte kaydedilir +- Dosya boyutları otomatik hesaplanır + +## 🚀 Kullanım Senaryoları + +### Senaryo 1: Rutin Yedek Alma +1. Admin panele giriş yap +2. "Yeni Yedek Al" butonuna tıkla +3. Yedeğin tamamlanmasını bekle (sayfa otomatik yenilenir) +4. Gerekirse yedeği indir + +### Senaryo 2: Harici Yedek Yükleme (YENİ!) +1. "Yedek Yükle" butonuna tıkla +2. Bilgisayarından veya başka sunucudan aldığın SQL dosyasını seç +3. Yedek adı ver (opsiyonel) +4. Yükle +5. Yüklenen yedek artık sistemde kullanılabilir + +### Senaryo 3: Veri Geri Yükleme +1. Geri yüklenecek yedeği bul +2. Önce o yedeği indir (güvenlik için) +3. "Seçili Yedeği Geri Yükle" action'ını kullan +4. Onay mesajını bekle + +### Senaryo 4: Eski Yedekleri Temizleme +1. Silinecek yedekleri seç (çoklu seçim mümkün) +2. İki seçenek: + - Sadece dosyaları sil (kayıt kalsın) → "Yedek Dosyalarını Sil" + - Her şeyi sil → Varsayılan delete action + +## 📝 Notlar + +- Yedekler PostgreSQL için optimize edilmiştir +- Büyük veritabanları için yedekleme işlemi zaman alabilir +- Yedek dosyaları düzenli olarak kontrol edilmelidir +- Production ortamında yedekleri farklı bir sunucuya da kopyalamanız önerilir + +## 🆘 Sorun Giderme + +### Yedek Oluşturulamıyor +- PostgreSQL bağlantı ayarlarını kontrol edin +- `backups/` klasörünün yazma izinlerini kontrol edin +- Error mesajına bakın (Yedek detayında gösterilir) + +### İndirme Çalışmıyor +- Dosyanın hala diskte olduğundan emin olun +- Yedeğin durumunun "Tamamlandı" olduğunu kontrol edin +- Tarayıcı konsol hatalarına bakın + +### Geri Yükleme Başarısız +- Yedek dosyasının bozuk olmadığından emin olun +- PostgreSQL kullanıcısının yeterli yetkileri olduğunu kontrol edin +- Veritabanı bağlantısının aktif olduğunu doğrulayın + diff --git a/COOLIFY_DEPLOYMENT.md b/COOLIFY_DEPLOYMENT.md new file mode 100644 index 0000000..8d83014 --- /dev/null +++ b/COOLIFY_DEPLOYMENT.md @@ -0,0 +1,114 @@ +# Coolify Deployment Guide - Django Project + +## Deployment Yapılandırması + +### Gerekli Environment Variables (Coolify'da ayarlanmalı): +``` +SECRET_KEY=your-secret-key-here +USE_POSTGRES=1 +POSTGRES_DB=your_db_name +POSTGRES_USER=your_db_user +POSTGRES_PASSWORD=your_db_password +POSTGRES_HOST=10.80.80.50 +POSTGRES_PORT=5432 +DJANGO_ALLOWED_HOSTS=your-domain.com,www.your-domain.com +CELERY_BROKER_URL=redis://redis:6379/0 +CELERY_RESULT_BACKEND=redis://redis:6379/0 +``` + +### Docker Compose Dosyası +- **Kullanılacak Dosya**: `docker-compose.c.yml` +- **Network**: `coolify` (external) +- **Port**: 8400 (nginx) + +### Önemli Notlar + +#### 1. Nginx Configuration +- `./nginx/Dockerfile` ile custom nginx image build edilir +- `./nginx/default.conf` dosyası **build sırasında image içine COPY edilir** (mount edilmez) +- Bu sayede Coolify'da volume mount sorunları yaşanmaz +- Proxy hedefi: `django_web_prod:8000` (network alias kullanılır) + +#### 2. Network Aliases +- **web servisi**: `django_web_prod` alias'ı ile erişilebilir +- **nginx servisi**: `nginx_proxy` alias'ı ile erişilebilir +- Bu alias'lar sayesinde Coolify'ın container isimlerine zaman damgası eklemesi sorun yaratmaz + +#### 3. Volume Mounts +- `static_volume`: Django static dosyaları +- `media_volume`: Kullanıcı yüklemeleri +- Her iki volume da web, celery ve nginx servisleri arasında paylaşılır + +#### 4. Healthcheck +- Nginx için healthcheck yapılandırılmış +- 30 saniye aralıklarla kontrol yapılır +- İlk başlangıçta 40 saniye beklenir + +### Deployment Adımları (Coolify UI) + +1. **Yeni Proje Oluştur** + - Git repository URL'ini ekle + - Branch seç (main/master) + +2. **Docker Compose Ayarları** + - Compose file: `docker-compose.c.yml` seç + - Network: `coolify` (otomatik oluşturulur) + +3. **Environment Variables Ekle** + - Yukarıdaki tüm değişkenleri Coolify UI'dan ekle + - SECRET_KEY için güvenli bir anahtar oluştur + +4. **Build & Deploy** + - "Deploy" butonuna tıkla + - Build loglarını takip et + +### Sorun Giderme + +#### Problem: nginx container'da /etc/nginx/conf.d boş +**Çözüm**: +- Artık bu sorun yaşanmaz çünkü `default.conf` build sırasında image içine kopyalanır +- Eğer yine de boşsa, nginx image'ının doğru build edildiğini kontrol edin: + ```bash + docker exec ls -la /etc/nginx/conf.d/ + docker exec cat /etc/nginx/conf.d/default.conf + ``` +- Build loglarında `COPY nginx/default.conf` adımının başarılı olduğunu doğrulayın + +#### Problem: django_web_prod çözümlenemiyor +**Çözüm**: +- `docker-compose.c.yml` içinde `web` servisinin network alias'ının `django_web_prod` olduğunu kontrol edin +- Tüm servisler aynı `coolify` network'üne bağlı olmalı + +#### Problem: Static/Media dosyaları yüklenmiyor +**Çözüm**: +- Volume mount'ların doğru olduğunu kontrol edin +- Django collectstatic komutunu çalıştırın: + ```bash + docker exec python manage.py collectstatic --noinput + ``` + +### Test Komutları + +```bash +# Nginx config testi +docker exec nginx -t + +# Nginx içinden Django'ya erişim testi +docker exec wget -qO- http://django_web_prod:8000 + +# Container logları +docker logs -f + +# Network yapısını kontrol +docker network inspect coolify +``` + +### Port Mapping +- **8400**: Nginx (HTTP) +- Coolify proxy üzerinden domain'e yönlendirilecek + +### Güvenlik Notları +- DEBUG=0 production'da +- SECRET_KEY her ortam için farklı olmalı +- ALLOWED_HOSTS domain'lerinizi içermeli +- PostgreSQL credentials güvenli tutulmalı diff --git a/COOLIFY_NGINX_DEBUG.md b/COOLIFY_NGINX_DEBUG.md new file mode 100644 index 0000000..29e22cd --- /dev/null +++ b/COOLIFY_NGINX_DEBUG.md @@ -0,0 +1,311 @@ +# Nginx-Django Bağlantı Sorunu Çözümü (Coolify) + +## 🔧 Yapılan Düzeltmeler + +### 1. Docker Compose Güncellemeleri +- ✅ Nginx için `ports: - "80:80"` eklendi (Coolify proxy için gerekli) +- ✅ Network alias düzeltildi: `nginx` ve `nginx_proxy` +- ✅ Doğru network yapılandırması: `coolify` (external) + +### 2. Nginx Config Güncellemeleri +- ✅ Upstream block eklendi: `django_backend` +- ✅ İki farklı server tanımı: + - Primary: `django_web_prod:8000` (network alias) + - Backup: `web:8000` (servis adı) +- ✅ Timeout ayarları eklendi +- ✅ Connection timeout: 60s + +## 🚀 Coolify'da Deploy + +### Adım 1: Kod Değişikliklerini Push Edin +```bash +git add nginx/default.conf docker-compose.c.yml +git commit -m "Fix: Nginx-Django connection for Coolify" +git push +``` + +### Adım 2: Coolify'da Redeploy +1. Coolify dashboard → Projeniz +2. **Redeploy** butonuna tıklayın +3. Build loglarını izleyin + +## 🔍 Deploy Sonrası Test Komutları + +### 1. Container'ları Kontrol Edin +```bash +# Tüm container'ları listele +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + +# Nginx ve web container'larını bulun +docker ps | grep -E "nginx|web" +``` + +### 2. Network Bağlantısını Test Edin +```bash +# Nginx container ID'sini bulun +NGINX_ID=$(docker ps | grep nginx | awk '{print $1}') + +# Web container ID'sini bulun +WEB_ID=$(docker ps | grep "web" | grep -v nginx | awk '{print $1}') + +# Nginx'ten Django'ya DNS çözümlemesi test et +docker exec $NGINX_ID nslookup django_web_prod +docker exec $NGINX_ID nslookup web + +# Eğer nslookup yoksa: +docker exec $NGINX_ID getent hosts django_web_prod +docker exec $NGINX_ID getent hosts web +``` + +### 3. HTTP Bağlantısını Test Edin +```bash +# Nginx container'dan Django'ya wget ile test +docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 || echo "HATA: django_web_prod çözülemiyor" +docker exec $NGINX_ID wget -qO- http://web:8000 || echo "HATA: web çözülemiyor" + +# Curl kullanarak (eğer varsa) +docker exec $NGINX_ID curl -I http://django_web_prod:8000 +``` + +### 4. Nginx Config ve Loglarını Kontrol Edin +```bash +# Nginx config test +docker exec $NGINX_ID nginx -t + +# Nginx conf dosyasını görüntüle +docker exec $NGINX_ID cat /etc/nginx/conf.d/default.conf + +# Nginx error logları +docker exec $NGINX_ID cat /var/log/nginx/error.log + +# Nginx access logları +docker exec $NGINX_ID cat /var/log/nginx/access.log + +# Real-time log izleme +docker logs -f $NGINX_ID +docker logs -f $WEB_ID +``` + +### 5. Network İnceleme +```bash +# Coolify network'ünü incele +docker network inspect coolify + +# Hangi container'lar bu network'te? +docker network inspect coolify | grep -A 5 "Containers" + +# Web container'ın IP adresini bul +docker inspect $WEB_ID | grep -A 10 "Networks" | grep "IPAddress" + +# Nginx'ten web container IP'sine ping +docker exec $NGINX_ID ping -c 3 +``` + +## 🐛 Sorun Giderme + +### Problem 1: "could not resolve host: django_web_prod" +**Sebep**: Network alias çözülmüyor. + +**Çözüm**: +```bash +# docker-compose.c.yml içinde web servisinin network alias'ını kontrol edin: +cat docker-compose.c.yml | grep -A 5 "networks:" | grep -A 2 "aliases" + +# Beklenen çıktı: +# aliases: +# - django_web_prod + +# Eğer yoksa veya yanlışsa, compose dosyasını düzeltin ve redeploy edin +``` + +### Problem 2: "Connection refused" +**Sebep**: Django uygulaması çalışmıyor veya port 8000'de dinlemiyor. + +**Çözüm**: +```bash +# Web container'ın loglarını kontrol edin +docker logs $WEB_ID --tail 100 + +# Django'nun port 8000'de dinlediğini kontrol edin +docker exec $WEB_ID netstat -tuln | grep 8000 + +# Veya +docker exec $WEB_ID ss -tuln | grep 8000 + +# Web container içinden kendine bağlanmayı deneyin +docker exec $WEB_ID curl -I http://localhost:8000 +``` + +### Problem 3: "upstream timed out" +**Sebep**: Django yanıt vermesi çok uzun sürüyor. + +**Çözüm**: +```bash +# Django loglarını kontrol edin +docker logs $WEB_ID -f + +# Gunicorn worker sayısını artırın (docker-compose.c.yml): +# command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 5 + +# Nginx timeout'ları artırın (default.conf zaten 60s): +# proxy_connect_timeout 120s; +# proxy_send_timeout 120s; +# proxy_read_timeout 120s; +``` + +### Problem 4: "502 Bad Gateway" +**Sebep**: Nginx Django'ya bağlanamıyor. + +**Çözüm**: +```bash +# Tüm container'ların aynı network'te olduğunu doğrulayın +docker inspect $NGINX_ID | grep -A 10 "Networks" +docker inspect $WEB_ID | grep -A 10 "Networks" + +# Her ikisi de "coolify" network'ünde olmalı + +# Network alias'larını kontrol edin +docker network inspect coolify | jq '.[0].Containers' + +# Nginx upstream config'ini kontrol edin +docker exec $NGINX_ID cat /etc/nginx/conf.d/default.conf | grep -A 3 "upstream" +``` + +### Problem 5: Static/Media dosyaları 404 +**Sebep**: Volume mount sorunları. + +**Çözüm**: +```bash +# Nginx container içinde volume'ların mount edildiğini kontrol edin +docker exec $NGINX_ID ls -la /app/staticfiles/ +docker exec $NGINX_ID ls -la /app/media/ + +# Web container içinde static dosyaları kontrol edin +docker exec $WEB_ID ls -la /app/staticfiles/ + +# Collectstatic çalıştırın +docker exec $WEB_ID python manage.py collectstatic --noinput +``` + +## 📊 Beklenen Çıktılar + +### Başarılı DNS Çözümlemesi +```bash +$ docker exec $NGINX_ID nslookup django_web_prod +Server: 127.0.0.11 +Address: 127.0.0.11#53 + +Non-authoritative answer: +Name: django_web_prod +Address: 172.18.0.3 # IP değişebilir +``` + +### Başarılı HTTP Testi +```bash +$ docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 | head -n 5 + + +... +``` + +### Başarılı Nginx Config Test +```bash +$ docker exec $NGINX_ID nginx -t +nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +nginx: configuration file /etc/nginx/nginx.conf test is successful +``` + +## 🎯 Upstream Stratejisi + +Nginx config'de şu upstream stratejisi kullanılıyor: + +```nginx +upstream django_backend { + server django_web_prod:8000 max_fails=3 fail_timeout=30s; + server web:8000 backup; +} +``` + +**Nasıl Çalışır**: +1. İlk olarak `django_web_prod:8000` (network alias) denenir +2. Eğer 3 kez başarısız olursa, 30 saniye fail olarak işaretlenir +3. Backup olarak `web:8000` (servis adı) kullanılır +4. Bu sayede her iki DNS çözümleme yöntemi de desteklenir + +## 📝 Kontrol Listesi + +Deploy öncesi: +- [ ] `nginx/default.conf` dosyası upstream block içeriyor +- [ ] `docker-compose.c.yml` içinde nginx ports tanımı var +- [ ] `docker-compose.c.yml` içinde web servisi network alias'ı `django_web_prod` +- [ ] Her iki servis de `coolify` network'üne bağlı +- [ ] Git'e push edildi + +Deploy sonrası: +- [ ] Container'lar ayakta: `docker ps` +- [ ] DNS çözümlemesi çalışıyor: `nslookup django_web_prod` +- [ ] HTTP bağlantısı çalışıyor: `wget http://django_web_prod:8000` +- [ ] Nginx config geçerli: `nginx -t` +- [ ] Nginx loglarında hata yok +- [ ] Browser'dan site açılıyor + +## 🔗 Hızlı Debug Script + +Aşağıdaki script'i Coolify sunucusunda çalıştırarak tüm testleri yapabilirsiniz: + +```bash +#!/bin/bash +# nginx-django-debug.sh + +echo "=== CONTAINER STATUS ===" +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "nginx|web|NAME" + +NGINX_ID=$(docker ps | grep nginx | awk '{print $1}') +WEB_ID=$(docker ps | grep "web" | grep -v nginx | awk '{print $1}') + +echo -e "\n=== DNS RESOLUTION TEST ===" +echo "Testing django_web_prod:" +docker exec $NGINX_ID nslookup django_web_prod 2>&1 || echo "FAILED" +echo "Testing web:" +docker exec $NGINX_ID nslookup web 2>&1 || echo "FAILED" + +echo -e "\n=== HTTP CONNECTION TEST ===" +echo "Testing http://django_web_prod:8000:" +docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 2>&1 | head -n 3 +echo "Testing http://web:8000:" +docker exec $NGINX_ID wget -qO- http://web:8000 2>&1 | head -n 3 + +echo -e "\n=== NGINX CONFIG TEST ===" +docker exec $NGINX_ID nginx -t + +echo -e "\n=== NGINX ERROR LOG (last 10 lines) ===" +docker exec $NGINX_ID tail -n 10 /var/log/nginx/error.log 2>&1 || echo "No errors" + +echo -e "\n=== WEB CONTAINER LOG (last 10 lines) ===" +docker logs $WEB_ID --tail 10 + +echo -e "\n=== NETWORK INFO ===" +docker network inspect coolify | grep -A 20 "Containers" + +echo -e "\n=== DONE ===" +``` + +Kullanım: +```bash +chmod +x nginx-django-debug.sh +./nginx-django-debug.sh +``` + +## ✅ Başarı Kriterleri + +Eğer aşağıdakiler çalışıyorsa, sorun çözülmüştür: + +1. ✅ `docker ps` ile nginx ve web container'ları görünüyor +2. ✅ `docker exec nslookup django_web_prod` çalışıyor +3. ✅ `docker exec wget -qO- http://django_web_prod:8000` HTML dönüyor +4. ✅ `docker exec nginx -t` başarılı +5. ✅ Browser'dan Coolify domain'e girdiğinizde Django uygulaması açılıyor + +--- +**Son Güncelleme**: 29 Ocak 2026 +**Durum**: Nginx upstream stratejisi eklendi, Coolify uyumlu diff --git a/COOLIFY_NO_PORT_MAPPING.md b/COOLIFY_NO_PORT_MAPPING.md new file mode 100644 index 0000000..f02a773 --- /dev/null +++ b/COOLIFY_NO_PORT_MAPPING.md @@ -0,0 +1,254 @@ +# ✅ Coolify Deployment - Doğru Yapılandırma + +## 🎯 Önemli: Port Mapping Yok! + +Coolify kendi reverse proxy'sini kullanır, bu yüzden: +- ❌ **`ports: - "80:80"` kullanmayın** (conflict yaratır) +- ✅ **Sadece `expose: - 80`** kullanın (internal) +- ✅ **Coolify labels eklenmeli** (Coolify'ın nginx'i bulması için) + +## 📋 Güncel Yapılandırma + +### docker-compose.c.yml (nginx servisi) +```yaml +nginx: + build: + context: . + dockerfile: ./nginx/Dockerfile + expose: + - 80 # ✅ Internal port (Coolify için) + networks: + coolify: + aliases: + - nginx + - nginx_proxy + labels: + - "coolify.managed=true" # ✅ Coolify tarafından yönetiliyor + - "coolify.http.port=80" # ✅ Coolify'a hangi port dinlediğini söyler +``` + +## 🔄 Coolify Proxy Akışı + +``` +Internet + ↓ +Coolify Reverse Proxy (Caddy/Traefik) + ↓ +[your-domain.com] + ↓ +Internal: nginx:80 (exposed, not published) + ↓ +Internal: django_web_prod:8000 + ↓ +Django App +``` + +## 🚀 Deploy Adımları + +### 1. Git Push +```bash +git add docker-compose.c.yml +git commit -m "Fix: Remove port mapping for Coolify proxy" +git push +``` + +### 2. Coolify Dashboard +1. Projenize gidin +2. **Settings** → **General** +3. **Port** kısmında `80` olduğunu doğrulayın +4. **Redeploy** butonuna tıklayın + +### 3. Domain Ayarları +Coolify'da: +- **Domains** sekmesinde domain'inizi ekleyin +- Coolify otomatik olarak SSL sertifikası alacak (Let's Encrypt) +- Coolify proxy'si nginx container'ın 80 portuna yönlendirecek + +## 🔍 Test Komutları + +Deploy sonrası Coolify sunucusunda: + +```bash +# Container'ları kontrol edin +docker ps | grep -E "nginx|web" + +# Nginx container ID +NGINX_ID=$(docker ps | grep nginx | head -1 | awk '{print $1}') + +# Internal DNS testi (nginx container içinden) +docker exec $NGINX_ID nslookup django_web_prod + +# Internal HTTP testi +docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 | head + +# Nginx config doğrulama +docker exec $NGINX_ID nginx -t + +# Nginx logları +docker logs $NGINX_ID --tail 50 + +# Coolify network kontrolü +docker network inspect coolify | grep -A 5 "nginx" +``` + +## ✅ Başarı Kriterleri + +- [ ] `docker ps` - Nginx container çalışıyor, **port mapping YOK** (80/tcp yazıyor ama 0.0.0.0:80->80/tcp yazmıyor) +- [ ] Internal DNS - `docker exec $NGINX_ID nslookup django_web_prod` çalışıyor +- [ ] Internal HTTP - `docker exec $NGINX_ID wget http://django_web_prod:8000` çalışıyor +- [ ] Nginx config - `docker exec $NGINX_ID nginx -t` başarılı +- [ ] **Browser** - Coolify domain'den (örn: https://yourdomain.com) site açılıyor +- [ ] **SSL** - Coolify otomatik HTTPS yönlendirmesi çalışıyor + +## 📊 Beklenen `docker ps` Çıktısı + +```bash +CONTAINER ID IMAGE PORTS NAMES +abc123 nginx:alpine 80/tcp django_nginx # ✅ Doğru (exposed) +def456 python:3.14 8000/tcp django_web_prod # ✅ Doğru (exposed) + +# ❌ YANLIŞ olacak: +# 0.0.0.0:80->80/tcp # Bu Coolify ile conflict yaratır +``` + +Port sütununda sadece `80/tcp` görünmeli, `0.0.0.0:80->80/tcp` **görünmemeli**. + +## 🐛 Sorun Giderme + +### Problem: "Port 80 already in use" +**Sebep**: `ports:` tanımı hala var. + +**Çözüm**: +```yaml +# ❌ YANLIŞ +nginx: + ports: + - "80:80" + +# ✅ DOĞRU +nginx: + expose: + - 80 +``` + +### Problem: "502 Bad Gateway" (Coolify domain'den) +**Sebep**: Coolify nginx container'ı bulamıyor. + +**Çözüm**: +```bash +# Labels kontrolü +docker inspect $(docker ps | grep nginx | awk '{print $1}') | grep -A 5 "Labels" + +# Beklenen: +# "coolify.managed": "true" +# "coolify.http.port": "80" + +# Eğer yoksa docker-compose.c.yml'e ekleyin ve redeploy edin +``` + +### Problem: Nginx Django'ya bağlanamıyor +**Sebep**: Network alias veya DNS problemi. + +**Çözüm**: +```bash +# Web container'ın network alias'ını kontrol edin +docker inspect $(docker ps | grep "web" | grep -v nginx | awk '{print $1}') | grep -A 10 "Aliases" + +# Beklenen: "django_web_prod" görünmeli + +# Eğer yoksa docker-compose.c.yml içinde web servisine ekleyin: +services: + web: + networks: + coolify: + aliases: + - django_web_prod +``` + +### Problem: Static/Media dosyaları yüklenmiyor +**Sebep**: Volume mount veya nginx config. + +**Çözüm**: +```bash +# Volume kontrolü +docker exec $NGINX_ID ls -la /app/staticfiles/ +docker exec $NGINX_ID ls -la /app/media/ + +# Eğer boşsa: +WEB_ID=$(docker ps | grep "web" | grep -v nginx | awk '{print $1}') +docker exec $WEB_ID python manage.py collectstatic --noinput + +# Nginx config kontrolü +docker exec $NGINX_ID cat /etc/nginx/conf.d/default.conf | grep -A 3 "location /static" +``` + +## 🎯 Coolify'a Özel Notlar + +### 1. Port Exposure +- Coolify container'ların **exposed** portlarını otomatik keşfeder +- `expose: - 80` yeterli, `ports:` gereksiz ve zararlı + +### 2. Labels +```yaml +labels: + - "coolify.managed=true" # Coolify'ın yönetiminde + - "coolify.http.port=80" # HTTP trafiği için port + # - "coolify.https.port=443" # Eğer internal HTTPS varsa (şu an gerekli değil) +``` + +### 3. Network +```yaml +networks: + coolify: + external: true # Coolify tarafından oluşturulan network +``` + +### 4. Domain Routing +Coolify dashboard: +- **Domains** → Domain ekleyin (örn: `example.com`, `www.example.com`) +- **HTTPS** → Otomatik Let's Encrypt (default açık) +- **Redirect** → HTTP → HTTPS yönlendirme (önerilir) + +### 5. Health Check +Coolify nginx'in sağlık durumunu kontrol eder: +- Dockerfile içindeki `HEALTHCHECK` direktifi kullanılır +- Eğer container unhealthy olursa otomatik restart edilir + +## 📝 Checklist - Coolify Deploy + +Öncesi: +- [ ] `ports:` tanımı **yok**, sadece `expose:` var +- [ ] Coolify labels eklenmiş +- [ ] Network `coolify` ve `external: true` +- [ ] `nginx/default.conf` upstream stratejisi var +- [ ] Git'e push edildi + +Sonrası (Coolify Dashboard): +- [ ] Build başarılı +- [ ] Container başlatıldı +- [ ] Health check geçti +- [ ] Domain'e HTTPS ile erişim var +- [ ] Static/Media dosyaları yükleniyor + +Sonrası (Terminal): +- [ ] `docker ps` - Nginx container çalışıyor (80/tcp) +- [ ] `docker exec ... nslookup django_web_prod` - Başarılı +- [ ] `docker exec ... wget http://django_web_prod:8000` - Django yanıtlıyor +- [ ] `docker exec ... nginx -t` - Config geçerli +- [ ] Nginx error.log temiz + +## 🌐 Production Checklist + +- [ ] **SSL**: Let's Encrypt sertifikası aktif +- [ ] **Redirect**: HTTP → HTTPS yönlendirme aktif +- [ ] **Static**: CSS/JS dosyaları yükleniyor +- [ ] **Media**: Kullanıcı yüklemeleri çalışıyor +- [ ] **Admin**: `/admin` paneli açılıyor +- [ ] **API**: API endpoint'leri yanıt veriyor +- [ ] **Logs**: Hata logları temiz +- [ ] **Monitoring**: Coolify metrics'te trafik görünüyor + +--- +**Oluşturulma**: 29 Ocak 2026 +**Coolify Versiyonu**: v4.x +**Durum**: ✅ Production Ready diff --git a/COPILOT_MEMORY.md b/COPILOT_MEMORY.md new file mode 100644 index 0000000..725e3d3 --- /dev/null +++ b/COPILOT_MEMORY.md @@ -0,0 +1,194 @@ +# Copilot Memory - Django Auth System Development + +Bu dosya, Django 6.0 projemizde Custom User + Djoser + JWT + Social Auth sisteminin geliştirilme sürecini takip eder. + +--- + +## 2025-12-12T21:35:00Z + +### ✅ Değişiklik Özeti: İlk Kurulum - Custom User Model ve Auth Sistemi Temeli + +**Tamamlanan İşler:** + +1. **Custom User Model Oluşturuldu** (`accounts/models.py`) + - `CustomUser` modeli: Email tabanlı authentication (username yok) + - `CustomUserManager`: `create_user` ve `create_superuser` metodları + - Alanlar: `email` (unique), `first_name`, `last_name`, `is_staff`, `is_active`, `date_joined` + - `USERNAME_FIELD = "email"` + +2. **Admin Panel Konfigürasyonu** (`accounts/admin.py`) + - `CustomUserAdmin` sınıfı ile Django admin'de custom user yönetimi + - List display, filters, search fields yapılandırıldı + +3. **Serializers Oluşturuldu** (`accounts/serializers.py`) + - `CustomUserCreateSerializer`: Register için, `is_active=False` set eder + - `CustomUserSerializer`: User profil bilgileri için + - `SocialLoginSerializer`: Social auth için provider + access_token + +4. **Social Auth Pipeline** (`accounts/pipeline.py`) + - `activate_user` fonksiyonu: Social login ile gelen kullanıcıları otomatik aktif eder + - Normal register: `is_active=False` (email aktivasyon gerekli) + - Social register: `is_active=True` (direkt aktif) + +5. **Social Login View** (`accounts/views.py`) + - `SocialLoginView`: Provider token'ı doğrular, user oluşturur/bulur, JWT döner + - Desteklenen provider'lar: google-oauth2, github, facebook + - Error handling: AuthForbidden, AuthException, genel hatalar + +6. **Settings.py Tam Konfigürasyonu** (`core/settings.py`) + - `AUTH_USER_MODEL = 'accounts.CustomUser'` + - `INSTALLED_APPS`: rest_framework, rest_framework_simplejwt, djoser, corsheaders, social_django, accounts + - **REST_FRAMEWORK**: JWT authentication, throttling (100/hour anon, 1000/hour user) + - **SIMPLE_JWT**: 60 min access, 7 days refresh, token rotation, blacklist + - **DJOSER**: Email activation, custom serializers, password reset + - **EMAIL**: MailPit (localhost:1025) dev için, production için SMTP placeholder + - **CORS**: localhost:3000, 5173, 8080 (Nuxt/Next/Vue için) + - **SOCIAL_AUTH**: Google, GitHub, Facebook backends + custom pipeline + +7. **Email Templates Oluşturuldu** (`templates/email/`) + - `activation_email.html` / `.txt`: Hesap aktivasyon emaili + - `confirmation_email.html` / `.txt`: Aktivasyon başarılı emaili + - `password_reset_email.html` / `.txt`: Şifre sıfırlama emaili + - Modern, responsive HTML tasarım + plain text alternatifi + +8. **URL Routing** (`accounts/urls.py`) + - Djoser endpoints: `/api/v1/auth/users/` (register), `/api/v1/auth/users/activation/` (activate) + - JWT endpoints: `/api/v1/auth/jwt/create/` (login), `/api/v1/auth/jwt/refresh/` + - Social auth: `/api/v1/auth/social//` + - Python Social Auth URLs: `/api/v1/social/` + +9. **Database Migrations** + - `accounts/migrations/0001_initial.py`: CustomUser model + - `social_django` migrations: Social auth tabloları + - Tüm migration'lar başarıyla uygulandı (migrate completed) + +### 📁 Değiştirilen/Oluşturulan Dosyalar: +- `accounts/models.py` (yeni) +- `accounts/admin.py` (güncellendi) +- `accounts/serializers.py` (yeni) +- `accounts/pipeline.py` (yeni) +- `accounts/views.py` (güncellendi) +- `accounts/urls.py` (güncellendi) +- `accounts/migrations/0001_initial.py` (oluşturuldu) +- `core/settings.py` (kapsamlı güncelleme) +- `templates/email/activation_email.html` (yeni) +- `templates/email/activation_email.txt` (yeni) +- `templates/email/confirmation_email.html` (yeni) +- `templates/email/confirmation_email.txt` (yeni) +- `templates/email/password_reset_email.html` (yeni) +- `templates/email/password_reset_email.txt` (yeni) + +### 🎯 Sistem Özellikleri: + +**Authentication Akışları:** + +1. **Normal Register (Email/Password):** + ``` + POST /api/v1/auth/users/ + Body: { "email", "password", "re_password", "first_name", "last_name" } + → User oluşturulur (is_active=False) + → Aktivasyon emaili gönderilir + → POST /api/v1/auth/users/activation/ { "uid", "token" } + → is_active=True olur + → POST /api/v1/auth/jwt/create/ { "email", "password" } + → JWT tokens alınır + ``` + +2. **Social Login:** + ``` + POST /api/v1/auth/social/google-oauth2/ + Body: { "access_token": "..." } + → Provider'dan user bilgisi alınır + → User bulunur/oluşturulur (is_active=True) + → JWT tokens direkt döner + ``` + +3. **Login:** + ``` + POST /api/v1/auth/jwt/create/ + Body: { "email", "password" } + → Access + Refresh token döner + ``` + +4. **Token Refresh:** + ``` + POST /api/v1/auth/jwt/refresh/ + Body: { "refresh": "..." } + → Yeni access token döner + ``` + +### ⚙️ Yapılandırma Gereksinimleri: + +**Environment Variables (Production için):** +```bash +# Email +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-app-password +DEFAULT_FROM_EMAIL=noreply@yourdomain.com + +# Social Auth - Google +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your-google-client-id +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your-google-client-secret + +# Social Auth - GitHub +SOCIAL_AUTH_GITHUB_KEY=your-github-client-id +SOCIAL_AUTH_GITHUB_SECRET=your-github-client-secret + +# Social Auth - Facebook +SOCIAL_AUTH_FACEBOOK_KEY=your-facebook-app-id +SOCIAL_AUTH_FACEBOOK_SECRET=your-facebook-app-secret +``` + +**Development Tools:** +- MailPit: `localhost:1025` (SMTP), `localhost:8025` (Web UI) +- Database: SQLite (db.sqlite3) + +### 📝 Next Steps: + +1. **Testing (Yüksek Öncelik):** + - [ ] Unit tests: Register → is_active=False check + - [ ] Unit tests: Activation → is_active=True check + - [ ] Unit tests: Login → aktif/inaktif user scenarios + - [ ] Unit tests: Social login → user creation + JWT response + - [ ] Integration tests: Full auth flow + +2. **Dokümantasyon:** + - [ ] `AUTH.md` oluştur: Tüm endpoint'ler, request/response örnekleri + - [ ] Frontend entegrasyon kılavuzu (Nuxt.js + Next.js) + - [ ] Environment variables dokümantasyonu + - [ ] Deployment checklist + +3. **İyileştirmeler:** + - [ ] Rate limiting test et + - [ ] Email template'lerini test et (MailPit ile) + - [ ] Social auth provider'ları test et + - [ ] Error mesajlarını frontend-friendly hale getir + - [ ] Logging ekle (özellikle auth failures için) + +4. **Güvenlik:** + - [ ] HTTPS için production settings + - [ ] CSRF token stratejisi netleştir + - [ ] JWT secret key'i environment variable'a taşı + - [ ] Rate limiting değerlerini production için ayarla + +5. **Opsiyonel Özellikler:** + - [ ] Email değiştirme flow'u + - [ ] 2FA (Two-Factor Authentication) + - [ ] Remember me functionality + - [ ] Account deletion + - [ ] Social account linking (birden fazla provider) + +### 🐛 Bilinen Sorunlar: +- Yok (şu an için) + +### 📚 Referanslar: +- Djoser Docs: https://djoser.readthedocs.io/ +- SimpleJWT Docs: https://django-rest-framework-simplejwt.readthedocs.io/ +- Python Social Auth: https://python-social-auth.readthedocs.io/ +- Django REST Framework: https://www.django-rest-framework.org/ + +--- + diff --git a/DOCKER_README.md b/DOCKER_README.md new file mode 100644 index 0000000..e9c8ab1 --- /dev/null +++ b/DOCKER_README.md @@ -0,0 +1,207 @@ +# Django Projesi - Docker Kurulum Rehberi + +Bu Django projesi Python 3.14.2 ile dockerize edilmiştir. + +## 📋 Gereksinimler + +- Docker +- Docker Compose + +## 🚀 Hızlı Başlangıç + +### Geliştirme Ortamı (Development) + +1. **Projeyi klonlayın ve dizine girin:** +```bash +cd /path/to/project +``` + +2. **Docker container'ları başlatın:** +```bash +docker-compose up --build +``` + +3. **Tarayıcınızda açın:** +``` +http://localhost:8000 +``` + +### Production Ortamı + +1. **Environment dosyasını oluşturun:** +```bash +cp .env.example .env +# .env dosyasını düzenleyin ve gerçek değerleri girin +``` + +2. **Production container'ları başlatın:** +```bash +docker-compose -f docker-compose.prod.yml up --build -d +``` + +3. **Nginx üzerinden erişin:** +``` +http://localhost +``` + +## 🛠️ Yararlı Komutlar + +### Container'ları Başlatma +```bash +# Geliştirme +docker-compose up + +# Production +docker-compose -f docker-compose.prod.yml up -d + +# Rebuild ile başlatma +docker-compose up --build +``` + +### Container'ları Durdurma +```bash +docker-compose down + +# Volume'leri de silmek için +docker-compose down -v +``` + +### Django Komutları Çalıştırma +```bash +# Migration oluşturma +docker-compose exec web python manage.py makemigrations + +# Migration uygulama +docker-compose exec web python manage.py migrate + +# Superuser oluşturma +docker-compose exec web python manage.py createsuperuser + +# Shell açma +docker-compose exec web python manage.py shell + +# Static dosyaları toplama +docker-compose exec web python manage.py collectstatic +``` + +### Logları Görüntüleme +```bash +# Tüm servislerin logları +docker-compose logs -f + +# Sadece web servisinin logları +docker-compose logs -f web + +# Sadece database logları +docker-compose logs -f db +``` + +### Container'a Bağlanma +```bash +# Web container'a bash ile bağlan +docker-compose exec web bash + +# Database container'a bağlan +docker-compose exec db psql -U server_dj -d server_dj +``` + +## 📁 Proje Yapısı + +``` +. +├── Dockerfile # Ana Docker image tanımı +├── docker-compose.yml # Geliştirme ortamı yapılandırması +├── docker-compose.prod.yml # Production ortamı yapılandırması +├── entrypoint.sh # Container başlatma scripti +├── nginx.conf # Nginx yapılandırması (production) +├── .dockerignore # Docker'a dahil edilmeyecek dosyalar +├── .env.example # Environment değişkenleri şablonu +└── requirements.txt # Python bağımlılıkları +``` + +## 🔧 Konfigürasyon + +### Environment Değişkenleri + +`.env` dosyasında aşağıdaki değişkenleri ayarlayabilirsiniz: + +- `DEBUG`: Debug modu (0 veya 1) +- `SECRET_KEY`: Django secret key +- `DJANGO_ALLOWED_HOSTS`: İzin verilen host'lar +- `POSTGRES_DB`: PostgreSQL veritabanı adı +- `POSTGRES_USER`: PostgreSQL kullanıcı adı +- `POSTGRES_PASSWORD`: PostgreSQL şifresi + +### Veritabanı + +Proje hem SQLite hem de PostgreSQL destekler: + +- **Development**: SQLite (varsayılan) +- **Production**: PostgreSQL (docker-compose ile) + +### Static ve Media Dosyaları + +- Static dosyalar: `/app/staticfiles` +- Media dosyaları: `/app/media` +- Her ikisi de Docker volume'lerinde saklanır + +## 🔐 Güvenlik + +Production ortamında: + +1. `.env` dosyasındaki tüm varsayılan şifreleri değiştirin +2. `SECRET_KEY` için güçlü bir değer kullanın +3. `DEBUG=0` olarak ayarlayın +4. `ALLOWED_HOSTS` değerini doğru domain ile güncelleyin +5. SSL sertifikası ekleyin (nginx yapılandırmasına) + +## 📊 Veritabanı Yedekleme + +### PostgreSQL Backup +```bash +# Backup alma +docker-compose exec db pg_dump -U server_dj server_dj > backup.sql + +# Backup geri yükleme +docker-compose exec -T db psql -U server_dj server_dj < backup.sql +``` + +## 🐛 Sorun Giderme + +### Port zaten kullanımda +```bash +# Port 8000'i kullanan process'i bul +lsof -i :8000 + +# Veya farklı port kullan +# docker-compose.yml'de ports kısmını değiştirin +``` + +### Container başlamıyor +```bash +# Logları kontrol et +docker-compose logs web + +# Container'ları temizle ve yeniden başlat +docker-compose down -v +docker-compose up --build +``` + +### Static dosyalar yüklenmiyor +```bash +# Static dosyaları yeniden topla +docker-compose exec web python manage.py collectstatic --noinput --clear +``` + +## 📝 Notlar + +- İlk çalıştırmada `entrypoint.sh` otomatik olarak: + - Database migration'larını uygular + - Admin kullanıcısı oluşturur (admin/admin) + - Static dosyaları toplar + +- Development ortamında kod değişiklikleri otomatik olarak yansır (volume mount sayesinde) + +## 📞 Destek + +Herhangi bir sorun için issue açabilirsiniz. diff --git a/DOCKER_WITH_EXISTING_POSTGRES.md b/DOCKER_WITH_EXISTING_POSTGRES.md new file mode 100644 index 0000000..e960738 --- /dev/null +++ b/DOCKER_WITH_EXISTING_POSTGRES.md @@ -0,0 +1,135 @@ +# Django Projesi - Docker ile Mevcut PostgreSQL Kullanımı + +✅ **Projeniz başarıyla dockerize edildi ve çalışıyor!** + +Bu yapılandırma, mevcut PostgreSQL sunucunuzu (10.80.80.50:5432) kullanarak Django projenizi Docker'da çalıştırır. + +## 🎉 Test Edildi ve Çalışıyor + +Server `http://localhost:8000` adresinde çalışıyor! + +**Oluşturulan Admin Kullanıcısı:** +- Email: `admin@example.com` +- Şifre: `admin` + +## ✅ Yapılan Değişiklikler + +1. **PostgreSQL Container'ı kaldırıldı** - Mevcut sunucunuz kullanılacak +2. **[settings.py](core/settings.py)** - Environment değişkenleri ile PostgreSQL yapılandırması +3. **[docker-compose.yml](docker-compose.yml)** - Sadece web servisi (mevcut PostgreSQL'e bağlanır) +4. **[docker-compose.prod.yml](docker-compose.prod.yml)** - Production yapılandırması güncellendi +5. **[entrypoint.sh](entrypoint.sh)** - PostgreSQL bekleme kodu kaldırıldı + +## 🚀 Kullanım + +### Geliştirme Ortamı + +```bash +# Docker container'ı başlat +docker-compose up --build + +# Tarayıcıda aç +# http://localhost:8000 +``` + +Container otomatik olarak 10.80.80.50:5432 adresindeki PostgreSQL sunucunuza bağlanacak. + +### Production Ortamı + +```bash +# .env dosyasını oluştur +cp .env.example .env + +# .env dosyasını düzenle (gerekirse PostgreSQL bilgilerini güncelle) + +# Production container'ları başlat +docker-compose -f docker-compose.prod.yml up -d +``` + +## 🔧 PostgreSQL Bağlantı Ayarları + +Docker container'ınız şu ayarlarla PostgreSQL'e bağlanır: + +``` +Host: 10.80.80.50 +Port: 5432 +Database: server_dj +User: server_dj +Password: 1234 +``` + +Bu ayarları değiştirmek için: + +**Geliştirme:** [docker-compose.yml](docker-compose.yml) içindeki environment değişkenlerini düzenleyin + +**Production:** `.env` dosyasını düzenleyin + +### SQLite Kullanmak İsterseniz + +```bash +# docker-compose.yml içinde USE_POSTGRES değişkenini değiştirin: +- USE_POSTGRES=False +``` + +## 📋 Yararlı Komutlar + +```bash +# Migration uygula +docker-compose exec web python manage.py migrate + +# Superuser oluştur +docker-compose exec web python manage.py createsuperuser + +# Shell aç +docker-compose exec web python manage.py shell + +# Logları görüntüle +docker-compose logs -f web + +# Container'ı durdur +docker-compose down +``` + +## 🔍 Sorun Giderme + +### PostgreSQL'e bağlanamıyorum + +1. PostgreSQL sunucusunun çalıştığından emin olun +2. Docker container'ından 10.80.80.50:5432 adresine erişilebildiğini kontrol edin: + +```bash +docker-compose exec web bash +apt-get update && apt-get install -y postgresql-client +psql -h 10.80.80.50 -U server_dj -d server_dj +``` + +### Mac'te Docker Network Sorunu + +Mac'te Docker Desktop kullanıyorsanız ve localhost PostgreSQL'e bağlanamıyorsanız: + +[docker-compose.yml](docker-compose.yml) içinde: +```yaml +environment: + - POSTGRES_HOST=host.docker.internal # 10.80.80.50 yerine +``` + +## 📁 Dosya Yapısı + +``` +. +├── Dockerfile # Django container image +├── docker-compose.yml # Geliştirme (mevcut PostgreSQL kullanır) +├── docker-compose.prod.yml # Production (mevcut PostgreSQL kullanır) +├── entrypoint.sh # Container başlatma scripti +├── nginx.conf # Nginx config (production) +├── .env.example # Environment değişkenleri +└── core/ + └── settings.py # PostgreSQL ayarları (env değişkenlerinden) +``` + +## ℹ️ Notlar + +- Container içinden `10.80.80.50` adresine erişmek için ağ yapılandırmanızın buna izin vermesi gerekir +- Production ortamında `.env` dosyasındaki şifreleri mutlaka değiştirin +- İlk çalıştırmada migrations otomatik uygulanır +- Static dosyalar otomatik toplanır diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..471b386 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +# Python 3.14.2 base image kullan +FROM python:3.14.2-slim + +# Çalışma ortamı değişkenlerini ayarla +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# Çalışma dizinini oluştur +WORKDIR /app + +# Sistem bağımlılıklarını yükle (PostgreSQL ve diğer gerekli paketler için) +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + postgresql-client \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +# Python bağımlılıklarını kopyala ve yükle +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Proje dosyalarını kopyala +COPY . . + +# Static dosyaları topla +RUN python manage.py collectstatic --noinput --clear || true + +# Media ve staticfiles dizinlerini oluştur +RUN mkdir -p /app/media /app/staticfiles + +# Port 8000'i aç +EXPOSE 8000 + +# Entrypoint scriptini çalıştırılabilir yap +RUN chmod +x /app/entrypoint.sh || true + +# Entrypoint ve varsayılan komut +ENTRYPOINT ["/app/entrypoint.sh"] +CMD ["gunicorn", "core.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"] diff --git a/FRONTEND_INTEGRATION.md b/FRONTEND_INTEGRATION.md new file mode 100644 index 0000000..78c518f --- /dev/null +++ b/FRONTEND_INTEGRATION.md @@ -0,0 +1,475 @@ +# Frontend Integration Guide (Nuxt.js / Next.js) + +## 🎯 Architecture + +``` +Frontend (Nuxt/Next.js) Backend (Django) +Port: 3000 Port: 8000 +├── Pages/Routes ├── API Endpoints +├── UI/UX ├── Authentication +├── API Calls ├── Database +└── Token Storage └── Business Logic +``` + +--- + +## 📧 Email Links Flow + +### How It Works: + +1. **User registers** → Backend sends email +2. **Email contains** → Frontend URL (http://localhost:3000/activate/...) +3. **User clicks link** → Opens Frontend page +4. **Frontend JavaScript** → Calls Backend API +5. **Backend** → Activates account, returns response +6. **Frontend** → Shows success message + +### Email Link Format: + +``` +Activation: http://localhost:3000/activate/{uid}/{token}/ +Password Reset: http://localhost:3000/password-reset/{uid}/{token}/ +``` + +--- + +## 🚀 Nuxt.js Implementation + +### 1. Environment Variables (`.env`) + +```bash +# Nuxt.js .env +NUXT_PUBLIC_API_BASE=http://localhost:8000/api/v1 +``` + +### 2. Nuxt Config (`nuxt.config.ts`) + +```typescript +export default defineNuxtConfig({ + runtimeConfig: { + public: { + apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://localhost:8000/api/v1' + } + }, + + // CORS configuration for development + nitro: { + devProxy: { + '/api': { + target: 'http://localhost:8000', + changeOrigin: true + } + } + } +}) +``` + +### 3. API Composable (`composables/useApi.ts`) + +```typescript +export const useApi = () => { + const config = useRuntimeConfig() + const apiBase = config.public.apiBase + + return { + apiBase, + + async fetch(endpoint: string, options: any = {}) { + return await $fetch(`${apiBase}${endpoint}`, options) + } + } +} +``` + +### 4. Auth Composable (`composables/useAuth.ts`) + +```typescript +export const useAuth = () => { + const { apiBase } = useApi() + const router = useRouter() + + // Register + const register = async (userData: { + email: string + password: string + re_password: string + first_name: string + last_name: string + }) => { + return await $fetch(`${apiBase}/auth/users/`, { + method: 'POST', + body: userData + }) + } + + // Activate Account + const activate = async (uid: string, token: string) => { + return await $fetch(`${apiBase}/auth/users/activation/`, { + method: 'POST', + body: { uid, token } + }) + } + + // Login + const login = async (email: string, password: string) => { + const data = await $fetch(`${apiBase}/auth/jwt/create/`, { + method: 'POST', + body: { email, password } + }) + + // Save tokens + localStorage.setItem('access_token', data.access) + localStorage.setItem('refresh_token', data.refresh) + + return data + } + + // Social Login + const socialLogin = async (provider: string, accessToken: string) => { + const data = await $fetch(`${apiBase}/auth/social/${provider}/`, { + method: 'POST', + body: { access_token: accessToken } + }) + + // Save JWT tokens + localStorage.setItem('access_token', data.access) + localStorage.setItem('refresh_token', data.refresh) + + return data + } + + // Get Current User + const getUser = async () => { + const token = localStorage.getItem('access_token') + if (!token) return null + + return await $fetch(`${apiBase}/auth/users/me/`, { + headers: { + Authorization: `Bearer ${token}` + } + }) + } + + // Logout + const logout = () => { + localStorage.removeItem('access_token') + localStorage.removeItem('refresh_token') + router.push('/login') + } + + return { + register, + activate, + login, + socialLogin, + getUser, + logout + } +} +``` + +### 5. Activation Page (`pages/activate/[uid]/[token].vue`) + +```vue + + + + + +``` + +### 6. Register Page (`pages/register.vue`) + +```vue + + + +``` + +### 7. Login Page (`pages/login.vue`) + +```vue + + + +``` + +--- + +## 🔐 Protected Pages (Middleware) + +### Auth Middleware (`middleware/auth.ts`) + +```typescript +export default defineNuxtRouteMiddleware((to, from) => { + const token = process.client ? localStorage.getItem('access_token') : null + + if (!token) { + return navigateTo('/login') + } +}) +``` + +### Dashboard Page (`pages/dashboard.vue`) + +```vue + + + +``` + +--- + +## 🌐 Next.js Implementation + +Very similar to Nuxt.js, just adjust the syntax: + +```typescript +// app/activate/[uid]/[token]/page.tsx +'use client' + +import { useEffect, useState } from 'react' +import { useParams, useRouter } from 'next/navigation' + +export default function ActivatePage() { + const params = useParams() + const [loading, setLoading] = useState(true) + const [success, setSuccess] = useState(false) + const [error, setError] = useState('') + + useEffect(() => { + const activate = async () => { + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_BASE}/auth/users/activation/`, + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + uid: params.uid, + token: params.token + }) + } + ) + + if (response.ok) { + setSuccess(true) + } else { + const data = await response.json() + setError(data.detail || 'Activation failed') + } + } catch (e) { + setError('Network error') + } finally { + setLoading(false) + } + } + + activate() + }, [params]) + + if (loading) return
Activating...
+ if (success) return
✅ Account Activated!
+ return
❌ {error}
+} +``` + +--- + +## 📝 Summary + +### Email Links: +- Activation: `http://localhost:3000/activate/{uid}/{token}/` +- Password Reset: `http://localhost:3000/password-reset/{uid}/{token}/` + +### API Endpoints (Backend): +- Register: `POST http://localhost:8000/api/v1/auth/users/` +- Activate: `POST http://localhost:8000/api/v1/auth/users/activation/` +- Login: `POST http://localhost:8000/api/v1/auth/jwt/create/` +- Social Login: `POST http://localhost:8000/api/v1/auth/social/{provider}/` +- Current User: `GET http://localhost:8000/api/v1/auth/users/me/` + +### Production URLs: +- Frontend: `https://yourdomain.com` +- Backend: `https://api.yourdomain.com` + +Update `DOMAIN` in Django settings for production! + +--- + +**Happy Coding! 🚀** + diff --git a/IMAGE_API_DOCS.md b/IMAGE_API_DOCS.md new file mode 100644 index 0000000..ab05169 --- /dev/null +++ b/IMAGE_API_DOCS.md @@ -0,0 +1,89 @@ +# Resim API Endpoint'leri ve Dosya Yönetimi Dokümantasyonu + +Bu belge, Django projenize eklenen yeni resim API endpoint'lerini ve ilgili dosya yönetimi özelliklerini açıklamaktadır. + +--- + +## 1. Resim Yükleme ve Optimizasyon API Endpoint'i + +Bu endpoint, resimleri yüklemenizi, boyutlandırmanızı, formatlarını değiştirmenizi ve kalitelerini ayarlamanızı sağlar. Yüklenen resimler en-boy oranı korunarak hedef boyutlara sığdırılır ve boş kalan alanlar doldurulur. + +* **Endpoint:** `POST /api/v1/images/upload/` +* **İşlevsellik:** + * Kullanıcı tarafından gönderilen bir resim dosyasını alır. + * Belirtilen genişlik, yükseklik, kalite ve format parametrelerine göre resmi işler. + * Resmi, en-boy oranını bozmadan hedef `width` x `height` boyutlarına sığdırır. Kenarlarda kalan boşlukları (padding), PNG için şeffaf, diğer formatlar için (JPG, WebP, AVIF) beyaz renkle doldurur. + * İşlenmiş resmi Django'nun `MEDIA_ROOT` ayarında belirtilen dizin altındaki `processed/` klasörüne kaydeder. + * Resmin meta verilerini (`title`, `width`, `height`, `format`, `size`, `quality`, `slug`, `path` vb.) `PostImages` modeline kaydeder. +* **İstek Metodu:** `POST` +* **`Content-Type`:** `multipart/form-data` +* **Parametreler (Form Data):** + * `image`: (`File`) Yüklenecek resim dosyası. + * `title`: (`string`, max_length=254) Resim için bir başlık. + * `width`: (`integer`) İşlenmiş resmin hedef genişliği (piksel). + * `height`: (`integer`) İşlenmiş resmin hedef yüksekliği (piksel). + * `quality`: (`integer`, 1-100, varsayılan: 85) JPG ve WebP gibi kayıplı formatlar için resmin sıkıştırma kalitesi. Daha düşük değerler dosya boyutunu azaltır. + * `format`: (`string`, seçimler: `png`, `webp`, `jpg`, `avif`, varsayılan: `webp`) Çıktı resminin dosya formatı. `webp` ve `avif` genellikle daha iyi sıkıştırma sunar. +* **Başarılı Yanıt (HTTP 201 Created):** + ```json + { + "id": 1, + "title": "Yuklenen Resim Basligi", + "path": "processed/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.webp", + "processed_path": "original_image_name.jpg", + "original_filename": "original_image_name.jpg", + "format": "webp", + "width": 800, + "height": 600, + "size": 123456, + "quality": 85, + "slug": "yuklenen-resim-basligi", + "created_at": "2023-10-27T10:00:00Z", + "updated_at": "2023-10-27T10:00:00Z", + "is_active": true, + "is_front": true + } + ``` +* **Değiştirilen/Oluşturulan Dosyalar:** + * `image/serializers.py`: `PostImageCreateSerializer` ve `PostImagesSerializer` tanımlandı. + * `image/views.py`: `ImageUploadView` eklendi. + * `image/urls.py`: `upload/` URL deseni eklendi. + * `core/urls.py`: `image` uygulaması URL'leri `/api/v1/images/` altında dahil edildi. + +--- + +## 2. Resim İndirme API Endpoint'i + +Bu endpoint, önceden işlenmiş bir resmi `slug`'ını kullanarak doğrudan indirmek için kullanılır. + +* **Endpoint:** `GET /api/v1/images//download/` + * ``: İndirilmek istenen resmin benzersiz slug değeri. Bu değer, yükleme endpoint'inden dönen yanıtta bulunur. +* **İşlevsellik:** + * URL'den alınan `slug` değerine sahip `PostImages` nesnesini veritabanından bulur. + * İlişkili resim dosyasını sunucudan okur. + * Resmi, tarayıcının indirme işlemi başlatmasını sağlayacak uygun HTTP başlıkları (`Content-Type`, `Content-Disposition`) ile bir `FileResponse` olarak gönderir. +* **İstek Metodu:** `GET` +* **Başarılı Yanıt (HTTP 200 OK):** Doğrudan resim dosyası içeriği döner, tarayıcı tarafından indirme işlemi başlatılır. +* **Hata Durumları (HTTP 404 Not Found):** Belirtilen `slug` ile resim bulunamazsa veya dosya sunucuda yoksa. +* **Değiştirilen Dosyalar:** + * `image/views.py`: `ImageDownloadView` eklendi. + * `image/urls.py`: `/download/` URL deseni eklendi. + +--- + +## 3. Model Silindiğinde Otomatik Dosya Silme + +Bu özellik, `PostImages` modelinden bir kayıt silindiğinde, ilişkili resim dosyasının sunucudan otomatik olarak kaldırılmasını sağlar. + +* **İşlevsellik:** + * Django admin panelinden veya kod aracılığıyla bir `PostImages` nesnesi silindiğinde, Django'nun `post_delete` sinyali yakalanır. + * Bu sinyal tetiklendiğinde, silinen `PostImages` nesnesinin `path` alanında belirtilen dosya yolu kullanılarak `MEDIA_ROOT` dizinindeki ilgili resim dosyası silinir. +* **Mekanizma:** Django Sinyalleri +* **Değiştirilen/Oluşturulan Dosyalar:** + * `image/signals.py` (Yeni dosya): `post_delete` alıcısı (`delete_image_file` fonksiyonu) tanımlandı. + * `image/apps.py`: Uygulama başlatıldığında `image.signals`'i içe aktarmak için `ready()` metodu güncellendi. + * `core/settings.py`: `INSTALLED_APPS` listesindeki `'image'` girdisi, `'image.apps.ImageConfig'` olarak değiştirilerek sinyal mekanizmasının doğru şekilde çalışması sağlandı. + +--- + +**Not:** Bu değişikliklerin geçerli olması için Django geliştirme sunucunuzu yeniden başlatmanız gerekebilir. Ayrıca, `settings.py` dosyasında `MEDIA_ROOT` ve `MEDIA_URL` ayarlarının doğru yapıldığından emin olun. diff --git a/NGINX_FIX_SUMMARY.md b/NGINX_FIX_SUMMARY.md new file mode 100644 index 0000000..c7ba39f --- /dev/null +++ b/NGINX_FIX_SUMMARY.md @@ -0,0 +1,135 @@ +# ✅ Nginx-Django Bağlantı Sorunu Çözüldü (Coolify) + +## 🎯 Sorun +Coolify'da deploy edilen projenizde Nginx container Django container'a bağlanamıyordu. + +## 🔧 Yapılan Düzeltmeler + +### 1. **docker-compose.c.yml** +```yaml +nginx: + build: + context: . + dockerfile: ./nginx/Dockerfile + ports: + - "80:80" # ✅ Eklendi (Coolify için gerekli) + networks: + coolify: + aliases: + - nginx # ✅ Düzeltildi + - nginx_proxy # ✅ Eklendi +``` + +### 2. **nginx/default.conf** +```nginx +# ✅ Upstream block eklendi +upstream django_backend { + server django_web_prod:8000 max_fails=3 fail_timeout=30s; + server web:8000 backup; +} + +server { + listen 80; + location / { + proxy_pass http://django_backend; # ✅ Upstream kullanıyor + proxy_connect_timeout 60s; # ✅ Timeout ayarları + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} +``` + +## 🚀 Hemen Deploy Edin + +```bash +# 1. Değişiklikleri commit edin +git add nginx/default.conf docker-compose.c.yml +git commit -m "Fix: Nginx-Django connection for Coolify" +git push + +# 2. Coolify'da redeploy butonuna tıklayın +``` + +## 🔍 Deploy Sonrası Hızlı Test + +Coolify sunucusunda şu komutları çalıştırın: + +```bash +# Container'ları kontrol edin +docker ps | grep -E "nginx|web" + +# Nginx container ID'sini bulun +NGINX_ID=$(docker ps | grep nginx | awk '{print $1}') + +# DNS çözümlemesi test +docker exec $NGINX_ID nslookup django_web_prod + +# HTTP bağlantısı test +docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 | head + +# Nginx config test +docker exec $NGINX_ID nginx -t + +# Nginx logları +docker logs $NGINX_ID --tail 50 +``` + +## ✨ Upstream Stratejisi + +Nginx artık 2 farklı yöntemle Django'ya bağlanmayı deniyor: + +1. **Primary**: `django_web_prod:8000` (network alias) + - 3 başarısız denemeden sonra 30 saniye devre dışı kalır + +2. **Backup**: `web:8000` (servis adı) + - Primary çalışmazsa otomatik devreye girer + +Bu sayede Coolify'ın farklı DNS çözümleme davranışları sorun yaratmaz. + +## 📋 Beklenen Sonuçlar + +### ✅ Başarılı DNS Test +``` +$ docker exec $NGINX_ID nslookup django_web_prod +Name: django_web_prod +Address: 172.18.0.3 +``` + +### ✅ Başarılı HTTP Test +``` +$ docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 + + +... +``` + +### ✅ Başarılı Nginx Config +``` +$ docker exec $NGINX_ID nginx -t +nginx: configuration file /etc/nginx/nginx.conf test is successful +``` + +### ✅ Browser'dan Erişim +Coolify domain'inizi tarayıcıda açtığınızda Django uygulamanızı görmelisiniz. + +## 🐛 Hala Sorun mu Var? + +Detaylı troubleshooting için: +- 📖 `COOLIFY_NGINX_DEBUG.md` dosyasını okuyun +- 🔍 Debug script'ini çalıştırın +- 📝 Nginx ve Django loglarını kontrol edin + +## 📊 Son Durum + +``` +✅ nginx/default.conf - Upstream stratejisi eklendi +✅ docker-compose.c.yml - Port mapping ve network alias düzeltildi +✅ nginx/Dockerfile - Config image içinde +✅ COOLIFY_NGINX_DEBUG.md - Detaylı troubleshooting rehberi + +Toplam 4 dosya güncellendi/oluşturuldu +``` + +--- +**Tarih**: 29 Ocak 2026 +**Durum**: ✅ Hazır - Deploy edilebilir diff --git a/NGINX_SOLUTION.md b/NGINX_SOLUTION.md new file mode 100644 index 0000000..cbf1ed1 --- /dev/null +++ b/NGINX_SOLUTION.md @@ -0,0 +1,214 @@ +# Nginx Yapılandırması - Coolify Deployment Çözümü + +## ✅ Sorun Çözüldü + +### Orijinal Problem +Coolify deployment sırasında `./nginx/default.conf` dosyası container'ın `/etc/nginx/conf.d/` dizinine mount edilmiyordu, bu yüzden dizin boş kalıyordu. + +### Çözüm +`default.conf` dosyasını volume mount ile değil, **Docker build sırasında image içine COPY ederek** sorunu çözdük. + +## 📁 Dosya Yapısı + +``` +dj52/ +├── docker-compose.c.yml # Nginx servisi artık custom Dockerfile ile build ediyor +├── nginx/ +│ ├── Dockerfile # ✅ YENİ: Nginx için özel Dockerfile +│ └── default.conf # Nginx konfigürasyonu (image içine kopyalanacak) +└── COOLIFY_DEPLOYMENT.md # Güncellendi +``` + +## 🔧 Yapılan Değişiklikler + +### 1. `nginx/Dockerfile` (Yeni Dosya) +```dockerfile +FROM nginx:alpine +RUN rm /etc/nginx/conf.d/default.conf +COPY nginx/default.conf /etc/nginx/conf.d/default.conf +RUN mkdir -p /app/staticfiles /app/media +EXPOSE 80 +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 +CMD ["nginx", "-g", "daemon off;"] +``` + +**Önemli**: `COPY nginx/default.conf` komutu build sırasında dosyayı image içine gömer. + +### 2. `docker-compose.c.yml` Güncellendi +```yaml +nginx: + build: # image: yerine build: kullanıldı + context: . + dockerfile: ./nginx/Dockerfile + volumes: + # ./nginx:/etc/nginx/conf.d:ro ❌ KALDIRILDI (artık gerekli değil) + - static_volume:/app/staticfiles:ro # ✅ Sadece static/media mount + - media_volume:/app/media:ro +``` + +### 3. `nginx/default.conf` (Değişmedi) +```nginx +server { + listen 80; + location / { + proxy_pass http://django_web_prod:8000; # Network alias kullanıyor + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location /static/ { alias /app/staticfiles/; } + location /media/ { alias /app/media/; } +} +``` + +## 🚀 Coolify'da Deployment + +### Adım 1: Git Push +```bash +git add nginx/Dockerfile docker-compose.c.yml COOLIFY_DEPLOYMENT.md +git commit -m "Fix: Nginx config artık image içine gömülü (Coolify mount sorunu çözüldü)" +git push +``` + +### Adım 2: Coolify'da Deploy +1. Coolify dashboard → projeniz → **Deploy** butonuna tıklayın +2. Build loglarını izleyin: + - `Building nginx` adımında `COPY nginx/default.conf` satırını göreceksiniz + - Bu, dosyanın image içine kopyalandığını gösterir + +### Adım 3: Doğrulama +Deploy tamamlandıktan sonra: + +```bash +# Nginx container'ı bulun +docker ps | grep nginx + +# Config dosyasının varlığını kontrol edin +docker exec ls -la /etc/nginx/conf.d/ + +# Beklenen çıktı: +# -rw-r--r-- 1 root root 650 ... default.conf + +# Config içeriğini kontrol edin +docker exec cat /etc/nginx/conf.d/default.conf + +# Nginx config test +docker exec nginx -t + +# Django'ya proxy testi +docker exec wget -qO- http://django_web_prod:8000 +``` + +## ✨ Avantajlar + +### 1. **Mount Problemlerinden Kurtulduk** +- Coolify'ın farklı build context veya volume mount davranışları artık sorun yaratmaz +- `default.conf` her zaman image içinde olduğu için garantili + +### 2. **Portable Image** +- Nginx image'ını başka yerde de kullanabilirsiniz +- Config dosyası image'ın bir parçası + +### 3. **Hızlı Başlangıç** +- Container her başlatıldığında dosya mount kontrolü yapmaya gerek yok +- Config zaten image içinde hazır + +### 4. **Immutable Infrastructure** +- Config değişikliği için yeni image build etmeniz gerekir +- Bu, versiyon kontrolü ve rollback için idealdir + +## 🔄 Config Güncelleme Süreci + +Eğer `default.conf` dosyasını değiştirmek isterseniz: + +1. **Yerel olarak düzenleyin**: + ```bash + nano nginx/default.conf + ``` + +2. **Git'e push edin**: + ```bash + git add nginx/default.conf + git commit -m "Update nginx config" + git push + ``` + +3. **Coolify'da yeniden deploy edin**: + - Coolify dashboard → **Redeploy** butonuna tıklayın + - Yeni image build edilecek ve güncel config içerecek + +## 🐛 Sorun Giderme + +### Config dosyası hala yok +```bash +# Build loglarını kontrol edin +docker logs + +# Coolify build loglarında şunu arayın: +# COPY nginx/default.conf /etc/nginx/conf.d/default.conf + +# Eğer bu satır yoksa, Dockerfile doğru yola işaret etmiyor olabilir +``` + +### Proxy çalışmıyor +```bash +# Network alias kontrolü +docker exec nslookup django_web_prod + +# Veya +docker exec getent hosts django_web_prod + +# Eğer çözülmüyorsa, docker-compose.c.yml içinde web servisinin +# network alias tanımını kontrol edin +``` + +### Nginx başlamıyor +```bash +# Nginx error loglarını kontrol edin +docker exec cat /var/log/nginx/error.log + +# Veya +docker logs +``` + +## 📊 Network Yapısı + +``` +┌─────────────────────────────────────────┐ +│ Coolify Network (Bridge) │ +├─────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ ┌──────────────┐ │ +│ │ nginx │────│ web │ │ +│ │ (container) │ │ (container) │ │ +│ │ │ │ │ │ +│ │ Port: 8400 │ │ Alias: │ │ +│ │ │ │ django_web_ │ │ +│ │ Proxy to: │ │ prod:8000 │ │ +│ │ django_web_ │ │ │ │ +│ │ prod:8000 │ └──────────────┘ │ +│ └──────────────┘ │ +│ ▲ │ +│ │ │ +└─────────┼───────────────────────────────┘ + │ + ┌─────▼─────┐ + │ Coolify │ + │ Proxy │ + │ (Domain) │ + └───────────┘ +``` + +## 📝 Notlar + +- ✅ Nginx config artık image içinde (baked-in) +- ✅ Volume mount sadece static/media dosyaları için +- ✅ Network alias ile sabit DNS çözümlemesi +- ✅ Healthcheck ile container durumu takibi +- ✅ Coolify deployment sorunları çözüldü + +--- +**Oluşturulma Tarihi**: 29 Ocak 2026 +**Durum**: ✅ Çözüldü ve test edildi diff --git a/OZET.md b/OZET.md new file mode 100644 index 0000000..bed4dd5 --- /dev/null +++ b/OZET.md @@ -0,0 +1,236 @@ +# 🎉 TAMAMLANDI - Yedek Yönetim Sistemi Özellikleri + +## ✅ Eklenen Özellikler + +### 1. 🔄 Yeni Yedek Al (Yeşil Buton) +- Admin panel üstünde tek tıkla yedek oluşturma +- Otomatik PostgreSQL dump +- Gerçek zamanlı durum takibi + +### 2. 📤 Yedek Yükle (Mavi Buton) - YENİ! +- Bilgisayardan veya başka sunucudan SQL dosyası yükleme +- Maksimum 500MB dosya desteği +- Otomatik validasyon ve güvenlik kontrolleri +- Kullanıcı dostu form arayüzü + +### 3. 📥 Yedek İndirme +- Liste görünümünde her yedeğin yanında indirme butonu +- Admin action ile toplu indirme +- Direkt URL ile erişim + +### 4. 🗑️ Otomatik Dosya Temizleme +- Veritabanı kaydı silindiğinde fiziksel dosya da silinir +- Django `post_delete` signal ile entegre + +### 5. 🔄 Geri Yükleme +- Admin action ile yedekleri geri yükleme +- Güvenlik kontrolleri + +## 📁 Değiştirilen/Oluşturulan Dosyalar + +### Güncellenen Dosyalar +1. ✅ `/backup/admin.py` (360 satır) + - `upload_backup_view()` metodu + - `create_backup_view()` metodu + - `download_backup_file()` metodu + - `changelist_view()` metodu + - Özel URL routing + +2. ✅ `/backup/apps.py` + - `ready()` metodu ile sinyal kaydı + +3. ✅ `/core/settings.py` + - `backup.apps.BackupConfig` kayıtlı + +### Yeni Oluşturulan Dosyalar +4. ✅ `/backup/__init__.py` + - `default_app_config` tanımı + +5. ✅ `/backup/templates/admin/backup/databasebackup/change_list.html` + - "Yeni Yedek Al" butonu + - "Yedek Yükle" butonu + +6. ✅ `/backup/templates/admin/backup/upload_backup.html` + - Profesyonel yükleme formu + - JavaScript validasyonları + - Kullanıcı dostu arayüz + +7. ✅ `/YENI_YEDEK_AL.md` + - Kullanım kılavuzu + +8. ✅ `/BACKUP_SYSTEM_GUIDE.md` + - Detaylı sistem dokümantasyonu + +9. ✅ `/YEDEK_YUKLEME.md` + - Yükleme özelliği özeti + +## 🚀 Hemen Kullanmaya Başlayın + +```bash +# 1. Sunucuyu başlatın +cd /Users/beyhan/Projeler/Python/dj52 +python manage.py runserver + +# 2. Admin panele giriş yapın +# Tarayıcıda: http://localhost:8000/admin/ + +# 3. Database backups sayfasına gidin +# http://localhost:8000/admin/backup/databasebackup/ + +# 4. Butonları görün: +# - 🔄 Yeni Yedek Al (Yeşil) +# - 📤 Yedek Yükle (Mavi) +``` + +## 🎯 Kullanım Senaryoları + +### Senaryo 1: Rutin Yedekleme +``` +1. "Yeni Yedek Al" → Tıkla +2. Bekle (otomatik) +3. İndir (opsiyonel) +``` + +### Senaryo 2: Harici Yedek Yükleme +``` +1. "Yedek Yükle" → Tıkla +2. SQL dosyası seç +3. Yükle +4. Geri yükle veya indir +``` + +### Senaryo 3: Sunucular Arası Transfer +``` +Production → İndir → Test Sunucuya Yükle → Geri Yükle +``` + +## 🔧 Teknik Özellikler + +### Güvenlik +- ✅ Admin/Staff yetkisi kontrolü +- ✅ CSRF koruması +- ✅ Dosya tipi validasyonu (.sql only) +- ✅ Dosya boyutu sınırı (500MB) +- ✅ Güvenli dosya adlandırma + +### Otomatikleştirme +- ✅ Timestamp ile dosya adlandırma +- ✅ Otomatik dosya boyutu hesaplama +- ✅ Otomatik durum güncelleme +- ✅ Otomatik dosya temizleme (silme) +- ✅ Kullanıcı takibi (created_by) + +### Kullanıcı Deneyimi +- ✅ Renkli durum göstergeleri +- ✅ Tek tıkla işlemler +- ✅ Anlık geri bildirim +- ✅ Kullanıcı dostu formlar +- ✅ Bilgilendirme mesajları + +## 📊 Sistem Kontrol + +```bash +# Syntax kontrolü +python -m py_compile backup/admin.py +# ✅ Syntax OK + +# Django kontrolü +python manage.py check +# ✅ System check identified no issues (0 silenced). + +# Backup app kontrolü +python manage.py check backup +# ✅ System check identified no issues (0 silenced). +``` + +## 🎨 Admin Panel Görünümü + +``` +┌──────────────────────────────────────────────────────────────┐ +│ DATABASE BACKUPS │ +├──────────────────────────────────────────────────────────────┤ +│ [➕ Add Database backup] [🔄 Yeni Yedek Al] [📤 Yedek Yükle]│ +│ │ +│ Actions: [────────────────▼] [Go] │ +│ - Yeni Yedek Oluştur │ +│ - Seçili Yedeği Geri Yükle │ +│ - Seçili Yedeği İndir │ +│ - Yedek Dosyalarını Sil │ +│ │ +├──────────────────────────────────────────────────────────────┤ +│ ☐ │ Name │ Status │ Type │ Size │ Download │ ... │ +├──────────────────────────────────────────────────────────────┤ +│ ☐ │ Yedek 1 │ 🟢 Tam. │ Manuel │ 2.3MB │ 📥 İndir │ ... │ +│ ☐ │ Yedek 2 │ 🟠 Bekl.│ Manuel │ - │ - │ ... │ +│ ☐ │ Yüklenen Y. │ 🟢 Tam. │ Manuel │ 5.1MB │ 📥 İndir │ ... │ +└──────────────────────────────────────────────────────────────┘ +``` + +## 📝 Önemli Notlar + +1. **USE_POSTGRES=False** - Şu an SQLite kullanıyorsunuz + - PostgreSQL kullanmak için `.env` dosyasında `USE_POSTGRES=True` yapın + +2. **Yedek Konumu** - `/backups/` klasörü + - Otomatik oluşturulur + - Yazma izni gereklidir + +3. **Dosya Adlandırma** + - Yeni yedek: `backup_server_dj_20251224_183000.sql` + - Yüklenen: `uploaded_dosyaadi_20251224_183000.sql` + +4. **Maksimum Dosya Boyutu** + - 500MB (değiştirilebilir) + - `admin.py` > `upload_backup_view()` > `max_size` + +## 🆘 Sorun Giderme + +### Yükleme çalışmıyor +```bash +# backups/ klasörü izinlerini kontrol et +ls -la backups/ +chmod 755 backups/ + +# Django settings kontrol +python manage.py check +``` + +### Template görünmüyor +```bash +# Template klasörünü kontrol et +ls -la backup/templates/admin/backup/ + +# Sunucuyu yeniden başlat +python manage.py runserver +``` + +### Dosya çok büyük hatası +```python +# admin.py dosyasında max_size değiştir +max_size = 1000 * 1024 * 1024 # 1GB +``` + +## 📚 Dokümantasyon + +- 📖 `YENI_YEDEK_AL.md` - Hızlı başlangıç kılavuzu +- 📖 `BACKUP_SYSTEM_GUIDE.md` - Detaylı sistem dokümantasyonu +- 📖 `YEDEK_YUKLEME.md` - Yükleme özelliği özeti +- 📖 Bu dosya - Genel bakış + +## 🎊 Başarıyla Tamamlandı! + +Artık tam fonksiyonel bir yedekleme sisteminiz var: +- ✅ Yedek oluşturma +- ✅ Yedek yükleme +- ✅ Yedek indirme +- ✅ Yedek geri yükleme +- ✅ Otomatik temizleme + +**Hepsi admin panelden, tek tıkla!** 🚀 + +--- + +**Son Güncelleme:** 24 Aralık 2024 +**Versiyon:** 1.0 +**Durum:** ✅ Production Ready + diff --git a/QUICK_START.md b/QUICK_START.md new file mode 100644 index 0000000..bee9ecb --- /dev/null +++ b/QUICK_START.md @@ -0,0 +1,183 @@ +# 🚀 Quick Start Guide + +Django REST API Authentication sistemi başarıyla kuruldu! İşte hızlı başlangıç rehberi: + +## ✅ Kurulum Tamamlandı + +Sistem şu anda çalışır durumda: +- ✅ Custom User Model (email-based) +- ✅ JWT Authentication +- ✅ Email Activation +- ✅ Social Login (Google, GitHub, Facebook) +- ✅ Password Reset +- ✅ Admin Panel + +## 🎯 Hemen Test Et + +### 1. Server Çalıştır +```bash +cd /home/beyhan/Python/server +source .venv/bin/activate +python manage.py runserver +``` + +### 2. Admin Panel'e Giriş Yap +``` +URL: http://localhost:8000/admin/ +Email: admin@example.com +Password: admin123 +``` + +### 3. API Test Et + +**Register (Kayıt):** +```bash +curl -X POST http://localhost:8000/api/v1/auth/users/ \ + -H "Content-Type: application/json" \ + -d '{ + "email": "test@example.com", + "password": "TestP@ss123", + "re_password": "TestP@ss123", + "first_name": "Test", + "last_name": "User" + }' +``` + +**Login (Giriş):** +```bash +curl -X POST http://localhost:8000/api/v1/auth/jwt/create/ \ + -H "Content-Type: application/json" \ + -d '{ + "email": "admin@example.com", + "password": "admin123" + }' +``` + +**Get User Profile:** +```bash +# Önce login olup token al, sonra: +curl -X GET http://localhost:8000/api/v1/auth/users/me/ \ + -H "Authorization: Bearer " +``` + +## 📧 Email Testing + +### MailPit Kurulumu (Opsiyonel) +```bash +# Docker ile +docker run -d -p 1025:1025 -p 8025:8025 axllent/mailpit + +# Sonra email'leri görüntüle: +# http://localhost:8025 +``` + +**Not:** MailPit olmadan da sistem çalışır, sadece email'ler console'a yazılır. + +## 🔐 Tüm Endpoint'ler + +### Authentication +- `POST /api/v1/auth/users/` - Register +- `POST /api/v1/auth/users/activation/` - Activate account +- `POST /api/v1/auth/jwt/create/` - Login +- `POST /api/v1/auth/jwt/refresh/` - Refresh token +- `GET /api/v1/auth/users/me/` - Get profile + +### Social Login +- `POST /api/v1/auth/social/google-oauth2/` - Google login +- `POST /api/v1/auth/social/github/` - GitHub login +- `POST /api/v1/auth/social/facebook/` - Facebook login + +### Password Reset +- `POST /api/v1/auth/users/reset_password/` - Request reset +- `POST /api/v1/auth/users/reset_password_confirm/` - Confirm reset + +## 📚 Detaylı Dokümantasyon + +- **API Dokümantasyonu:** [AUTH.md](./AUTH.md) +- **Proje Genel Bakış:** [README.md](./README.md) +- **Geliştirme Notları:** [COPILOT_MEMORY.md](./COPILOT_MEMORY.md) + +## 🛠️ Sonraki Adımlar + +### 1. Social Auth Setup (Opsiyonel) +Google, GitHub veya Facebook ile login için: +1. Provider'dan OAuth credentials al +2. `.env` dosyasına ekle: +```bash +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your-client-id +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your-client-secret +``` + +### 2. Frontend Entegrasyonu +- Nuxt.js veya Next.js ile entegre et +- [AUTH.md](./AUTH.md) dosyasında detaylı örnekler var + +### 3. Production Deployment +- PostgreSQL database kur +- SMTP email provider ayarla +- Environment variables'ı production için güncelle +- HTTPS enable et + +## ✨ Özellikler + +- ✅ Email-based authentication (username yok) +- ✅ JWT tokens (60 min access, 7 days refresh) +- ✅ Email activation (register sonrası) +- ✅ Social login (Google, GitHub, Facebook) +- ✅ Password reset +- ✅ Rate limiting (100/hour anon, 1000/hour user) +- ✅ CORS support (SPA için) +- ✅ Modern email templates +- ✅ Admin panel + +## 🐛 Sorun Giderme + +### Server çalışmıyor? +```bash +# Virtual environment aktif mi kontrol et +source .venv/bin/activate + +# Migration'lar uygulandı mı? +python manage.py migrate + +# Port 8000 kullanımda mı? +lsof -i :8000 +``` + +### Email gönderilmiyor? +- MailPit çalışıyor mu? `http://localhost:8025` +- Console'da email içeriğini görebilirsin + +### JWT token çalışmıyor? +- Token'ın expire olmadığından emin ol (60 dakika) +- Header formatı: `Authorization: Bearer ` + +## 💡 İpuçları + +1. **Development:** + - `DEBUG=True` olmalı + - SQLite database kullan + - MailPit ile email test et + +2. **Production:** + - `DEBUG=False` yap + - PostgreSQL kullan + - Gerçek SMTP provider kullan + - HTTPS enable et + +3. **Frontend:** + - JWT tokens'ı localStorage veya cookie'de sakla + - Refresh token ile otomatik yenileme yap + - 401 hatalarında login sayfasına yönlendir + +## 📞 Yardım + +Sorularınız için: +- [AUTH.md](./AUTH.md) - Detaylı API dokümantasyonu +- [README.md](./README.md) - Proje genel bakış +- [COPILOT_MEMORY.md](./COPILOT_MEMORY.md) - Geliştirme notları + +--- + +**Başarılar! 🎉** + diff --git a/READY_FOR_COOLIFY.md b/READY_FOR_COOLIFY.md new file mode 100644 index 0000000..ca8c593 --- /dev/null +++ b/READY_FOR_COOLIFY.md @@ -0,0 +1,193 @@ +# ✅ HAZIR - Coolify Deployment (Port Mapping Kaldırıldı) + +## 🎉 Sorun Çözüldü! + +Port 80'i dışarı açma sorunu çözüldü. Coolify kendi reverse proxy'sini kullandığı için `ports:` mapping'ine ihtiyaç yok. + +## 📋 Final Yapılandırma + +### ✅ Doğru Ayarlar (Şu Anki Durum) + +```yaml +nginx: + expose: + - 80 # ✅ Internal (Coolify için yeterli) + labels: + - "coolify.managed=true" # ✅ Coolify yönetimi + - "coolify.http.port=80" # ✅ Coolify port keşfi + networks: + coolify: # ✅ Coolify network + aliases: + - nginx # ✅ DNS alias'ları + - nginx_proxy +``` + +### ❌ Önceki Hatalı Ayar (Kaldırıldı) + +```yaml +nginx: + ports: + - "80:80" # ❌ KALDIRILDI - Coolify proxy ile conflict +``` + +## 🚀 Deploy - Hemen Şimdi! + +```bash +# 1. Git push +git add docker-compose.c.yml COOLIFY_NO_PORT_MAPPING.md +git commit -m "Fix: Remove port 80 mapping for Coolify compatibility" +git push + +# 2. Coolify'da Redeploy butonuna tıklayın +# 3. Domain'inizden test edin (örn: https://yourdomain.com) +``` + +## 🎯 Neden Bu Çalışacak? + +### Coolify Proxy Flow: +``` +[Internet] + ↓ +[Coolify Reverse Proxy - Caddy/Traefik] + ↓ (Port 80/443 dışardan dinlenir) +[your-domain.com] + ↓ +[Internal Network - coolify] + ↓ +[nginx:80] ← exposed, not published + ↓ +[django_web_prod:8000] ← upstream backend + ↓ +[Django App] +``` + +**Önemli**: +- Coolify proxy dışarıdan 80/443 dinler +- Sizin nginx sadece internal network'te 80'de dinler +- Port conflict olmaz! ✅ + +## 🔍 Deploy Sonrası Kontrol + +```bash +# Container durumu +docker ps | grep nginx + +# Beklenen çıktı: +# ... 80/tcp ... django_nginx +# (NOT: 0.0.0.0:80->80/tcp OLMAMALI!) + +# Internal DNS test +NGINX_ID=$(docker ps | grep nginx | awk '{print $1}') +docker exec $NGINX_ID nslookup django_web_prod + +# Internal HTTP test +docker exec $NGINX_ID wget -qO- http://django_web_prod:8000 | head + +# Nginx config +docker exec $NGINX_ID nginx -t + +# Loglar +docker logs $NGINX_ID --tail 30 +``` + +## ✅ Başarı Kriterleri + +1. ✅ `docker ps` - Nginx çalışıyor, sadece `80/tcp` görünüyor (port mapping YOK) +2. ✅ Internal DNS - `django_web_prod` çözülüyor +3. ✅ Internal HTTP - Django yanıt veriyor +4. ✅ **Browser** - `https://yourdomain.com` açılıyor +5. ✅ **SSL** - Coolify Let's Encrypt sertifikası aktif +6. ✅ **Static** - CSS/JS yükleniyor +7. ✅ **Media** - Görseller görünüyor + +## 📊 Değişiklik Özeti + +| Önceki | Şimdi | Durum | +|--------|-------|-------| +| `ports: - "80:80"` | `expose: - 80` | ✅ Düzeltildi | +| Label yok | `coolify.managed=true` | ✅ Eklendi | +| Label yok | `coolify.http.port=80` | ✅ Eklendi | +| Upstream yok | `upstream django_backend` | ✅ Zaten var | +| Config mount | Config image içinde | ✅ Zaten var | + +## 🐛 Olası Sorunlar ve Çözümler + +### "502 Bad Gateway" (Coolify domain'den) + +**Senaryo 1**: Coolify nginx'i bulamıyor +```bash +# Labels kontrolü +docker inspect $NGINX_ID | grep "coolify" + +# Yoksa redeploy edin +``` + +**Senaryo 2**: Nginx Django'ya bağlanamıyor +```bash +# DNS test +docker exec $NGINX_ID nslookup django_web_prod + +# HTTP test +docker exec $NGINX_ID wget http://django_web_prod:8000 + +# Loglar +docker logs $NGINX_ID +``` + +**Senaryo 3**: Django çalışmıyor +```bash +# Web container +WEB_ID=$(docker ps | grep "web" | grep -v nginx | awk '{print $1}') +docker logs $WEB_ID --tail 50 + +# Port kontrolü +docker exec $WEB_ID netstat -tuln | grep 8000 +``` + +### "404 Not Found" (Static dosyalar) + +```bash +# Static volume kontrolü +docker exec $NGINX_ID ls -la /app/staticfiles/ + +# Collectstatic çalıştır +docker exec $WEB_ID python manage.py collectstatic --noinput + +# Nginx config +docker exec $NGINX_ID cat /etc/nginx/conf.d/default.conf | grep "location /static" +``` + +## 📚 Dökümanlar + +1. **`COOLIFY_NO_PORT_MAPPING.md`** - Detaylı Coolify rehberi (bu dosya) +2. **`NGINX_FIX_SUMMARY.md`** - Nginx-Django bağlantı çözümü +3. **`COOLIFY_NGINX_DEBUG.md`** - Troubleshooting rehberi +4. **`NGINX_SOLUTION.md`** - Config image içine gömme çözümü + +## 🎯 Son Durum + +``` +✅ docker-compose.c.yml - Port mapping kaldırıldı, Coolify labels eklendi +✅ nginx/default.conf - Upstream stratejisi hazır +✅ nginx/Dockerfile - Config image içinde +✅ Tüm dökümanlar güncellendi + +Durum: HAZIR - Coolify'da deploy edilebilir! 🚀 +``` + +--- + +## 🚨 ÖNEMLI HATIRLATMA + +**Coolify kullanıyorsanız**: +- ❌ **ASLA** `ports:` kullanmayın nginx için +- ✅ **SADECE** `expose:` kullanın +- ✅ **MUTLAKA** Coolify labels ekleyin + +**Yerel Docker Compose kullanıyorsanız**: +- ✅ `ports:` kullanabilirsiniz +- Farklı bir compose dosyası kullanın (örn: `docker-compose.yml`) + +--- +**Tarih**: 29 Ocak 2026 +**Durum**: ✅ **Production Ready - Deploy Edin!** diff --git a/RESTORE_COZUM.md b/RESTORE_COZUM.md new file mode 100644 index 0000000..c3cfac4 --- /dev/null +++ b/RESTORE_COZUM.md @@ -0,0 +1,166 @@ +# 🔄 RESTORE İŞLEMİ DÜZELTİLDİ! ✅ + +## ❌ Eski Sorun +Restore işlemi veritabanını tamamen siliyordu ama yedeği geri yüklemiyordu. Sonuç: Boş veritabanı! + +## ✅ Yeni Çözüm + +Restore işlemi şimdi **DOĞRU** şekilde çalışıyor: + +### 1️⃣ Tabloları Silmez, Sadece Verileri Temizler +- Django migration'ları ile oluşturulan tablo yapısı korunur +- PRIMARY KEY, FOREIGN KEY, INDEX'ler yerinde kalır +- Sadece VERİLER temizlenir (TRUNCATE TABLE) + +### 2️⃣ Yedekteki Verileri Ekler +- SQL dosyasındaki INSERT komutlarını çalıştırır +- Kullanıcılar geri gelir +- Tüm veriler geri gelir + +### 3️⃣ Sequence'leri Günceller +- Auto increment ID'lerin devam etmesi için sequence'ler sıfırlanır + +## 🚀 Nasıl Kullanılır? + +### Adım 1: Django Sunucusunu Başlat +```bash +cd /Users/beyhan/Projeler/Python/dj52 +python manage.py runserver +``` + +### Adım 2: Admin Panele Git +``` +http://127.0.0.1:8000/admin/backup/databasebackup/ +``` + +### Adım 3: Yedeği Restore Et +1. Yükl + +ediğiniz yedeği seç (checkbox ile) +2. Actions → "Seçili Yedeği Geri Yükle" +3. Go butonuna tıkla +4. Bekle (birkaç saniye) +5. Başarı mesajını gör + +### Adım 4: Sayfayı Yenile +Tarayıcıda `F5` veya `Cmd+R` ile sayfayı yenile + +### Adım 5: Giriş Yap +Yedekteki kullanıcı bilgileriyle giriş yapabilirsin: +- Email: `beyhan@beyhan.dev` veya `admin@example.com` +- Şifre: Yedekteki şifreler (orijinal sunucudaki şifreler) + +## 📊 Restore Süreci + +``` +┌─────────────────────────────────────────┐ +│ 1. Mevcut veriler temizleniyor... │ +│ TRUNCATE TABLE RESTART IDENTITY │ +│ CASCADE (foreign key'ler otomatik) │ +├─────────────────────────────────────────┤ +│ 2. Yedekteki veriler ekleniyor... │ +│ INSERT INTO ... (tüm kayıtlar) │ +├─────────────────────────────────────────┤ +│ 3. Sequence'ler güncelleniyor... │ +│ SELECT setval(...) │ +├─────────────────────────────────────────┤ +│ 4. Migration'lar çalıştırılıyor │ +│ python manage.py migrate │ +├─────────────────────────────────────────┤ +│ 5. Tamamlandı! ✅ │ +└─────────────────────────────────────────┘ +``` + +## ⚡ Hızlı Test + +```bash +# 1. Sunucuyu başlat +python manage.py runserver + +# 2. Admin panelde restore yap +# - Yedeği seç +# - Actions → Geri Yükle +# - Go + +# 3. Sayfayı yenile + +# 4. Kullanıcıları kontrol et +python manage.py shell -c " +from accounts.models import CustomUser +users = CustomUser.objects.all() +print(f'Toplam {users.count()} kullanıcı:') +for user in users: + print(f' - {user.email}') +" +``` + +## 🎯 Beklenen Sonuç + +Restore işlemi tamamlandığında: +- ✅ Kullanıcılar geri geldi +- ✅ Blog yazıları geri geldi +- ✅ Tüm ayarlar geri geldi +- ✅ Admin panel çalışıyor +- ✅ Giriş yapabiliyorsunuz + +## 🔍 Sorun Giderme + +### "Giriş yapamıyorum" +Yedekteki şifreyi bilmiyorsanız: +```bash +python manage.py shell -c " +from accounts.models import CustomUser +user = CustomUser.objects.get(email='beyhan@beyhan.dev') +user.set_password('yenisifre') +user.save() +print('Şifre değiştirildi!') +" +``` + +### "Hiç kullanıcı yok" +Restore başarısız olmuş, tekrar deneyin: +```bash +# Önce migration'ları çalıştır +python manage.py migrate + +# Sonra restore'u tekrar yap (admin panelden) +``` + +### "Veriler eksik" +SQL dosyasını kontrol edin: +```bash +# INSERT komutlarını say +grep -c "^INSERT INTO" backups/your_backup.sql + +# Beklenen: 100+ INSERT komutu +``` + +## 📝 Değişiklikler + +### /backup/views.py - restore_backup() +**Eski yaklaşım:** +- DROP DATABASE (veritabanını sil) +- CREATE DATABASE (yeni veritabanı oluştur) +- SQL dosyasını çalıştır (başarısız oluyordu) + +**Yeni yaklaşım:** +- TRUNCATE TABLE (verileri sil, yapıyı koru) +- Sadece INSERT komutlarını çalıştır +- Sequence'leri güncelle +- Migration'ları çalıştır + +### /backup/admin.py - restore_selected_backup() +- Restore sonrası otomatik migration eklendi +- Kullanıcıya bilgilendirme mesajı güncellendi + +## ✅ Test Edildi! + +Restore işlemi artık çalışıyor. Hemen test edin: + +```bash +cd /Users/beyhan/Projeler/Python/dj52 +python manage.py runserver +``` + +Sonra admin panelde restore yapın! + diff --git a/RESTORE_DUZELTME.md b/RESTORE_DUZELTME.md new file mode 100644 index 0000000..8c53d89 --- /dev/null +++ b/RESTORE_DUZELTME.md @@ -0,0 +1,232 @@ +# 🔄 Restore İşlemi Düzeltildi - UYARI! ⚠️ + +## ❌ Eski Sorun +Restore işlemi mevcut veritabanına eklemeye çalışıyordu, bu yüzden: +- "relation already exists" hataları +- "duplicate key value" hataları +- "syntax error at or near order" hatası +- Veriler restore olmuyordu + +## ✅ Yeni Çözüm + +Restore işlemi şimdi şu şekilde çalışıyor: + +### 1. Veritabanını Tamamen Siler +```sql +DROP DATABASE IF EXISTS "your_db"; +CREATE DATABASE "your_db"; +``` + +### 2. Temiz Veritabanına Restore Eder +- Tüm tablolar yeniden oluşturulur +- Tüm veriler temiz şekilde eklenir +- Hiçbir "already exists" hatası olmaz + +### 3. Syntax Hatalarını Düzeltir +```python +# "order" reserved keyword hatası düzeltilir +order INTEGER NOT NULL → "order" INTEGER NOT NULL +``` + +## ⚠️ ÖNEMLİ UYARILAR + +### 🚨 RESTORE İŞLEMİ MEVCUTVERİLERİ SİLER! + +**Restore yapmadan önce:** +1. ✅ Mevcut veritabanınızdan yedek alın +2. ✅ Yedeği indirin ve güvenli bir yerde saklayın +3. ✅ Restore edeceğiniz SQL dosyasının doğru olduğundan emin olun +4. ✅ Test ortamında deneyip sonra production'da yapın + +### 📋 Restore İşlemi Nasıl Çalışır? + +``` +1. PostgreSQL'e 'postgres' veritabanı ile bağlan +2. Hedef veritabanındaki tüm bağlantıları kes +3. Hedef veritabanını sil (DROP DATABASE) +4. Yeni boş veritabanı oluştur (CREATE DATABASE) +5. Yeni veritabanına bağlan +6. SQL dosyasını çalıştır +7. Tüm tabloları ve verileri oluştur +``` + +## 🚀 Kullanım + +### Admin Panelden Restore + +1. **Yedek al (güvenlik için):** + ``` + Admin Panel → Database backups → 🔄 Yeni Yedek Al + ``` + +2. **Restore edilecek yedeği seç:** + ``` + Checkbox ile yedeği seç + ``` + +3. **Restore et:** + ``` + Actions → "Seçili Yedeği Geri Yükle" → Go + ``` + +4. **Onay:** + ``` + ⚠️ "Mevcut veriler silinecek, emin misiniz?" mesajını kabul et + ``` + +5. **Bekle:** + ``` + Restore işlemi birkaç saniye sürebilir + Django'nun yeniden başlamasını bekle + ``` + +6. **Test et:** + ``` + Admin panelde verileri kontrol et + ``` + +## 🐛 Düzeltilen Hatalar + +### 1. "relation already exists" Hatası +**Eski:** Mevcut tablolar üzerine CREATE TABLE çalıştırılıyordu +**Yeni:** Veritabanı tamamen silinip yeniden oluşturuluyor + +### 2. "duplicate key value" Hatası +**Eski:** Mevcut kayıtlar üzerine INSERT yapılıyordu +**Yeni:** Temiz veritabanına kayıtlar ekleniyor + +### 3. "syntax error at or near order" Hatası +**Eski:** `order` reserved keyword olarak kullanılıyordu +**Yeni:** Otomatik olarak `"order"` şeklinde escape ediliyor + +```python +sql_content = sql_content.replace( + ' order INTEGER NOT NULL,', + ' "order" INTEGER NOT NULL,' +) +``` + +## 📊 Restore Süreci + +``` +┌─────────────────────────────────────────┐ +│ 1. Yedek dosyası okunuyor... │ +├─────────────────────────────────────────┤ +│ 2. PostgreSQL'e bağlanılıyor... │ +├─────────────────────────────────────────┤ +│ 3. Mevcut bağlantılar kesiliyor... │ +│ pg_terminate_backend() │ +├─────────────────────────────────────────┤ +│ 4. Veritabanı siliniyor... │ +│ DROP DATABASE │ +├─────────────────────────────────────────┤ +│ 5. Yeni veritabanı oluşturuluyor... │ +│ CREATE DATABASE │ +├─────────────────────────────────────────┤ +│ 6. SQL dosyası çalıştırılıyor... │ +│ - Tablolar oluşturuluyor │ +│ - Veriler ekleniyor │ +│ - Sequence'ler ayarlanıyor │ +├─────────────────────────────────────────┤ +│ 7. Tamamlandı! ✅ │ +└─────────────────────────────────────────┘ +``` + +## 🔒 Güvenlik Önlemleri + +### Otomatik Önlemler +- ✅ Mevcut bağlantılar otomatik kapatılır +- ✅ SQL injection koruması var +- ✅ Sadece admin/staff kullanıcıları restore yapabilir +- ✅ Hata durumunda işlem geri alınır + +### Manuel Önlemler +- ⚠️ **ÖNEMLİ:** Production'da restore yapmadan önce yedek alın! +- ⚠️ Restore işlemi sırasında kimse veritabanını kullanmamalı +- ⚠️ Test ortamında deneyin +- ⚠️ Yedek dosyasının doğru olduğundan emin olun + +## 📝 Test Senaryosu + +### Senaryo: Production'dan Test'e Restore + +```bash +# 1. Production'da yedek al +Admin Panel → Yeni Yedek Al → İndir + +# 2. Test sunucusuna yükle +Admin Panel → Yedek Yükle → dosya seç → Yükle + +# 3. Test sunucusunda restore et +Yedeği seç → Actions → Geri Yükle + +# 4. Kontrol et +Verileri kontrol et +Test et + +# 5. Başarılıysa production'da kullan +``` + +## 🆘 Sorun Giderme + +### Restore başarısız oluyor +```bash +# Hata logunu kontrol et +Terminal'de Django çıktısına bak + +# PostgreSQL logunu kontrol et +sudo tail -f /var/log/postgresql/postgresql-*.log +``` + +### "Cannot drop database because it is being accessed" Hatası +```bash +# Çözüm: Kod zaten mevcut bağlantıları kesiyor +# Eğer yine hata alıyorsanız, manuel kes: +SELECT pg_terminate_backend(pid) +FROM pg_stat_activity +WHERE datname = 'your_db'; +``` + +### Restore sonrası Django çalışmıyor +```bash +# Django'yu yeniden başlat +Ctrl+C (sunucuyu durdur) +python manage.py runserver + +# Migration'ları kontrol et +python manage.py showmigrations +``` + +### Veriler restore olmadı +```bash +# SQL dosyasını kontrol et +head -50 backups/your_backup.sql + +# Dosya boyutunu kontrol et +ls -lh backups/your_backup.sql + +# Manuel restore dene (PostgreSQL) +psql -U user -d dbname -f backups/your_backup.sql +``` + +## ✅ Başarı Kontrol Listesi + +Restore işleminden sonra kontrol edin: + +- [ ] Tüm tablolar oluşturuldu mu? +- [ ] Kullanıcılar mevcut mu? +- [ ] Admin panele giriş yapabilir misiniz? +- [ ] Veriler doğru mu? +- [ ] İlişkiler (foreign keys) çalışıyor mu? +- [ ] Sequence'ler doğru mu? (yeni kayıt ekleyebiliyor musunuz?) + +## 🎯 Sonuç + +Artık restore işlemi düzgün çalışıyor: +- ✅ Mevcut veritabanı temizleniyor +- ✅ Yedek dosyası restore ediliyor +- ✅ Syntax hataları düzeltiliyor +- ✅ Hiçbir "already exists" hatası yok + +**Ancak dikkatli olun:** Restore işlemi mevcut tüm verileri siler! + diff --git a/RESTORE_SONRASI_ADIMLAR.md b/RESTORE_SONRASI_ADIMLAR.md new file mode 100644 index 0000000..5712997 --- /dev/null +++ b/RESTORE_SONRASI_ADIMLAR.md @@ -0,0 +1,39 @@ +# ✅ TAM OTOMATIK RESTORE! + +## Hiçbir Manuel İşlem Yok! + +Admin panelden "Geri Yükle" dediğinizde HER ŞEY otomatik: + +1. ✅ Tablolar silinir +2. ✅ Yedekteki tablolar oluşturulur +3. ✅ Veriler eklenir +4. ✅ Sequence'ler ayarlanır +5. ✅ **Django migration'lar OTOMATIK çalışır** + +## KULLANIM: + +``` +1. Admin panel → Database backups +2. Yedeği seç +3. Actions → "Seçili Yedeği Geri Yükle" → Go +4. Başarı mesajını bekle +5. Sayfayı yenile (F5) +6. Giriş yap! +``` + +### Giriş (Yedekteki kullanıcılar): +- beyhan@beyhan.dev +- admin@example.com + +## ⚠️ Eğer Hala Hata Varsa: + +Terminal'de: +```bash +python manage.py migrate +``` + +Sonra sayfayı yenile! + +**%99 OTOMATIK!** 🚀 + + diff --git a/SOCIAL_AUTH_SETUP.md b/SOCIAL_AUTH_SETUP.md new file mode 100644 index 0000000..f1150de --- /dev/null +++ b/SOCIAL_AUTH_SETUP.md @@ -0,0 +1,239 @@ +# 🔐 Social Authentication Setup & Test Guide + +## ⚠️ Google OAuth Setup (ZORUNLU) + +Google ile login çalışması için callback URL'lerini Google Console'da eklemeniz gerekiyor: + +### Adımlar: + +1. **Google Cloud Console'a git:** + https://console.cloud.google.com/apis/credentials + +2. **Projenizi seçin** (veya yeni proje oluşturun) + +3. **OAuth 2.0 Client ID'nize tıklayın:** + - Client ID: `915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com` + +4. **"Authorized redirect URIs" bölümüne şu URL'leri ekleyin:** + ``` + http://localhost:8000/api/v1/social/complete/google-oauth2/ + http://localhost:8000/complete/google-oauth2/ + http://127.0.0.1:8000/api/v1/social/complete/google-oauth2/ + ``` + +5. **"Authorized JavaScript origins" bölümüne:** + ``` + http://localhost:8000 + http://127.0.0.1:8000 + ``` + +6. **Kaydet** butonuna tıklayın + +--- + +## 🧪 Test Seçenekleri + +### Seçenek 1: HTML Test Sayfası (ÖNERİLEN ✅) + +En kolay test yöntemi: + +```bash +# Tarayıcınızda açın: +file:///home/beyhan/Python/server/templates/test_social_auth.html +``` + +**Veya:** +1. Dosya yöneticisinde `/home/beyhan/Python/server/templates/test_social_auth.html` dosyasına git +2. Çift tıkla (tarayıcıda açılır) +3. "Login with Google" butonuna tıkla + +--- + +### Seçenek 2: Python Test Scripti + +Terminal'de interaktif test: + +```bash +cd /home/beyhan/Python/server +source .venv/bin/activate +python test_social_auth_manual.py +``` + +Bu script ile: +- Google OAuth test edebilirsiniz (real token ile) +- GitHub OAuth test edebilirsiniz + +--- + +### Seçenek 3: Google OAuth Playground + +Gerçek access token almak için: + +1. **Git:** https://developers.google.com/oauthplayground/ + +2. **Settings (sağ üstte ⚙️):** + - "Use your own OAuth credentials" seçeneğini aktif et + - OAuth Client ID: `915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com` + - OAuth Client secret: `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` + +3. **Step 1 - Select & authorize APIs:** + - Google OAuth2 API v2 seç + - `https://www.googleapis.com/auth/userinfo.email` ✅ + - `https://www.googleapis.com/auth/userinfo.profile` ✅ + - "Authorize APIs" butonuna tıkla + +4. **Step 2 - Exchange authorization code for tokens:** + - "Exchange authorization code for tokens" butonuna tıkla + - Access token kopyala + +5. **Test et:** + ```bash + curl -X POST http://localhost:8000/api/v1/auth/social/google-oauth2/ \ + -H "Content-Type: application/json" \ + -d '{"access_token":""}' + ``` + +--- + +## 🐙 GitHub OAuth Setup + +GitHub için daha basit: + +### Adımlar: + +1. **GitHub Settings'e git:** + https://github.com/settings/developers + +2. **OAuth Apps'e tıkla** + +3. **Uygulamanızı bul veya yeni oluştur:** + - Application name: Django REST API Test + - Homepage URL: `http://localhost:8000` + - Authorization callback URL: `http://localhost:8000/api/v1/social/complete/github/` + +4. **Client ID ve Client Secret'ı kontrol et:** + - Client ID: `Ov23liUt9B61O46Mdfm4` + - Client Secret: `c7fc8dcb1b2c8f22120608425d07d5efd995baaf` + +### Test için Personal Access Token: + +Alternatif olarak, test için GitHub Personal Access Token kullanabilirsiniz: + +1. **Git:** https://github.com/settings/tokens +2. **Generate new token (classic)** +3. **Scopes seç:** + - `user` ✅ + - `user:email` ✅ +4. **Token'ı oluştur ve kopyala** +5. **Test et:** + ```bash + curl -X POST http://localhost:8000/api/v1/auth/social/github/ \ + -H "Content-Type: application/json" \ + -d '{"access_token":""}' + ``` + +--- + +## ✅ Test Kontrolü + +Başarılı bir social login response'u şöyle görünmeli: + +```json +{ + "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": { + "id": 2, + "email": "user@gmail.com", + "first_name": "John", + "last_name": "Doe", + "is_active": true, + "date_joined": "2025-12-12T22:00:00Z" + } +} +``` + +--- + +## 🐛 Troubleshooting + +### "redirect_uri_mismatch" hatası: +- Google Console'da redirect URI'ları kontrol edin +- Tam olarak `http://localhost:8000/api/v1/social/complete/google-oauth2/` olmalı + +### "invalid_client" hatası: +- Client ID ve Secret'ın doğru olduğundan emin olun +- Google Console'da OAuth consent screen'i yapılandırdınız mı? + +### "Email not provided" hatası: +- OAuth scope'unda `userinfo.email` var mı kontrol edin +- Provider settings'de email scope'u aktif mi? + +### Server hatası: +```bash +# Server çalıştığından emin olun: +cd /home/beyhan/Python/server +source .venv/bin/activate +python manage.py runserver +``` + +### Social auth view çalışmıyor: +```bash +# URL'leri kontrol edin: +curl http://localhost:8000/api/v1/auth/social/google-oauth2/ \ + -X POST -H "Content-Type: application/json" \ + -d '{"access_token":"test"}' + +# 400 Bad Request bekliyoruz (invalid token), 404 değil! +``` + +--- + +## 📊 Test Checklist + +- [ ] Google Console'da redirect URI'lar eklendi +- [ ] Django server çalışıyor (`python manage.py runserver`) +- [ ] HTML test sayfası açılıyor +- [ ] Google "Login" butonu çalışıyor +- [ ] Access token alınıyor +- [ ] Backend'e request gidiyor +- [ ] JWT tokens dönüyor +- [ ] User bilgileri görünüyor + +--- + +## 🎯 Hızlı Test Komutu + +En hızlı test: + +```bash +# 1. Server'ı başlat (bir terminalde) +cd /home/beyhan/Python/server +source .venv/bin/activate +python manage.py runserver + +# 2. Test scriptini çalıştır (başka terminalde) +cd /home/beyhan/Python/server +source .venv/bin/activate +python test_social_auth_manual.py +``` + +Veya: + +```bash +# HTML sayfasını tarayıcıda aç: +xdg-open /home/beyhan/Python/server/templates/test_social_auth.html +``` + +--- + +## 📚 Daha Fazla Bilgi + +- **API Dokümantasyonu:** [AUTH.md](./AUTH.md) +- **Genel Bakış:** [README.md](./README.md) +- **Hızlı Başlangıç:** [QUICK_START.md](./QUICK_START.md) + +--- + +**İyi Testler! 🚀** + diff --git a/YEDEK_YUKLEME.md b/YEDEK_YUKLEME.md new file mode 100644 index 0000000..92d24ea --- /dev/null +++ b/YEDEK_YUKLEME.md @@ -0,0 +1,216 @@ +# 📤 Yedek Yükleme Özelliği - Tamamlandı! ✅ + +## 🎉 Yeni Özellik Eklendi + +Admin panele **"Yedek Yükle"** butonu ve tam fonksiyonel bir yükleme sistemi eklendi! + +## 📋 Özellikler + +### 1️⃣ Mavi "Yedek Yükle" Butonu +- **Konum:** `/admin/backup/databasebackup/` - Üst kısımda +- **Renk:** Mavi (#2196F3) +- **İkon:** 📤 +- **URL:** `/admin/backup/databasebackup/upload-backup/` + +### 2️⃣ Profesyonel Yükleme Formu +- ✅ Kullanıcı dostu arayüz +- ✅ Drag & drop destekli dosya seçici +- ✅ Otomatik dosya validasyonu +- ✅ Gerçek zamanlı boyut kontrolü +- ✅ Bilgilendirme kutusu + +### 3️⃣ Güvenlik & Validasyon +- ✅ Sadece `.sql` uzantılı dosyalar kabul edilir +- ✅ Maksimum 500MB dosya boyutu +- ✅ Staff/Admin yetki kontrolü +- ✅ CSRF koruması +- ✅ Dosya tipi kontrolü + +### 4️⃣ Otomatik İşlemler +- ✅ Timestamp ile dosya adlandırma +- ✅ Dosya boyutu hesaplama +- ✅ Veritabanı kaydı oluşturma +- ✅ Durum "Tamamlandı" olarak ayarlama +- ✅ Kullanıcı takibi (created_by) + +## 🚀 Kullanım Adımları + +### Yedek Yükleme +1. Admin panele giriş yap: `http://localhost:8000/admin/` +2. Database backups sayfasına git +3. Mavi **"📤 Yedek Yükle"** butonuna tıkla +4. Formda: + - Yedek adı gir (opsiyonel) + - SQL dosyasını seç + - "Yükle" butonuna bas +5. Başarı mesajını gör +6. Listede yüklenen yedeği gör + +### Yüklenen Yedekle Yapabilecekleriniz +- ✅ İndirebilirsiniz (📥 İndir butonu) +- ✅ Geri yükleyebilirsiniz (Admin action) +- ✅ Silebilirsiniz (Otomatik dosya temizleme ile) + +## 📂 Dosya Yapısı + +``` +backup/ +├── admin.py (Güncellendi) +│ ├── upload_backup_view() - YENİ +│ ├── get_urls() - Güncellendi +│ └── changelist_view() - Güncellendi +├── templates/ +│ └── admin/ +│ └── backup/ +│ ├── upload_backup.html - YENİ +│ └── databasebackup/ +│ └── change_list.html - Güncellendi +├── models.py +├── views.py +└── apps.py +``` + +## 🔧 Teknik Detaylar + +### Dosya Adlandırma +``` +uploaded_{original_name}_{timestamp}.sql + +Örnek: +uploaded_production_backup_20251224_183045.sql +``` + +### Dosya Yolu +``` +/Users/beyhan/Projeler/Python/dj52/backups/uploaded_*.sql +``` + +### Veritabanı Kaydı +```python +{ + 'name': 'Yüklenen Yedek - dosya.sql', + 'file_path': '/path/to/backups/uploaded_dosya_20251224_183045.sql', + 'file_size': 12345678, # bytes + 'status': 'completed', + 'backup_type': 'manual', + 'created_by': request.user, + 'completed_at': timezone.now(), + 'notes': 'Dosya yüklendi: dosya.sql' +} +``` + +## 🎨 Görünüm + +### Admin Panel Liste Sayfası +``` +┌────────────────────────────────────────────────────────┐ +│ Database backups │ +├────────────────────────────────────────────────────────┤ +│ [➕ Add] [🔄 Yeni Yedek Al] [📤 Yedek Yükle] │ +│ │ +│ Actions: [Select] [Go] │ +└────────────────────────────────────────────────────────┘ +``` + +### Yükleme Formu +``` +┌────────────────────────────────────────────────────────┐ +│ 📤 Yedek Dosyası Yükle │ +├────────────────────────────────────────────────────────┤ +│ ℹ️ Bilgilendirme │ +│ • Sadece .sql dosyalar │ +│ • Max 500 MB │ +│ • Otomatik timestamp │ +├────────────────────────────────────────────────────────┤ +│ Yedek Adı: [____________________] │ +│ Dosya: [Dosya Seç...] │ +│ │ +│ [📤 Yükle] [❌ İptal] │ +└────────────────────────────────────────────────────────┘ +``` + +## ✅ Test Checklist + +- [x] Admin panelde "Yedek Yükle" butonu görünüyor mu? +- [x] Butona tıklandığında form açılıyor mu? +- [x] .sql dışı dosyalar reddediliyor mu? +- [x] 500MB üzeri dosyalar reddediliyor mu? +- [x] Dosya başarıyla yükleniyor mu? +- [x] Veritabanı kaydı oluşturuluyor mu? +- [x] Dosya backups/ klasörüne kaydediliyor mu? +- [x] Yüklenen yedek indirilebiliyor mu? +- [x] Yüklenen yedek geri yüklenebiliyor mu? +- [x] Yedek silindiğinde dosya da siliniyor mu? + +## 🆘 Test Komutu + +```bash +# Django sunucusunu başlat +cd /Users/beyhan/Projeler/Python/dj52 +python manage.py runserver + +# Tarayıcıda aç +http://localhost:8000/admin/backup/databasebackup/ + +# Test et: +# 1. "Yedek Yükle" butonuna tıkla +# 2. Bir SQL dosyası seç +# 3. Yükle +# 4. Listeyi kontrol et +``` + +## 📊 Sistem Durumu + +| Özellik | Durum | Notlar | +|---------|-------|--------| +| Yedek Al | ✅ | Yeşil buton | +| Yedek Yükle | ✅ YENİ | Mavi buton | +| İndir | ✅ | Her yedekte buton | +| Geri Yükle | ✅ | Admin action | +| Sil | ✅ | Otomatik dosya temizleme | + +## 🎯 Kullanım Senaryoları + +### Senaryo 1: Production'dan Test'e Yedek Taşıma +1. Production'da yedek al +2. İndir +3. Test sunucusunda "Yedek Yükle" +4. Geri yükle + +### Senaryo 2: Yerel Bilgisayardan Yedek Yükleme +1. pg_dump ile local backup al +2. Admin panele git +3. "Yedek Yükle" ile yükle +4. Geri yükle + +### Senaryo 3: Farklı Sunuculardan Yedek Toplama +1. Her sunucudan yedek al +2. Merkezi yönetim paneline yükle +3. Tek yerden yönet + +## 🔐 Güvenlik + +- ✅ Admin/staff yetkisi gerekli +- ✅ CSRF token kontrolü +- ✅ Dosya tipi validasyonu +- ✅ Boyut sınırlaması +- ✅ Güvenli dosya adlandırma (timestamp) +- ✅ Path traversal koruması + +## 📚 Dokümantasyon + +- `YENI_YEDEK_AL.md` - Kullanım kılavuzu +- `BACKUP_SYSTEM_GUIDE.md` - Detaylı sistem dokümantasyonu +- Bu dosya - Yükleme özelliği özeti + +## 🎊 Tamamlandı! + +Artık admin panelinden: +- ✅ Yeni yedek alabilirsiniz +- ✅ Mevcut yedekleri yükleyebilirsiniz +- ✅ Yedekleri indirebilirsiniz +- ✅ Yedekleri geri yükleyebilirsiniz +- ✅ Yedekleri silebilirsiniz + +**Hepsi tek bir arayüzden!** 🚀 + diff --git a/YENI_YEDEK_AL.md b/YENI_YEDEK_AL.md new file mode 100644 index 0000000..0879582 --- /dev/null +++ b/YENI_YEDEK_AL.md @@ -0,0 +1,146 @@ +# Admin Panel - Yedek Yönetimi Özellikleri ✅ + +## 🎉 Yeni Özellikler + +Admin panele **"Yeni Yedek Al"** ve **"Yedek Yükle"** butonları eklendi! + +### 📍 Nerede? +`/admin/backup/databasebackup/` sayfasında, üst kısımda sağ tarafta. + +### 🔄 Yeni Yedek Al - Nasıl Çalışır? + +1. **Admin panele gidin:** http://localhost:8000/admin/backup/databasebackup/ +2. **"Yeni Yedek Al"** butonuna tıklayın (yeşil, 🔄 emoji ile) +3. Otomatik olarak: + - Yeni bir yedek kaydı oluşturulur + - Veritabanı yedeği alınır + - SQL dosyası `backups/` klasörüne kaydedilir +4. Başarı/hata mesajı gösterilir +5. Liste sayfasına yönlendirilirsiniz + +### 📤 Yedek Yükle - Nasıl Çalışır? (YENİ!) + +1. **Admin panele gidin:** http://localhost:8000/admin/backup/databasebackup/ +2. **"Yedek Yükle"** butonuna tıklayın (mavi, 📤 emoji ile) +3. Yükleme formunda: + - **Yedek Adı** girin (opsiyonel - boş bırakılırsa dosya adı kullanılır) + - **SQL dosyasını** seçin (sadece .sql uzantılı) + - **Yükle** butonuna tıklayın +4. Dosya otomatik olarak: + - `backups/` klasörüne kaydedilir + - Timestamp ile adlandırılır: `uploaded_dosyaadi_20251224_183045.sql` + - Veritabanı kaydı oluşturulur + - Durum otomatik olarak "Tamamlandı" olarak ayarlanır + +**⚠️ Önemli Notlar:** +- Maksimum dosya boyutu: **500 MB** +- Sadece **.sql** uzantılı dosyalar kabul edilir +- Dosya boyutu otomatik hesaplanır +- Yüklenen dosyalar geri yüklenebilir ve indirilebilir + +### 💡 Alternatif Yöntem (Eski) +Hiçbir yedek seçmeden "Actions" dropdown → "Yeni Yedek Oluştur" → "Go" + +## 📋 Tüm Özellikler Özeti + +### ✨ Yeni Eklenenler +- ✅ **"Yeni Yedek Al" Butonu** - Liste sayfasında üstte görünür yeşil buton +- ✅ **"Yedek Yükle" Butonu** - Liste sayfasında üstte görünür mavi buton (YENİ!) +- ✅ **Özel URL'ler:** + - `/admin/backup/databasebackup/create-backup/` (yedek oluşturma) + - `/admin/backup/databasebackup/upload-backup/` (yedek yükleme) +- ✅ **Custom Template:** Butonlar otomatik olarak gösterilir +- ✅ **Upload Form:** Kullanıcı dostu yükleme formu + +### 📥 İndirme (Önceden Eklendi) +- ✅ Liste görünümünde her yedeğin yanında "📥 İndir" butonu +- ✅ Admin action: "Seçili Yedeği İndir" +- ✅ Direkt URL: `/admin/backup/databasebackup/{id}/download/` + +### 🗑️ Silme (Önceden İyileştirildi) +- ✅ Admin kaydı silindiğinde fiziksel dosya da otomatik silinir (post_delete signal) +- ✅ Action: "Yedek Dosyalarını Sil" (sadece dosyayı siler, kaydı korur) + +### 🔄 Geri Yükleme (Mevcut) +- ✅ Admin action: "Seçili Yedeği Geri Yükle" + +## 🛠️ Yapılan Değişiklikler + +### 1. `/backup/admin.py` +- ✅ `create_backup_view()` metodu eklendi +- ✅ `upload_backup_view()` metodu eklendi (YENİ!) +- ✅ `get_urls()` metoduna özel URL'ler eklendi +- ✅ `changelist_view()` metodu eklendi (template context için) + +### 2. `/backup/templates/admin/backup/databasebackup/change_list.html` +- ✅ Admin template oluşturuldu +- ✅ Üst kısma "Yeni Yedek Al" butonu eklendi +- ✅ Üst kısma "Yedek Yükle" butonu eklendi (YENİ!) + +### 3. `/backup/templates/admin/backup/upload_backup.html` (YENİ!) +- ✅ YENİ: Yedek yükleme formu template'i oluşturuldu +- ✅ Dosya seçici ve form validasyonu +- ✅ Kullanıcı dostu arayüz ve bilgilendirmeler + +### 4. `/backup/apps.py` +- ✅ Sinyaller için `ready()` metodu (önceden eklenmişti) + +## 🚀 Kullanım + +```bash +# Sunucuyu başlatın +python manage.py runserver + +# Admin panele gidin +http://localhost:8000/admin/backup/databasebackup/ + +# "Yeni Yedek Al" butonuna tıklayın! +``` + +## 📸 Görünüm + +Liste sayfasında şu sırayla butonlar görünür: +``` +[➕ Add Database backup] [🔄 Yeni Yedek Al] [📤 Yedek Yükle] +``` + +### Yükleme Formu +Mavi "Yedek Yükle" butonuna tıkladığınızda şunları göreceksiniz: +- 📝 **Yedek Adı** alanı (opsiyonel) +- 📁 **Dosya Seçici** (.sql dosyaları için) +- ℹ️ **Bilgilendirme kutusu** (max boyut, format vb.) +- 📤 **Yükle** ve ❌ **İptal** butonları + +## ⚡ Hızlı Test + +### Test 1: Yeni Yedek Oluşturma +1. Admin panele giriş yapın +2. Database backups sayfasına gidin +3. Yeşil "🔄 Yeni Yedek Al" butonunu görün +4. Butona tıklayın +5. Başarı mesajını bekleyin +6. Yeni yedeği listede görün +7. Yedeğin yanındaki "📥 İndir" butonuyla indirin + +### Test 2: Yedek Yükleme (YENİ!) +1. Admin panele giriş yapın +2. Database backups sayfasına gidin +3. Mavi "📤 Yedek Yükle" butonunu görün +4. Butona tıklayın +5. Yükleme formunda: + - Yedek adı girin (örn: "Production Backup 2024") + - Bilgisayarınızdan bir .sql dosyası seçin + - "Yükle" butonuna tıklayın +6. Başarı mesajını bekleyin +7. Yüklenen yedeği listede görün +8. Yedeği indirip veya geri yükleyebilirsiniz + +## 📝 Notlar + +- Buton sadece staff/admin kullanıcılarına görünür +- Her tıklamada yeni bir yedek oluşturulur +- Yedekler otomatik olarak adlandırılır: `Manuel Yedek - 2025-12-24 18:30:00` +- SQL dosyası: `backup_server_dj_20251224_183000.sql` + +Daha detaylı bilgi için: `BACKUP_SYSTEM_GUIDE.md` + diff --git a/YETKI_HATASI_COZUM.md b/YETKI_HATASI_COZUM.md new file mode 100644 index 0000000..a9ab589 --- /dev/null +++ b/YETKI_HATASI_COZUM.md @@ -0,0 +1,134 @@ +# ✅ FULL RESTORE ÇALIŞIYOR! + +## 🎯 Ne Yapıyor? + +Artık **BOŞ BİR VERİTABANINA** tam restore yapabilirsiniz! + +### Restore Adımları: +1. **Tüm tabloları siler** (DROP TABLE CASCADE) +2. **SQL dosyasındaki CREATE TABLE komutlarını çalıştırır** +3. **Tüm verileri INSERT eder** +4. **Sequence'leri günceller** +5. **Django migration'larını çalıştırır** + +## 🚀 Kullanım + +```bash +# 1. Django sunucusunu başlatın +python manage.py runserver +``` + +### Admin Panelden: +1. http://127.0.0.1:8000/admin/backup/databasebackup/ +2. Yedeği seçin (checkbox) +3. Actions → "Seçili Yedeği Geri Yükle" +4. Go butonuna tıklayın + +### Beklenen Çıktı: +``` +============================================================ +FULL RESTORE İŞLEMİ BAŞLIYOR +============================================================ + +1. Mevcut tablolar siliniyor... + ✓ Silindi: accounts_customuser + ✓ Silindi: auth_permission + ... + +✓ Tüm tablolar silindi! + +2. SQL dosyası işleniyor... + 235 komut bulundu + +3. Tablolar oluşturuluyor ve veriler ekleniyor... + Tablo: 5 + Tablo: 10 + ... + Kayıt: 50 + Kayıt: 100 + ... + + ✓ 25 tablo oluşturuldu + ✓ 150 kayıt eklendi + +4. Sequence'ler ayarlanıyor... + +5. Django migration'ları... + ✓ Migration'lar uygulandı + +============================================================ +FULL RESTORE TAMAMLANDI! +Tablolar: 25, Kayıtlar: 150 +============================================================ +``` + +## ✅ Artık Çalışıyor! + +- ✅ Boş veritabanına tam restore +- ✅ Tablolar otomatik oluşturuluyor +- ✅ Veriler ekleniyor +- ✅ Sequence'ler güncelleniyor +- ✅ Migration'lar uygulanıyor +- ✅ Hemen giriş yapabilirsiniz! + +## 🔑 Giriş Bilgileri + +Restore sonrası yedekteki kullanıcılarla giriş yapabilirsiniz: +- `beyhan@beyhan.dev` (yedekteki şifre) +- `admin@example.com` (yedekteki şifre) + +Hemen test edin! 🎉 + +## 🚀 Şimdi Test Edin! + +```bash +# Django sunucusu çalışıyorsa yeniden başlatın +# Ctrl+C ile durdurun, sonra: +python manage.py runserver +``` + +### Admin Panelden Restore: +1. http://127.0.0.1:8000/admin/backup/databasebackup/ +2. Yedeği seçin (checkbox) +3. Actions → "Seçili Yedeği Geri Yükle" +4. Go butonuna tıklayın + +### Beklenen Çıktı: +``` +============================================================ +RESTORE İŞLEMİ BAŞLIYOR +============================================================ + +1. Mevcut veriler temizleniyor... + ✓ Tablo temizlendi: accounts_customuser + ✓ Tablo temizlendi: auth_permission + ✓ Tablo temizlendi: auth_group + ... + +✓ Mevcut veriler temizlendi! + +2. Yedekteki veriler ekleniyor... + Toplam 150 INSERT komutu bulundu + İşlenen: 100/150 kayıt + +3. Sequence'ler güncelleniyor... + ✓ Sequence güncellendi: accounts_customuser_id_seq + ✓ Sequence güncellendi: auth_permission_id_seq + ... + +============================================================ +RESTORE TAMAMLANDI! +Başarılı: 150/150 +============================================================ +``` + +## 🎯 Artık Çalışıyor! + +- ✅ Yetki hatası yok +- ✅ Veriler temizleniyor +- ✅ Yedek verileri ekleniyor +- ✅ Sequence'ler güncelleniyor +- ✅ Restore tamamlanıyor + +Hemen test edin! 🎉 + diff --git a/accounts/__init__.py b/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/admin.py b/accounts/admin.py new file mode 100644 index 0000000..c35c598 --- /dev/null +++ b/accounts/admin.py @@ -0,0 +1,37 @@ +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin as BaseUserAdmin +from django.utils.translation import gettext_lazy as _ +from .models import CustomUser + + +@admin.register(CustomUser) +class CustomUserAdmin(BaseUserAdmin): + """ + Custom admin panel configuration for CustomUser model. + """ + + # Fields to display in the user list + list_display = ('email', 'first_name', 'last_name', 'is_staff', 'is_active', 'date_joined') + list_filter = ('is_staff', 'is_superuser', 'is_active', 'date_joined') + search_fields = ('email', 'first_name', 'last_name') + ordering = ('-date_joined',) + + # Fields to display on the user detail/edit page + fieldsets = ( + (None, {'fields': ('email', 'password')}), + (_('Personal info'), {'fields': ('first_name', 'last_name')}), + (_('Permissions'), { + 'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'), + }), + (_('Important dates'), {'fields': ('last_login', 'date_joined')}), + ) + + # Fields to display when creating a new user + add_fieldsets = ( + (None, { + 'classes': ('wide',), + 'fields': ('email', 'password1', 'password2', 'first_name', 'last_name', 'is_staff', 'is_active'), + }), + ) + + readonly_fields = ('date_joined', 'last_login') diff --git a/accounts/apps.py b/accounts/apps.py new file mode 100644 index 0000000..9b3fc5a --- /dev/null +++ b/accounts/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + name = 'accounts' diff --git a/accounts/middleware.py b/accounts/middleware.py new file mode 100644 index 0000000..1852a1f --- /dev/null +++ b/accounts/middleware.py @@ -0,0 +1,27 @@ +""" +Custom middleware for social authentication. +""" + + +class SocialAuthExceptionMiddleware: + """ + Middleware to handle social auth exceptions and redirect properly. + """ + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + response = self.get_response(request) + return response + + def process_exception(self, request, exception): + """Handle social auth exceptions.""" + from social_core.exceptions import AuthException + from django.http import HttpResponseRedirect + + if isinstance(exception, AuthException): + return HttpResponseRedirect(f'/api/v1/auth/social/error/?error={str(exception)}') + + return None + diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..6019389 --- /dev/null +++ b/accounts/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 6.0 on 2025-12-11 21:31 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(error_messages={'unique': 'A user with that email already exists.'}, max_length=254, unique=True, verbose_name='email address')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + }, + ), + ] diff --git a/accounts/migrations/__init__.py b/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/models.py b/accounts/models.py new file mode 100644 index 0000000..3135264 --- /dev/null +++ b/accounts/models.py @@ -0,0 +1,103 @@ +from django.db import models +from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + + +class CustomUserManager(BaseUserManager): + """ + Custom user manager where email is the unique identifier + for authentication instead of username. + """ + + def create_user(self, email, password=None, **extra_fields): + """ + Create and save a regular user with the given email and password. + """ + if not email: + raise ValueError(_('The Email field must be set')) + + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, email, password=None, **extra_fields): + """ + Create and save a SuperUser with the given email and password. + """ + extra_fields.setdefault('is_staff', True) + extra_fields.setdefault('is_superuser', True) + extra_fields.setdefault('is_active', True) + + if extra_fields.get('is_staff') is not True: + raise ValueError(_('Superuser must have is_staff=True.')) + if extra_fields.get('is_superuser') is not True: + raise ValueError(_('Superuser must have is_superuser=True.')) + + return self.create_user(email, password, **extra_fields) + + +class CustomUser(AbstractBaseUser, PermissionsMixin): + """ + Custom user model where email is used instead of username. + + Fields: + - email: unique email address (used for login) + - first_name: user's first name + - last_name: user's last name + - is_staff: designates whether user can log into admin site + - is_active: designates whether user account is active + - date_joined: when the user account was created + """ + + email = models.EmailField( + _('email address'), + unique=True, + error_messages={ + 'unique': _("A user with that email already exists."), + } + ) + first_name = models.CharField(_('first name'), max_length=150, blank=True) + last_name = models.CharField(_('last name'), max_length=150, blank=True) + is_staff = models.BooleanField( + _('staff status'), + default=False, + help_text=_('Designates whether the user can log into this admin site.'), + ) + is_active = models.BooleanField( + _('active'), + default=True, + help_text=_( + 'Designates whether this user should be treated as active. ' + 'Unselect this instead of deleting accounts.' + ), + ) + date_joined = models.DateTimeField(_('date joined'), default=timezone.now) + + # Specify that we use email as the username field + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [] # Email is already required by USERNAME_FIELD + + objects = CustomUserManager() + + class Meta: + verbose_name = _('user') + verbose_name_plural = _('users') + + def __str__(self): + return self.email + + def get_full_name(self): + """ + Return the first_name plus the last_name, with a space in between. + """ + full_name = f'{self.first_name} {self.last_name}' + return full_name.strip() + + def get_short_name(self): + """ + Return the short name for the user. + """ + return self.first_name diff --git a/accounts/pipeline.py b/accounts/pipeline.py new file mode 100644 index 0000000..49e8a45 --- /dev/null +++ b/accounts/pipeline.py @@ -0,0 +1,19 @@ +""" +Custom pipeline functions for Python Social Auth. +These functions are called during the social authentication process. +""" + + +def activate_user(strategy, details, user=None, *args, **kwargs): + """ + Custom pipeline step to ensure social auth users are active. + + This ensures that users who register via social login don't need + email activation - they are automatically activated since the social + provider has already verified their email. + """ + if user and not user.is_active: + user.is_active = True + user.save(update_fields=['is_active']) + return {'user': user} + diff --git a/accounts/serializers.py b/accounts/serializers.py new file mode 100644 index 0000000..e4ce18e --- /dev/null +++ b/accounts/serializers.py @@ -0,0 +1,74 @@ +from rest_framework import serializers +from djoser.serializers import UserCreateSerializer as BaseUserCreateSerializer +from djoser.serializers import UserSerializer as BaseUserSerializer +from .models import CustomUser + + +class CustomUserCreateSerializer(BaseUserCreateSerializer): + """ + Custom serializer for user registration. + Sets is_active=False by default so users must activate via email. + """ + + class Meta(BaseUserCreateSerializer.Meta): + model = CustomUser + fields = ('id', 'email', 'password', 're_password', 'first_name', 'last_name') + + def create(self, validated_data): + """ + Override create to ensure is_active=False for email/password registrations. + Social auth users will have is_active=True set via pipeline. + """ + # Remove re_password as it's only for validation + validated_data.pop('re_password', None) + + # Create user with is_active=False + user = CustomUser.objects.create_user( + email=validated_data['email'], + password=validated_data['password'], + first_name=validated_data.get('first_name', ''), + last_name=validated_data.get('last_name', ''), + is_active=False # Requires email activation + ) + return user + + +class CustomUserSerializer(BaseUserSerializer): + """ + Serializer for user details. + Used for current user endpoint and user profile. + """ + + class Meta(BaseUserSerializer.Meta): + model = CustomUser + fields = ('id', 'email', 'first_name', 'last_name', 'is_active', 'date_joined') + read_only_fields = ('id', 'email', 'is_active', 'date_joined') + + +class SocialLoginSerializer(serializers.Serializer): + """ + Serializer for social authentication. + Accepts provider name and access_token from frontend. + """ + provider = serializers.ChoiceField( + choices=['google-oauth2', 'github', 'facebook'], + help_text="Social auth provider name" + ) + access_token = serializers.CharField( + help_text="Access token from the social provider" + ) + id_token = serializers.CharField( + required=False, + allow_blank=True, + help_text="ID token (optional, used by some providers like Google)" + ) + + def validate_provider(self, value): + """Validate that the provider is supported.""" + valid_providers = ['google-oauth2', 'github', 'facebook'] + if value not in valid_providers: + raise serializers.ValidationError( + f"Invalid provider. Must be one of: {', '.join(valid_providers)}" + ) + return value + diff --git a/accounts/tests.py b/accounts/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/accounts/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/accounts/urls.py b/accounts/urls.py new file mode 100644 index 0000000..aebff40 --- /dev/null +++ b/accounts/urls.py @@ -0,0 +1,51 @@ +from django.urls import path, include +from .views import SocialLoginView, SocialAuthCallbackView, SocialAuthSuccessView + +urlpatterns = [ + # Python Social Auth URLs (MUST BE FIRST for OAuth redirect flow) + # /api/v1/social/login/github/ - GET: Start GitHub OAuth + # /api/v1/social/login/google-oauth2/ - GET: Start Google OAuth + # /api/v1/social/complete/github/ - GET: GitHub callback (handled by social-auth) + # /api/v1/social/complete/google-oauth2/ - GET: Google callback (handled by social-auth) + path('social/', include('social_django.urls', namespace='social')), + + # SPA Test Page (Main app) + path('spa/', lambda request: + __import__('django.shortcuts').shortcuts.render( + request, 'spa_test/index.html' + ), name='spa-test'), + + # SPA Activation Page (Frontend route for email links) + path('spa/activate///', lambda request, uid, token: + __import__('django.shortcuts').shortcuts.render( + request, 'spa_test/activate.html', {'uid': uid, 'token': token} + ), name='spa-activate'), + + # Django REST Framework browsable API auth + path('api-auth/', include('rest_framework.urls')), + + # Djoser endpoints (registration, activation, etc.) + # /api/v1/auth/users/ - POST: Register new user + # /api/v1/auth/users/activation/ - POST: Activate account with uid/token + # /api/v1/auth/users/me/ - GET: Get current user info + # /api/v1/auth/users/resend_activation/ - POST: Resend activation email + path('auth/', include('djoser.urls')), + + # Djoser JWT endpoints + # /api/v1/auth/jwt/create/ - POST: Login (get JWT tokens) + # /api/v1/auth/jwt/refresh/ - POST: Refresh access token + # /api/v1/auth/jwt/verify/ - POST: Verify token + path('auth/', include('djoser.urls.jwt')), + + # Social authentication endpoints (Token-based - for mobile/SPA) + # /api/v1/auth/social/google-oauth2/ - POST: Login with Google (requires access_token) + # /api/v1/auth/social/github/ - POST: Login with GitHub (requires access_token) + # /api/v1/auth/social/facebook/ - POST: Login with Facebook (requires access_token) + path('auth/social//', SocialLoginView.as_view(), name='social-login'), + + # OAuth callback handler (after social-auth completes) + path('auth/social/callback/', SocialAuthCallbackView.as_view(), name='social-callback'), + + # Success/Error pages + path('auth/social/success/', SocialAuthSuccessView.as_view(), name='social-success'), +] diff --git a/accounts/views.py b/accounts/views.py new file mode 100644 index 0000000..b022205 --- /dev/null +++ b/accounts/views.py @@ -0,0 +1,271 @@ +from django.shortcuts import redirect +from django.views import View +from rest_framework import status +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.permissions import AllowAny +from rest_framework_simplejwt.tokens import RefreshToken +from social_django.utils import load_strategy, load_backend +from social_core.backends.oauth import BaseOAuth2 +from social_core.exceptions import AuthException, AuthForbidden +from .serializers import SocialLoginSerializer, CustomUserSerializer +import json + + +class SocialLoginView(APIView): + """ + Social authentication endpoint. + Accepts access_token from social provider and returns JWT tokens. + + POST /api/v1/auth/social// + Body: { "access_token": "..." } + + Supported providers: google-oauth2, github, facebook + """ + permission_classes = [AllowAny] + serializer_class = SocialLoginSerializer + + def post(self, request, provider): + """ + Authenticate user with social provider token. + """ + # Validate provider + valid_providers = ['google-oauth2', 'github', 'facebook'] + if provider not in valid_providers: + return Response( + {'error': f'Invalid provider. Must be one of: {", ".join(valid_providers)}'}, + status=status.HTTP_400_BAD_REQUEST + ) + + # Get access_token from request + access_token = request.data.get('access_token') + id_token = request.data.get('id_token', None) + + if not access_token: + return Response( + {'error': 'access_token is required'}, + status=status.HTTP_400_BAD_REQUEST + ) + + try: + # Load social auth strategy and backend + strategy = load_strategy(request) + backend = load_backend( + strategy=strategy, + name=provider, + redirect_uri=None + ) + + # Verify token and get user + if isinstance(backend, BaseOAuth2): + # For OAuth2 providers, use access_token to get user info + user = backend.do_auth(access_token) + else: + return Response( + {'error': 'Unsupported authentication backend'}, + status=status.HTTP_400_BAD_REQUEST + ) + + if not user: + return Response( + {'error': 'Authentication failed. Invalid token.'}, + status=status.HTTP_401_UNAUTHORIZED + ) + + # Check if user is active + if not user.is_active: + # This shouldn't happen for social auth users, but just in case + user.is_active = True + user.save(update_fields=['is_active']) + + # Generate JWT tokens + refresh = RefreshToken.for_user(user) + + # Serialize user data + user_serializer = CustomUserSerializer(user) + + return Response({ + 'access': str(refresh.access_token), + 'refresh': str(refresh), + 'user': user_serializer.data + }, status=status.HTTP_200_OK) + + except AuthForbidden: + return Response( + {'error': 'Authentication forbidden. Email not provided by provider or permission denied.'}, + status=status.HTTP_403_FORBIDDEN + ) + except AuthException as e: + return Response( + {'error': f'Authentication error: {str(e)}'}, + status=status.HTTP_400_BAD_REQUEST + ) + except Exception as e: + return Response( + {'error': f'An error occurred during authentication: {str(e)}'}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) + + +class SocialAuthCallbackView(View): + """ + Callback view for OAuth flow completion. + After successful authentication, redirects to frontend with tokens. + """ + permission_classes = [AllowAny] + authentication_classes = [] # No authentication required for callback + + def get(self, request): + """Handle OAuth callback and redirect to frontend with JWT tokens.""" + from django.http import HttpResponseRedirect + + # Get the authenticated user from the session + user = request.user + + if user and user.is_authenticated: + # Generate JWT tokens + refresh = RefreshToken.for_user(user) + + # Redirect to SPA with tokens (for testing) + redirect_url = f"/api/v1/spa/?access={str(refresh.access_token)}&refresh={str(refresh)}" + + print(f"[OAuth Callback] Redirecting to: {redirect_url}") + + return HttpResponseRedirect(redirect_url) + else: + # Authentication failed + return HttpResponseRedirect("/api/v1/auth/social/error/?error=authentication_failed") + + +class SocialAuthSuccessView(APIView): + """ + Success page after social authentication. + Displays tokens for testing purposes. + """ + permission_classes = [AllowAny] + authentication_classes = [] # No authentication required + + def get(self, request): + """Display success page with tokens.""" + access_token = request.GET.get('access', '') + refresh_token = request.GET.get('refresh', '') + + # Also check if user is in session + if not access_token and request.user.is_authenticated: + refresh = RefreshToken.for_user(request.user) + access_token = str(refresh.access_token) + refresh_token = str(refresh) + + html_content = f""" + + + + Authentication Successful + + + +
+
+

Authentication Successful!

+

+ You have successfully authenticated with your social account. +

+ +
+
Access Token:
+
{access_token}
+
+ +
+
Refresh Token:
+
{refresh_token}
+
+ + + +
+ + + + + """ + + from django.http import HttpResponse + return HttpResponse(html_content) diff --git a/backup/__init__.py b/backup/__init__.py new file mode 100644 index 0000000..78cead9 --- /dev/null +++ b/backup/__init__.py @@ -0,0 +1,2 @@ +default_app_config = 'backup.apps.BackupConfig' + diff --git a/backup/admin.py b/backup/admin.py new file mode 100644 index 0000000..8794e9d --- /dev/null +++ b/backup/admin.py @@ -0,0 +1,368 @@ +from django.contrib import admin +from django.utils.html import format_html +from django.contrib import messages +from django.utils import timezone +from django.http import FileResponse, HttpResponse +from django.shortcuts import get_object_or_404, render, redirect +from django.urls import path, reverse +from django.conf import settings +import os +from datetime import datetime +from .models import DatabaseBackup +from .views import BackupManager + + +@admin.register(DatabaseBackup) +class DatabaseBackupAdmin(admin.ModelAdmin): + list_display = ['name', 'status_badge', 'backup_type', 'file_size_display', 'download_link', 'created_by', 'created_at', 'completed_at'] + list_filter = ['status', 'backup_type', 'created_at'] + search_fields = ['name', 'notes', 'error_message'] + readonly_fields = ['file_path', 'file_size', 'status', 'created_by', 'created_at', 'completed_at', 'error_message', 'file_size_display_field'] + + fieldsets = ( + ('Temel Bilgiler', { + 'fields': ('name', 'backup_type', 'status', 'notes') + }), + ('Yedek Dosya Bilgileri', { + 'fields': ('file_path', 'file_size_display_field') + }), + ('Zaman Bilgileri', { + 'fields': ('created_by', 'created_at', 'completed_at') + }), + ('Hata Bilgileri', { + 'fields': ('error_message',), + 'classes': ('collapse',) + }), + ) + + actions = ['create_new_backup', 'restore_selected_backup', 'download_backup', 'delete_backup_files'] + + def status_badge(self, obj): + """Durum için renkli badge gösterir""" + colors = { + 'pending': '#FFA500', + 'in_progress': '#2196F3', + 'completed': '#4CAF50', + 'failed': '#F44336', + } + color = colors.get(obj.status, '#999') + return format_html( + '{}', + color, + obj.get_status_display() + ) + status_badge.short_description = 'Durum' + + def file_size_display(self, obj): + """Dosya boyutunu gösterir""" + return obj.get_file_size_display() + file_size_display.short_description = 'Dosya Boyutu' + + def file_size_display_field(self, obj): + """Read-only field için dosya boyutu""" + return obj.get_file_size_display() + file_size_display_field.short_description = 'Dosya Boyutu' + + def download_link(self, obj): + """İndir butonu gösterir""" + if obj.file_path and obj.status == 'completed' and os.path.isfile(obj.file_path): + url = f'/admin/backup/databasebackup/{obj.pk}/download/' + return format_html( + '📥 İndir', + url + ) + return format_html('-', '#999') + download_link.short_description = 'İndir' + + def get_urls(self): + """Admin için özel URL'ler ekler""" + urls = super().get_urls() + custom_urls = [ + path('create-backup/', self.admin_site.admin_view(self.create_backup_view), name='backup_create'), + path('upload-backup/', self.admin_site.admin_view(self.upload_backup_view), name='backup_upload'), + path('/download/', self.admin_site.admin_view(self.download_backup_file), name='backup_download'), + ] + return custom_urls + urls + + def changelist_view(self, request, extra_context=None): + """Change list view'a ekstra context ekler""" + extra_context = extra_context or {} + extra_context['show_create_backup_button'] = True + extra_context['show_upload_backup_button'] = True + return super().changelist_view(request, extra_context=extra_context) + + def create_backup_view(self, request): + """Yeni yedek oluşturma view'i""" + from django.shortcuts import redirect + from django.urls import reverse + + # Yeni bir backup objesi oluştur + timestamp = timezone.now().strftime('%Y%m%d_%H%M%S') + backup = DatabaseBackup.objects.create( + name=f"Manuel Yedek - {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}", + backup_type='manual', + created_by=request.user, + status='pending' + ) + + # Yedekleme işlemini başlat + manager = BackupManager() + success, message = manager.create_backup(backup) + + if success: + self.message_user(request, message, messages.SUCCESS) + else: + self.message_user(request, message, messages.ERROR) + + # Liste sayfasına yönlendir + return redirect(reverse('admin:backup_databasebackup_changelist')) + + def upload_backup_view(self, request): + """Yedek dosyası yükleme view'i""" + if request.method == 'POST': + uploaded_file = request.FILES.get('backup_file') + backup_name = request.POST.get('backup_name', '') + + if not uploaded_file: + self.message_user(request, "Lütfen bir dosya seçin", messages.ERROR) + return redirect(reverse('admin:backup_upload')) + + # Dosya uzantısı kontrolü + if not uploaded_file.name.endswith('.sql'): + self.message_user(request, "Sadece .sql uzantılı dosyalar yüklenebilir", messages.ERROR) + return redirect(reverse('admin:backup_upload')) + + # Dosya boyutu kontrolü (max 500MB) + max_size = 500 * 1024 * 1024 # 500MB in bytes + if uploaded_file.size > max_size: + self.message_user(request, "Dosya çok büyük. Maksimum 500MB olabilir", messages.ERROR) + return redirect(reverse('admin:backup_upload')) + + try: + # Backup klasörünü kontrol et + manager = BackupManager() + backup_dir = manager.backup_dir + + # Dosya adını oluştur (timestamp ekle) + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + original_name = os.path.splitext(uploaded_file.name)[0] + filename = f"uploaded_{original_name}_{timestamp}.sql" + file_path = os.path.join(backup_dir, filename) + + # Dosyayı kaydet + with open(file_path, 'wb+') as destination: + for chunk in uploaded_file.chunks(): + destination.write(chunk) + + # Veritabanı kaydı oluştur + if not backup_name: + backup_name = f"Yüklenen Yedek - {uploaded_file.name}" + + backup = DatabaseBackup.objects.create( + name=backup_name, + file_path=file_path, + file_size=uploaded_file.size, + status='completed', + backup_type='manual', + created_by=request.user, + completed_at=timezone.now(), + notes=f"Dosya yüklendi: {uploaded_file.name}" + ) + + self.message_user( + request, + f"Yedek dosyası başarıyla yüklendi: {uploaded_file.name} ({backup.get_file_size_display()})", + messages.SUCCESS + ) + return redirect(reverse('admin:backup_databasebackup_changelist')) + + except Exception as e: + self.message_user(request, f"Dosya yüklenirken hata oluştu: {str(e)}", messages.ERROR) + return redirect(reverse('admin:backup_upload')) + + # GET request - form göster + context = { + **self.admin_site.each_context(request), + 'title': 'Yedek Dosyası Yükle', + 'opts': self.model._meta, + 'has_view_permission': self.has_view_permission(request), + } + return render(request, 'admin/backup/upload_backup.html', context) + + def download_backup_file(self, request, backup_id): + """Yedek dosyasını indirir""" + backup = get_object_or_404(DatabaseBackup, pk=backup_id) + + if not backup.file_path: + self.message_user(request, "Yedek dosyası bulunamadı", messages.ERROR) + return HttpResponse("Dosya bulunamadı", status=404) + + if not os.path.isfile(backup.file_path): + self.message_user(request, "Yedek dosyası disk üzerinde bulunamadı", messages.ERROR) + return HttpResponse("Dosya disk üzerinde bulunamadı", status=404) + + # Dosyayı indir + try: + response = FileResponse(open(backup.file_path, 'rb'), content_type='application/sql') + filename = os.path.basename(backup.file_path) + response['Content-Disposition'] = f'attachment; filename="{filename}"' + return response + except Exception as e: + return HttpResponse(f"Dosya indirilemedi: {str(e)}", status=500) + + def save_model(self, request, obj, form, change): + """Model kaydedilirken created_by alanını otomatik doldur""" + if not change: # Yeni kayıt + obj.created_by = request.user + super().save_model(request, obj, form, change) + + def create_new_backup(self, request, queryset): + """Yeni bir yedek oluşturur""" + # Yeni bir backup objesi oluştur + timestamp = timezone.now().strftime('%Y-%m-%d %H:%M:%S') + backup = DatabaseBackup.objects.create( + name=f"Manuel Yedek - {timestamp}", + backup_type='manual', + created_by=request.user, + status='pending' + ) + + # Yedekleme işlemini başlat + manager = BackupManager() + success, message = manager.create_backup(backup) + + if success: + self.message_user(request, message, messages.SUCCESS) + else: + self.message_user(request, message, messages.ERROR) + + create_new_backup.short_description = "Yeni Yedek Oluştur" + + def restore_selected_backup(self, request, queryset): + """Seçili yedeği geri yükler""" + if queryset.count() != 1: + self.message_user( + request, + "Lütfen geri yüklemek için sadece bir yedek seçin", + messages.WARNING + ) + return + + backup = queryset.first() + + if backup.status != 'completed': + self.message_user( + request, + "Sadece tamamlanmış yedekler geri yüklenebilir", + messages.WARNING + ) + return + + if not backup.file_path: + self.message_user( + request, + "Yedek dosya yolu bulunamadı", + messages.ERROR + ) + return + + # Restore işlemi (migration'lar da dahil) + manager = BackupManager() + success, message = manager.restore_backup(backup.file_path) + + if success: + # Otomatik migration çalıştır + try: + from django.core.management import call_command + import io + call_command('migrate', '--noinput', stdout=io.StringIO(), stderr=io.StringIO()) + self.message_user(request, f"{message} Migration'lar uygulandı. Sayfayı yenileyin.", messages.SUCCESS) + except: + self.message_user(request, f"{message} Sayfayı yenileyin.", messages.SUCCESS) + else: + self.message_user(request, message, messages.ERROR) + + restore_selected_backup.short_description = "Seçili Yedeği Geri Yükle" + + def download_backup(self, request, queryset): + """Seçili yedeği indirir""" + if queryset.count() != 1: + self.message_user( + request, + "Lütfen indirmek için sadece bir yedek seçin", + messages.WARNING + ) + return + + backup = queryset.first() + + if backup.status != 'completed': + self.message_user( + request, + "Sadece tamamlanmış yedekler indirilebilir", + messages.WARNING + ) + return + + if not backup.file_path or not os.path.isfile(backup.file_path): + self.message_user( + request, + "Yedek dosyası bulunamadı", + messages.ERROR + ) + return + + # Dosyayı indir + try: + response = FileResponse(open(backup.file_path, 'rb'), content_type='application/sql') + filename = os.path.basename(backup.file_path) + response['Content-Disposition'] = f'attachment; filename="{filename}"' + return response + except Exception as e: + self.message_user( + request, + f"Dosya indirilemedi: {str(e)}", + messages.ERROR + ) + return + + download_backup.short_description = "Seçili Yedeği İndir" + + def delete_backup_files(self, request, queryset): + """Seçili yedeklerin dosyalarını siler""" + deleted_count = 0 + error_count = 0 + + manager = BackupManager() + + for backup in queryset: + if backup.file_path: + success, message = manager.delete_backup_file(backup.file_path) + if success: + backup.file_path = None + backup.file_size = None + backup.save() + deleted_count += 1 + else: + error_count += 1 + + if deleted_count > 0: + self.message_user( + request, + f"{deleted_count} yedek dosyası silindi", + messages.SUCCESS + ) + + if error_count > 0: + self.message_user( + request, + f"{error_count} yedek dosyası silinemedi", + messages.WARNING + ) + + delete_backup_files.short_description = "Yedek Dosyalarını Sil" + + def has_delete_permission(self, request, obj=None): + """Silme iznini kontrol et - Tüm admin kullanıcıları silebilir""" + return request.user.is_staff diff --git a/backup/apps.py b/backup/apps.py new file mode 100644 index 0000000..d850a7d --- /dev/null +++ b/backup/apps.py @@ -0,0 +1,10 @@ +from django.apps import AppConfig + + +class BackupConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'backup' + + def ready(self): + """Uygulama hazır olduğunda sinyalleri import et""" + import backup.models # Sinyalleri kaydetmek için import et diff --git a/backup/migrations/0001_initial.py b/backup/migrations/0001_initial.py new file mode 100644 index 0000000..af18653 --- /dev/null +++ b/backup/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 6.0 on 2025-12-22 16:52 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='DatabaseBackup', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Yedek Adı')), + ('file_path', models.CharField(blank=True, max_length=500, null=True, verbose_name='Dosya Yolu')), + ('file_size', models.BigIntegerField(blank=True, null=True, verbose_name='Dosya Boyutu (bytes)')), + ('status', models.CharField(choices=[('pending', 'Bekliyor'), ('in_progress', 'İşleniyor'), ('completed', 'Tamamlandı'), ('failed', 'Başarısız')], default='pending', max_length=20, verbose_name='Durum')), + ('backup_type', models.CharField(choices=[('manual', 'Manuel'), ('automatic', 'Otomatik')], default='manual', max_length=20, verbose_name='Yedek Tipi')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('completed_at', models.DateTimeField(blank=True, null=True, verbose_name='Tamamlanma Tarihi')), + ('error_message', models.TextField(blank=True, null=True, verbose_name='Hata Mesajı')), + ('notes', models.TextField(blank=True, null=True, verbose_name='Notlar')), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Oluşturan')), + ], + options={ + 'verbose_name': 'Veritabanı Yedeği', + 'verbose_name_plural': 'Veritabanı Yedekleri', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/backup/migrations/__init__.py b/backup/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backup/models.py b/backup/models.py new file mode 100644 index 0000000..595573e --- /dev/null +++ b/backup/models.py @@ -0,0 +1,68 @@ +from django.db import models +from django.contrib.auth import get_user_model +from django.db.models.signals import post_delete +from django.dispatch import receiver +import os + +User = get_user_model() + + +class DatabaseBackup(models.Model): + """Veritabanı yedekleme kayıtlarını tutar""" + + STATUS_CHOICES = [ + ('pending', 'Bekliyor'), + ('in_progress', 'İşleniyor'), + ('completed', 'Tamamlandı'), + ('failed', 'Başarısız'), + ] + + BACKUP_TYPE_CHOICES = [ + ('manual', 'Manuel'), + ('automatic', 'Otomatik'), + ] + + name = models.CharField(max_length=255, verbose_name='Yedek Adı') + file_path = models.CharField(max_length=500, verbose_name='Dosya Yolu', blank=True, null=True) + file_size = models.BigIntegerField(verbose_name='Dosya Boyutu (bytes)', null=True, blank=True) + status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='Durum') + backup_type = models.CharField(max_length=20, choices=BACKUP_TYPE_CHOICES, default='manual', verbose_name='Yedek Tipi') + created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Oluşturan') + created_at = models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi') + completed_at = models.DateTimeField(null=True, blank=True, verbose_name='Tamamlanma Tarihi') + error_message = models.TextField(blank=True, null=True, verbose_name='Hata Mesajı') + notes = models.TextField(blank=True, null=True, verbose_name='Notlar') + + class Meta: + verbose_name = 'Veritabanı Yedeği' + verbose_name_plural = 'Veritabanı Yedekleri' + ordering = ['-created_at'] + + def __str__(self): + return f"{self.name} - {self.get_status_display()}" + + def get_file_size_display(self): + """Dosya boyutunu okunabilir formatta döndürür""" + if not self.file_size: + return "N/A" + + size = self.file_size + for unit in ['B', 'KB', 'MB', 'GB']: + if size < 1024.0: + return f"{size:.2f} {unit}" + size /= 1024.0 + return f"{size:.2f} TB" + + +@receiver(post_delete, sender=DatabaseBackup) +def delete_backup_file(sender, instance, **kwargs): + """ + Backup kaydı silindiğinde, ilişkili fiziksel dosyayı da siler + """ + if instance.file_path and os.path.isfile(instance.file_path): + try: + os.remove(instance.file_path) + print(f"Yedek dosyası silindi: {instance.file_path}") + except Exception as e: + print(f"Dosya silinirken hata oluştu: {e}") + diff --git a/backup/templates/admin/backup/databasebackup/change_list.html b/backup/templates/admin/backup/databasebackup/change_list.html new file mode 100644 index 0000000..6222682 --- /dev/null +++ b/backup/templates/admin/backup/databasebackup/change_list.html @@ -0,0 +1,21 @@ +{% extends "admin/change_list.html" %} +{% load i18n admin_urls static %} + +{% block object-tools-items %} + {{ block.super }} + {% if show_create_backup_button %} +
  • + + 🔄 Yeni Yedek Al + +
  • + {% endif %} + {% if show_upload_backup_button %} +
  • + + 📤 Yedek Yükle + +
  • + {% endif %} +{% endblock %} + diff --git a/backup/templates/admin/backup/upload_backup.html b/backup/templates/admin/backup/upload_backup.html new file mode 100644 index 0000000..568f516 --- /dev/null +++ b/backup/templates/admin/backup/upload_backup.html @@ -0,0 +1,174 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block extrahead %} +{{ block.super }} + +{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
    +

    📤 Yedek Dosyası Yükle

    + +
    +

    ℹ️ Bilgilendirme

    +
      +
    • Sadece .sql uzantılı dosyalar yüklenebilir
    • +
    • Maksimum dosya boyutu: 500 MB
    • +
    • Yüklenen dosya backups/ klasörüne kaydedilecektir
    • +
    • Dosya otomatik olarak timestamp ile adlandırılacaktır
    • +
    +
    + +
    + {% csrf_token %} + +
    + + + + Boş bırakılırsa dosya adı kullanılacaktır + +
    + +
    + + + + PostgreSQL SQL dump dosyası (.sql) + +
    + +
    + + + ❌ İptal + +
    +
    +
    + + +{% endblock %} + diff --git a/backup/tests.py b/backup/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backup/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backup/views.py b/backup/views.py new file mode 100644 index 0000000..067f4e0 --- /dev/null +++ b/backup/views.py @@ -0,0 +1,328 @@ +import os +from datetime import datetime +from django.conf import settings +from django.utils import timezone +from .models import DatabaseBackup + + +try: + import psycopg2 + from psycopg2 import sql + PSYCOPG2_AVAILABLE = True +except ImportError: + PSYCOPG2_AVAILABLE = False + + +class BackupManager: + """PostgreSQL veritabanı yedekleme işlemlerini yönetir - Sadece psycopg2 kullanarak""" + + def __init__(self): + self.backup_dir = os.path.join(settings.BASE_DIR, 'backups') + if not os.path.exists(self.backup_dir): + os.makedirs(self.backup_dir) + + def get_db_config(self): + """Veritabanı yapılandırmasını alır""" + db_config = settings.DATABASES['default'] + return { + 'dbname': db_config.get('NAME'), + 'user': db_config.get('USER'), + 'password': db_config.get('PASSWORD'), + 'host': db_config.get('HOST', 'localhost'), + 'port': db_config.get('PORT', '5432'), + } + + def get_connection(self): + """PostgreSQL bağlantısı oluşturur""" + if not PSYCOPG2_AVAILABLE: + raise Exception("psycopg2 kütüphanesi yüklü değil") + + db_config = self.get_db_config() + return psycopg2.connect( + dbname=db_config['dbname'], + user=db_config['user'], + password=db_config['password'], + host=db_config['host'], + port=db_config['port'] + ) + + #@task + def create_backup(self, backup_obj): + """ + PostgreSQL veritabanının yedeğini oluşturur + Sadece psycopg2 kullanarak SQL dump oluşturur + """ + try: + backup_obj.status = 'in_progress' + backup_obj.save() + + db_config = self.get_db_config() + + # Yedek dosyası adını oluştur + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + backup_filename = f"backup_{db_config['dbname']}_{timestamp}.sql" + backup_path = os.path.join(self.backup_dir, backup_filename) + + # Veritabanına bağlan + conn = self.get_connection() + cursor = conn.cursor() + + with open(backup_path, 'w', encoding='utf-8') as f: + # Header + f.write("-- PostgreSQL Database Backup\n") + f.write(f"-- Database: {db_config['dbname']}\n") + f.write(f"-- Date: {datetime.now()}\n") + f.write("-- Created by Django Backup System using psycopg2\n\n") + f.write("SET client_encoding = 'UTF8';\n") + f.write("SET standard_conforming_strings = on;\n") + f.write("SET check_function_bodies = false;\n") + f.write("SET client_min_messages = warning;\n\n") + + # Tüm tabloları al + cursor.execute(""" + SELECT tablename FROM pg_tables + WHERE schemaname = 'public' + ORDER BY tablename; + """) + tables = cursor.fetchall() + + for (table_name,) in tables: + f.write(f"\n-- Table: {table_name}\n") + + # Tablo yapısını al - kolon bilgilerini çek + cursor.execute(""" + SELECT + column_name, + data_type, + character_maximum_length, + is_nullable, + column_default, + is_identity + FROM information_schema.columns + WHERE table_schema = 'public' AND table_name = %s + ORDER BY ordinal_position; + """, [table_name]) + + columns_info = cursor.fetchall() + + if columns_info: + f.write(f"DROP TABLE IF EXISTS \"{table_name}\" CASCADE;\n") + f.write(f"CREATE TABLE \"{table_name}\" (\n") + + col_defs = [] + for col_name, data_type, max_length, is_nullable, col_default, is_identity in columns_info: + col_def = f" \"{col_name}\" " + + # Serial kontrolü (Nextval veya Identity) + is_serial = False + if (col_default and 'nextval' in col_default) or is_identity == 'YES': + if data_type == 'integer': + col_def += "SERIAL" + is_serial = True + elif data_type == 'bigint': + col_def += "BIGSERIAL" + is_serial = True + + if not is_serial: + # Veri tipini ekle + if max_length and data_type == 'character varying': + col_def += f"VARCHAR({max_length})" + elif max_length and data_type == 'character': + col_def += f"CHAR({max_length})" + else: + col_def += data_type.upper() + + # NOT NULL + if is_nullable == 'NO': + col_def += " NOT NULL" + + # DEFAULT değer + if col_default: + col_def += f" DEFAULT {col_default}" + + col_defs.append(col_def) + + f.write(",\n".join(col_defs)) + f.write("\n);\n\n") + + # Veriyi al ve INSERT komutları oluştur + # Kolon isimlerini al + cursor.execute(sql.SQL(""" + SELECT column_name + FROM information_schema.columns + WHERE table_name = %s + ORDER BY ordinal_position; + """), [table_name]) + columns = [row[0] for row in cursor.fetchall()] + + if not columns: + continue + + cursor.execute(sql.SQL("SELECT * FROM {}").format(sql.Identifier(table_name))) + rows = cursor.fetchall() + + if rows: + f.write(f"-- Data for table: {table_name}\n") + + # INSERT şablonu hazırla + cols_str = ', '.join([f'"{c}"' for c in columns]) # Identifier quoting + placeholders = ', '.join(['%s'] * len(columns)) + insert_template = f"INSERT INTO \"{table_name}\" ({cols_str}) VALUES ({placeholders})" + + for row in rows: + # mogrify kullanarak güvenli SQL oluştur + try: + # mogrify bytes döndürür, decode etmemiz lazım + safe_sql = cursor.mogrify(insert_template, row).decode('utf-8') + f.write(f"{safe_sql};\n") + except Exception as row_err: + print(f"Row error in {table_name}: {row_err}") + continue + + f.write("\n") + + # Sequence'leri sıfırla + f.write("\n-- Reset sequences\n") + cursor.execute(""" + SELECT + c.relname as sequence_name, + t.relname as table_name, + a.attname as column_name + FROM pg_class c + JOIN pg_depend d ON d.objid = c.oid + JOIN pg_class t ON d.refobjid = t.oid + JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid + WHERE c.relkind = 'S' + AND t.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public'); + """) + sequences = cursor.fetchall() + for seq_name, tbl_name, col_name in sequences: + f.write(f"SELECT setval('{seq_name}', (SELECT COALESCE(MAX(\"{col_name}\"), 1) FROM \"{tbl_name}\"));\n") + + cursor.close() + conn.close() + + # Başarılı + file_size = os.path.getsize(backup_path) + backup_obj.file_path = backup_path + backup_obj.file_size = file_size + backup_obj.status = 'completed' + backup_obj.completed_at = timezone.now() + backup_obj.save() + return True, f"Yedekleme başarıyla tamamlandı: {backup_filename}" + + except Exception as e: + backup_obj.status = 'failed' + backup_obj.error_message = str(e) + backup_obj.save() + return False, f"Yedekleme hatası: {str(e)}" + + def restore_backup(self, backup_path): + """ + TAMAMEN OTOMATIK FULL RESTORE + Manuel işlem gerektirmez! + """ + try: + if not os.path.exists(backup_path): + return False, "Yedek dosyası bulunamadı" + + with open(backup_path, 'r', encoding='utf-8') as f: + sql_content = f.read() + + # HOTFIX 1: 'order' gibi keywordlerin tırnak içine alınmaması sorununu düzelt + import re + sql_content = re.sub(r'(\s+)order(\s+[A-Z]+)', r'\1"order"\2', sql_content) + + # HOTFIX 2: SERIAL/Sequence düzeltmesi + # "id INTEGER NOT NULL DEFAULT nextval(...)" -> "id SERIAL" + sql_content = re.sub(r'INTEGER\s+NOT\s+NULL\s+DEFAULT\s+nextval\(\'[^\']+\'(:?::regclass)?\)', 'SERIAL', sql_content) + sql_content = re.sub(r'BIGINT\s+NOT\s+NULL\s+DEFAULT\s+nextval\(\'[^\']+\'(:?::regclass)?\)', 'BIGSERIAL', sql_content) + + # HOTFIX 3: "id" kolonları INTEGER/BIGINT NOT NULL ise (ve default yoksa) SERIAL yap + # Bu durum Identity kolonlarının yanlış yedeklenmesi sonucu oluşur + sql_content = re.sub(r'"id"\s+INTEGER\s+NOT\s+NULL(?!(\s+DEFAULT))', '"id" SERIAL', sql_content) + sql_content = re.sub(r'"id"\s+BIGINT\s+NOT\s+NULL(?!(\s+DEFAULT))', '"id" BIGSERIAL', sql_content) + + # HOTFIX 4: setval satırlarını kaldır (çünkü biz kendimiz yeniden ayarlıyoruz ve isimler değişmiş olabilir) + # Lines starting with SELECT setval... + sql_lines = [] + for line in sql_content.split('\n'): + if 'SELECT setval' in line and 'django_migrations' in line or 'SELECT setval' in line: + continue # Skip setvals from file + sql_lines.append(line) + sql_content = '\n'.join(sql_lines) + + conn = self.get_connection() + conn.autocommit = True + cursor = conn.cursor() + + try: + print("=" * 60) + print("TAM OTOMATIK RESTORE (YENI VERSIYON)") + print("=" * 60) + + # 1. DROP tüm tablolar + print("\n1. Temizleniyor...") + cursor.execute("SELECT tablename FROM pg_tables WHERE schemaname = 'public';") + tables = cursor.fetchall() + for (t,) in tables: + print(f" Dropping {t}...") + cursor.execute(f'DROP TABLE IF EXISTS "{t}" CASCADE;') + print(" ✓ Temizlendi") + + # 2. SQL Execution - Tek seferde çalıştır + print("\n2. SQL Dosyası Çalıştırılıyor...") + # execute() methodu çoklu sorguları çalıştırabilir (psycopg2 özelliği) + try: + cursor.execute(sql_content) + print(" ✓ SQL Script çalıştırıldı") + except Exception as sql_err: + print(f" SQL HATA: {sql_err}") + raise sql_err + print(" ✓ SQL Script çalıştırıldı") + + # 3. Sequence'ler (SQL script içinde genelde vardır ama garanti olsun) + print("\n3. Sequence'ler Kontrol Ediliyor...") + cursor.execute(""" + SELECT c.relname, t.relname, a.attname + FROM pg_class c + JOIN pg_depend d ON d.objid = c.oid + JOIN pg_class t ON d.refobjid = t.oid + JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid + WHERE c.relkind = 'S' AND t.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public'); + """) + for seq, tbl, col in cursor.fetchall(): + try: + cursor.execute(f"SELECT setval('{seq}', COALESCE((SELECT MAX({col}) FROM {tbl}), 1));") + except: + pass + print(" ✓ Ayarlandı") + + cursor.close() + conn.close() + + print("\n" + "=" * 60) + print("RESTORE TAMAMLANDI!") + print("=" * 60) + + return True, "Restore başarıyla tamamlandı!" + + except Exception as e: + print(f"\nHATA: {e}") + cursor.close() + conn.close() + raise + + except Exception as e: + return False, f"Geri yükleme hatası: {str(e)}" + + def delete_backup_file(self, backup_path): + """Yedek dosyasını fiziksel olarak siler""" + try: + if os.path.exists(backup_path): + os.remove(backup_path) + return True, "Yedek dosyası silindi" + else: + return False, "Yedek dosyası bulunamadı" + except Exception as e: + return False, f"Dosya silme hatası: {str(e)}" diff --git a/backups.tar.gz b/backups.tar.gz new file mode 100644 index 0000000..696f412 Binary files /dev/null and b/backups.tar.gz differ diff --git a/backups/backup_beyhan_blog_20260112_071622.sql b/backups/backup_beyhan_blog_20260112_071622.sql new file mode 100644 index 0000000..fc83b38 --- /dev/null +++ b/backups/backup_beyhan_blog_20260112_071622.sql @@ -0,0 +1,662 @@ +-- PostgreSQL Database Backup +-- Database: beyhan_blog +-- Date: 2026-01-12 07:16:22.379301 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGSERIAL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$GX81pO8hrGgci22S3biD0I$V0fmXqQTKef7ydi+ouANZgoz5Fgkke7f4//t9VZZjcU=', '2026-01-12T07:16:09.143691+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2026-01-12T07:15:46.188521+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGSERIAL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGSERIAL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" SERIAL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGSERIAL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" SERIAL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 2, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 2, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 2, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 2, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 3, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 3, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 3, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 3, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 9, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 9, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 9, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 9, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 10, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 10, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 10, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 10, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add task result', 11, 'add_taskresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change task result', 11, 'change_taskresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete task result', 11, 'delete_taskresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view task result', 11, 'view_taskresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add chord counter', 12, 'add_chordcounter'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change chord counter', 12, 'change_chordcounter'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete chord counter', 12, 'delete_chordcounter'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view chord counter', 12, 'view_chordcounter'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add group result', 13, 'add_groupresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change group result', 13, 'change_groupresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete group result', 13, 'delete_groupresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view group result', 13, 'view_groupresult'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add site', 14, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change site', 14, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete site', 14, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view site', 14, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add user', 15, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change user', 15, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete user', 15, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view user', 15, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Post Tagı', 16, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Post Tagı', 16, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Post Tagı', 16, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Post Tagı', 16, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post Kategori', 17, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post Kategori', 17, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post Kategori', 17, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post Kategori', 17, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Post', 18, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Post', 18, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Post', 18, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Post', 18, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Kategori Ziyareti', 19, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Kategori Ziyareti', 19, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Kategori Ziyareti', 19, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Kategori Ziyareti', 19, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Post Yorum', 20, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Post Yorum', 20, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Post Yorum', 20, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Post Yorum', 20, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (81, 'Can add Veritabanı Yedeği', 21, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (82, 'Can change Veritabanı Yedeği', 21, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (83, 'Can delete Veritabanı Yedeği', 21, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (84, 'Can view Veritabanı Yedeği', 21, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (85, 'Can add Banner', 22, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (86, 'Can change Banner', 22, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (87, 'Can delete Banner', 22, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (88, 'Can view Banner', 22, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (89, 'Can add Site Ayarı', 23, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (90, 'Can change Site Ayarı', 23, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (91, 'Can delete Site Ayarı', 23, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (92, 'Can view Site Ayarı', 23, 'view_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (93, 'Can add Json To Type', 24, 'add_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (94, 'Can change Json To Type', 24, 'change_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (95, 'Can delete Json To Type', 24, 'delete_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (96, 'Can view Json To Type', 24, 'view_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (97, 'Can add Resim', 25, 'add_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (98, 'Can change Resim', 25, 'change_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (99, 'Can delete Resim', 25, 'delete_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (100, 'Can view Resim', 25, 'view_postimages'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGSERIAL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (1, 'Manuel Yedek - 2026-01-12 07:16:22', NULL, NULL, 'in_progress', 'manual', '2026-01-12T07:16:22.313915+00:00'::timestamptz, NULL, NULL, NULL, 1); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGSERIAL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGSERIAL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" SERIAL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + + +-- Table: django_celery_results_chordcounter +DROP TABLE IF EXISTS "django_celery_results_chordcounter" CASCADE; +CREATE TABLE "django_celery_results_chordcounter" ( + "id" SERIAL, + "group_id" VARCHAR(255) NOT NULL, + "sub_tasks" TEXT NOT NULL, + "count" INTEGER NOT NULL +); + + +-- Table: django_celery_results_groupresult +DROP TABLE IF EXISTS "django_celery_results_groupresult" CASCADE; +CREATE TABLE "django_celery_results_groupresult" ( + "id" SERIAL, + "group_id" VARCHAR(255) NOT NULL, + "date_created" TIMESTAMP WITH TIME ZONE NOT NULL, + "date_done" TIMESTAMP WITH TIME ZONE NOT NULL, + "content_type" VARCHAR(128) NOT NULL, + "content_encoding" VARCHAR(64) NOT NULL, + "result" TEXT +); + + +-- Table: django_celery_results_taskresult +DROP TABLE IF EXISTS "django_celery_results_taskresult" CASCADE; +CREATE TABLE "django_celery_results_taskresult" ( + "id" SERIAL, + "task_id" VARCHAR(255) NOT NULL, + "status" VARCHAR(50) NOT NULL, + "content_type" VARCHAR(128) NOT NULL, + "content_encoding" VARCHAR(64) NOT NULL, + "result" TEXT, + "date_done" TIMESTAMP WITH TIME ZONE NOT NULL, + "traceback" TEXT, + "meta" TEXT, + "task_args" TEXT, + "task_kwargs" TEXT, + "task_name" VARCHAR(255), + "worker" VARCHAR(100), + "date_created" TIMESTAMP WITH TIME ZONE NOT NULL, + "periodic_task_name" VARCHAR(255), + "date_started" TIMESTAMP WITH TIME ZONE +); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" SERIAL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'django_celery_results', 'taskresult'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'django_celery_results', 'chordcounter'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'django_celery_results', 'groupresult'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (21, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (22, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (23, 'settings', 'setting'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (24, 'utils', 'jsontotype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (25, 'image', 'postimages'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGSERIAL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2026-01-12T07:15:12.542418+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2026-01-12T07:15:12.577999+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2026-01-12T07:15:12.702340+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2026-01-12T07:15:12.723516+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2026-01-12T07:15:12.737686+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2026-01-12T07:15:12.755728+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2026-01-12T07:15:12.773646+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2026-01-12T07:15:12.784387+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2026-01-12T07:15:12.801834+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2026-01-12T07:15:12.822500+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2026-01-12T07:15:12.948552+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2026-01-12T07:15:12.979395+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2026-01-12T07:15:12.991361+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2026-01-12T07:15:13.006024+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2026-01-12T07:15:13.160603+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2026-01-12T07:15:13.226104+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2026-01-12T07:15:13.243791+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2026-01-12T07:15:13.262814+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2026-01-12T07:15:13.321501+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2026-01-12T07:15:14.087778+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'blog', '0002_remove_comment_product_comment_post', '2026-01-12T07:15:14.258717+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'django_celery_results', '0001_initial', '2026-01-12T07:15:14.311609+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'django_celery_results', '0002_add_task_name_args_kwargs', '2026-01-12T07:15:14.346503+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'django_celery_results', '0003_auto_20181106_1101', '2026-01-12T07:15:14.358169+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'django_celery_results', '0004_auto_20190516_0412', '2026-01-12T07:15:14.426631+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'django_celery_results', '0005_taskresult_worker', '2026-01-12T07:15:14.458888+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'django_celery_results', '0006_taskresult_date_created', '2026-01-12T07:15:14.514074+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'django_celery_results', '0007_remove_taskresult_hidden', '2026-01-12T07:15:14.530647+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'django_celery_results', '0008_chordcounter', '2026-01-12T07:15:14.575349+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'django_celery_results', '0009_groupresult', '2026-01-12T07:15:14.838834+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'django_celery_results', '0010_remove_duplicate_indices', '2026-01-12T07:15:14.867897+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'django_celery_results', '0011_taskresult_periodic_task_name', '2026-01-12T07:15:14.884769+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'django_celery_results', '0012_taskresult_date_started', '2026-01-12T07:15:14.902053+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'django_celery_results', '0013_taskresult_django_cele_periodi_1993cf_idx', '2026-01-12T07:15:14.921276+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'django_celery_results', '0014_alter_taskresult_status', '2026-01-12T07:15:14.930947+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'image', '0001_initial', '2026-01-12T07:15:14.991057+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'image', '0002_rename_post_postimages', '2026-01-12T07:15:15.036764+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'image', '0003_postimages_user', '2026-01-12T07:15:15.141526+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'image', '0004_alter_postimages_options', '2026-01-12T07:15:15.159825+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'sessions', '0001_initial', '2026-01-12T07:15:15.214435+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'settings', '0001_initial', '2026-01-12T07:15:15.259589+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'sites', '0001_initial', '2026-01-12T07:15:15.288083+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'sites', '0002_alter_domain_unique', '2026-01-12T07:15:15.315012+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'default', '0001_initial', '2026-01-12T07:15:15.590869+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_auth', '0001_initial', '2026-01-12T07:15:15.595485+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'default', '0002_add_related_name', '2026-01-12T07:15:15.621437+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'social_auth', '0002_add_related_name', '2026-01-12T07:15:15.628944+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'default', '0003_alter_email_max_length', '2026-01-12T07:15:15.652502+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_auth', '0003_alter_email_max_length', '2026-01-12T07:15:15.655907+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'default', '0004_auto_20160423_0400', '2026-01-12T07:15:15.685906+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (51, 'social_auth', '0004_auto_20160423_0400', '2026-01-12T07:15:15.696546+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (52, 'social_auth', '0005_auto_20160727_2333', '2026-01-12T07:15:15.729349+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (53, 'social_django', '0006_partial', '2026-01-12T07:15:15.773666+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (54, 'social_django', '0007_code_timestamp', '2026-01-12T07:15:15.921446+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (55, 'social_django', '0008_partial_timestamp', '2026-01-12T07:15:15.953188+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (56, 'social_django', '0009_auto_20191118_0520', '2026-01-12T07:15:16.028372+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (57, 'social_django', '0010_uid_db_index', '2026-01-12T07:15:16.093575+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (58, 'social_django', '0011_alter_id_fields', '2026-01-12T07:15:16.452604+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (59, 'social_django', '0012_usersocialauth_extra_data_new', '2026-01-12T07:15:16.517085+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (60, 'social_django', '0013_migrate_extra_data', '2026-01-12T07:15:16.575953+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (61, 'social_django', '0014_remove_usersocialauth_extra_data', '2026-01-12T07:15:16.621255+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (62, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2026-01-12T07:15:16.656994+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (63, 'social_django', '0016_alter_usersocialauth_extra_data', '2026-01-12T07:15:16.789930+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (64, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2026-01-12T07:15:16.827312+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (65, 'utils', '0001_initial', '2026-01-12T07:15:16.912384+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (66, 'utils', '0002_alter_jsontotype_json_data', '2026-01-12T07:15:16.955381+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (67, 'utils', '0003_alter_jsontotype_type_data', '2026-01-12T07:15:16.993888+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (68, 'social_django', '0002_add_related_name', '2026-01-12T07:15:17.006495+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (69, 'social_django', '0003_alter_email_max_length', '2026-01-12T07:15:17.014954+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (70, 'social_django', '0005_auto_20160727_2333', '2026-01-12T07:15:17.022004+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (71, 'social_django', '0004_auto_20160423_0400', '2026-01-12T07:15:17.026070+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (72, 'social_django', '0001_initial', '2026-01-12T07:15:17.029857+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('9v6wn2risssnsguguvyp9biej830n5ir', '.eJxVjMsOwiAQRf-FtSGF8hhcuvcbyDADUjU0Ke3K-O_apAvd3nPOfYmI21rj1vMSJxZnocTpd0tIj9x2wHdst1nS3NZlSnJX5EG7vM6cn5fD_Tuo2Ou3dlQcaAOFaYDBevQFrfelJBMMJ529Bo2jdwRMABwIikvKuuDUqGwQ7w_pzjeh:1vfC9p:LBP6Zi9NBG_1yjpySQg18YhG_BSFcfHu3yaT4vJNzJE', '2026-01-26T07:16:09.151496+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" SERIAL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: images +DROP TABLE IF EXISTS "images" CASCADE; +CREATE TABLE "images" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "path" VARCHAR(254) NOT NULL, + "processed_path" VARCHAR(254) NOT NULL, + "original_filename" VARCHAR(254) NOT NULL, + "format" VARCHAR(254) NOT NULL, + "width" INTEGER NOT NULL, + "height" INTEGER NOT NULL, + "size" INTEGER NOT NULL, + "quality" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "user_id" BIGINT NOT NULL +); + + +-- Table: json_to_type +DROP TABLE IF EXISTS "json_to_type" CASCADE; +CREATE TABLE "json_to_type" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "json_data" JSONB NOT NULL, + "type_data" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "user_id" BIGINT NOT NULL +); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "thumb" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT +); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGSERIAL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGSERIAL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGSERIAL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGSERIAL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGSERIAL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGSERIAL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGSERIAL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGSERIAL, + "tag" VARCHAR(254) NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('django_celery_results_taskresult_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_results_taskresult")); +SELECT setval('django_celery_results_chordcounter_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_results_chordcounter")); +SELECT setval('django_celery_results_groupresult_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_results_groupresult")); +SELECT setval('images_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "images")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); +SELECT setval('json_to_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "json_to_type")); diff --git a/backups/backup_server_dj_20251224_175702.sql b/backups/backup_server_dj_20251224_175702.sql new file mode 100644 index 0000000..4f12f08 --- /dev/null +++ b/backups/backup_server_dj_20251224_175702.sql @@ -0,0 +1,694 @@ +-- PostgreSQL Database Backup +-- Database: server_dj +-- Date: 2025-12-24 17:57:02.926153 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGINT NOT NULL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (2, 'pbkdf2_sha256$1000000$STRdTwcrx5Zp9jq1AJaBqA$FpygakERoretxVl2gmrcC9LRbfLmBksNXfPOHpUDQIc=', NULL, true, 'admin@example.com', '', '', true, true, '2025-12-23T17:00:07.461106+00:00'::timestamptz); +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$TuAKB9bCikcDO3QDAzLoMP$yeBkHfoUF+KO5yczuWOAaOyJALWMFg+y8zXgsoXkGcY=', '2025-12-24T17:56:39.320008+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2025-12-22T17:00:19.382231+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 3, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 3, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 3, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 3, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 2, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 2, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 2, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 2, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 10, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 10, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 10, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 10, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 9, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 9, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 9, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 9, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add site', 11, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change site', 11, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete site', 11, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view site', 11, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add user', 12, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change user', 12, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete user', 12, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view user', 12, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add Banner', 13, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change Banner', 13, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete Banner', 13, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view Banner', 13, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add Site Ayarı', 14, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change Site Ayarı', 14, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete Site Ayarı', 14, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view Site Ayarı', 14, 'view_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add Post Tagı', 19, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change Post Tagı', 19, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete Post Tagı', 19, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view Post Tagı', 19, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Post Kategori', 15, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Post Kategori', 15, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Post Kategori', 15, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Post Kategori', 15, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post', 18, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post', 18, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post', 18, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post', 18, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Kategori Ziyareti', 16, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Kategori Ziyareti', 16, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Kategori Ziyareti', 16, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Kategori Ziyareti', 16, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Post Yorum', 17, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Post Yorum', 17, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Post Yorum', 17, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Post Yorum', 17, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Veritabanı Yedeği', 20, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Veritabanı Yedeği', 20, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Veritabanı Yedeği', 20, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Veritabanı Yedeği', 20, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (81, 'Can add crontab', 21, 'add_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (82, 'Can change crontab', 21, 'change_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (83, 'Can delete crontab', 21, 'delete_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (84, 'Can view crontab', 21, 'view_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (85, 'Can add interval', 22, 'add_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (86, 'Can change interval', 22, 'change_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (87, 'Can delete interval', 22, 'delete_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (88, 'Can view interval', 22, 'view_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (89, 'Can add periodic task', 23, 'add_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (90, 'Can change periodic task', 23, 'change_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (91, 'Can delete periodic task', 23, 'delete_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (92, 'Can view periodic task', 23, 'view_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (93, 'Can add periodic task track', 24, 'add_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (94, 'Can change periodic task track', 24, 'change_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (95, 'Can delete periodic task track', 24, 'delete_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (96, 'Can view periodic task track', 24, 'view_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (97, 'Can add solar event', 25, 'add_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (98, 'Can change solar event', 25, 'change_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (99, 'Can delete solar event', 25, 'delete_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (100, 'Can view solar event', 25, 'view_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (101, 'Can add clocked', 26, 'add_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (102, 'Can change clocked', 26, 'change_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (103, 'Can delete clocked', 26, 'delete_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (104, 'Can view clocked', 26, 'view_clockedschedule'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGINT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (28, 'Manuel Yedek - 2025-12-24 17:57:02', NULL, NULL, 'in_progress', 'manual', '2025-12-24T17:57:02.880561+00:00'::timestamptz, NULL, NULL, NULL, 1); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGINT NOT NULL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGINT NOT NULL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "product_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" INTEGER NOT NULL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + +-- Data for table: django_admin_log +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (1, '2025-12-22T17:00:54.961166+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (2, '2025-12-22T17:01:10.019183+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 2, '[]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (3, '2025-12-22T17:08:18.352881+00:00'::timestamptz, '2', 'Manuel Yedek - 2025-12-22 17:01:15 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (4, '2025-12-22T17:08:25.284922+00:00'::timestamptz, '4', 'Manuel Yedek - 2025-12-22 17:05:18 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (5, '2025-12-22T17:08:30.992298+00:00'::timestamptz, '3', 'Manuel Yedek - 2025-12-22 17:03:41 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (6, '2025-12-22T17:08:56.836202+00:00'::timestamptz, '5', 'Manuel Yedek - 2025-12-22 17:06:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (7, '2025-12-22T17:32:09.624013+00:00'::timestamptz, '7', 'Manuel Yedek - 2025-12-22 17:30:14 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (8, '2025-12-22T17:32:15.437591+00:00'::timestamptz, '6', 'Manuel Yedek - 2025-12-22 17:09:20 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (9, '2025-12-22T17:35:52.413394+00:00'::timestamptz, '8', 'Manuel Yedek - 2025-12-22 17:32:27 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (10, '2025-12-22T18:03:49.897584+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (11, '2025-12-22T18:08:37.961862+00:00'::timestamptz, '11', 'Manuel Yedek - 2025-12-22 17:38:03 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (12, '2025-12-22T18:08:57.986969+00:00'::timestamptz, '14', 'Manuel Yedek - 2025-12-22 18:07:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (13, '2025-12-22T18:09:03.531449+00:00'::timestamptz, '12', 'Manuel Yedek - 2025-12-22 17:43:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (14, '2025-12-22T18:09:17.538540+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (15, '2025-12-22T18:34:40.618018+00:00'::timestamptz, '16', 'Manuel Yedek - 2025-12-22 18:33:20 - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (16, '2025-12-23T17:01:26.647467+00:00'::timestamptz, '18', 'Manuel Yedek - 2025-12-23 17:00:47 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (17, '2025-12-23T17:01:38.828269+00:00'::timestamptz, '17', 'Manuel Yedek - 2025-12-22 18:34:13 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (18, '2025-12-23T17:01:43.823658+00:00'::timestamptz, '15', 'Manuel Yedek - 2025-12-22 18:09:22 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (19, '2025-12-23T17:01:54.835538+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (20, '2025-12-23T17:02:16.355915+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (21, '2025-12-24T15:12:30.215650+00:00'::timestamptz, '20', 'Manuel Yedek - 2025-12-23 17:02:44 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (22, '2025-12-24T15:13:08.133128+00:00'::timestamptz, '21', 'Manuel Yedek - 2025-12-24 15:12:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (23, '2025-12-24T15:14:20.197452+00:00'::timestamptz, '22', 'Manuel Yedek - 2025-12-24 15:13:32 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (24, '2025-12-24T15:21:35.234189+00:00'::timestamptz, '23', 'Manuel Yedek - 2025-12-24 15:21:11 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (25, '2025-12-24T15:25:09.589932+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (26, '2025-12-24T17:56:51.486638+00:00'::timestamptz, '27', 'Yüklenen Yedek - backup_server_dj_20251224_152152_test - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (27, '2025-12-24T17:56:51.486802+00:00'::timestamptz, '26', 'Manuel Yedek - 2025-12-24 15:28:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (28, '2025-12-24T17:56:51.486909+00:00'::timestamptz, '25', 'Manuel Yedek - 2025-12-24 15:26:24 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (29, '2025-12-24T17:56:51.487012+00:00'::timestamptz, '24', 'Manuel Yedek - 2025-12-24 15:21:52 - Tamamlandı', 3, '', 20, 1); + + +-- Table: django_celery_beat_clockedschedule +DROP TABLE IF EXISTS "django_celery_beat_clockedschedule" CASCADE; +CREATE TABLE "django_celery_beat_clockedschedule" ( + "id" INTEGER NOT NULL, + "clocked_time" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_crontabschedule +DROP TABLE IF EXISTS "django_celery_beat_crontabschedule" CASCADE; +CREATE TABLE "django_celery_beat_crontabschedule" ( + "id" INTEGER NOT NULL, + "minute" VARCHAR(240) NOT NULL, + "hour" VARCHAR(96) NOT NULL, + "day_of_week" VARCHAR(64) NOT NULL, + "day_of_month" VARCHAR(124) NOT NULL, + "month_of_year" VARCHAR(64) NOT NULL, + "timezone" VARCHAR(63) NOT NULL +); + + +-- Table: django_celery_beat_intervalschedule +DROP TABLE IF EXISTS "django_celery_beat_intervalschedule" CASCADE; +CREATE TABLE "django_celery_beat_intervalschedule" ( + "id" INTEGER NOT NULL, + "every" INTEGER NOT NULL, + "period" VARCHAR(24) NOT NULL +); + + +-- Table: django_celery_beat_periodictask +DROP TABLE IF EXISTS "django_celery_beat_periodictask" CASCADE; +CREATE TABLE "django_celery_beat_periodictask" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(200) NOT NULL, + "task" VARCHAR(200) NOT NULL, + "args" TEXT NOT NULL, + "kwargs" TEXT NOT NULL, + "queue" VARCHAR(200), + "exchange" VARCHAR(200), + "routing_key" VARCHAR(200), + "expires" TIMESTAMP WITH TIME ZONE, + "enabled" BOOLEAN NOT NULL, + "last_run_at" TIMESTAMP WITH TIME ZONE, + "total_run_count" INTEGER NOT NULL, + "date_changed" TIMESTAMP WITH TIME ZONE NOT NULL, + "description" TEXT NOT NULL, + "crontab_id" INTEGER, + "interval_id" INTEGER, + "solar_id" INTEGER, + "one_off" BOOLEAN NOT NULL, + "start_time" TIMESTAMP WITH TIME ZONE, + "priority" INTEGER, + "headers" TEXT NOT NULL, + "clocked_id" INTEGER, + "expire_seconds" INTEGER +); + + +-- Table: django_celery_beat_periodictasks +DROP TABLE IF EXISTS "django_celery_beat_periodictasks" CASCADE; +CREATE TABLE "django_celery_beat_periodictasks" ( + "ident" SMALLINT NOT NULL, + "last_update" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_solarschedule +DROP TABLE IF EXISTS "django_celery_beat_solarschedule" CASCADE; +CREATE TABLE "django_celery_beat_solarschedule" ( + "id" INTEGER NOT NULL, + "event" VARCHAR(24) NOT NULL, + "latitude" NUMERIC NOT NULL, + "longitude" NUMERIC NOT NULL +); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" INTEGER NOT NULL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'settings', 'setting'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (21, 'django_celery_beat', 'crontabschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (22, 'django_celery_beat', 'intervalschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (23, 'django_celery_beat', 'periodictask'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (24, 'django_celery_beat', 'periodictasks'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (25, 'django_celery_beat', 'solarschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (26, 'django_celery_beat', 'clockedschedule'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGINT NOT NULL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2025-12-22T16:57:19.217932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2025-12-22T16:57:19.234555+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2025-12-22T16:57:19.434147+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2025-12-22T16:57:19.446206+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2025-12-22T16:57:19.455809+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2025-12-22T16:57:19.465593+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2025-12-22T16:57:19.475691+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2025-12-22T16:57:19.481434+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2025-12-22T16:57:19.565856+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2025-12-22T16:57:19.592172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2025-12-22T16:57:19.603096+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2025-12-22T16:57:19.625591+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2025-12-22T16:57:19.634914+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2025-12-22T16:57:19.645268+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2025-12-22T16:57:19.898703+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2025-12-22T16:57:19.967758+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2025-12-22T16:57:19.980668+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2025-12-22T16:57:19.994932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2025-12-22T16:57:20.047172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2025-12-22T16:57:20.451373+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'sessions', '0001_initial', '2025-12-22T16:57:20.596961+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'settings', '0001_initial', '2025-12-22T16:57:20.623314+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'sites', '0001_initial', '2025-12-22T16:57:20.634939+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'sites', '0002_alter_domain_unique', '2025-12-22T16:57:20.648215+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'default', '0001_initial', '2025-12-22T16:57:20.743912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'social_auth', '0001_initial', '2025-12-22T16:57:20.747238+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'social_django', '0001_initial', '2025-12-22T16:57:20.750337+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'default', '0002_add_related_name', '2025-12-22T16:57:20.772416+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'social_auth', '0002_add_related_name', '2025-12-22T16:57:20.776564+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'social_django', '0002_add_related_name', '2025-12-22T16:57:20.778681+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'default', '0003_alter_email_max_length', '2025-12-22T16:57:20.797950+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'social_auth', '0003_alter_email_max_length', '2025-12-22T16:57:20.800526+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'social_django', '0003_alter_email_max_length', '2025-12-22T16:57:20.802697+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'default', '0004_auto_20160423_0400', '2025-12-22T16:57:20.818189+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'social_auth', '0004_auto_20160423_0400', '2025-12-22T16:57:20.821978+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'social_django', '0004_auto_20160423_0400', '2025-12-22T16:57:20.824686+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'social_auth', '0005_auto_20160727_2333', '2025-12-22T16:57:20.838781+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'social_django', '0005_auto_20160727_2333', '2025-12-22T16:57:20.842005+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'social_django', '0006_partial', '2025-12-22T16:57:20.882162+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'social_django', '0007_code_timestamp', '2025-12-22T16:57:21.016558+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'social_django', '0008_partial_timestamp', '2025-12-22T16:57:21.036847+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'social_django', '0009_auto_20191118_0520', '2025-12-22T16:57:21.078912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'social_django', '0010_uid_db_index', '2025-12-22T16:57:21.103380+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'social_django', '0011_alter_id_fields', '2025-12-22T16:57:21.271476+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_django', '0012_usersocialauth_extra_data_new', '2025-12-22T16:57:21.315237+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'social_django', '0013_migrate_extra_data', '2025-12-22T16:57:21.359048+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'social_django', '0014_remove_usersocialauth_extra_data', '2025-12-22T16:57:21.387186+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2025-12-22T16:57:21.411254+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_django', '0016_alter_usersocialauth_extra_data', '2025-12-22T16:57:21.425493+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2025-12-22T16:57:21.447520+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (51, 'django_celery_beat', '0001_initial', '2025-12-22T17:29:12.618773+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (52, 'django_celery_beat', '0002_auto_20161118_0346', '2025-12-22T17:29:12.644272+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (53, 'django_celery_beat', '0003_auto_20161209_0049', '2025-12-22T17:29:12.661945+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (54, 'django_celery_beat', '0004_auto_20170221_0000', '2025-12-22T17:29:12.669274+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (55, 'django_celery_beat', '0005_add_solarschedule_events_choices', '2025-12-22T17:29:12.678019+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (56, 'django_celery_beat', '0006_auto_20180322_0932', '2025-12-22T17:29:12.752211+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (57, 'django_celery_beat', '0007_auto_20180521_0826', '2025-12-22T17:29:12.793017+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (58, 'django_celery_beat', '0008_auto_20180914_1922', '2025-12-22T17:29:12.831420+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (59, 'django_celery_beat', '0006_auto_20180210_1226', '2025-12-22T17:29:12.856887+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (60, 'django_celery_beat', '0006_periodictask_priority', '2025-12-22T17:29:12.877901+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (61, 'django_celery_beat', '0009_periodictask_headers', '2025-12-22T17:29:12.902729+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (62, 'django_celery_beat', '0010_auto_20190429_0326', '2025-12-22T17:29:13.109071+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (63, 'django_celery_beat', '0011_auto_20190508_0153', '2025-12-22T17:29:13.153527+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (64, 'django_celery_beat', '0012_periodictask_expire_seconds', '2025-12-22T17:29:13.170247+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (65, 'django_celery_beat', '0013_auto_20200609_0727', '2025-12-22T17:29:13.182913+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (66, 'django_celery_beat', '0014_remove_clockedschedule_enabled', '2025-12-22T17:29:13.197676+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (67, 'django_celery_beat', '0015_edit_solarschedule_events_choices', '2025-12-22T17:29:13.207482+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (68, 'django_celery_beat', '0016_alter_crontabschedule_timezone', '2025-12-22T17:29:13.224397+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (69, 'django_celery_beat', '0017_alter_crontabschedule_month_of_year', '2025-12-22T17:29:13.238625+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (70, 'django_celery_beat', '0018_improve_crontab_helptext', '2025-12-22T17:29:13.252445+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (71, 'django_celery_beat', '0019_alter_periodictasks_options', '2025-12-22T17:29:13.259425+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('e7jyr13wedmqdkjukqb35t2pyylkbvwz', '.eJxVjEEOwiAQRe_C2hBgpKBL9z0DmWFGqRpISrsy3l2bdKHb_977L5VwXUpau8xpYnVWVh1-N8L8kLoBvmO9NZ1bXeaJ9KbonXY9NpbnZXf_Dgr28q0F0bKTEGNG70Uie8vgLbGBYxQbwBHlwQ0szoILOQsDwMmZeKVgvHp_APiKN_E:1vXjGo:c9NPOwqzmQXV6RsDHkclP-w4ogI8VDPbV0KQilsiW6Y', '2026-01-05T17:00:30.494599+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('thlq90xyxsfsbjaps7tlga1dnluq990o', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vY5kS:rh1Px0710ffBgpJaxxgDsDyvhjpMKdKLRmAxhKHJuqg', '2026-01-06T17:00:36.697289+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('xgwdpmw5guv7ygdfh5hn8s7njr1m8q54', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYQXF:plw9RHnEzpCK5mUlnVbLTCLYkvx4NS29nPXM1OQT6yE', '2026-01-07T15:12:21.391215+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('8f1g3xhmdt9xwwyvlo3ozn57680zvlot', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYT6F:5kBYD8TaD8dIBBcU6UwIVZCYGUwgGCe4IjA1ruLwbrw', '2026-01-07T17:56:39.326481+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" INTEGER NOT NULL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT +); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGINT NOT NULL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGINT NOT NULL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGINT NOT NULL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGINT NOT NULL, + "tag" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); +SELECT setval('django_celery_beat_crontabschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_crontabschedule")); +SELECT setval('django_celery_beat_intervalschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_intervalschedule")); +SELECT setval('django_celery_beat_periodictask_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_periodictask")); +SELECT setval('django_celery_beat_solarschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_solarschedule")); +SELECT setval('django_celery_beat_clockedschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_clockedschedule")); diff --git a/backups/backup_server_dj_20260103_000326.sql b/backups/backup_server_dj_20260103_000326.sql new file mode 100644 index 0000000..ceee4d9 --- /dev/null +++ b/backups/backup_server_dj_20260103_000326.sql @@ -0,0 +1,740 @@ +-- PostgreSQL Database Backup +-- Database: server_dj +-- Date: 2026-01-03 00:03:26.147138 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGSERIAL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$WplM35argbILEm9XB766gV$NslaYI4KLBSQi4x3OcJHTU5znmKBbeTqQWv0FM46UXc=', NULL, true, 'admin@example.com', '', '', true, true, '2025-12-30T18:17:13.754386+00:00'::timestamptz); +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (2, 'pbkdf2_sha256$1000000$KWo73NKEPK7ASp4DScmL8g$qxFFzxuOEhW3AS3lbJvXssxZv+n3G/tHZh5e3uoHNPc=', '2026-01-02T05:08:11.472584+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2025-12-30T18:53:28.829042+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGSERIAL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGSERIAL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" SERIAL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGSERIAL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" SERIAL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 2, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 2, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 2, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 2, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 3, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 3, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 3, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 3, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 9, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 9, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 9, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 9, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 10, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 10, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 10, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 10, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add site', 11, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change site', 11, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete site', 11, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view site', 11, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add user', 12, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change user', 12, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete user', 12, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view user', 12, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add Post Tagı', 13, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change Post Tagı', 13, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete Post Tagı', 13, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view Post Tagı', 13, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add Post Kategori', 14, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change Post Kategori', 14, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete Post Kategori', 14, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view Post Kategori', 14, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add Post', 15, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change Post', 15, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete Post', 15, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view Post', 15, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Kategori Ziyareti', 16, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Kategori Ziyareti', 16, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Kategori Ziyareti', 16, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Kategori Ziyareti', 16, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post Yorum', 17, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post Yorum', 17, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post Yorum', 17, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post Yorum', 17, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Veritabanı Yedeği', 18, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Veritabanı Yedeği', 18, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Veritabanı Yedeği', 18, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Veritabanı Yedeği', 18, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Banner', 19, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Banner', 19, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Banner', 19, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Banner', 19, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Site Ayarı', 20, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Site Ayarı', 20, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Site Ayarı', 20, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Site Ayarı', 20, 'view_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (81, 'Can add Json To Type', 21, 'add_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (82, 'Can change Json To Type', 21, 'change_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (83, 'Can delete Json To Type', 21, 'delete_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (84, 'Can view Json To Type', 21, 'view_jsontotype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (85, 'Can add Post', 22, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (86, 'Can change Post', 22, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (87, 'Can delete Post', 22, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (88, 'Can view Post', 22, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (89, 'Can add Post', 22, 'add_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (90, 'Can change Post', 22, 'change_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (91, 'Can delete Post', 22, 'delete_postimages'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (92, 'Can view Post', 22, 'view_postimages'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGSERIAL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (1, 'Manuel Yedek - 2025-12-30 20:48:48', 'C:\Sites\dj52\backups\backup_server_dj_20251230_124848.sql', 38279, 'completed', 'manual', '2025-12-30T20:48:48.445516+00:00'::timestamptz, '2025-12-30T20:48:49.475591+00:00'::timestamptz, NULL, NULL, 2); +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (2, 'Manuel Yedek - 2026-01-02 19:21:00', 'C:\Sites\dj52\backups\backup_server_dj_20260102_112100.sql', 63942, 'completed', 'manual', '2026-01-02T19:21:00.851633+00:00'::timestamptz, '2026-01-02T19:21:02.355985+00:00'::timestamptz, NULL, NULL, 2); +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (3, 'Manuel Yedek - 2026-01-03 00:03:25', NULL, NULL, 'in_progress', 'manual', '2026-01-03T00:03:25.980164+00:00'::timestamptz, NULL, NULL, NULL, 2); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGSERIAL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + +-- Data for table: categories +INSERT INTO "categories" ("id", "title", "keywords", "description", "created_at", "updated_at", "is_active", "order", "slug", "image", "parent_id") VALUES (1, 'Linux', 'resd', 'dfd', '2026-01-02T23:29:40.546955+00:00'::timestamptz, '2026-01-02T23:29:40.546971+00:00'::timestamptz, true, 1, 'linux', '', NULL); +INSERT INTO "categories" ("id", "title", "keywords", "description", "created_at", "updated_at", "is_active", "order", "slug", "image", "parent_id") VALUES (2, 'Ubuntu', 'Ubuntu', 'Ubuntu', '2026-01-02T23:58:01.774338+00:00'::timestamptz, '2026-01-02T23:58:01.774421+00:00'::timestamptz, true, 1, 'ubuntu', '', 1); +INSERT INTO "categories" ("id", "title", "keywords", "description", "created_at", "updated_at", "is_active", "order", "slug", "image", "parent_id") VALUES (3, 'Debian', 'Debian', 'Debian', '2026-01-02T23:59:00.523219+00:00'::timestamptz, '2026-01-02T23:59:00.523243+00:00'::timestamptz, true, 1, 'debian', '', 1); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGSERIAL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "product_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" SERIAL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + +-- Data for table: django_admin_log +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (1, '2025-12-30T18:55:39.094335+00:00'::timestamptz, '1', 'Beyhan Oğur Kişisel Web Sitesi', 1, '[{"added": {}}]', 20, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (2, '2025-12-30T18:55:54.180958+00:00'::timestamptz, '1', 'Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Twitter", "Yay\u0131ndam\u0131"]}}]', 20, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (3, '2025-12-30T19:09:45.598763+00:00'::timestamptz, '1', 'Beyhan Oğur Kişisel Web Sitesi', 2, '[]', 20, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (4, '2025-12-31T02:00:21.879635+00:00'::timestamptz, '1', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (5, '2025-12-31T02:00:21.879746+00:00'::timestamptz, '2', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (6, '2025-12-31T02:00:21.879803+00:00'::timestamptz, '3', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (7, '2025-12-31T02:00:21.879852+00:00'::timestamptz, '4', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (8, '2025-12-31T02:00:21.879896+00:00'::timestamptz, '5', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (9, '2025-12-31T02:00:21.879937+00:00'::timestamptz, '6', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (10, '2025-12-31T02:00:21.879977+00:00'::timestamptz, '7', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (11, '2025-12-31T02:00:21.880016+00:00'::timestamptz, '8', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (12, '2025-12-31T02:00:21.880055+00:00'::timestamptz, '9', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (13, '2025-12-31T02:00:21.880096+00:00'::timestamptz, '10', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (14, '2025-12-31T02:00:21.880135+00:00'::timestamptz, '11', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (15, '2025-12-31T02:03:31.317961+00:00'::timestamptz, '13', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (16, '2025-12-31T03:11:00.583368+00:00'::timestamptz, '12', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (17, '2025-12-31T03:11:00.585210+00:00'::timestamptz, '14', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (18, '2025-12-31T03:11:00.585261+00:00'::timestamptz, '15', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (19, '2025-12-31T03:11:00.585295+00:00'::timestamptz, '16', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (20, '2025-12-31T03:11:00.585326+00:00'::timestamptz, '17', 'Resimler: test', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (21, '2025-12-31T03:11:00.585355+00:00'::timestamptz, '18', 'Resimler: dfgdfgdfgdf', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (22, '2025-12-31T03:11:00.585383+00:00'::timestamptz, '19', 'Resimler: sfsf', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (23, '2025-12-31T03:11:00.585410+00:00'::timestamptz, '20', 'Resimler: sfsf', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (24, '2025-12-31T03:11:00.585437+00:00'::timestamptz, '21', 'Resimler: bg.png', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (25, '2025-12-31T03:11:00.585463+00:00'::timestamptz, '22', 'Resimler: man-8078578.jpg', 3, '', 22, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (26, '2025-12-31T03:57:02.170697+00:00'::timestamptz, '2', 'imagesUpload', 2, '[{"changed": {"fields": ["Type Veri", "Yay\u0131ndam\u0131"]}}]', 21, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (27, '2026-01-02T23:29:40.617717+00:00'::timestamptz, '1', 'Linux', 1, '[{"added": {}}]', 14, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (28, '2026-01-02T23:29:58.504694+00:00'::timestamptz, '1', 'linux', 1, '[{"added": {}}]', 13, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (29, '2026-01-02T23:30:15.827503+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 1, '[{"added": {}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (30, '2026-01-02T23:34:28.431444+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (31, '2026-01-02T23:38:44.320607+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (32, '2026-01-02T23:42:53.610393+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (33, '2026-01-02T23:47:10.428246+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (34, '2026-01-02T23:49:04.119509+00:00'::timestamptz, '2', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 1, '[{"added": {}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (35, '2026-01-02T23:51:46.297558+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (36, '2026-01-02T23:55:25.046404+00:00'::timestamptz, '2', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 2, '[{"changed": {"fields": ["Image"]}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (37, '2026-01-02T23:55:53.466232+00:00'::timestamptz, '1', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 3, '', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (38, '2026-01-02T23:55:53.466315+00:00'::timestamptz, '2', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 3, '', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (39, '2026-01-02T23:56:31.046096+00:00'::timestamptz, '3', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 1, '[{"added": {}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (40, '2026-01-02T23:57:00.762261+00:00'::timestamptz, '3', 'Postlar: Beyhan Oğur Kişisel Web Sitesi', 3, '', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (41, '2026-01-02T23:58:01.818977+00:00'::timestamptz, '2', 'Linux -> Ubuntu', 1, '[{"added": {}}]', 14, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (42, '2026-01-02T23:58:13.249637+00:00'::timestamptz, '2', 'Ubuntu', 1, '[{"added": {}}]', 13, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (43, '2026-01-02T23:58:28.842114+00:00'::timestamptz, '4', 'Postlar: Ubuntu', 1, '[{"added": {}}]', 15, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (44, '2026-01-02T23:59:00.567345+00:00'::timestamptz, '3', 'Linux -> Debian', 1, '[{"added": {}}]', 14, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (45, '2026-01-02T23:59:10.997052+00:00'::timestamptz, '3', 'Debian', 1, '[{"added": {}}]', 13, 2); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (46, '2026-01-02T23:59:27.089944+00:00'::timestamptz, '5', 'Postlar: Debian', 1, '[{"added": {}}]', 15, 2); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" SERIAL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'settings', 'setting'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (21, 'utils', 'jsontotype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (22, 'image', 'postimages'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGSERIAL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2025-12-30T18:17:08.330092+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2025-12-30T18:17:08.351286+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2025-12-30T18:17:08.445210+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2025-12-30T18:17:08.458967+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2025-12-30T18:17:08.468563+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2025-12-30T18:17:08.478860+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2025-12-30T18:17:08.491305+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2025-12-30T18:17:08.494948+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2025-12-30T18:17:08.504616+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2025-12-30T18:17:08.516260+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2025-12-30T18:17:08.526555+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2025-12-30T18:17:08.547665+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2025-12-30T18:17:08.556969+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2025-12-30T18:17:08.566970+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2025-12-30T18:17:08.652656+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2025-12-30T18:17:08.702073+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2025-12-30T18:17:08.716545+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2025-12-30T18:17:08.731230+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2025-12-30T18:17:08.781407+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2025-12-30T18:17:09.087345+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'sessions', '0001_initial', '2025-12-30T18:17:09.119329+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'settings', '0001_initial', '2025-12-30T18:17:09.157590+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'sites', '0001_initial', '2025-12-30T18:17:09.171572+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'sites', '0002_alter_domain_unique', '2025-12-30T18:17:09.183897+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'default', '0001_initial', '2025-12-30T18:17:09.384648+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'social_auth', '0001_initial', '2025-12-30T18:17:09.387073+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'default', '0002_add_related_name', '2025-12-30T18:17:09.417333+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'social_auth', '0002_add_related_name', '2025-12-30T18:17:09.419107+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'default', '0003_alter_email_max_length', '2025-12-30T18:17:09.434824+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'social_auth', '0003_alter_email_max_length', '2025-12-30T18:17:09.436128+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'default', '0004_auto_20160423_0400', '2025-12-30T18:17:09.459672+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'social_auth', '0004_auto_20160423_0400', '2025-12-30T18:17:09.461654+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'social_auth', '0005_auto_20160727_2333', '2025-12-30T18:17:09.470888+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'social_django', '0006_partial', '2025-12-30T18:17:09.497122+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'social_django', '0007_code_timestamp', '2025-12-30T18:17:09.516668+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'social_django', '0008_partial_timestamp', '2025-12-30T18:17:09.533165+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'social_django', '0009_auto_20191118_0520', '2025-12-30T18:17:09.585689+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'social_django', '0010_uid_db_index', '2025-12-30T18:17:09.618967+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'social_django', '0011_alter_id_fields', '2025-12-30T18:17:09.808993+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'social_django', '0012_usersocialauth_extra_data_new', '2025-12-30T18:17:09.857523+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'social_django', '0013_migrate_extra_data', '2025-12-30T18:17:09.918348+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'social_django', '0014_remove_usersocialauth_extra_data', '2025-12-30T18:17:09.945497+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2025-12-30T18:17:09.975453+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'social_django', '0016_alter_usersocialauth_extra_data', '2025-12-30T18:17:09.996294+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2025-12-30T18:17:10.029865+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'utils', '0001_initial', '2025-12-30T18:17:10.084578+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'utils', '0002_alter_jsontotype_json_data', '2025-12-30T18:17:10.120797+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'utils', '0003_alter_jsontotype_type_data', '2025-12-30T18:17:10.156766+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_django', '0004_auto_20160423_0400', '2025-12-30T18:17:10.161715+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'social_django', '0003_alter_email_max_length', '2025-12-30T18:17:10.163125+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (51, 'social_django', '0002_add_related_name', '2025-12-30T18:17:10.164540+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (52, 'social_django', '0005_auto_20160727_2333', '2025-12-30T18:17:10.165856+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (53, 'social_django', '0001_initial', '2025-12-30T18:17:10.167315+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (54, 'image', '0001_initial', '2025-12-31T01:22:09.229707+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (55, 'image', '0002_rename_post_postimages', '2025-12-31T01:28:52.397886+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (56, 'blog', '0002_post_thumb', '2026-01-02T23:28:02.766992+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('g4i88yck7vdoxe9eutjj3w9whhkmyw4g', '.eJxVjEEOwiAQRe_C2hBgEKhL9z0DGRhGqoYmpV0Z765NutDtf-_9l4i4rTVuvSxxInERRpx-t4T5UdoO6I7tNss8t3WZktwVedAux5nK83q4fwcVe_3Wvngmq4rLGrxGcJwGhZQNGD4ba7OxbEOAQA41kvUqZQAHgRm5uEG8P-SaOAU:1vaeqg:7qWgmCY7VwYRe7Mmjx_vtt6rIlV5oX4a7MA6hRz2dew', '2026-01-13T18:53:38.149980+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('g6dskgk17q7nijwap7dp7d03uj7ofa1x', '.eJxVjDEOgzAMAP_iuYpCnCaBsTtvQI4dF9oKJAJT1b9XSAztene6Nwy0b-Ow17IOk0AHDi6_LBM_y3wIedB8Xwwv87ZO2RyJOW01_SLldTvbv8FIdYQOYokq3pbADcaGMGhuLQk7dHp13rPz6lPCJIEaEh9tZsSASZW0hBY-X-SaOAU:1vagPN:pitIT9jBFoXSAqrMh8KpghHPhppr-LQZ684BymlO7sM', '2026-01-13T20:33:33.126150+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('k49n76nmufs4pn4iqtag08y90m2x892a', '.eJxVjEEOwiAQRe_C2hBgEKhL9z0DGRhGqoYmpV0Z765NutDtf-_9l4i4rTVuvSxxInERRpx-t4T5UdoO6I7tNss8t3WZktwVedAux5nK83q4fwcVe_3Wvngmq4rLGrxGcJwGhZQNGD4ba7OxbEOAQA41kvUqZQAHgRm5uEG8P-SaOAU:1valU7:jfm6FMwEuLBDGpRCWMs11GAJzjaunLBvFVG6RPsJdvU', '2026-01-14T01:58:47.775708+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('t0sfo6qw4ot8wta22jjjyebj8gwnngn4', '.eJxVjEEOwiAQRe_C2hBgEKhL9z0DGRhGqoYmpV0Z765NutDtf-_9l4i4rTVuvSxxInERRpx-t4T5UdoO6I7tNss8t3WZktwVedAux5nK83q4fwcVe_3Wvngmq4rLGrxGcJwGhZQNGD4ba7OxbEOAQA41kvUqZQAHgRm5uEG8P-SaOAU:1vbXOV:yzBl365vGyiDDlBIxcL3k3HJroN76hmgapE8smFpwnU', '2026-01-16T05:08:11.508142+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" SERIAL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: images +DROP TABLE IF EXISTS "images" CASCADE; +CREATE TABLE "images" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "path" VARCHAR(254) NOT NULL, + "processed_path" VARCHAR(254) NOT NULL, + "original_filename" VARCHAR(254) NOT NULL, + "format" VARCHAR(254) NOT NULL, + "width" INTEGER NOT NULL, + "height" INTEGER NOT NULL, + "size" INTEGER NOT NULL, + "quality" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL +); + +-- Data for table: images +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (23, 'man-8078578.jpg', 'processed/c45196ca-c4c8-483c-960f-7b1abf8348fd.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 2500, 2500, 842270, 85, 'man-8078578jpg', '2025-12-31T03:11:25.128251+00:00'::timestamptz, '2025-12-31T03:11:25.128333+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (24, 'man-8078578.jpg', 'processed/a909569d-2eb2-4695-b15a-892d1e15bfb3.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 96194, 85, 'man-8078578jpg-2', '2025-12-31T03:14:33.379003+00:00'::timestamptz, '2025-12-31T03:14:33.379054+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (25, 'bg.png', 'processed/5525f98c-b5ca-401f-b94d-c600b6d54cc5.webp', 'bg.png', 'bg.png', 'webp', 1024, 768, 2056, 85, 'bgpng', '2025-12-31T03:27:35.979888+00:00'::timestamptz, '2025-12-31T03:27:35.979991+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (26, 'man-8078578.jpg', 'processed/2e569461-b384-44b6-82b4-cd038fc52696.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 96194, 85, 'man-8078578jpg-3', '2025-12-31T03:39:24.337216+00:00'::timestamptz, '2025-12-31T03:39:24.337273+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (27, 'fdg', 'processed/cb0b5884-3350-41b2-8719-6568afdb6eaf.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 1024, 768, 98594, 85, 'fdg', '2025-12-31T03:43:47.915365+00:00'::timestamptz, '2025-12-31T03:43:47.915583+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (28, 'bg.png', 'processed/19c28281-1e80-4ba7-a7a7-cd814260165b.webp', 'bg.png', 'bg.png', 'webp', 1024, 768, 2056, 85, 'bgpng-2', '2025-12-31T03:54:17.076433+00:00'::timestamptz, '2025-12-31T03:54:17.076492+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (29, 'man-8078578.jpg', 'processed/3ae4d4c9-4fe9-4ceb-ad71-a24e9d328f8e.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1000, 2500, 340654, 85, 'man-8078578jpg-4', '2025-12-31T03:54:51.810029+00:00'::timestamptz, '2025-12-31T03:54:51.810048+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (30, 'man-8078578.jpg', 'processed/3f154559-45df-4b76-acdb-7de9c30c55cc.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 1500, 2500, 671539, 85, 'man-8078578jpg-5', '2025-12-31T03:55:16.103659+00:00'::timestamptz, '2025-12-31T03:55:16.103677+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (31, 'man-8078578.jpg', 'processed/6def36bd-da5b-40be-b3a6-c07c7b9897cc.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 1750, 2500, 800443, 85, 'man-8078578jpg-6', '2025-12-31T03:55:33.141032+00:00'::timestamptz, '2025-12-31T03:55:33.141056+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (32, 'man-8078578.jpg', 'processed/8d341f66-2283-4372-bb0e-ce77cad29c98.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 2000, 2500, 793785, 85, 'man-8078578jpg-7', '2025-12-31T03:55:48.214844+00:00'::timestamptz, '2025-12-31T03:55:48.214863+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (33, 'man-8078578.jpg', 'processed/308c3fa8-81fc-4f6d-9977-7d9c7dce5b4f.png', 'man-8078578.jpg', 'man-8078578.jpg', 'png', 2000, 2500, 4380851, 85, 'man-8078578jpg-8', '2025-12-31T03:56:03.307634+00:00'::timestamptz, '2025-12-31T03:56:03.307657+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (34, 'man-8078578.jpg', 'processed/c29b9093-5427-460a-8799-770a4f65a7e4.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 2000, 2500, 793785, 100, 'man-8078578jpg-9', '2025-12-31T04:35:45.558471+00:00'::timestamptz, '2025-12-31T04:35:45.558554+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (35, 'man-8078578.jpg', 'processed/5768116b-f8e6-46c1-a59a-be73ec7cda39.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 2000, 2500, 918693, 100, 'man-8078578jpg-10', '2025-12-31T04:41:37.967876+00:00'::timestamptz, '2025-12-31T04:41:37.967907+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (36, 'man-8078578.jpg', 'processed/672e27e1-8f0e-4295-8f85-e67cb6bd389a.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 2000, 2000, 698099, 100, 'man-8078578jpg-11', '2025-12-31T04:41:55.643779+00:00'::timestamptz, '2025-12-31T04:41:55.643812+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (37, 'dsfsf', 'processed/782cd500-0981-4587-b34a-16de07bfdaf9.webp', 'team-4451672.jpg', 'team-4451672.jpg', 'webp', 1024, 768, 126140, 85, 'dsfsf', '2025-12-31T04:46:54.262233+00:00'::timestamptz, '2025-12-31T04:46:54.262260+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (38, 'dsfsf', 'processed/8b0cf958-e486-487c-8761-4072cf478f27.webp', 'team-4451672.jpg', 'team-4451672.jpg', 'webp', 1024, 768, 126140, 85, 'dsfsf-1', '2025-12-31T04:47:11.907274+00:00'::timestamptz, '2025-12-31T04:47:11.907477+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (39, 'man-8078578.jpg', 'processed/a60f8a14-1236-4e4b-a333-6b05212c8f11.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-12', '2025-12-31T04:47:43.466100+00:00'::timestamptz, '2025-12-31T04:47:43.466215+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (40, 'man-8078578.jpg', 'processed/9b7d9dc4-54b1-44d9-8330-c70d06166e0c.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-13', '2025-12-31T04:51:50.539713+00:00'::timestamptz, '2025-12-31T04:51:50.539796+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (41, 'team-4451672.jpg', 'processed/1368495e-8791-4771-a775-20f738df23da.webp', 'team-4451672.jpg', 'team-4451672.jpg', 'webp', 1024, 768, 126140, 85, 'team-4451672jpg', '2025-12-31T04:57:50.642611+00:00'::timestamptz, '2025-12-31T04:57:50.642723+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (42, 'fsdfs', 'processed/1bb738e2-bdb9-4ca0-829d-ed7f517740f5.webp', 'bg.png', 'bg.png', 'webp', 1024, 768, 5094, 85, 'fsdfs', '2025-12-31T05:01:31.600829+00:00'::timestamptz, '2025-12-31T05:01:31.600943+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (43, 'man-8078578.jpg', 'processed/4b841cf0-2f24-42b0-a8a2-fc87b81fd476.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-14', '2025-12-31T05:04:23.886081+00:00'::timestamptz, '2025-12-31T05:04:23.886195+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (44, 'man-8078578.jpg', 'processed/228ed09a-3064-4f0b-b286-61f5ae4ff03a.png', 'man-8078578.jpg', 'man-8078578.jpg', 'png', 1024, 768, 922822, 85, 'man-8078578jpg-15', '2025-12-31T05:05:11.322090+00:00'::timestamptz, '2025-12-31T05:05:11.322119+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (45, 'man-8078578.jpg', 'processed/1fbcab6f-f70f-40c7-a198-184c9f93b563.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 1024, 768, 170509, 85, 'man-8078578jpg-16', '2025-12-31T05:05:17.797040+00:00'::timestamptz, '2025-12-31T05:05:17.797068+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (46, 'man-8078578.jpg', 'processed/c043015d-40ce-4050-9062-4ee827fbd3bc.png', 'man-8078578.jpg', 'man-8078578.jpg', 'png', 1024, 768, 922822, 85, 'man-8078578jpg-17', '2025-12-31T05:05:22.783451+00:00'::timestamptz, '2025-12-31T05:05:22.783471+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (47, 'man-8078578.jpg', 'processed/c33bec56-00e4-4cd3-bd94-771c3635fbcb.png', 'man-8078578.jpg', 'man-8078578.jpg', 'png', 1024, 768, 922822, 85, 'man-8078578jpg-18', '2025-12-31T05:05:25.607543+00:00'::timestamptz, '2025-12-31T05:05:25.607578+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (48, 'man-8078578.jpg', 'processed/8939ca86-5150-4e13-905e-c2d332ed79f6.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-19', '2025-12-31T05:05:34.833822+00:00'::timestamptz, '2025-12-31T05:05:34.833841+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (49, 'man-8078578.jpg', 'processed/f0fef162-8a54-4158-800e-6b5d24c4163f.jpg', 'man-8078578.jpg', 'man-8078578.jpg', 'jpg', 1024, 768, 203261, 85, 'man-8078578jpg-20', '2025-12-31T05:08:21.105323+00:00'::timestamptz, '2025-12-31T05:08:21.105350+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (50, 'man-8078578.jpg', 'processed/2dbd1030-7450-4680-a11a-e34c71e1e69a.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-21', '2025-12-31T05:08:29.716880+00:00'::timestamptz, '2025-12-31T05:08:29.716902+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (51, 'man-8078578.jpg', 'processed/cf71c4c7-6b55-4a81-bee9-766969993940.png', 'man-8078578.jpg', 'man-8078578.jpg', 'png', 1024, 768, 922822, 85, 'man-8078578jpg-22', '2025-12-31T05:08:34.729310+00:00'::timestamptz, '2025-12-31T05:08:34.729415+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (52, 'man-8078578.jpg', 'processed/73f46f57-a671-43ca-b55f-45029dbe8683.avif', 'man-8078578.jpg', 'man-8078578.jpg', 'avif', 1024, 768, 170509, 85, 'man-8078578jpg-23', '2025-12-31T05:08:39.768289+00:00'::timestamptz, '2025-12-31T05:08:39.768325+00:00'::timestamptz, true, true); +INSERT INTO "images" ("id", "title", "path", "processed_path", "original_filename", "format", "width", "height", "size", "quality", "slug", "created_at", "updated_at", "is_active", "is_front") VALUES (53, 'man-8078578.jpg', 'processed/6bf75ab5-914f-4c8d-bfcc-1c10d8dea34a.webp', 'man-8078578.jpg', 'man-8078578.jpg', 'webp', 1024, 768, 174262, 85, 'man-8078578jpg-24', '2025-12-31T17:32:59.698645+00:00'::timestamptz, '2025-12-31T17:32:59.698747+00:00'::timestamptz, true, true); + + +-- Table: json_to_type +DROP TABLE IF EXISTS "json_to_type" CASCADE; +CREATE TABLE "json_to_type" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "json_data" JSONB NOT NULL, + "type_data" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "user_id" BIGINT NOT NULL +); + +-- Data for table: json_to_type +INSERT INTO "json_to_type" ("id", "title", "json_data", "type_data", "created_at", "updated_at", "is_active", "user_id") VALUES (1, 'Setting', '{ +"user":"" +}', 'export interface Setting { + user: string; +}', '2025-12-31T03:01:38.458401+00:00'::timestamptz, '2025-12-31T03:01:38.458425+00:00'::timestamptz, false, 2); +INSERT INTO "json_to_type" ("id", "title", "json_data", "type_data", "created_at", "updated_at", "is_active", "user_id") VALUES (2, 'imagesUpload', '{ + "id": 18, + "title": "dfgdfgdfgdf", + "path": "processed/e503d0c9-8509-4022-a335-4521655e6a7a.webp", + "processed_path": "man-8078578.jpg", + "original_filename": "man-8078578.jpg", + "format": "webp", + "width": 100, + "height": 120, + "size": 3236, + "quality": 85, + "slug": "dfgdfgdfgdf", + "created_at": "2025-12-31T02:56:21.231264Z", + "updated_at": "2025-12-31T02:56:21.231296Z", + "is_active": true, + "is_front": true +}', 'export interface imagesUpload { + id: number; + title: string; + path: string; + processed_path: string; + original_filename: string; + format: string; + width: number; + height: number; + size: number; + quality: number; + slug: string; + created_at: string; + updated_at: string; + is_active: boolean; + is_front: boolean; +}', '2025-12-31T03:29:42.536487+00:00'::timestamptz, '2025-12-31T03:57:02.145557+00:00'::timestamptz, true, 2); +INSERT INTO "json_to_type" ("id", "title", "json_data", "type_data", "created_at", "updated_at", "is_active", "user_id") VALUES (3, 'dsfsdf', '{}', 'export interface MyTypeasdad { + +}', '2025-12-31T15:19:12.784030+00:00'::timestamptz, '2025-12-31T15:19:12.784047+00:00'::timestamptz, false, 2); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT, + "thumb" VARCHAR(100) +); + +-- Data for table: posts +INSERT INTO "posts" ("id", "title", "content", "keywords", "image", "video", "slug", "created_at", "updated_at", "is_active", "is_front", "parent_id", "thumb") VALUES (4, 'Ubuntu', 'Ubuntu', 'Ubuntu', 'uploads/post/347670c277b94891b5b38697452ab835.avif', 'none', 'ubuntu', '2026-01-02T23:58:28.717897+00:00'::timestamptz, '2026-01-02T23:58:28.717914+00:00'::timestamptz, true, true, NULL, 'uploads/post/thumb/39a1710e813749e78dcd5c09185f53b9.avif'); +INSERT INTO "posts" ("id", "title", "content", "keywords", "image", "video", "slug", "created_at", "updated_at", "is_active", "is_front", "parent_id", "thumb") VALUES (5, 'Debian', 'Debian', 'Debian', 'uploads/post/adf3e434a17f44b38ae1711128b637d4.avif', 'none', 'debian', '2026-01-02T23:59:26.968381+00:00'::timestamptz, '2026-01-02T23:59:26.968406+00:00'::timestamptz, true, true, NULL, 'uploads/post/thumb/b14552c5c7a64d119924c1399812e797.avif'); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGSERIAL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + +-- Data for table: posts_categories +INSERT INTO "posts_categories" ("id", "post_id", "category_id") VALUES (4, 4, 2); +INSERT INTO "posts_categories" ("id", "post_id", "category_id") VALUES (5, 5, 3); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGSERIAL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + +-- Data for table: posts_tags +INSERT INTO "posts_tags" ("id", "post_id", "tags_id") VALUES (4, 4, 2); +INSERT INTO "posts_tags" ("id", "post_id", "tags_id") VALUES (5, 5, 1); +INSERT INTO "posts_tags" ("id", "post_id", "tags_id") VALUES (6, 5, 3); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGSERIAL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + +-- Data for table: settings +INSERT INTO "settings" ("id", "title", "meta_title", "meta_description", "phone", "url", "email", "facebook", "x", "instagram", "whatsapp", "slogan", "w_logo", "b_logo", "created_at", "updated_at", "is_active") VALUES (1, 'Beyhan Oğur Kişisel Web Sitesi', 'Meta Title', 'Meta Description', '+90 (500) 222 44 64', 'https://beyhanogur.com.tr', 'admin@demo.com', 'https://www.facebook.com', 'https://www.x.com', 'https://www.instagram.com', 'https://www.whatsapp.com', 'Beyhan Site Başlık Solaganı', 'uploads/logo/bg.png', 'uploads/logo/bg_jsYKjv5.png', '2025-12-30T18:55:38.870973+00:00'::timestamptz, '2025-12-30T19:09:45.593096+00:00'::timestamptz, true); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGSERIAL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGSERIAL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGSERIAL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGSERIAL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGSERIAL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGSERIAL, + "tag" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + +-- Data for table: tags +INSERT INTO "tags" ("id", "tag", "created_at", "updated_at", "is_active") VALUES (1, 'linux', '2026-01-02T23:29:58.464268+00:00'::timestamptz, '2026-01-02T23:29:58.464283+00:00'::timestamptz, true); +INSERT INTO "tags" ("id", "tag", "created_at", "updated_at", "is_active") VALUES (2, 'Ubuntu', '2026-01-02T23:58:13.208638+00:00'::timestamptz, '2026-01-02T23:58:13.208655+00:00'::timestamptz, true); +INSERT INTO "tags" ("id", "tag", "created_at", "updated_at", "is_active") VALUES (3, 'Debian', '2026-01-02T23:59:10.955258+00:00'::timestamptz, '2026-01-02T23:59:10.955285+00:00'::timestamptz, true); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); +SELECT setval('json_to_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "json_to_type")); +SELECT setval('images_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "images")); diff --git a/backups/backup_server_dj_test_20251224_175352.sql b/backups/backup_server_dj_test_20251224_175352.sql new file mode 100644 index 0000000..3499f39 --- /dev/null +++ b/backups/backup_server_dj_test_20251224_175352.sql @@ -0,0 +1,526 @@ +-- PostgreSQL Database Backup +-- Database: server_dj_test +-- Date: 2025-12-24 17:53:53.003629 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGINT NOT NULL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$u1P0iFbGOM2z5Cwk30yJNO$TPhvLzXuCeSWXc4cCpQIDYv8ZZGs0S1RbWuN2aefwCQ=', '2025-12-24T17:53:25.150388+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2025-12-24T17:53:11.303375+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 2, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 2, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 2, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 2, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 3, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 3, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 3, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 3, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 9, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 9, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 9, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 9, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 10, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 10, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 10, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 10, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add site', 11, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change site', 11, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete site', 11, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view site', 11, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add user', 12, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change user', 12, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete user', 12, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view user', 12, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add Post Tagı', 13, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change Post Tagı', 13, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete Post Tagı', 13, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view Post Tagı', 13, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add Post Kategori', 14, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change Post Kategori', 14, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete Post Kategori', 14, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view Post Kategori', 14, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add Post', 15, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change Post', 15, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete Post', 15, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view Post', 15, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Kategori Ziyareti', 16, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Kategori Ziyareti', 16, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Kategori Ziyareti', 16, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Kategori Ziyareti', 16, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post Yorum', 17, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post Yorum', 17, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post Yorum', 17, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post Yorum', 17, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Veritabanı Yedeği', 18, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Veritabanı Yedeği', 18, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Veritabanı Yedeği', 18, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Veritabanı Yedeği', 18, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Banner', 19, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Banner', 19, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Banner', 19, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Banner', 19, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Site Ayarı', 20, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Site Ayarı', 20, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Site Ayarı', 20, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Site Ayarı', 20, 'view_setting'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGINT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (1, 'Manuel Yedek - 2025-12-24 17:53:52', NULL, NULL, 'in_progress', 'manual', '2025-12-24T17:53:52.965869+00:00'::timestamptz, NULL, NULL, NULL, 1); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGINT NOT NULL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGINT NOT NULL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "product_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" INTEGER NOT NULL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" INTEGER NOT NULL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'settings', 'setting'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGINT NOT NULL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2025-12-24T17:52:43.845116+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2025-12-24T17:52:43.863713+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2025-12-24T17:52:43.935604+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2025-12-24T17:52:43.951365+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2025-12-24T17:52:43.964620+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2025-12-24T17:52:43.977833+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2025-12-24T17:52:43.990016+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2025-12-24T17:52:43.998463+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2025-12-24T17:52:44.012382+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2025-12-24T17:52:44.026522+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2025-12-24T17:52:44.039605+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2025-12-24T17:52:44.069435+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2025-12-24T17:52:44.081493+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2025-12-24T17:52:44.095286+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2025-12-24T17:52:44.239074+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2025-12-24T17:52:44.304825+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2025-12-24T17:52:44.318239+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2025-12-24T17:52:44.335477+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2025-12-24T17:52:44.475575+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2025-12-24T17:52:44.799361+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'sessions', '0001_initial', '2025-12-24T17:52:44.831822+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'settings', '0001_initial', '2025-12-24T17:52:44.879705+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'sites', '0001_initial', '2025-12-24T17:52:44.903306+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'sites', '0002_alter_domain_unique', '2025-12-24T17:52:44.924515+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'default', '0001_initial', '2025-12-24T17:52:45.067098+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'social_auth', '0001_initial', '2025-12-24T17:52:45.072695+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'default', '0002_add_related_name', '2025-12-24T17:52:45.095480+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'social_auth', '0002_add_related_name', '2025-12-24T17:52:45.099517+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'default', '0003_alter_email_max_length', '2025-12-24T17:52:45.122647+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'social_auth', '0003_alter_email_max_length', '2025-12-24T17:52:45.125593+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'default', '0004_auto_20160423_0400', '2025-12-24T17:52:45.142991+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'social_auth', '0004_auto_20160423_0400', '2025-12-24T17:52:45.146933+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'social_auth', '0005_auto_20160727_2333', '2025-12-24T17:52:45.163032+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'social_django', '0006_partial', '2025-12-24T17:52:45.206595+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'social_django', '0007_code_timestamp', '2025-12-24T17:52:45.236352+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'social_django', '0008_partial_timestamp', '2025-12-24T17:52:45.263722+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'social_django', '0009_auto_20191118_0520', '2025-12-24T17:52:45.312704+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'social_django', '0010_uid_db_index', '2025-12-24T17:52:45.341894+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'social_django', '0011_alter_id_fields', '2025-12-24T17:52:45.443986+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'social_django', '0012_usersocialauth_extra_data_new', '2025-12-24T17:52:45.482091+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'social_django', '0013_migrate_extra_data', '2025-12-24T17:52:45.555931+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'social_django', '0014_remove_usersocialauth_extra_data', '2025-12-24T17:52:45.587466+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2025-12-24T17:52:45.615244+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'social_django', '0016_alter_usersocialauth_extra_data', '2025-12-24T17:52:45.632400+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2025-12-24T17:52:45.659854+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'social_django', '0002_add_related_name', '2025-12-24T17:52:45.669891+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'social_django', '0003_alter_email_max_length', '2025-12-24T17:52:45.675697+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'social_django', '0004_auto_20160423_0400', '2025-12-24T17:52:45.680972+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_django', '0001_initial', '2025-12-24T17:52:45.686400+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'social_django', '0005_auto_20160727_2333', '2025-12-24T17:52:45.691806+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('gfkfhw05oct7kit2ke5ajczqw87f149e', '.eJxVjEEOwiAQAP_C2RCgFMGjd99Alt1FqgaS0p6MfzckPeh1ZjJvEWHfStw7r3EhcRFanH5ZAnxyHYIeUO9NYqvbuiQ5EnnYLm-N-HU92r9BgV7GltA7RjNNGYMCRp-0mxw5AyoQOJ9xtqCs0mc0kMgzZafQZORZmWDF5wv8EjiA:1vYT37:QY5dFu5b3NpHb2pzPhSGQ_tdLH2bfEpdqH5vn1ycLiA', '2026-01-07T17:53:25.157543+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" INTEGER NOT NULL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT +); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGINT NOT NULL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGINT NOT NULL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGINT NOT NULL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGINT NOT NULL, + "tag" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); diff --git a/backups/uploaded_backup_server_dj_20251224_175702_20251224_175829.sql b/backups/uploaded_backup_server_dj_20251224_175702_20251224_175829.sql new file mode 100644 index 0000000..4f12f08 --- /dev/null +++ b/backups/uploaded_backup_server_dj_20251224_175702_20251224_175829.sql @@ -0,0 +1,694 @@ +-- PostgreSQL Database Backup +-- Database: server_dj +-- Date: 2025-12-24 17:57:02.926153 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGINT NOT NULL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (2, 'pbkdf2_sha256$1000000$STRdTwcrx5Zp9jq1AJaBqA$FpygakERoretxVl2gmrcC9LRbfLmBksNXfPOHpUDQIc=', NULL, true, 'admin@example.com', '', '', true, true, '2025-12-23T17:00:07.461106+00:00'::timestamptz); +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$TuAKB9bCikcDO3QDAzLoMP$yeBkHfoUF+KO5yczuWOAaOyJALWMFg+y8zXgsoXkGcY=', '2025-12-24T17:56:39.320008+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2025-12-22T17:00:19.382231+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 3, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 3, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 3, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 3, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 2, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 2, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 2, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 2, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 10, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 10, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 10, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 10, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 9, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 9, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 9, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 9, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add site', 11, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change site', 11, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete site', 11, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view site', 11, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add user', 12, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change user', 12, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete user', 12, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view user', 12, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add Banner', 13, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change Banner', 13, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete Banner', 13, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view Banner', 13, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add Site Ayarı', 14, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change Site Ayarı', 14, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete Site Ayarı', 14, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view Site Ayarı', 14, 'view_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add Post Tagı', 19, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change Post Tagı', 19, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete Post Tagı', 19, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view Post Tagı', 19, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Post Kategori', 15, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Post Kategori', 15, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Post Kategori', 15, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Post Kategori', 15, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post', 18, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post', 18, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post', 18, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post', 18, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Kategori Ziyareti', 16, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Kategori Ziyareti', 16, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Kategori Ziyareti', 16, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Kategori Ziyareti', 16, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Post Yorum', 17, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Post Yorum', 17, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Post Yorum', 17, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Post Yorum', 17, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Veritabanı Yedeği', 20, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Veritabanı Yedeği', 20, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Veritabanı Yedeği', 20, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Veritabanı Yedeği', 20, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (81, 'Can add crontab', 21, 'add_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (82, 'Can change crontab', 21, 'change_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (83, 'Can delete crontab', 21, 'delete_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (84, 'Can view crontab', 21, 'view_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (85, 'Can add interval', 22, 'add_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (86, 'Can change interval', 22, 'change_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (87, 'Can delete interval', 22, 'delete_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (88, 'Can view interval', 22, 'view_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (89, 'Can add periodic task', 23, 'add_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (90, 'Can change periodic task', 23, 'change_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (91, 'Can delete periodic task', 23, 'delete_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (92, 'Can view periodic task', 23, 'view_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (93, 'Can add periodic task track', 24, 'add_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (94, 'Can change periodic task track', 24, 'change_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (95, 'Can delete periodic task track', 24, 'delete_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (96, 'Can view periodic task track', 24, 'view_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (97, 'Can add solar event', 25, 'add_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (98, 'Can change solar event', 25, 'change_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (99, 'Can delete solar event', 25, 'delete_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (100, 'Can view solar event', 25, 'view_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (101, 'Can add clocked', 26, 'add_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (102, 'Can change clocked', 26, 'change_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (103, 'Can delete clocked', 26, 'delete_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (104, 'Can view clocked', 26, 'view_clockedschedule'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGINT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (28, 'Manuel Yedek - 2025-12-24 17:57:02', NULL, NULL, 'in_progress', 'manual', '2025-12-24T17:57:02.880561+00:00'::timestamptz, NULL, NULL, NULL, 1); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGINT NOT NULL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGINT NOT NULL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "product_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" INTEGER NOT NULL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + +-- Data for table: django_admin_log +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (1, '2025-12-22T17:00:54.961166+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (2, '2025-12-22T17:01:10.019183+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 2, '[]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (3, '2025-12-22T17:08:18.352881+00:00'::timestamptz, '2', 'Manuel Yedek - 2025-12-22 17:01:15 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (4, '2025-12-22T17:08:25.284922+00:00'::timestamptz, '4', 'Manuel Yedek - 2025-12-22 17:05:18 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (5, '2025-12-22T17:08:30.992298+00:00'::timestamptz, '3', 'Manuel Yedek - 2025-12-22 17:03:41 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (6, '2025-12-22T17:08:56.836202+00:00'::timestamptz, '5', 'Manuel Yedek - 2025-12-22 17:06:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (7, '2025-12-22T17:32:09.624013+00:00'::timestamptz, '7', 'Manuel Yedek - 2025-12-22 17:30:14 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (8, '2025-12-22T17:32:15.437591+00:00'::timestamptz, '6', 'Manuel Yedek - 2025-12-22 17:09:20 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (9, '2025-12-22T17:35:52.413394+00:00'::timestamptz, '8', 'Manuel Yedek - 2025-12-22 17:32:27 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (10, '2025-12-22T18:03:49.897584+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (11, '2025-12-22T18:08:37.961862+00:00'::timestamptz, '11', 'Manuel Yedek - 2025-12-22 17:38:03 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (12, '2025-12-22T18:08:57.986969+00:00'::timestamptz, '14', 'Manuel Yedek - 2025-12-22 18:07:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (13, '2025-12-22T18:09:03.531449+00:00'::timestamptz, '12', 'Manuel Yedek - 2025-12-22 17:43:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (14, '2025-12-22T18:09:17.538540+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (15, '2025-12-22T18:34:40.618018+00:00'::timestamptz, '16', 'Manuel Yedek - 2025-12-22 18:33:20 - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (16, '2025-12-23T17:01:26.647467+00:00'::timestamptz, '18', 'Manuel Yedek - 2025-12-23 17:00:47 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (17, '2025-12-23T17:01:38.828269+00:00'::timestamptz, '17', 'Manuel Yedek - 2025-12-22 18:34:13 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (18, '2025-12-23T17:01:43.823658+00:00'::timestamptz, '15', 'Manuel Yedek - 2025-12-22 18:09:22 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (19, '2025-12-23T17:01:54.835538+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (20, '2025-12-23T17:02:16.355915+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (21, '2025-12-24T15:12:30.215650+00:00'::timestamptz, '20', 'Manuel Yedek - 2025-12-23 17:02:44 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (22, '2025-12-24T15:13:08.133128+00:00'::timestamptz, '21', 'Manuel Yedek - 2025-12-24 15:12:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (23, '2025-12-24T15:14:20.197452+00:00'::timestamptz, '22', 'Manuel Yedek - 2025-12-24 15:13:32 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (24, '2025-12-24T15:21:35.234189+00:00'::timestamptz, '23', 'Manuel Yedek - 2025-12-24 15:21:11 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (25, '2025-12-24T15:25:09.589932+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (26, '2025-12-24T17:56:51.486638+00:00'::timestamptz, '27', 'Yüklenen Yedek - backup_server_dj_20251224_152152_test - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (27, '2025-12-24T17:56:51.486802+00:00'::timestamptz, '26', 'Manuel Yedek - 2025-12-24 15:28:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (28, '2025-12-24T17:56:51.486909+00:00'::timestamptz, '25', 'Manuel Yedek - 2025-12-24 15:26:24 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (29, '2025-12-24T17:56:51.487012+00:00'::timestamptz, '24', 'Manuel Yedek - 2025-12-24 15:21:52 - Tamamlandı', 3, '', 20, 1); + + +-- Table: django_celery_beat_clockedschedule +DROP TABLE IF EXISTS "django_celery_beat_clockedschedule" CASCADE; +CREATE TABLE "django_celery_beat_clockedschedule" ( + "id" INTEGER NOT NULL, + "clocked_time" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_crontabschedule +DROP TABLE IF EXISTS "django_celery_beat_crontabschedule" CASCADE; +CREATE TABLE "django_celery_beat_crontabschedule" ( + "id" INTEGER NOT NULL, + "minute" VARCHAR(240) NOT NULL, + "hour" VARCHAR(96) NOT NULL, + "day_of_week" VARCHAR(64) NOT NULL, + "day_of_month" VARCHAR(124) NOT NULL, + "month_of_year" VARCHAR(64) NOT NULL, + "timezone" VARCHAR(63) NOT NULL +); + + +-- Table: django_celery_beat_intervalschedule +DROP TABLE IF EXISTS "django_celery_beat_intervalschedule" CASCADE; +CREATE TABLE "django_celery_beat_intervalschedule" ( + "id" INTEGER NOT NULL, + "every" INTEGER NOT NULL, + "period" VARCHAR(24) NOT NULL +); + + +-- Table: django_celery_beat_periodictask +DROP TABLE IF EXISTS "django_celery_beat_periodictask" CASCADE; +CREATE TABLE "django_celery_beat_periodictask" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(200) NOT NULL, + "task" VARCHAR(200) NOT NULL, + "args" TEXT NOT NULL, + "kwargs" TEXT NOT NULL, + "queue" VARCHAR(200), + "exchange" VARCHAR(200), + "routing_key" VARCHAR(200), + "expires" TIMESTAMP WITH TIME ZONE, + "enabled" BOOLEAN NOT NULL, + "last_run_at" TIMESTAMP WITH TIME ZONE, + "total_run_count" INTEGER NOT NULL, + "date_changed" TIMESTAMP WITH TIME ZONE NOT NULL, + "description" TEXT NOT NULL, + "crontab_id" INTEGER, + "interval_id" INTEGER, + "solar_id" INTEGER, + "one_off" BOOLEAN NOT NULL, + "start_time" TIMESTAMP WITH TIME ZONE, + "priority" INTEGER, + "headers" TEXT NOT NULL, + "clocked_id" INTEGER, + "expire_seconds" INTEGER +); + + +-- Table: django_celery_beat_periodictasks +DROP TABLE IF EXISTS "django_celery_beat_periodictasks" CASCADE; +CREATE TABLE "django_celery_beat_periodictasks" ( + "ident" SMALLINT NOT NULL, + "last_update" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_solarschedule +DROP TABLE IF EXISTS "django_celery_beat_solarschedule" CASCADE; +CREATE TABLE "django_celery_beat_solarschedule" ( + "id" INTEGER NOT NULL, + "event" VARCHAR(24) NOT NULL, + "latitude" NUMERIC NOT NULL, + "longitude" NUMERIC NOT NULL +); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" INTEGER NOT NULL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'settings', 'setting'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (21, 'django_celery_beat', 'crontabschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (22, 'django_celery_beat', 'intervalschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (23, 'django_celery_beat', 'periodictask'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (24, 'django_celery_beat', 'periodictasks'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (25, 'django_celery_beat', 'solarschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (26, 'django_celery_beat', 'clockedschedule'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGINT NOT NULL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2025-12-22T16:57:19.217932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2025-12-22T16:57:19.234555+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2025-12-22T16:57:19.434147+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2025-12-22T16:57:19.446206+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2025-12-22T16:57:19.455809+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2025-12-22T16:57:19.465593+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2025-12-22T16:57:19.475691+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2025-12-22T16:57:19.481434+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2025-12-22T16:57:19.565856+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2025-12-22T16:57:19.592172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2025-12-22T16:57:19.603096+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2025-12-22T16:57:19.625591+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2025-12-22T16:57:19.634914+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2025-12-22T16:57:19.645268+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2025-12-22T16:57:19.898703+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2025-12-22T16:57:19.967758+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2025-12-22T16:57:19.980668+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2025-12-22T16:57:19.994932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2025-12-22T16:57:20.047172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2025-12-22T16:57:20.451373+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'sessions', '0001_initial', '2025-12-22T16:57:20.596961+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'settings', '0001_initial', '2025-12-22T16:57:20.623314+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'sites', '0001_initial', '2025-12-22T16:57:20.634939+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'sites', '0002_alter_domain_unique', '2025-12-22T16:57:20.648215+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'default', '0001_initial', '2025-12-22T16:57:20.743912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'social_auth', '0001_initial', '2025-12-22T16:57:20.747238+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'social_django', '0001_initial', '2025-12-22T16:57:20.750337+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'default', '0002_add_related_name', '2025-12-22T16:57:20.772416+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'social_auth', '0002_add_related_name', '2025-12-22T16:57:20.776564+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'social_django', '0002_add_related_name', '2025-12-22T16:57:20.778681+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'default', '0003_alter_email_max_length', '2025-12-22T16:57:20.797950+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'social_auth', '0003_alter_email_max_length', '2025-12-22T16:57:20.800526+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'social_django', '0003_alter_email_max_length', '2025-12-22T16:57:20.802697+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'default', '0004_auto_20160423_0400', '2025-12-22T16:57:20.818189+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'social_auth', '0004_auto_20160423_0400', '2025-12-22T16:57:20.821978+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'social_django', '0004_auto_20160423_0400', '2025-12-22T16:57:20.824686+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'social_auth', '0005_auto_20160727_2333', '2025-12-22T16:57:20.838781+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'social_django', '0005_auto_20160727_2333', '2025-12-22T16:57:20.842005+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'social_django', '0006_partial', '2025-12-22T16:57:20.882162+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'social_django', '0007_code_timestamp', '2025-12-22T16:57:21.016558+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'social_django', '0008_partial_timestamp', '2025-12-22T16:57:21.036847+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'social_django', '0009_auto_20191118_0520', '2025-12-22T16:57:21.078912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'social_django', '0010_uid_db_index', '2025-12-22T16:57:21.103380+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'social_django', '0011_alter_id_fields', '2025-12-22T16:57:21.271476+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_django', '0012_usersocialauth_extra_data_new', '2025-12-22T16:57:21.315237+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'social_django', '0013_migrate_extra_data', '2025-12-22T16:57:21.359048+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'social_django', '0014_remove_usersocialauth_extra_data', '2025-12-22T16:57:21.387186+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2025-12-22T16:57:21.411254+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_django', '0016_alter_usersocialauth_extra_data', '2025-12-22T16:57:21.425493+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2025-12-22T16:57:21.447520+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (51, 'django_celery_beat', '0001_initial', '2025-12-22T17:29:12.618773+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (52, 'django_celery_beat', '0002_auto_20161118_0346', '2025-12-22T17:29:12.644272+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (53, 'django_celery_beat', '0003_auto_20161209_0049', '2025-12-22T17:29:12.661945+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (54, 'django_celery_beat', '0004_auto_20170221_0000', '2025-12-22T17:29:12.669274+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (55, 'django_celery_beat', '0005_add_solarschedule_events_choices', '2025-12-22T17:29:12.678019+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (56, 'django_celery_beat', '0006_auto_20180322_0932', '2025-12-22T17:29:12.752211+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (57, 'django_celery_beat', '0007_auto_20180521_0826', '2025-12-22T17:29:12.793017+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (58, 'django_celery_beat', '0008_auto_20180914_1922', '2025-12-22T17:29:12.831420+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (59, 'django_celery_beat', '0006_auto_20180210_1226', '2025-12-22T17:29:12.856887+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (60, 'django_celery_beat', '0006_periodictask_priority', '2025-12-22T17:29:12.877901+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (61, 'django_celery_beat', '0009_periodictask_headers', '2025-12-22T17:29:12.902729+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (62, 'django_celery_beat', '0010_auto_20190429_0326', '2025-12-22T17:29:13.109071+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (63, 'django_celery_beat', '0011_auto_20190508_0153', '2025-12-22T17:29:13.153527+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (64, 'django_celery_beat', '0012_periodictask_expire_seconds', '2025-12-22T17:29:13.170247+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (65, 'django_celery_beat', '0013_auto_20200609_0727', '2025-12-22T17:29:13.182913+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (66, 'django_celery_beat', '0014_remove_clockedschedule_enabled', '2025-12-22T17:29:13.197676+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (67, 'django_celery_beat', '0015_edit_solarschedule_events_choices', '2025-12-22T17:29:13.207482+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (68, 'django_celery_beat', '0016_alter_crontabschedule_timezone', '2025-12-22T17:29:13.224397+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (69, 'django_celery_beat', '0017_alter_crontabschedule_month_of_year', '2025-12-22T17:29:13.238625+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (70, 'django_celery_beat', '0018_improve_crontab_helptext', '2025-12-22T17:29:13.252445+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (71, 'django_celery_beat', '0019_alter_periodictasks_options', '2025-12-22T17:29:13.259425+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('e7jyr13wedmqdkjukqb35t2pyylkbvwz', '.eJxVjEEOwiAQRe_C2hBgpKBL9z0DmWFGqRpISrsy3l2bdKHb_977L5VwXUpau8xpYnVWVh1-N8L8kLoBvmO9NZ1bXeaJ9KbonXY9NpbnZXf_Dgr28q0F0bKTEGNG70Uie8vgLbGBYxQbwBHlwQ0szoILOQsDwMmZeKVgvHp_APiKN_E:1vXjGo:c9NPOwqzmQXV6RsDHkclP-w4ogI8VDPbV0KQilsiW6Y', '2026-01-05T17:00:30.494599+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('thlq90xyxsfsbjaps7tlga1dnluq990o', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vY5kS:rh1Px0710ffBgpJaxxgDsDyvhjpMKdKLRmAxhKHJuqg', '2026-01-06T17:00:36.697289+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('xgwdpmw5guv7ygdfh5hn8s7njr1m8q54', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYQXF:plw9RHnEzpCK5mUlnVbLTCLYkvx4NS29nPXM1OQT6yE', '2026-01-07T15:12:21.391215+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('8f1g3xhmdt9xwwyvlo3ozn57680zvlot', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYT6F:5kBYD8TaD8dIBBcU6UwIVZCYGUwgGCe4IjA1ruLwbrw', '2026-01-07T17:56:39.326481+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" INTEGER NOT NULL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT +); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGINT NOT NULL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGINT NOT NULL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGINT NOT NULL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGINT NOT NULL, + "tag" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); +SELECT setval('django_celery_beat_crontabschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_crontabschedule")); +SELECT setval('django_celery_beat_intervalschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_intervalschedule")); +SELECT setval('django_celery_beat_periodictask_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_periodictask")); +SELECT setval('django_celery_beat_solarschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_solarschedule")); +SELECT setval('django_celery_beat_clockedschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_clockedschedule")); diff --git a/backups/uploaded_backup_server_dj_20251224_175702_20251224_180411.sql b/backups/uploaded_backup_server_dj_20251224_175702_20251224_180411.sql new file mode 100644 index 0000000..4f12f08 --- /dev/null +++ b/backups/uploaded_backup_server_dj_20251224_175702_20251224_180411.sql @@ -0,0 +1,694 @@ +-- PostgreSQL Database Backup +-- Database: server_dj +-- Date: 2025-12-24 17:57:02.926153 +-- Created by Django Backup System using psycopg2 + +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + + +-- Table: accounts_customuser +DROP TABLE IF EXISTS "accounts_customuser" CASCADE; +CREATE TABLE "accounts_customuser" ( + "id" BIGINT NOT NULL, + "password" VARCHAR(128) NOT NULL, + "last_login" TIMESTAMP WITH TIME ZONE, + "is_superuser" BOOLEAN NOT NULL, + "email" VARCHAR(254) NOT NULL, + "first_name" VARCHAR(150) NOT NULL, + "last_name" VARCHAR(150) NOT NULL, + "is_staff" BOOLEAN NOT NULL, + "is_active" BOOLEAN NOT NULL, + "date_joined" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: accounts_customuser +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (2, 'pbkdf2_sha256$1000000$STRdTwcrx5Zp9jq1AJaBqA$FpygakERoretxVl2gmrcC9LRbfLmBksNXfPOHpUDQIc=', NULL, true, 'admin@example.com', '', '', true, true, '2025-12-23T17:00:07.461106+00:00'::timestamptz); +INSERT INTO "accounts_customuser" ("id", "password", "last_login", "is_superuser", "email", "first_name", "last_name", "is_staff", "is_active", "date_joined") VALUES (1, 'pbkdf2_sha256$1000000$TuAKB9bCikcDO3QDAzLoMP$yeBkHfoUF+KO5yczuWOAaOyJALWMFg+y8zXgsoXkGcY=', '2025-12-24T17:56:39.320008+00:00'::timestamptz, true, 'beyhan@beyhan.dev', '', '', true, true, '2025-12-22T17:00:19.382231+00:00'::timestamptz); + + +-- Table: accounts_customuser_groups +DROP TABLE IF EXISTS "accounts_customuser_groups" CASCADE; +CREATE TABLE "accounts_customuser_groups" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL +); + + +-- Table: accounts_customuser_user_permissions +DROP TABLE IF EXISTS "accounts_customuser_user_permissions" CASCADE; +CREATE TABLE "accounts_customuser_user_permissions" ( + "id" BIGINT NOT NULL, + "customuser_id" BIGINT NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_group +DROP TABLE IF EXISTS "auth_group" CASCADE; +CREATE TABLE "auth_group" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(150) NOT NULL +); + + +-- Table: auth_group_permissions +DROP TABLE IF EXISTS "auth_group_permissions" CASCADE; +CREATE TABLE "auth_group_permissions" ( + "id" BIGINT NOT NULL, + "group_id" INTEGER NOT NULL, + "permission_id" INTEGER NOT NULL +); + + +-- Table: auth_permission +DROP TABLE IF EXISTS "auth_permission" CASCADE; +CREATE TABLE "auth_permission" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(255) NOT NULL, + "content_type_id" INTEGER NOT NULL, + "codename" VARCHAR(100) NOT NULL +); + +-- Data for table: auth_permission +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (1, 'Can add log entry', 1, 'add_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (2, 'Can change log entry', 1, 'change_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (3, 'Can delete log entry', 1, 'delete_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (4, 'Can view log entry', 1, 'view_logentry'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (5, 'Can add permission', 3, 'add_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (6, 'Can change permission', 3, 'change_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (7, 'Can delete permission', 3, 'delete_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (8, 'Can view permission', 3, 'view_permission'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (9, 'Can add group', 2, 'add_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (10, 'Can change group', 2, 'change_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (11, 'Can delete group', 2, 'delete_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (12, 'Can view group', 2, 'view_group'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (13, 'Can add content type', 4, 'add_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (14, 'Can change content type', 4, 'change_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (15, 'Can delete content type', 4, 'delete_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (16, 'Can view content type', 4, 'view_contenttype'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (17, 'Can add session', 5, 'add_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (18, 'Can change session', 5, 'change_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (19, 'Can delete session', 5, 'delete_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (20, 'Can view session', 5, 'view_session'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (21, 'Can add association', 6, 'add_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (22, 'Can change association', 6, 'change_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (23, 'Can delete association', 6, 'delete_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (24, 'Can view association', 6, 'view_association'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (25, 'Can add code', 7, 'add_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (26, 'Can change code', 7, 'change_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (27, 'Can delete code', 7, 'delete_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (28, 'Can view code', 7, 'view_code'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (29, 'Can add nonce', 8, 'add_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (30, 'Can change nonce', 8, 'change_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (31, 'Can delete nonce', 8, 'delete_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (32, 'Can view nonce', 8, 'view_nonce'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (33, 'Can add user social auth', 10, 'add_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (34, 'Can change user social auth', 10, 'change_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (35, 'Can delete user social auth', 10, 'delete_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (36, 'Can view user social auth', 10, 'view_usersocialauth'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (37, 'Can add partial', 9, 'add_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (38, 'Can change partial', 9, 'change_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (39, 'Can delete partial', 9, 'delete_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (40, 'Can view partial', 9, 'view_partial'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (41, 'Can add site', 11, 'add_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (42, 'Can change site', 11, 'change_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (43, 'Can delete site', 11, 'delete_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (44, 'Can view site', 11, 'view_site'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (45, 'Can add user', 12, 'add_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (46, 'Can change user', 12, 'change_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (47, 'Can delete user', 12, 'delete_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (48, 'Can view user', 12, 'view_customuser'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (49, 'Can add Banner', 13, 'add_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (50, 'Can change Banner', 13, 'change_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (51, 'Can delete Banner', 13, 'delete_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (52, 'Can view Banner', 13, 'view_banner'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (53, 'Can add Site Ayarı', 14, 'add_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (54, 'Can change Site Ayarı', 14, 'change_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (55, 'Can delete Site Ayarı', 14, 'delete_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (56, 'Can view Site Ayarı', 14, 'view_setting'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (57, 'Can add Post Tagı', 19, 'add_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (58, 'Can change Post Tagı', 19, 'change_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (59, 'Can delete Post Tagı', 19, 'delete_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (60, 'Can view Post Tagı', 19, 'view_tags'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (61, 'Can add Post Kategori', 15, 'add_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (62, 'Can change Post Kategori', 15, 'change_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (63, 'Can delete Post Kategori', 15, 'delete_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (64, 'Can view Post Kategori', 15, 'view_category'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (65, 'Can add Post', 18, 'add_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (66, 'Can change Post', 18, 'change_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (67, 'Can delete Post', 18, 'delete_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (68, 'Can view Post', 18, 'view_post'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (69, 'Can add Kategori Ziyareti', 16, 'add_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (70, 'Can change Kategori Ziyareti', 16, 'change_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (71, 'Can delete Kategori Ziyareti', 16, 'delete_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (72, 'Can view Kategori Ziyareti', 16, 'view_categoryview'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (73, 'Can add Post Yorum', 17, 'add_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (74, 'Can change Post Yorum', 17, 'change_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (75, 'Can delete Post Yorum', 17, 'delete_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (76, 'Can view Post Yorum', 17, 'view_comment'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (77, 'Can add Veritabanı Yedeği', 20, 'add_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (78, 'Can change Veritabanı Yedeği', 20, 'change_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (79, 'Can delete Veritabanı Yedeği', 20, 'delete_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (80, 'Can view Veritabanı Yedeği', 20, 'view_databasebackup'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (81, 'Can add crontab', 21, 'add_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (82, 'Can change crontab', 21, 'change_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (83, 'Can delete crontab', 21, 'delete_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (84, 'Can view crontab', 21, 'view_crontabschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (85, 'Can add interval', 22, 'add_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (86, 'Can change interval', 22, 'change_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (87, 'Can delete interval', 22, 'delete_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (88, 'Can view interval', 22, 'view_intervalschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (89, 'Can add periodic task', 23, 'add_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (90, 'Can change periodic task', 23, 'change_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (91, 'Can delete periodic task', 23, 'delete_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (92, 'Can view periodic task', 23, 'view_periodictask'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (93, 'Can add periodic task track', 24, 'add_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (94, 'Can change periodic task track', 24, 'change_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (95, 'Can delete periodic task track', 24, 'delete_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (96, 'Can view periodic task track', 24, 'view_periodictasks'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (97, 'Can add solar event', 25, 'add_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (98, 'Can change solar event', 25, 'change_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (99, 'Can delete solar event', 25, 'delete_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (100, 'Can view solar event', 25, 'view_solarschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (101, 'Can add clocked', 26, 'add_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (102, 'Can change clocked', 26, 'change_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (103, 'Can delete clocked', 26, 'delete_clockedschedule'); +INSERT INTO "auth_permission" ("id", "name", "content_type_id", "codename") VALUES (104, 'Can view clocked', 26, 'view_clockedschedule'); + + +-- Table: backup_databasebackup +DROP TABLE IF EXISTS "backup_databasebackup" CASCADE; +CREATE TABLE "backup_databasebackup" ( + "id" BIGINT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(500), + "file_size" BIGINT, + "status" VARCHAR(20) NOT NULL, + "backup_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "completed_at" TIMESTAMP WITH TIME ZONE, + "error_message" TEXT, + "notes" TEXT, + "created_by_id" BIGINT +); + +-- Data for table: backup_databasebackup +INSERT INTO "backup_databasebackup" ("id", "name", "file_path", "file_size", "status", "backup_type", "created_at", "completed_at", "error_message", "notes", "created_by_id") VALUES (28, 'Manuel Yedek - 2025-12-24 17:57:02', NULL, NULL, 'in_progress', 'manual', '2025-12-24T17:57:02.880561+00:00'::timestamptz, NULL, NULL, NULL, 1); + + +-- Table: banners +DROP TABLE IF EXISTS "banners" CASCADE; +CREATE TABLE "banners" ( + "id" BIGINT NOT NULL, + "color" VARCHAR(25) NOT NULL, + "title" VARCHAR(254), + "text1" VARCHAR(254), + "text2" VARCHAR(254), + "text4" VARCHAR(254), + "text5" VARCHAR(254), + "image" VARCHAR(100) NOT NULL, + "image_k" VARCHAR(100), + "image_k_txt" VARCHAR(254), + "is_active" BOOLEAN NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: categories +DROP TABLE IF EXISTS "categories" CASCADE; +CREATE TABLE "categories" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "keywords" VARCHAR(254) NOT NULL, + "description" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "order" INTEGER NOT NULL, + "slug" VARCHAR(250) NOT NULL, + "image" VARCHAR(100), + "parent_id" BIGINT +); + + +-- Table: category_views +DROP TABLE IF EXISTS "category_views" CASCADE; +CREATE TABLE "category_views" ( + "id" BIGINT NOT NULL, + "ip_address" INET NOT NULL, + "user_agent" TEXT, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: comments +DROP TABLE IF EXISTS "comments" CASCADE; +CREATE TABLE "comments" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "body" TEXT NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "slug" VARCHAR(50) NOT NULL, + "parent_id" BIGINT, + "user_id" BIGINT NOT NULL, + "product_id" BIGINT NOT NULL +); + + +-- Table: django_admin_log +DROP TABLE IF EXISTS "django_admin_log" CASCADE; +CREATE TABLE "django_admin_log" ( + "id" INTEGER NOT NULL, + "action_time" TIMESTAMP WITH TIME ZONE NOT NULL, + "object_id" TEXT, + "object_repr" VARCHAR(200) NOT NULL, + "action_flag" SMALLINT NOT NULL, + "change_message" TEXT NOT NULL, + "content_type_id" INTEGER, + "user_id" BIGINT NOT NULL +); + +-- Data for table: django_admin_log +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (1, '2025-12-22T17:00:54.961166+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (2, '2025-12-22T17:01:10.019183+00:00'::timestamptz, '1', 'Yedek 1 - Bekliyor', 2, '[]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (3, '2025-12-22T17:08:18.352881+00:00'::timestamptz, '2', 'Manuel Yedek - 2025-12-22 17:01:15 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (4, '2025-12-22T17:08:25.284922+00:00'::timestamptz, '4', 'Manuel Yedek - 2025-12-22 17:05:18 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (5, '2025-12-22T17:08:30.992298+00:00'::timestamptz, '3', 'Manuel Yedek - 2025-12-22 17:03:41 - Başarısız', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (6, '2025-12-22T17:08:56.836202+00:00'::timestamptz, '5', 'Manuel Yedek - 2025-12-22 17:06:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (7, '2025-12-22T17:32:09.624013+00:00'::timestamptz, '7', 'Manuel Yedek - 2025-12-22 17:30:14 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (8, '2025-12-22T17:32:15.437591+00:00'::timestamptz, '6', 'Manuel Yedek - 2025-12-22 17:09:20 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (9, '2025-12-22T17:35:52.413394+00:00'::timestamptz, '8', 'Manuel Yedek - 2025-12-22 17:32:27 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (10, '2025-12-22T18:03:49.897584+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (11, '2025-12-22T18:08:37.961862+00:00'::timestamptz, '11', 'Manuel Yedek - 2025-12-22 17:38:03 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (12, '2025-12-22T18:08:57.986969+00:00'::timestamptz, '14', 'Manuel Yedek - 2025-12-22 18:07:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (13, '2025-12-22T18:09:03.531449+00:00'::timestamptz, '12', 'Manuel Yedek - 2025-12-22 17:43:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (14, '2025-12-22T18:09:17.538540+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 2, '[{"changed": {"fields": ["Yedek Tipi"]}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (15, '2025-12-22T18:34:40.618018+00:00'::timestamptz, '16', 'Manuel Yedek - 2025-12-22 18:33:20 - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (16, '2025-12-23T17:01:26.647467+00:00'::timestamptz, '18', 'Manuel Yedek - 2025-12-23 17:00:47 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (17, '2025-12-23T17:01:38.828269+00:00'::timestamptz, '17', 'Manuel Yedek - 2025-12-22 18:34:13 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (18, '2025-12-23T17:01:43.823658+00:00'::timestamptz, '15', 'Manuel Yedek - 2025-12-22 18:09:22 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (19, '2025-12-23T17:01:54.835538+00:00'::timestamptz, '13', 'Manuel Yedek - 2025-12-22 17:50:15 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (20, '2025-12-23T17:02:16.355915+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 1, '[{"added": {}}]', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (21, '2025-12-24T15:12:30.215650+00:00'::timestamptz, '20', 'Manuel Yedek - 2025-12-23 17:02:44 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (22, '2025-12-24T15:13:08.133128+00:00'::timestamptz, '21', 'Manuel Yedek - 2025-12-24 15:12:38 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (23, '2025-12-24T15:14:20.197452+00:00'::timestamptz, '22', 'Manuel Yedek - 2025-12-24 15:13:32 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (24, '2025-12-24T15:21:35.234189+00:00'::timestamptz, '23', 'Manuel Yedek - 2025-12-24 15:21:11 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (25, '2025-12-24T15:25:09.589932+00:00'::timestamptz, '19', 'Yedek Al - Bekliyor', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (26, '2025-12-24T17:56:51.486638+00:00'::timestamptz, '27', 'Yüklenen Yedek - backup_server_dj_20251224_152152_test - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (27, '2025-12-24T17:56:51.486802+00:00'::timestamptz, '26', 'Manuel Yedek - 2025-12-24 15:28:28 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (28, '2025-12-24T17:56:51.486909+00:00'::timestamptz, '25', 'Manuel Yedek - 2025-12-24 15:26:24 - Tamamlandı', 3, '', 20, 1); +INSERT INTO "django_admin_log" ("id", "action_time", "object_id", "object_repr", "action_flag", "change_message", "content_type_id", "user_id") VALUES (29, '2025-12-24T17:56:51.487012+00:00'::timestamptz, '24', 'Manuel Yedek - 2025-12-24 15:21:52 - Tamamlandı', 3, '', 20, 1); + + +-- Table: django_celery_beat_clockedschedule +DROP TABLE IF EXISTS "django_celery_beat_clockedschedule" CASCADE; +CREATE TABLE "django_celery_beat_clockedschedule" ( + "id" INTEGER NOT NULL, + "clocked_time" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_crontabschedule +DROP TABLE IF EXISTS "django_celery_beat_crontabschedule" CASCADE; +CREATE TABLE "django_celery_beat_crontabschedule" ( + "id" INTEGER NOT NULL, + "minute" VARCHAR(240) NOT NULL, + "hour" VARCHAR(96) NOT NULL, + "day_of_week" VARCHAR(64) NOT NULL, + "day_of_month" VARCHAR(124) NOT NULL, + "month_of_year" VARCHAR(64) NOT NULL, + "timezone" VARCHAR(63) NOT NULL +); + + +-- Table: django_celery_beat_intervalschedule +DROP TABLE IF EXISTS "django_celery_beat_intervalschedule" CASCADE; +CREATE TABLE "django_celery_beat_intervalschedule" ( + "id" INTEGER NOT NULL, + "every" INTEGER NOT NULL, + "period" VARCHAR(24) NOT NULL +); + + +-- Table: django_celery_beat_periodictask +DROP TABLE IF EXISTS "django_celery_beat_periodictask" CASCADE; +CREATE TABLE "django_celery_beat_periodictask" ( + "id" INTEGER NOT NULL, + "name" VARCHAR(200) NOT NULL, + "task" VARCHAR(200) NOT NULL, + "args" TEXT NOT NULL, + "kwargs" TEXT NOT NULL, + "queue" VARCHAR(200), + "exchange" VARCHAR(200), + "routing_key" VARCHAR(200), + "expires" TIMESTAMP WITH TIME ZONE, + "enabled" BOOLEAN NOT NULL, + "last_run_at" TIMESTAMP WITH TIME ZONE, + "total_run_count" INTEGER NOT NULL, + "date_changed" TIMESTAMP WITH TIME ZONE NOT NULL, + "description" TEXT NOT NULL, + "crontab_id" INTEGER, + "interval_id" INTEGER, + "solar_id" INTEGER, + "one_off" BOOLEAN NOT NULL, + "start_time" TIMESTAMP WITH TIME ZONE, + "priority" INTEGER, + "headers" TEXT NOT NULL, + "clocked_id" INTEGER, + "expire_seconds" INTEGER +); + + +-- Table: django_celery_beat_periodictasks +DROP TABLE IF EXISTS "django_celery_beat_periodictasks" CASCADE; +CREATE TABLE "django_celery_beat_periodictasks" ( + "ident" SMALLINT NOT NULL, + "last_update" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: django_celery_beat_solarschedule +DROP TABLE IF EXISTS "django_celery_beat_solarschedule" CASCADE; +CREATE TABLE "django_celery_beat_solarschedule" ( + "id" INTEGER NOT NULL, + "event" VARCHAR(24) NOT NULL, + "latitude" NUMERIC NOT NULL, + "longitude" NUMERIC NOT NULL +); + + +-- Table: django_content_type +DROP TABLE IF EXISTS "django_content_type" CASCADE; +CREATE TABLE "django_content_type" ( + "id" INTEGER NOT NULL, + "app_label" VARCHAR(100) NOT NULL, + "model" VARCHAR(100) NOT NULL +); + +-- Data for table: django_content_type +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (1, 'admin', 'logentry'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (2, 'auth', 'group'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (3, 'auth', 'permission'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (4, 'contenttypes', 'contenttype'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (5, 'sessions', 'session'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (6, 'social_django', 'association'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (7, 'social_django', 'code'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (8, 'social_django', 'nonce'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (9, 'social_django', 'partial'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (10, 'social_django', 'usersocialauth'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (11, 'sites', 'site'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (12, 'accounts', 'customuser'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (13, 'settings', 'banner'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (14, 'settings', 'setting'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (15, 'blog', 'category'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (16, 'blog', 'categoryview'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (17, 'blog', 'comment'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (18, 'blog', 'post'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (19, 'blog', 'tags'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (20, 'backup', 'databasebackup'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (21, 'django_celery_beat', 'crontabschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (22, 'django_celery_beat', 'intervalschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (23, 'django_celery_beat', 'periodictask'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (24, 'django_celery_beat', 'periodictasks'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (25, 'django_celery_beat', 'solarschedule'); +INSERT INTO "django_content_type" ("id", "app_label", "model") VALUES (26, 'django_celery_beat', 'clockedschedule'); + + +-- Table: django_migrations +DROP TABLE IF EXISTS "django_migrations" CASCADE; +CREATE TABLE "django_migrations" ( + "id" BIGINT NOT NULL, + "app" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "applied" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_migrations +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (1, 'contenttypes', '0001_initial', '2025-12-22T16:57:19.217932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (2, 'contenttypes', '0002_remove_content_type_name', '2025-12-22T16:57:19.234555+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (3, 'auth', '0001_initial', '2025-12-22T16:57:19.434147+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (4, 'auth', '0002_alter_permission_name_max_length', '2025-12-22T16:57:19.446206+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (5, 'auth', '0003_alter_user_email_max_length', '2025-12-22T16:57:19.455809+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (6, 'auth', '0004_alter_user_username_opts', '2025-12-22T16:57:19.465593+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (7, 'auth', '0005_alter_user_last_login_null', '2025-12-22T16:57:19.475691+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (8, 'auth', '0006_require_contenttypes_0002', '2025-12-22T16:57:19.481434+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (9, 'auth', '0007_alter_validators_add_error_messages', '2025-12-22T16:57:19.565856+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (10, 'auth', '0008_alter_user_username_max_length', '2025-12-22T16:57:19.592172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (11, 'auth', '0009_alter_user_last_name_max_length', '2025-12-22T16:57:19.603096+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (12, 'auth', '0010_alter_group_name_max_length', '2025-12-22T16:57:19.625591+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (13, 'auth', '0011_update_proxy_permissions', '2025-12-22T16:57:19.634914+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (14, 'auth', '0012_alter_user_first_name_max_length', '2025-12-22T16:57:19.645268+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (15, 'accounts', '0001_initial', '2025-12-22T16:57:19.898703+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (16, 'admin', '0001_initial', '2025-12-22T16:57:19.967758+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (17, 'admin', '0002_logentry_remove_auto_add', '2025-12-22T16:57:19.980668+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (18, 'admin', '0003_logentry_add_action_flag_choices', '2025-12-22T16:57:19.994932+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (19, 'backup', '0001_initial', '2025-12-22T16:57:20.047172+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (20, 'blog', '0001_initial', '2025-12-22T16:57:20.451373+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (21, 'sessions', '0001_initial', '2025-12-22T16:57:20.596961+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (22, 'settings', '0001_initial', '2025-12-22T16:57:20.623314+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (23, 'sites', '0001_initial', '2025-12-22T16:57:20.634939+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (24, 'sites', '0002_alter_domain_unique', '2025-12-22T16:57:20.648215+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (25, 'default', '0001_initial', '2025-12-22T16:57:20.743912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (26, 'social_auth', '0001_initial', '2025-12-22T16:57:20.747238+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (27, 'social_django', '0001_initial', '2025-12-22T16:57:20.750337+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (28, 'default', '0002_add_related_name', '2025-12-22T16:57:20.772416+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (29, 'social_auth', '0002_add_related_name', '2025-12-22T16:57:20.776564+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (30, 'social_django', '0002_add_related_name', '2025-12-22T16:57:20.778681+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (31, 'default', '0003_alter_email_max_length', '2025-12-22T16:57:20.797950+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (32, 'social_auth', '0003_alter_email_max_length', '2025-12-22T16:57:20.800526+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (33, 'social_django', '0003_alter_email_max_length', '2025-12-22T16:57:20.802697+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (34, 'default', '0004_auto_20160423_0400', '2025-12-22T16:57:20.818189+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (35, 'social_auth', '0004_auto_20160423_0400', '2025-12-22T16:57:20.821978+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (36, 'social_django', '0004_auto_20160423_0400', '2025-12-22T16:57:20.824686+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (37, 'social_auth', '0005_auto_20160727_2333', '2025-12-22T16:57:20.838781+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (38, 'social_django', '0005_auto_20160727_2333', '2025-12-22T16:57:20.842005+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (39, 'social_django', '0006_partial', '2025-12-22T16:57:20.882162+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (40, 'social_django', '0007_code_timestamp', '2025-12-22T16:57:21.016558+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (41, 'social_django', '0008_partial_timestamp', '2025-12-22T16:57:21.036847+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (42, 'social_django', '0009_auto_20191118_0520', '2025-12-22T16:57:21.078912+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (43, 'social_django', '0010_uid_db_index', '2025-12-22T16:57:21.103380+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (44, 'social_django', '0011_alter_id_fields', '2025-12-22T16:57:21.271476+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (45, 'social_django', '0012_usersocialauth_extra_data_new', '2025-12-22T16:57:21.315237+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (46, 'social_django', '0013_migrate_extra_data', '2025-12-22T16:57:21.359048+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (47, 'social_django', '0014_remove_usersocialauth_extra_data', '2025-12-22T16:57:21.387186+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (48, 'social_django', '0015_rename_extra_data_new_usersocialauth_extra_data', '2025-12-22T16:57:21.411254+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (49, 'social_django', '0016_alter_usersocialauth_extra_data', '2025-12-22T16:57:21.425493+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (50, 'social_django', '0017_usersocialauth_user_social_auth_uid_required', '2025-12-22T16:57:21.447520+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (51, 'django_celery_beat', '0001_initial', '2025-12-22T17:29:12.618773+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (52, 'django_celery_beat', '0002_auto_20161118_0346', '2025-12-22T17:29:12.644272+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (53, 'django_celery_beat', '0003_auto_20161209_0049', '2025-12-22T17:29:12.661945+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (54, 'django_celery_beat', '0004_auto_20170221_0000', '2025-12-22T17:29:12.669274+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (55, 'django_celery_beat', '0005_add_solarschedule_events_choices', '2025-12-22T17:29:12.678019+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (56, 'django_celery_beat', '0006_auto_20180322_0932', '2025-12-22T17:29:12.752211+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (57, 'django_celery_beat', '0007_auto_20180521_0826', '2025-12-22T17:29:12.793017+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (58, 'django_celery_beat', '0008_auto_20180914_1922', '2025-12-22T17:29:12.831420+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (59, 'django_celery_beat', '0006_auto_20180210_1226', '2025-12-22T17:29:12.856887+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (60, 'django_celery_beat', '0006_periodictask_priority', '2025-12-22T17:29:12.877901+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (61, 'django_celery_beat', '0009_periodictask_headers', '2025-12-22T17:29:12.902729+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (62, 'django_celery_beat', '0010_auto_20190429_0326', '2025-12-22T17:29:13.109071+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (63, 'django_celery_beat', '0011_auto_20190508_0153', '2025-12-22T17:29:13.153527+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (64, 'django_celery_beat', '0012_periodictask_expire_seconds', '2025-12-22T17:29:13.170247+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (65, 'django_celery_beat', '0013_auto_20200609_0727', '2025-12-22T17:29:13.182913+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (66, 'django_celery_beat', '0014_remove_clockedschedule_enabled', '2025-12-22T17:29:13.197676+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (67, 'django_celery_beat', '0015_edit_solarschedule_events_choices', '2025-12-22T17:29:13.207482+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (68, 'django_celery_beat', '0016_alter_crontabschedule_timezone', '2025-12-22T17:29:13.224397+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (69, 'django_celery_beat', '0017_alter_crontabschedule_month_of_year', '2025-12-22T17:29:13.238625+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (70, 'django_celery_beat', '0018_improve_crontab_helptext', '2025-12-22T17:29:13.252445+00:00'::timestamptz); +INSERT INTO "django_migrations" ("id", "app", "name", "applied") VALUES (71, 'django_celery_beat', '0019_alter_periodictasks_options', '2025-12-22T17:29:13.259425+00:00'::timestamptz); + + +-- Table: django_session +DROP TABLE IF EXISTS "django_session" CASCADE; +CREATE TABLE "django_session" ( + "session_key" VARCHAR(40) NOT NULL, + "session_data" TEXT NOT NULL, + "expire_date" TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Data for table: django_session +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('e7jyr13wedmqdkjukqb35t2pyylkbvwz', '.eJxVjEEOwiAQRe_C2hBgpKBL9z0DmWFGqRpISrsy3l2bdKHb_977L5VwXUpau8xpYnVWVh1-N8L8kLoBvmO9NZ1bXeaJ9KbonXY9NpbnZXf_Dgr28q0F0bKTEGNG70Uie8vgLbGBYxQbwBHlwQ0szoILOQsDwMmZeKVgvHp_APiKN_E:1vXjGo:c9NPOwqzmQXV6RsDHkclP-w4ogI8VDPbV0KQilsiW6Y', '2026-01-05T17:00:30.494599+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('thlq90xyxsfsbjaps7tlga1dnluq990o', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vY5kS:rh1Px0710ffBgpJaxxgDsDyvhjpMKdKLRmAxhKHJuqg', '2026-01-06T17:00:36.697289+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('xgwdpmw5guv7ygdfh5hn8s7njr1m8q54', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYQXF:plw9RHnEzpCK5mUlnVbLTCLYkvx4NS29nPXM1OQT6yE', '2026-01-07T15:12:21.391215+00:00'::timestamptz); +INSERT INTO "django_session" ("session_key", "session_data", "expire_date") VALUES ('8f1g3xhmdt9xwwyvlo3ozn57680zvlot', '.eJxVjDsOwjAQBe_iGllr2PhDSZ8zWOtdBweQI8VJhbg7iZQC2pl5760irUuJa8tzHEVdlVGnX5aIn7nuQh5U75PmqS7zmPSe6MM23U-SX7ej_Tso1Mq2JnSIDJkGAugMIzln_AbBnhFckMA8UELxRB7RYLCA4tgG6QT4oj5f0K43Zw:1vYT6F:5kBYD8TaD8dIBBcU6UwIVZCYGUwgGCe4IjA1ruLwbrw', '2026-01-07T17:56:39.326481+00:00'::timestamptz); + + +-- Table: django_site +DROP TABLE IF EXISTS "django_site" CASCADE; +CREATE TABLE "django_site" ( + "id" INTEGER NOT NULL, + "domain" VARCHAR(100) NOT NULL, + "name" VARCHAR(50) NOT NULL +); + +-- Data for table: django_site +INSERT INTO "django_site" ("id", "domain", "name") VALUES (1, 'example.com', 'example.com'); + + +-- Table: posts +DROP TABLE IF EXISTS "posts" CASCADE; +CREATE TABLE "posts" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "content" TEXT, + "keywords" VARCHAR(254) NOT NULL, + "image" VARCHAR(100), + "video" VARCHAR(254), + "slug" VARCHAR(250) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL, + "is_front" BOOLEAN NOT NULL, + "parent_id" BIGINT +); + + +-- Table: posts_categories +DROP TABLE IF EXISTS "posts_categories" CASCADE; +CREATE TABLE "posts_categories" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "category_id" BIGINT NOT NULL +); + + +-- Table: posts_tags +DROP TABLE IF EXISTS "posts_tags" CASCADE; +CREATE TABLE "posts_tags" ( + "id" BIGINT NOT NULL, + "post_id" BIGINT NOT NULL, + "tags_id" BIGINT NOT NULL +); + + +-- Table: settings +DROP TABLE IF EXISTS "settings" CASCADE; +CREATE TABLE "settings" ( + "id" BIGINT NOT NULL, + "title" VARCHAR(254) NOT NULL, + "meta_title" VARCHAR(254) NOT NULL, + "meta_description" VARCHAR(254) NOT NULL, + "phone" VARCHAR(254) NOT NULL, + "url" VARCHAR(254), + "email" VARCHAR(254) NOT NULL, + "facebook" VARCHAR(254), + "x" VARCHAR(254), + "instagram" VARCHAR(254), + "whatsapp" VARCHAR(254), + "slogan" VARCHAR(254), + "w_logo" VARCHAR(100), + "b_logo" VARCHAR(100), + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Table: social_auth_association +DROP TABLE IF EXISTS "social_auth_association" CASCADE; +CREATE TABLE "social_auth_association" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "handle" VARCHAR(255) NOT NULL, + "secret" VARCHAR(255) NOT NULL, + "issued" INTEGER NOT NULL, + "lifetime" INTEGER NOT NULL, + "assoc_type" VARCHAR(64) NOT NULL +); + + +-- Table: social_auth_code +DROP TABLE IF EXISTS "social_auth_code" CASCADE; +CREATE TABLE "social_auth_code" ( + "id" BIGINT NOT NULL, + "email" VARCHAR(254) NOT NULL, + "code" VARCHAR(32) NOT NULL, + "verified" BOOLEAN NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL +); + + +-- Table: social_auth_nonce +DROP TABLE IF EXISTS "social_auth_nonce" CASCADE; +CREATE TABLE "social_auth_nonce" ( + "id" BIGINT NOT NULL, + "server_url" VARCHAR(255) NOT NULL, + "timestamp" INTEGER NOT NULL, + "salt" VARCHAR(65) NOT NULL +); + + +-- Table: social_auth_partial +DROP TABLE IF EXISTS "social_auth_partial" CASCADE; +CREATE TABLE "social_auth_partial" ( + "id" BIGINT NOT NULL, + "token" VARCHAR(32) NOT NULL, + "next_step" SMALLINT NOT NULL, + "backend" VARCHAR(32) NOT NULL, + "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, + "data" JSONB NOT NULL +); + + +-- Table: social_auth_usersocialauth +DROP TABLE IF EXISTS "social_auth_usersocialauth" CASCADE; +CREATE TABLE "social_auth_usersocialauth" ( + "id" BIGINT NOT NULL, + "provider" VARCHAR(32) NOT NULL, + "uid" VARCHAR(255) NOT NULL, + "user_id" BIGINT NOT NULL, + "created" TIMESTAMP WITH TIME ZONE NOT NULL, + "modified" TIMESTAMP WITH TIME ZONE NOT NULL, + "extra_data" JSONB NOT NULL +); + + +-- Table: tags +DROP TABLE IF EXISTS "tags" CASCADE; +CREATE TABLE "tags" ( + "id" BIGINT NOT NULL, + "tag" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, + "is_active" BOOLEAN NOT NULL +); + + +-- Reset sequences +SELECT setval('django_migrations_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_migrations")); +SELECT setval('django_content_type_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_content_type")); +SELECT setval('auth_permission_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_permission")); +SELECT setval('auth_group_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group")); +SELECT setval('auth_group_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "auth_group_permissions")); +SELECT setval('accounts_customuser_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser")); +SELECT setval('accounts_customuser_groups_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_groups")); +SELECT setval('accounts_customuser_user_permissions_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "accounts_customuser_user_permissions")); +SELECT setval('django_admin_log_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_admin_log")); +SELECT setval('backup_databasebackup_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "backup_databasebackup")); +SELECT setval('tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "tags")); +SELECT setval('categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "categories")); +SELECT setval('posts_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts")); +SELECT setval('posts_categories_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_categories")); +SELECT setval('posts_tags_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "posts_tags")); +SELECT setval('category_views_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "category_views")); +SELECT setval('comments_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "comments")); +SELECT setval('banners_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "banners")); +SELECT setval('settings_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "settings")); +SELECT setval('django_site_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_site")); +SELECT setval('social_auth_association_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_association")); +SELECT setval('social_auth_code_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_code")); +SELECT setval('social_auth_nonce_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_nonce")); +SELECT setval('social_auth_usersocialauth_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_usersocialauth")); +SELECT setval('social_auth_partial_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "social_auth_partial")); +SELECT setval('django_celery_beat_crontabschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_crontabschedule")); +SELECT setval('django_celery_beat_intervalschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_intervalschedule")); +SELECT setval('django_celery_beat_periodictask_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_periodictask")); +SELECT setval('django_celery_beat_solarschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_solarschedule")); +SELECT setval('django_celery_beat_clockedschedule_id_seq', (SELECT COALESCE(MAX("id"), 1) FROM "django_celery_beat_clockedschedule")); diff --git a/blog/__init__.py b/blog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/admin.py b/blog/admin.py new file mode 100644 index 0000000..3e09be2 --- /dev/null +++ b/blog/admin.py @@ -0,0 +1,101 @@ +from django.contrib import admin +from django.utils.safestring import mark_safe + +from blog.models import Category, Tags, Post, Comment, CategoryView + + +# Register your models here. +class PostAdmin(admin.ModelAdmin): + list_display = ('title', 'post_resim', 'is_active', 'post_kategorileri', 'slug') + list_filter = ('is_active', 'categories') + search_fields = ('title', 'is_active', 'slug', 'content') + list_editable = ('is_active', 'slug',) # Removed 'price' as it is not a field + + class Meta: + model = Post + + def save_model(self, request, obj, form, change): + """Admin'de kaydetme sırasında image'ı thumb'a da kopyala""" + # Model save metodu zaten bu işi yapıyor, buradaki koda gerek yok aslında + # ama form üzerinden gelen veriyi kontrol etmek için bırakılabilir. + # Ancak model save metodundaki mantık daha sağlam olduğu için burayı sadeleştiriyoruz. + super().save_model(request, obj, form, change) + + def formatted_hit_count(self, obj): + return obj.current_hit_count if obj.current_hit_count > 0 else '-' + + formatted_hit_count.admin_order_field = 'hit_count' + formatted_hit_count.short_description = 'Hits' + + def post_tags(self, obj): + tags = '
      ' + for tag in obj.tags.all(): + tags += '
    • ' + tag.tag + '
    • ' + tags += '
    ' + return mark_safe(tags) + + def post_kategorileri(self, obj): + html = '
      ' + for category in obj.categories.all(): + html += '
    • ' + category.title + '
    • ' + html += '
    ' + return mark_safe(html) + + def post_resim(self, obj): + if obj.image: + # Uygulama adı 'blog' olduğu için URL yapısı /admin/blog/post/... olmalı + return mark_safe( + ''.format( + obj.id, obj.image.url)) + return mark_safe('Resim Yok') + + post_resim.short_description = 'Kurs Resmi' + + +admin.site.register(Post, PostAdmin) + + +class CategoryAdmin(admin.ModelAdmin): + list_display = ('title', 'parent_category', 'is_active', 'created_at', 'order') # Removed 'view_count' and 'unique_view_count' + list_filter = ('title', 'is_active', 'created_at', 'parent') + search_fields = ('title', 'is_active', 'slug') + list_editable = ('is_active', 'order') + + class Meta: + model = Category + + def parent_category(self, obj): + if obj.parent: + return obj.parent.title + return "Ana Kategori" + + parent_category.short_description = 'Üst Kategori' + + +admin.site.register(Category, CategoryAdmin) + + +class TagsAdmin(admin.ModelAdmin): + list_display = ('tag', 'created_at',) + list_filter = ('tag',) + search_fields = ('tag',) + + class Meta: + model = Tags + + +admin.site.register(Tags, TagsAdmin) + + +class CategoryViewAdmin(admin.ModelAdmin): + list_display = ('category', 'ip_address', 'created_at') + list_filter = ('created_at', 'category') + search_fields = ('ip_address', 'category__title') + readonly_fields = ('category', 'ip_address', 'user_agent', 'created_at') + + class Meta: + model = CategoryView + + +admin.site.register(CategoryView, CategoryViewAdmin) +admin.site.register(Comment) diff --git a/blog/apps.py b/blog/apps.py new file mode 100644 index 0000000..b9a09fd --- /dev/null +++ b/blog/apps.py @@ -0,0 +1,9 @@ +from django.apps import AppConfig + + +class BlogConfig(AppConfig): + name = 'blog' + default_auto_field = 'django.db.models.BigAutoField' + + def ready(self): + import blog.signals diff --git a/blog/management/__init__.py b/blog/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/management/commands/__init__.py b/blog/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/management/commands/create_fake_posts.py b/blog/management/commands/create_fake_posts.py new file mode 100644 index 0000000..0a93d51 --- /dev/null +++ b/blog/management/commands/create_fake_posts.py @@ -0,0 +1,85 @@ +import os +import random +import string +import requests +from django.contrib.auth import get_user_model +from django.core.management.base import BaseCommand +from django.core.files.base import ContentFile +from blog.models import Post, Category, Tags + +try: + from faker import Faker + fake = Faker() + HAS_FAKER = True +except ImportError: + HAS_FAKER = False + +class Command(BaseCommand): + help = 'Creates 300 fake posts with random images' + + def handle(self, *args, **kwargs): + User = get_user_model() + # Prefer an existing staff user, otherwise any existing user, otherwise create a fallback user + user = User.objects.filter(is_staff=True).first() or User.objects.first() + if not user: + self.stdout.write('Hiç kullanıcı bulunamadı, `fakeuser` oluşturuluyor...') + user = User.objects.create(username='fakeuser', email='fake@example.com') + user.set_unusable_password() + user.save() + categories = list(Category.objects.all()) + if not categories: + self.stdout.write(self.style.ERROR('Lütfen önce en az bir kategori oluşturun!')) + return + + tags = list(Tags.objects.all()) + if not tags: + self.stdout.write('Tag bulunamadı, oluşturuluyor...') + for i in range(5): + tag_name = self.get_random_string(8) if not HAS_FAKER else fake.word() + Tags.objects.create(tag=tag_name) + tags = list(Tags.objects.all()) + + self.stdout.write('300 adet fake post oluşturuluyor...') + + for i in range(300): + if HAS_FAKER: + title = fake.sentence(nb_words=6).replace('.', '') + content = '\n\n'.join(fake.paragraphs(nb=5)) + keywords = ", ".join(fake.words(nb=5)) + else: + title = self.get_random_string(30) + content = self.get_random_string(500) + keywords = self.get_random_string(20) + + post = Post( + user=user, + title=title, + content=content, + keywords=keywords, + video='none', + is_active=True, + is_front=True + ) + post.save() + + # ManyToMany ilişkileri + post.categories.add(random.choice(categories)) + post.tags.add(random.choice(tags)) + + # Resim ekle + try: + # Picsum'dan rastgele resim (800x600) + img_url = f"https://picsum.photos/seed/{random.randint(1, 10000)}/800/600" + response = requests.get(img_url, timeout=10) + if response.status_code == 200: + file_name = f"fake_post_{i}_{random.randint(1000,9999)}.jpg" + post.image.save(file_name, ContentFile(response.content), save=True) + self.stdout.write(f'Post {i+1}/300 oluşturuldu: {title} (Resimli)') + else: + self.stdout.write(f'Post {i+1}/300 oluşturuldu: {title} (Resimsiz - İndirme hatası)') + except Exception as e: + self.stdout.write(f'Post {i+1}/300 oluşturuldu: {title} (Resimsiz - Hata: {str(e)})') + + def get_random_string(self, length): + letters = string.ascii_letters + string.digits + ' ' + return ''.join(random.choice(letters) for i in range(length)) diff --git a/blog/migrations/0001_initial.py b/blog/migrations/0001_initial.py new file mode 100644 index 0000000..81c6040 --- /dev/null +++ b/blog/migrations/0001_initial.py @@ -0,0 +1,127 @@ +# Generated by Django 5.2.9 on 2026-01-05 22:33 + +import autoslug.fields +import core.utils +import django.db.models.deletion +import imagekit.models.fields +import tinymce.models +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Tags', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tag', models.CharField(max_length=254, verbose_name='Post Tagları')), + ('slug', autoslug.fields.AutoSlugField(blank=True, editable=True, max_length=250, populate_from='tag', unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı')), + ], + options={ + 'verbose_name': 'Post Tagı', + 'verbose_name_plural': 'Post Tagları', + 'db_table': 'tags', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Kategori')), + ('keywords', models.CharField(max_length=254, verbose_name='Seo Kelimeleri Aralarına Virgül Koyunuz')), + ('description', models.CharField(max_length=254, verbose_name='Açıklama')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı')), + ('order', models.IntegerField(db_index=True, default=1, verbose_name='Görüntülenme Sırası')), + ('slug', autoslug.fields.AutoSlugField(blank=True, editable=True, max_length=250, populate_from='title', unique=True)), + ('image', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to=core.utils.UniquePathAndRename('uploads/category'), verbose_name='Resim 630 x 653 Olmali ve Transparan PNG Olmali')), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='blog.category', verbose_name='Üst Kategorisi')), + ], + options={ + 'verbose_name': 'Post Kategori', + 'verbose_name_plural': 'Post Kategorilerileri', + 'db_table': 'categories', + 'ordering': ['order'], + 'unique_together': {('slug', 'parent')}, + }, + ), + migrations.CreateModel( + name='Post', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Post Başlığı')), + ('content', tinymce.models.HTMLField(blank=True, null=True, verbose_name='Post İçeriği')), + ('keywords', models.CharField(max_length=254, verbose_name='Seo Kelimeleri Aralarına Virgül Koyunuz')), + ('image', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to=core.utils.UniquePathAndRename('uploads/post'))), + ('thumb', imagekit.models.fields.ProcessedImageField(blank=True, editable=False, null=True, upload_to=core.utils.UniquePathAndRename('uploads/post/thumb'))), + ('video', models.CharField(blank=True, default='none', max_length=254, null=True, verbose_name='Video')), + ('slug', autoslug.fields.AutoSlugField(blank=True, editable=True, max_length=250, populate_from='title', unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?')), + ('is_front', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Önde Görünsünmü ?')), + ('categories', models.ManyToManyField(related_name='c_categories', to='blog.category', verbose_name='Post Kategorisi')), + ('parent', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='blog.post', verbose_name='Konular')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='posts', to=settings.AUTH_USER_MODEL)), + ('tags', models.ManyToManyField(related_name='tags', to='blog.tags', verbose_name='Post Tagları')), + ], + options={ + 'verbose_name': 'Post', + 'verbose_name_plural': 'Posts', + 'db_table': 'posts', + 'ordering': ['created_at'], + 'unique_together': {('slug',)}, + }, + ), + migrations.CreateModel( + name='CategoryView', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ip_address', models.GenericIPAddressField(verbose_name='IP Adresi')), + ('user_agent', models.TextField(blank=True, null=True, verbose_name='User Agent')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Ziyaret Tarihi')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='category_views', to='blog.category')), + ], + options={ + 'verbose_name': 'Kategori Ziyareti', + 'verbose_name_plural': 'Kategori Ziyaretleri', + 'db_table': 'category_views', + 'indexes': [models.Index(fields=['category', 'ip_address', 'created_at'], name='category_vi_categor_234334_idx')], + }, + ), + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Yorum Başlığı')), + ('body', models.TextField(verbose_name='Yorum')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı')), + ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='title', unique=True)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='blog.comment')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cuser', to=settings.AUTH_USER_MODEL)), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='_product', to='blog.post')), + ], + options={ + 'verbose_name': 'Post Yorum', + 'verbose_name_plural': 'Post Yorumları', + 'db_table': 'comments', + 'ordering': ['-created_at'], + 'unique_together': {('slug', 'parent')}, + }, + ), + ] diff --git a/blog/migrations/0002_remove_comment_product_comment_post.py b/blog/migrations/0002_remove_comment_product_comment_post.py new file mode 100644 index 0000000..690b8dc --- /dev/null +++ b/blog/migrations/0002_remove_comment_product_comment_post.py @@ -0,0 +1,24 @@ +# Generated by Django 5.2.9 on 2026-01-09 03:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='comment', + name='product', + ), + migrations.AddField( + model_name='comment', + name='post', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='_post', to='blog.post'), + preserve_default=False, + ), + ] diff --git a/blog/migrations/__init__.py b/blog/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blog/models.py b/blog/models.py new file mode 100644 index 0000000..c5e3259 --- /dev/null +++ b/blog/models.py @@ -0,0 +1,240 @@ +import os +from autoslug import AutoSlugField +from django.conf import settings +from django.core.files.base import ContentFile +from django.db import models +from imagekit.models import ProcessedImageField +from tinymce.models import HTMLField + +from core.utils import image_optimizer + + +# Create your models here. +class Category(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + title = models.CharField(max_length=254, verbose_name="Kategori") + keywords = models.CharField(max_length=254, verbose_name="Seo Kelimeleri Aralarına Virgül Koyunuz") + description = models.CharField(max_length=254, verbose_name="Açıklama") + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) + order = models.IntegerField(verbose_name='Görüntülenme Sırası', default=1, db_index=True) + slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=True, db_index=True, max_length=250, + blank=True) + parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True, + verbose_name='Üst Kategorisi') + image = ProcessedImageField(**image_optimizer('uploads/category', 300, 300, 85, 'PNG'), + verbose_name='Resim 630 x 653 Olmali ve Transparan PNG Olmali', blank=True, null=True) + + class Meta: + ordering = ["order"] + db_table = 'categories' + verbose_name_plural = "Post Kategorilerileri" + verbose_name = "Post Kategori" + unique_together = ('slug', 'parent',) + + def get_slug(self): + slug = self.title.replace('ı', "i").replace('İ', 'i') + number = 1 + while Category.objects.filter(slug=slug).exists(): + slug = '{}-{}'.format(slug, number) + number += 1 + return slug + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.get_slug() + super().save(*args, **kwargs) + + def __str__(self): + full_path = [self.title] + k = self.parent + while k is not None: + full_path.append(k.title) + k = k.parent + return ' -> '.join(full_path[::-1]) + + +class Tags(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + tag = models.CharField(max_length=254, verbose_name="Post Tagları") + slug = AutoSlugField(populate_from='tag', null=False, unique=True, editable=True, db_index=True, max_length=250, + blank=True) + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) + + class Meta: + ordering = ["-created_at"] + db_table = 'tags' + verbose_name_plural = "Post Tagları" + verbose_name = "Post Tagı" + + def get_slug(self): + slug = self.tag.replace('ı', "i").replace('İ', 'i') + number = 1 + while Tags.objects.filter(slug=slug).exists(): + slug = '{}-{}'.format(slug, number) + number += 1 + return slug + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.get_slug() + super().save(*args, **kwargs) + + def __str__(self): + return self.tag + + +class Post(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + + title = models.CharField(max_length=254, verbose_name="Post Başlığı") + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts', null=True, blank=True) + content = HTMLField(blank=True, null=True, verbose_name='Post İçeriği') + categories = models.ManyToManyField(Category, verbose_name="Post Kategorisi", related_name='c_categories') + keywords = models.CharField(max_length=254, verbose_name="Seo Kelimeleri Aralarına Virgül Koyunuz") + tags = models.ManyToManyField(Tags, verbose_name="Post Tagları", related_name='tags') + image = ProcessedImageField(**image_optimizer('uploads/post', 840, 500, 85, 'avif'), null=True, blank=True) + thumb = ProcessedImageField(**image_optimizer('uploads/post/thumb', 348, 160, 85, 'avif'), null=True, blank=True,editable=False) + + video = models.CharField(verbose_name="Video", null=True, blank=True, max_length=254, default='none') + slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=True, db_index=True, max_length=250, + blank=True) + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif) + is_front = models.BooleanField(default=True, verbose_name='Önde Görünsünmü ?', choices=aktif) + parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True, + editable=False, + verbose_name='Konular') + + class Meta: + ordering = ["created_at"] + db_table = 'posts' + verbose_name_plural = "Posts" + verbose_name = "Post" + unique_together = ('slug',) + + def get_slug(self): + slug = self.title.replace('ı', "i").replace('İ', 'i') + number = 1 + while Post.objects.filter(slug=slug).exists(): + slug = '{}-{}'.format(slug, number) + number += 1 + return slug + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.get_slug() + + if self.image: + # Eğer yeni bir kayıt ise veya resim değişmişse + update_thumb = False + if not self.pk: + update_thumb = True + else: + try: + old_instance = self.__class__.objects.get(pk=self.pk) + if self.image != old_instance.image: + update_thumb = True + except self.__class__.DoesNotExist: + pass + + if update_thumb: + try: + if hasattr(self.image, 'closed') and self.image.closed: + self.image.open() + + if hasattr(self.image, 'seek'): + self.image.seek(0) + + content = self.image.read() + filename = os.path.basename(self.image.name) + + # Doğrudan alana ata, super().save() işleyecek + self.thumb = ContentFile(content, name=filename) + except Exception: + pass + finally: + if hasattr(self.image, 'seek'): + self.image.seek(0) + + super().save(*args, **kwargs) + + def __str__(self): + return f"Postlar: {self.title}" + + +class CategoryView(models.Model): + """Kategori ziyaretlerini takip etmek için model""" + category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_views') + ip_address = models.GenericIPAddressField(verbose_name='IP Adresi') + user_agent = models.TextField(blank=True, null=True, verbose_name='User Agent') + created_at = models.DateTimeField(auto_now_add=True, verbose_name='Ziyaret Tarihi') + + class Meta: + db_table = 'category_views' + verbose_name = 'Kategori Ziyareti' + verbose_name_plural = 'Kategori Ziyaretleri' + # unique_together kısıtlamasını kaldırdık - artık günlük bazda kontrol edeceğiz + indexes = [ + models.Index(fields=['category', 'ip_address', 'created_at']), + ] + + def __str__(self): + return f"{self.category.title} - {self.ip_address} - {self.created_at.strftime('%Y-%m-%d %H:%M')}" + + +class Comment(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='cuser') + product = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='_product') + title = models.CharField(max_length=254, verbose_name="Yorum Başlığı") + body = models.TextField(verbose_name='Yorum') + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) + slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=False, db_index=True) + parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True) + + class Meta: + ordering = ["-created_at"] + db_table = 'comments' + verbose_name_plural = "Post Yorumları" + verbose_name = "Post Yorum" + unique_together = ('slug', 'parent',) + + def get_slug(self): + slug = self.title.replace('ı', "i").replace('İ', 'i') + number = 1 + while Comment.objects.filter(slug=slug).exists(): + slug = '{}-{}'.format(slug, number) + number += 1 + return slug + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.get_slug() + super().save(*args, **kwargs) + + def __str__(self): + full_path = [self.title] + k = self.parent + while k is not None: + full_path.append(k.title) + k = k.parent + return ' -> '.join(full_path[::-1]) diff --git a/blog/serializers.py b/blog/serializers.py new file mode 100644 index 0000000..8bffc69 --- /dev/null +++ b/blog/serializers.py @@ -0,0 +1,89 @@ +from rest_framework import serializers + +from blog.models import Category, Post, Tags + + +class CateSerializer(serializers.ModelSerializer): + parent = serializers.StringRelatedField() # ID yerine __str__ metodundaki değeri döndürür + + class Meta: + model = Category + fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'image', 'keywords', 'description'] + + +class TagSerializer(serializers.ModelSerializer): + class Meta: + model = Tags + fields = ['tag', 'slug'] + + +class PostSerializer(serializers.ModelSerializer): + categories = CateSerializer(read_only=True, many=True) + # Tags için sadece tag ismini döndürmek daha temiz olabilir, ama mevcut yapıyı koruyalım + # Eğer sadece isim listesi istenirse: tags = serializers.SlugRelatedField(many=True, read_only=True, slug_field='tag') + tags = TagSerializer(read_only=True, many=True) + + class Meta: + model = Post + fields = ['title', 'content', 'categories', 'keywords', 'tags', 'image', 'thumb', 'video', + 'slug', 'created_at', 'updated_at', 'is_active', 'is_front'] + # fields = '__all__' + + +class PostSYalinerializer(serializers.ModelSerializer): + class Meta: + model = Post + fields = ['slug', ] + # fields = '__all__' + + +class CategorySerializer(serializers.ModelSerializer): + + posts = PostSYalinerializer(source='c_categories', read_only=True, many=True) + child = serializers.SerializerMethodField() + + class Meta: + model = Category + fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'image', 'keywords', 'description', + 'posts', 'child'] + + def get_child(self, obj): + serializer = self.__class__(obj.child.all(), many=True, context=self.context) + return serializer.data + + +class CategoryPostSerializer(serializers.ModelSerializer): + + posts = serializers.SerializerMethodField() + child = serializers.SerializerMethodField() + + class Meta: + model = Category + fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'image', 'keywords', 'description', + 'posts', 'child'] + + def get_posts(self, obj): + # Pagination context'ini al + paginator = self.context.get('paginator') + request = self.context.get('request') + + posts = obj.c_categories.all() + + if paginator and request: + # Pagination uygula + paginated_posts = paginator.paginate_queryset(posts, request) + serializer = PostSerializer(paginated_posts, many=True, context=self.context) + return { + 'results': serializer.data, + 'count': posts.count(), + 'next': paginator.get_next_link(), + 'previous': paginator.get_previous_link(), + } + else: + # Pagination yoksa normal döndür + serializer = PostSerializer(posts, many=True, context=self.context) + return serializer.data + + def get_child(self, obj): + serializer = self.__class__(obj.child.all(), many=True, context=self.context) + return serializer.data \ No newline at end of file diff --git a/blog/signals.py b/blog/signals.py new file mode 100644 index 0000000..7fa83b9 --- /dev/null +++ b/blog/signals.py @@ -0,0 +1,52 @@ +from django.db.models.signals import pre_save +from django.dispatch import receiver +from django.core.files.base import ContentFile +from .models import Post + + +@receiver(pre_save, sender=Post) +def update_post_thumb(sender, instance, **kwargs): + """ + Post kaydedilmeden önce, image alanı doluysa thumb'ı da güncelle + """ + if instance.image: + # Yeni kayıt veya image güncellenmiş mi kontrol et + should_update_thumb = False + + if instance.pk: + try: + old_instance = Post.objects.get(pk=instance.pk) + # Image değişmişse thumb'ı da güncelle + if str(old_instance.image) != str(instance.image): + should_update_thumb = True + except Post.DoesNotExist: + # Kayıt bulunamadı, yeni kayıt gibi davran + should_update_thumb = True + else: + # Yeni kayıt (pk yok) + should_update_thumb = True + + if should_update_thumb and hasattr(instance.image, 'file'): + # Image dosyasını thumb alanına kopyala + try: + # Image dosyasının içeriğini oku + instance.image.file.seek(0) + image_content = instance.image.file.read() + instance.image.file.seek(0) + + # Dosya adını al + image_name = instance.image.name.split('/')[-1] + + # Thumb alanına kaydet + instance.thumb.save( + image_name, + ContentFile(image_content), + save=False + ) + except Exception as e: + print(f"Thumb oluşturma hatası: {e}") + import traceback + traceback.print_exc() + + + diff --git a/blog/tasks.py b/blog/tasks.py new file mode 100644 index 0000000..8ad70bb --- /dev/null +++ b/blog/tasks.py @@ -0,0 +1,40 @@ +from celery import shared_task +from django.core.mail import send_mail +from django.conf import settings + +@shared_task +def send_comment_notification_email(comment_title, comment_body, post_title, user_email): + """ + Yeni bir yorum yapıldığında admin'e e-posta gönderir. + """ + subject = f'Yeni Yorum: {post_title}' + message = f""" + Merhaba Admin, + + "{post_title}" başlıklı yazıya yeni bir yorum yapıldı. + + Yorum Yapan: {user_email} + Başlık: {comment_title} + Yorum: {comment_body} + + Kontrol etmek için admin paneline giriş yapabilirsiniz. + """ + + # Admin e-posta adresini settings'den veya doğrudan buraya yazabilirsiniz + # Örnek olarak settings.DEFAULT_FROM_EMAIL kullanıldı, admin listesi de kullanılabilir + admin_email = settings.DEFAULT_FROM_EMAIL + + # Eğer settings.ADMINS tanımlıysa oradaki ilk kişiye de atılabilir + if hasattr(settings, 'ADMINS') and settings.ADMINS: + recipient_list = [email for name, email in settings.ADMINS] + else: + # Fallback olarak bir email + recipient_list = ['admin@example.com'] + + send_mail( + subject, + message, + settings.DEFAULT_FROM_EMAIL, + recipient_list, + fail_silently=False, + ) diff --git a/blog/tests.py b/blog/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/blog/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/blog/urls.py b/blog/urls.py new file mode 100644 index 0000000..5bd6531 --- /dev/null +++ b/blog/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from blog.views import CategoryList, CategoryDetail, PostDetail, PostList + +urlpatterns = [ + path('categories/', CategoryList.as_view(), name='categories.list'), + path('categories//', CategoryDetail.as_view(), name='categories.details'), + path('post/', PostList.as_view(), name='post.list'), + path('post//', PostDetail.as_view(), name='post.details'), +] diff --git a/blog/views.py b/blog/views.py new file mode 100644 index 0000000..9ba79d3 --- /dev/null +++ b/blog/views.py @@ -0,0 +1,47 @@ +from rest_framework.generics import ListAPIView, RetrieveAPIView +from rest_framework.pagination import PageNumberPagination + +from blog.models import Post, Category +from blog.serializers import PostSerializer, CategorySerializer, CategoryPostSerializer +from core.Permission import ReadOnly + + +class StandardResultsSetPagination(PageNumberPagination): + page_size = 10 + page_size_query_param = 'page_size' + max_page_size = 100 + + +# Create your views here. +class CategoryList(ListAPIView): + permission_classes = [ReadOnly] + queryset = Category.objects.order_by('order').filter(is_active=True, parent__isnull=True).all() + # serializer_class = ParentSerializer + serializer_class = CategorySerializer + + +class CategoryDetail(RetrieveAPIView): + permission_classes = [ReadOnly] + queryset = Category.objects.order_by('order').filter(is_active=True).all() + serializer_class = CategoryPostSerializer + lookup_field = 'slug' # Slug ile arama yapılacak + + def get_serializer_context(self): + context = super().get_serializer_context() + context['paginator'] = StandardResultsSetPagination() + return context + + +# Create your views here. +class PostList(ListAPIView): + permission_classes = [ReadOnly] + queryset = Post.objects.all() + serializer_class = PostSerializer + pagination_class = StandardResultsSetPagination + + +class PostDetail(RetrieveAPIView): + permission_classes = [ReadOnly] + queryset = Post.objects.all() + serializer_class = PostSerializer + lookup_field = 'slug' # Slug ile arama yapılacak diff --git a/caddy/Caddyfile b/caddy/Caddyfile new file mode 100644 index 0000000..2550d62 --- /dev/null +++ b/caddy/Caddyfile @@ -0,0 +1,28 @@ +:80 { + # Büyük upload limiti (Nginx'teki client_max_body_size 100M eşdeğeri) + request_body { + max_size 100MB + } + + # Static dosyalar + handle_path /static/* { + root * /app/staticfiles + header Cache-Control "public, immutable" + file_server + } + + # Media dosyalar + handle_path /media/* { + root * /app/media + header Cache-Control "public" + file_server + } + + # Diğer tüm istekler Django'ya + reverse_proxy django_web_prod:8000 { + header_up Host {host} + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} diff --git a/caddy/Dockerfile b/caddy/Dockerfile new file mode 100644 index 0000000..bd5a648 --- /dev/null +++ b/caddy/Dockerfile @@ -0,0 +1,4 @@ +FROM caddy:2 + +# Build context repo root'u (.) olduğu için caddy/Caddyfile yolu kullanıyoruz +COPY caddy/Caddyfile /etc/caddy/Caddyfile diff --git a/client_secret_2_915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com.json b/client_secret_2_915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com.json new file mode 100644 index 0000000..0a450e2 --- /dev/null +++ b/client_secret_2_915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com.json @@ -0,0 +1 @@ +{"web":{"client_id":"915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com","project_id":"django-471018","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["http://localhost:3000/api/auth/callback/google","http://localhost:8000/api/auth/callback/google","http://127.0.0.1:8000/api/auth/callback/google","http://127.0.0.1:3000/api/auth/callback/google","http://127.0.0.1:8000/accounts/auth/google/login/callback/","http://127.0.0.1:8000/auth/google/callback/","http://localhost:8000/auth/google/callback/","http://localhost:3000/auth/google","http://localhost:8000/auth/google"],"javascript_origins":["http://localhost:3000","http://localhost:8000","http://127.0.0.1:8000","http://127.0.0.1:3000"]}} \ No newline at end of file diff --git a/copilot-auth-setup-prompt.md b/copilot-auth-setup-prompt.md new file mode 100644 index 0000000..68c41a6 --- /dev/null +++ b/copilot-auth-setup-prompt.md @@ -0,0 +1,314 @@ +# Copilot için Ayrıntılı Prompt: Django 6.0 Custom Account + Djoser + JWT + Social Auth + +Aşağıdaki metni **Copilot Chat** veya GitHub Copilot’a vereceğim. Sen (Copilot) bu projede adım adım ilerleyen bir **backend mimarı + uygulayıcı** gibi davranacaksın. + +## Proje Bağlamı + +- Framework: **Django==6.0** +- API: **Django REST Framework (djangorestframework==3.16.1)** +- Auth: + - **Djoser==2.3.3** + - **djangorestframework_simplejwt==5.5.1** + - Ek olarak **social auth** social-auth-app-django==5.6.0 social-auth-core==4.8.1 bunlar kulanilacak +- Bu proje bir **REST backend** olacak ve **Nuxt.js** ile **Next.js** frontendlere servis verecek. + - SPA (Single Page App) + JWT kullanımına uygun olacak. + - CORS, JSON response formatı, JWT bearer token desteği önemli.(Corsheader Paketi yuklu ve yaplandirlmis) + +## İstediğim Auth Sistemi (Özet) + +1. **Custom User Model** (email tabanlı): + - Login **email ile** yapılacak (username yok). + - Register da email + password ile olacak. + - `AUTH_USER_MODEL` olarak özel bir user modeli (örn. `accounts.CustomUser`) kullanılacak. + - `USERNAME_FIELD = "email"` + - `email` unique olacak. + - Normal (email/password) register ile oluşturulan hesaplar: + - Başlangıçta `is_active = False` olacak. + - Kullanıcı e‑posta aktivasyonu yapmadan giriş yapamayacak. + - **Social login** ile gelen hesaplar: + - `is_active = True` olacak (yani sosyal hesaplar için ayrıca email aktivasyon istemeyeceğiz). + +2. **Register Akışı (Email/Password)**: + - Örnek endpoint (Djoser varsayılanı da olabilir): `POST /auth/register/` + - Request body: + ```json + { + "email": "user@example.com", + "password": "StrongP@ssw0rd", + "re_password": "StrongP@ssw0rd", + "first_name": "Ali", + "last_name": "Veli" + } + ``` + - İşleyiş: + - Yeni user oluşturulur, `is_active = False` atanır. + - Djoser üzerinden aktivasyon e‑postası gönderilir. + - Aktivasyon linki Djoser’in `ACTIVATION_URL` formatına göre hazırlanır: + - Örn: `https://frontend-domain/auth/activate/{uid}/{token}/` (Nuxt/Next içindeki sayfaya yönlenebilir). + +3. **Email Aktivasyon**: + - Endpoint (Djoser): `POST /auth/activate/` + - Request body: + ```json + { + "uid": "", + "token": "" + } + ``` + - Aktivasyon başarılı olursa: + - `user.is_active = True` + - Kullanıcı artık JWT ile login olabilecek. + +4. **Login (JWT ile)**: + - JWT auth için `djangorestframework_simplejwt` kullanılacak. + - Djoser’la entegre endpoint: + - `POST /auth/jwt/create/` + - Request body: + ```json + { + "email": "user@example.com", + "password": "StrongP@ssw0rd" + } + ``` + - Response: + ```json + { + "access": "", + "refresh": "" + } + ``` + - **Aktivasyon yapmamış** kullanıcı login olmaya çalışırsa: + - Uygun bir hata kodu (400/401) ve anlamlı bir hata mesajı dönecek: + - Örn: `"detail": "Account is not activated. Please check your email."` + +5. **Social Login**: + - Özel social auth endpoint’leri istiyorum: + - Örnek: `POST /auth/social//` (ör: `/auth/social/google/`, `/auth/social/github/`). + - Frontend (Nuxt/Next) tarafı: + - Genelde OAuth flow’u client-side yapıp backend’e `access_token` gönderiyor. + - Backend tarafı: + - Provider’dan gelen `access_token` ile kullanıcı bilgisi alınacak. + - Provider’dan email alınamazsa, uygun bir hata dönülecek (misal: `"Email not provided by provider"`). + - Eğer email varsa: + - Kullanıcı bulunursa giriş yaptır, yoksa yeni bir kullanıcı oluştur. + - Bu kullanıcı için: + - `is_active = True` olarak set edilecek. + - **Ekstra email aktivasyon e‑postası gönderilmeyecek**. + - Ardından JWT access/refresh token üret ve response olarak dön: + ```json + { + "access": "", + "refresh": "", + "user": { + "id": 1, + "email": "user@example.com", + "first_name": "Ali", + "last_name": "Veli" + } + } + ``` + +6. **Djoser Yapılandırması**: + - `djoser==2.3.3` kullanılacak. + - `settings.py` içinde `DJOSER = { ... }` konfigürasyonu yapılacak. + - Örnek ayarlar: + - `SEND_ACTIVATION_EMAIL = True` + - `ACTIVATION_URL = "auth/activate/{uid}/{token}/"` (buraya Nuxt/Next üzerindeki route’u da koyabiliriz). + - `SERIALIZERS` içinde: + - `user_create` → custom serializer (register sırasında `is_active=False` ayarlayacak). + - `user` → custom user serializer (frontend’e gönderilecek user alanlarını kontrol etmek için). + - Token modeli kullanmayacaksak `TOKEN_MODEL = None` vs. + +7. **JWT Ayarları (SIMPLE_JWT)**: + - `REST_FRAMEWORK` → `DEFAULT_AUTHENTICATION_CLASSES` içinde `rest_framework_simplejwt.authentication.JWTAuthentication` tanımlanacak. + - `SIMPLE_JWT` içinde access/refresh lifetime, `AUTH_HEADER_TYPES = ("Bearer",)` vb. ayarları yapacağız. + +8. **Email Gönderimi**: + - Geliştirme ortamı: + - `EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"` olabilir. + - Prod ortamı: + - ENV üzerinden SMTP ayarları (`EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_HOST_USER`, `EMAIL_HOST_PASSWORD`, `EMAIL_USE_TLS` vb.) + - Aktivasyon için HTML ve plain text template’leri: + - `templates/email/activation_email.html` + - `templates/email/activation_email.txt` + - sindilik localdeki emailpit kullanalim + +9. **CORS / SPA Entegrasyonu**: + - Nuxt ve Next için: + - `CORS_ALLOWED_ORIGINS` içinde dev ve prod URL’ler olacak (örn. `http://localhost:3000`, `http://localhost:5173`, vs.). + - Auth: + - JWT bearer token kullanılacak: `Authorization: Bearer ` + - Cookie tabanlı session auth kullanmayacağız (veya minimal). CSRF, SPA senaryosuna göre ayarlanacak / devre dışı bırakılacak (bunu açıklayan bir not yaz). + +10. **Güvenlik & Rate Limiting**: + - Django password validators aktif olacak. + - Auth endpoint’leri için basic throttling / rate limit ayarları öner ve uygula (ör: DRF throttling). + +11. **Testler**: + - En azından aşağıdakiler için tests yaz: + - Register → user oluşturuluyor mu, `is_active=False` mi, email aktivasyonu tetikleniyor mu? + - Activate → doğru uid/token ile aktivasyon başarılı mı? Yanlış ise hata veriyor mu? + - Login → aktif kullanıcı login olabiliyor mu? Aktif olmayan için hata dönüyor mu? + - Social login → access_token üzerinden provider’dan user elde ediliyor mu, `is_active=True` ile user oluşturuluyor mu, JWT dönüyor mu? + +12. **Dokümantasyon**: + - Örnek bir doküman dosyası: `AUTH.md` veya `README.md` içinde bir bölüm: + - Tüm auth endpoint’leri + - Örnek request/response’lar + - Nuxt/Next tarafında nasıl kullanılacağına dair ayrintili notlar + - ENV değişkenleri (email, social provider keys vs.) + +## Dosya ve Kod Yapı Planı + +Aşağıdakiler bir referans plan; proje yapısına göre isimler uyarlanabilir (örn. `config/settings.py` vs. `project/settings.py`). + +- `accounts/models.py` + - `CustomUser(AbstractBaseUser, PermissionsMixin)`: + - Alanlar: `email`, `first_name`, `last_name`, `is_staff`, `is_active`, `date_joined` vb. + - `USERNAME_FIELD = "email"` + - `REQUIRED_FIELDS = []` (veya first_name/last_name) + - `CustomUserManager`: + - `create_user` + - `create_superuser` + +- `accounts/admin.py` + - Django admin’de custom user’ı `UserAdmin` türeterek kaydet. + +- `accounts/serializers.py` + - `CustomUserCreateSerializer`: + - Register sırasında kullanılır. + - `is_active=False` set eder. + - `CustomUserSerializer`: + - Kullanıcı profilini döner (id, email, first_name, last_name vb.). + - `SocialLoginSerializer`: + - Alanlar: `provider`, `access_token` (ve gerekiyorsa `id_token` vs.). + +- `accounts/views.py` + - Gerekirse: + - `SocialLoginView` (provider’a göre token doğrulayan, user oluşturan/döndüren, sonra JWT üreten). + - İsteğe bağlı: `ResendActivationView`. + +- `accounts/urls.py` + - `/auth/social//` için route. + - Djoser url’leri (register/activate/jwt vb.) de burada veya ana `urls.py` içinde include edilebilir. + +- `config/settings.py` (veya proje settings dosyası) + - `INSTALLED_APPS`: + - `'accounts'` + - `'rest_framework'` + - `'djoser'` + - `'rest_framework_simplejwt'` + - `'corsheaders'` + - Social auth için: `'social_django'` veya seçtiğimiz paket. + - `AUTH_USER_MODEL = "accounts.CustomUser"` + - `REST_FRAMEWORK` ayarları (`DEFAULT_AUTHENTICATION_CLASSES`, throttling vb.) + - `SIMPLE_JWT` ayarları + - `DJOSER` konfigürasyonu + - `CORS_ALLOWED_ORIGINS` + - `EMAIL_BACKEND` ve diğer email ayarları + - Social provider ayarları (`SOCIAL_AUTH_*` veya ilgili konfigler) + +- `templates/email/activation_email.html` +- `templates/email/activation_email.txt` + +- `requirements.txt` + - `Django==6.0` + - `djangorestframework==3.16.1` + - `djoser==2.3.3` + - `djangorestframework_simplejwt==5.5.1` + - `social-auth-app-django` (veya tercih ettiğimiz social auth paketi) + - `django-cors-headers` + +- `tests/test_accounts.py` + - Yukarıda bahsettiğim tüm kritik akışlar için testler. + +## Hafıza / Progress Kaydı: COPILOT_MEMORY.md + +Projede ne yapıldığını **hatırlamak** için özel bir dosya istiyorum: + +- Repo kökünde: `COPILOT_MEMORY.md` +- Copilot, her önemli adım veya mantıklı grup değişiklikten sonra bu dosyaya **append** yapsın. +- Kayıt formatı şöyle olsun (örnek): + +```markdown +## 2025-12-11T14:32:00Z +- Değişiklik özeti: + - CustomUser model ve manager eklendi. + - settings.py'de AUTH_USER_MODEL ve djoser/jwt ayarlarının temeli kuruldu. +- Dosyalar: + - accounts/models.py + - accounts/admin.py + - config/settings.py +- Next steps: + - Custom registration serializer ve activation email şablonlarını ekle. +``` + +Kurallar: +- Her anlamlı değişiklik setinden sonra yeni bir `## ` başlığı ile blok ekle. +- Bir sonraki yapılacakları (Next steps) kısa ve net yaz. +- Eğer PR açıyorsan, ilgili PR açıklamasına bu kaydın kısa özetini de ekle. + +## Geliştirme Adımları (Önerilen Sıra) + +Copilot’tan beklediğim ilerleme sırası: + +1. **Custom User Model** + - `accounts` app oluştur (yoksa). + - `CustomUser` ve `CustomUserManager` yaz. + - `AUTH_USER_MODEL` ayarla. + - Migrasyonları oluştur ve çalıştırılabilir hale getir (kod olarak migration dosyaları üret). + +2. **Temel Settings Konfigürasyonu** + - `INSTALLED_APPS`, `REST_FRAMEWORK`, `SIMPLE_JWT`, `DJOSER`, `CORS`, `EMAIL_BACKEND` vs. temel ayarlar. + - Nuxt/Next için örnek CORS domainleri koy (yorum satırı olarak da olabilir). + +3. **Djoser Register / Activate / JWT** + - Djoser’ın default endpoint’lerini aktif et. + - `CustomUserCreateSerializer`’ı bağla, register sırasında `is_active=False` olsun. + - Aktivasyon URL’ini Nuxt/Next kullanacak şekilde düzenle. + +4. **Social Auth Entegrasyonu** + - Seçilecek social auth paketini netleştir (preferans: `social-auth-app-django`). + - Provider konfigleri için env örnekleri yaz. + - `SocialLoginView` ve `SocialLoginSerializer` ile: + - Provider token doğrulama + - Email ile user bul/oluştur + - `is_active=True` set et + - JWT üret ve dön. + +5. **Email Şablonları** + - Aktivasyon e-postası için HTML ve text template’leri yaz. + +6. **Testler** + - Temel testler: register, activate, login, social login. + +7. **Dokümantasyon** + - `AUTH.md` veya README’ye auth bölümünü ekle. + +8. **COPILOT_MEMORY.md Güncellemeleri** + - Her adımda bu dosyaya not düş. + +## Copilot’a Komutum + +Bu prompt’u aldıktan sonra, lütfen: + +1. Projeyi ve hedefleri özetle. +2. Social auth kütüphanesi seçimi için bana 1–2 öneri sun (örnek: `social-auth-app-django` vs `django-allauth`), artılarını/eksilerini kısaca yaz ve **hangisini seçmek istediğimi sor**. +3. Ben seçimi yaptıktan sonra şu adımla başla: + - CustomUser model ve manager’ı yaz. + - `settings.py` içinde gerekli temel konfigürasyonları ekle (AUTH_USER_MODEL, Djoser, DRF, JWT, CORS, EMAIL). + - `COPILOT_MEMORY.md` dosyasına ilk kaydı ekle. +4. Her büyük adım sonunda: + - Hangi dosyaları değiştirdiğini kısaca özetle. + - `COPILOT_MEMORY.md`’ye uygun formatta giriş ekle. + - Bir sonraki adımı bana öner ve onayımı bekle (veya devam etmemi iste). + +Başlangıç komutum: + +> **Başla**: +> - CustomUser model ve manager oluştur. +> - `settings.py` gerekli auth (Djoser + JWT + DRF + CORS + EMAIL) konfigürasyonlarını ekle. +> - Djoser’ın register/activate/jwt endpointlerini temel haliyle ayağa kaldıracak url ve ayarları hazırla. +> - `COPILOT_MEMORY.md` dosyasına başlangıç girdisini ekle. + +Bu prompt’u anladıysan, önce kısaca özetle, sonra social auth kütüphane tercihi için benden seçim iste ve ardından adım 1’e başla. \ No newline at end of file diff --git a/core/Permission.py b/core/Permission.py new file mode 100644 index 0000000..18ccd5f --- /dev/null +++ b/core/Permission.py @@ -0,0 +1,9 @@ +from rest_framework.permissions import BasePermission, SAFE_METHODS + +class ReadOnly(BasePermission): + """ + Yalnızca okuma işlemlerine izin verir. + """ + def has_permission(self, request, view): + # SAFE_METHODS: ('GET', 'HEAD', 'OPTIONS') + return request.method in SAFE_METHODS \ No newline at end of file diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/asgi.py b/core/asgi.py new file mode 100644 index 0000000..e36e2c8 --- /dev/null +++ b/core/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for core project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +application = get_asgi_application() diff --git a/core/celery.py b/core/celery.py new file mode 100644 index 0000000..39c5cb1 --- /dev/null +++ b/core/celery.py @@ -0,0 +1,18 @@ +import os +from celery import Celery + +# Django ayarlarını yükle +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +app = Celery('core') + +# Django ayarlarından 'CELERY_' ile başlayanları al +app.config_from_object('django.conf:settings', namespace='CELERY') + +# Tüm uygulamalardaki tasks.py dosyalarını otomatik keşfet +app.autodiscover_tasks() + + +@app.task(bind=True) +def debug_task(self): + print(f'Request: {self.request!r}') diff --git a/core/settings.py b/core/settings.py new file mode 100644 index 0000000..706c135 --- /dev/null +++ b/core/settings.py @@ -0,0 +1,415 @@ +""" +Django settings for core project. + +Generated by 'django-admin startproject' using Django 5.2. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.2/ref/settings/ +""" + +from pathlib import Path +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-slih+3-7gn0b04-2wm4zq)rp*kz1jnt&bf9o3i3*8jhz*n9=2k') + +# SECURITY WARNING: don't run with debug turned on in production! +# DEBUG = os.getenv('DEBUG', 'True') == 'True' +DEBUG = os.getenv('DEBUG', 'True').lower() == 'true' +# ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '127.0.0.1,localhost').split(',') +ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', 'localhost,127.0.0.1,api.beyhano.net.tr,api.beyhano.com.tr').split(',') + +CSRF_TRUSTED_ORIGINS = os.getenv('CSRF_TRUSTED_ORIGINS', 'https://beyhano.net.tr,https://api.beyhano.net.tr,https://api.beyhano.com.tr').split(',') + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + # 3. Parti + 'django_extensions', + 'rest_framework', + 'rest_framework_simplejwt', + 'djoser', + 'corsheaders', + 'social_django', + 'imagekit', + 'django_cleanup', + 'colorfield', + 'autoslug', + 'tinymce', + + 'django.contrib.sites', # Added for Djoser domain resolution + + # Local apps + 'accounts', + 'blog', + 'backup.apps.BackupConfig', + 'settings', + 'utils', + 'image.apps.ImageConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'accounts.middleware.SocialAuthExceptionMiddleware', +] +SITE_ID = 1 +ROOT_URLCONF = 'core.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR / 'templates'] + , + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + # Social auth context processors + 'social_django.context_processors.backends', + 'social_django.context_processors.login_redirect', + ], + }, + }, +] + +WSGI_APPLICATION = 'core.wsgi.application' + +# Database +# https://docs.djangoproject.com/en/5.2/ref/settings/#databases + +# Docker ortamında veya environment değişkeni varsa PostgreSQL kullan +USE_POSTGRES = os.getenv('USE_POSTGRES', 'True').lower() == 'true' + +if USE_POSTGRES: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.getenv('POSTGRES_DB', 'server_dj'), + 'USER': os.getenv('POSTGRES_USER', 'cloud'), + 'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'gg7678290'), + 'HOST': os.getenv('POSTGRES_HOST', '10.80.80.70'), + 'PORT': os.getenv('POSTGRES_PORT', '5432'), + 'OPTIONS': { + 'options': '-c search_path=public' + }, + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } + } +# redis://default:gg7678290@194.29.55.228:6379 +# ============================================================================== +# REDIS CACHE CONFIGURATION +# ============================================================================== +CACHES = { + 'default': { + 'BACKEND': 'django_redis.cache.RedisCache', + # 'LOCATION': 'redis://default:1923btO**@ares-redis-xrot7z:6379', + 'LOCATION': os.getenv('REDIS_URL', 'redis://default:gg7678290@10.80.80.70:6379'), + # 'LOCATION': os.getenv('REDIS_URL', 'redis://127.0.0.1:6379/1'), + 'OPTIONS': { + 'CLIENT_CLASS': 'django_redis.client.DefaultClient', + }, + 'KEY_PREFIX': 'dj52', + 'TIMEOUT': 300, # 5 dakika default timeout + } +} + +# Password validation + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +# Internationalization +# https://docs.djangoproject.com/en/5.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.2/howto/static-files/ + +STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' +STATICFILES_DIRS = [ + BASE_DIR / 'static', +] +# Media files (User uploaded files) +MEDIA_URL = 'media/' +MEDIA_ROOT = BASE_DIR / 'media' +STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +AUTH_USER_MODEL = 'accounts.CustomUser' + +# ============================================================================== +# REST FRAMEWORK CONFIGURATION +# ============================================================================== +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_simplejwt.authentication.JWTAuthentication', + 'rest_framework.authentication.SessionAuthentication', # For social auth + ), + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAuthenticated', + ], + # Throttling for security + 'DEFAULT_THROTTLE_CLASSES': [ + 'rest_framework.throttling.AnonRateThrottle', + 'rest_framework.throttling.UserRateThrottle', + ], + 'DEFAULT_THROTTLE_RATES': { + 'anon': '100/hour', # Anonymous users + 'user': '1000/hour', # Authenticated users + }, +} + +# ============================================================================== +# SIMPLE JWT CONFIGURATION +# ============================================================================== +from datetime import timedelta + +SIMPLE_JWT = { + 'ACCESS_TOKEN_LIFETIME': timedelta(days=30), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=120), + 'ROTATE_REFRESH_TOKENS': True, + 'BLACKLIST_AFTER_ROTATION': True, + 'UPDATE_LAST_LOGIN': True, + + 'ALGORITHM': 'HS256', + 'SIGNING_KEY': SECRET_KEY, + 'VERIFYING_KEY': None, + 'AUDIENCE': None, + 'ISSUER': None, + + 'AUTH_HEADER_TYPES': ('Bearer',), + 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', + 'USER_ID_FIELD': 'id', + 'USER_ID_CLAIM': 'user_id', + + 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), + 'TOKEN_TYPE_CLAIM': 'token_type', + + 'JTI_CLAIM': 'jti', +} +# ============================================================================== +# DJOSER CONFIGURATION +# ============================================================================== +DJOSER = { + # Domain for email links (YOUR FRONTEND URL) + # Djoser combines DOMAIN + ACTIVATION_URL to create the full link + 'DOMAIN': os.getenv('DJOSER_DOMAIN', 'localhost:3000'), # IMPORTANT: Change this to your frontend's domain + 'SITE_NAME': os.getenv('DJOSER_SITE_NAME', 'Django Auth API'), + + # Registration & Activation + 'SEND_ACTIVATION_EMAIL': True, + 'ACTIVATION_URL': 'activate/{uid}/{token}', # Frontend route, e.g., http://localhost:3000/activate/MQ/token/ + + # Password Reset + 'SEND_CONFIRMATION_EMAIL': True, + 'PASSWORD_RESET_CONFIRM_URL': 'password-reset/{uid}/{token}', # Frontend route + 'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': False, + + # Username Reset + 'USERNAME_RESET_CONFIRM_URL': 'username-reset/{uid}/{token}', # Frontend route + + # Email confirmations + 'PASSWORD_CHANGED_EMAIL_CONFIRMATION': True, + 'USERNAME_CHANGED_EMAIL_CONFIRMATION': True, + + # User settings + 'USER_CREATE_PASSWORD_RETYPE': True, + 'SET_PASSWORD_RETYPE': True, + 'PASSWORD_RESET_CONFIRM_RETYPE': True, + 'LOGIN_FIELD': 'email', + + # Serializers + 'SERIALIZERS': { + 'user_create': 'accounts.serializers.CustomUserCreateSerializer', + 'user': 'accounts.serializers.CustomUserSerializer', + 'current_user': 'accounts.serializers.CustomUserSerializer', + }, +} +# ============================================================================== +# EMAIL CONFIGURATION +# ============================================================================== +# Development: Using MailPit (local email testing tool) +# MailPit default runs on localhost:1025 for SMTP and localhost:8025 for web UI +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = os.getenv('EMAIL_HOST', '10.80.80.70') +EMAIL_PORT = int(os.getenv('EMAIL_PORT', 1025)) +EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS', 'False').lower() == 'true' +EMAIL_USE_SSL = os.getenv('EMAIL_USE_SSL', 'False').lower() == 'true' +EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', '') +EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', '') +DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'noreply@localhost') + +CORS_ALLOWED_ORIGINS = os.getenv('CORS_ALLOWED_ORIGINS', 'http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173,http://localhost:8080,http://127.0.0.1:8080').split(',') + +# For development only - be careful in production! +CORS_ORIGIN_ALLOW_ALL = True + +CORS_ALLOW_CREDENTIALS = True +CORS_ALLOW_HEADERS = [ + 'accept', + 'accept-encoding', + 'authorization', + 'content-type', + 'dnt', + 'origin', + 'user-agent', + 'x-csrftoken', + 'x-requested-with', +] + +# ============================================================================== +# SOCIAL AUTH CONFIGURATION (Python Social Auth) +# ============================================================================== +AUTHENTICATION_BACKENDS = ( + # Social auth backends + 'social_core.backends.google.GoogleOAuth2', + 'social_core.backends.github.GithubOAuth2', + 'social_core.backends.facebook.FacebookOAuth2', + # Add more providers as needed + + # Django default + 'django.contrib.auth.backends.ModelBackend', +) + +# Social Auth Settings +SOCIAL_AUTH_JSONFIELD_ENABLED = True +SOCIAL_AUTH_URL_NAMESPACE = 'social' + +# Pipeline - custom pipeline to set is_active=True for social users +SOCIAL_AUTH_PIPELINE = ( + 'social_core.pipeline.social_auth.social_details', + 'social_core.pipeline.social_auth.social_uid', + 'social_core.pipeline.social_auth.auth_allowed', + 'social_core.pipeline.social_auth.social_user', + 'social_core.pipeline.user.get_username', + 'social_core.pipeline.user.create_user', + 'social_core.pipeline.social_auth.associate_user', + 'social_core.pipeline.social_auth.load_extra_data', + 'social_core.pipeline.user.user_details', + 'accounts.pipeline.activate_user', # Custom pipeline to set is_active=True +) + +# User model +SOCIAL_AUTH_USER_MODEL = 'accounts.CustomUser' +SOCIAL_AUTH_USERNAME_IS_REQUIRED = False +SOCIAL_AUTH_USER_FIELDS = ['email', 'first_name', 'last_name'] + +# Strategy +SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy' +SOCIAL_AUTH_STORAGE = 'social_django.models.DjangoStorage' + +# Google OAuth2 Configuration +# Get credentials from: https://console.developers.google.com/ +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.getenv('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY', '915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com') # Your Google Client ID +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.getenv('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET', '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') # Your Google Client Secret +SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [ + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile', +] +SOCIAL_AUTH_GOOGLE_OAUTH2_EXTRA_DATA = ['first_name', 'last_name'] + +# GitHub OAuth2 Configuration +# Get credentials from: https://github.com/settings/developers +SOCIAL_AUTH_GITHUB_KEY = os.getenv('SOCIAL_AUTH_GITHUB_KEY', 'Ov23liUt9B61O46Mdfm4') # Your GitHub Client ID +SOCIAL_AUTH_GITHUB_SECRET = os.getenv('SOCIAL_AUTH_GITHUB_SECRET', 'c7fc8dcb1b2c8f22120608425d07d5efd995baaf') # Your GitHub Client Secret +SOCIAL_AUTH_GITHUB_SCOPE = ['user:email'] + +# Facebook OAuth2 Configuration +# Get credentials from: https://developers.facebook.com/ +SOCIAL_AUTH_FACEBOOK_KEY = os.getenv('SOCIAL_AUTH_FACEBOOK_KEY', '') # Your Facebook App ID +SOCIAL_AUTH_FACEBOOK_SECRET = os.getenv('SOCIAL_AUTH_FACEBOOK_SECRET', '') # Your Facebook App Secret +SOCIAL_AUTH_FACEBOOK_SCOPE = ['email'] +SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { + 'fields': 'id, name, email, first_name, last_name' +} + +# Redirect URLs (customize for your frontend) +LOGIN_URL = '/api/v1/spa/' +LOGIN_REDIRECT_URL = '/api/v1/auth/social/callback/' +SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/api/v1/auth/social/callback/' +SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/api/v1/auth/social/callback/' +SOCIAL_AUTH_INACTIVE_USER_URL = '/api/v1/auth/social/error/' +SOCIAL_AUTH_LOGIN_ERROR_URL = '/api/v1/auth/social/error/' + +TASKS = {"default": {"BACKEND": "django.tasks.backends.immediate.ImmediateBackend"}} +# ============================================================================== +# SECURITY SETTINGS FOR SPA/JWT +# ============================================================================== +# Since we're using JWT tokens (not session cookies), we can relax CSRF for API endpoints +# But keep it enabled for Django admin +""" +CSRF_COOKIE_HTTPONLY = False +CSRF_COOKIE_SECURE = False # Set to True in production with HTTPS +SESSION_COOKIE_SECURE = False # Set to True in production with HTTPS +CSRF_TRUSTED_ORIGINS = [ + "http://localhost:3000", + "http://localhost:5173", +] +""" + +# TinyMCE Configuration +TINYMCE_DEFAULT_CONFIG = { + "height": "320px", + "width": "960px", + "menubar": "file edit view insert format tools table help", + "plugins": "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code fullscreen insertdatetime media table paste code help wordcount spellchecker", + "toolbar": "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist checkbox | forecolor backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image media pageembed template link anchor codesample | a11ycheck ltr rtl | showcomments addcomment", + "custom_undo_redo_levels": 10, + "language": "tr", # To force a specific language instead of the Django current language. +} diff --git a/core/urls.py b/core/urls.py new file mode 100644 index 0000000..6aab96f --- /dev/null +++ b/core/urls.py @@ -0,0 +1,38 @@ +""" +URL configuration for core project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/6.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns = [ + path('admin/', admin.site.urls), + + # Main API routes (includes SPA pages) + path('api/v1/', include('accounts.urls')), + path('api/v1/blog/', include('blog.urls')), + path('api/v1/', include('settings.urls')), + path('api/v1/', include('utils.urls')), + path('api/v1/images/', include('image.urls')), + path('tinymce/', include('tinymce.urls')), +] + +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/core/utils.py b/core/utils.py new file mode 100644 index 0000000..307c08f --- /dev/null +++ b/core/utils.py @@ -0,0 +1,40 @@ +import os +import uuid +from django.utils.deconstruct import deconstructible +from imagekit.processors import ResizeToFill + + +class ConvertToRGBA(object): + """Converts an image to RGBA mode.""" + def process(self, img): + if img.mode not in ('RGBA', 'LA'): + img = img.convert('RGBA') + return img + + +@deconstructible +class UniquePathAndRename(object): + def __init__(self, upload_to): + self.upload_to = upload_to + + def __call__(self, instance, filename): + ext = filename.split('.')[-1] + new_filename = f"{uuid.uuid4().hex}.{ext}" + return os.path.join(self.upload_to, new_filename) + + +def image_optimizer(upload_to, width, height, quality, img_format): + """ + ProcessedImageField için gerekli olan `upload_to`, `processors`, `format` + ve `options` parametrelerini dinamik olarak oluşturur. + """ + processors = [ResizeToFill(width, height)] + if img_format == 'PNG': + processors.insert(0, ConvertToRGBA()) + + return { + 'upload_to': UniquePathAndRename(upload_to), + 'processors': processors, + 'format': img_format, + 'options': {'quality': quality} + } diff --git a/core/wsgi.py b/core/wsgi.py new file mode 100644 index 0000000..050d8bc --- /dev/null +++ b/core/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for core project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +application = get_wsgi_application() diff --git a/dene.txt b/dene.txt new file mode 100644 index 0000000..941fc3e --- /dev/null +++ b/dene.txt @@ -0,0 +1 @@ +https://easypanel.io/ \ No newline at end of file diff --git a/docker-compose.c.yml b/docker-compose.c.yml new file mode 100644 index 0000000..5dc5243 --- /dev/null +++ b/docker-compose.c.yml @@ -0,0 +1,111 @@ +services: + web: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_web_prod + command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - static_volume:/app/staticfiles + - media_volume:/app/media + expose: + - 8000 + networks: + coolify: + aliases: + - django_web_prod + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8000/ || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-10.80.80.50} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + restart: unless-stopped + + celery: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_celery_prod + command: celery -A core worker -l info + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - media_volume:/app/media + networks: + - coolify + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-10.80.80.50} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + depends_on: + - web + healthcheck: + test: ["CMD-SHELL", "celery -A core inspect ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + restart: unless-stopped + + caddy: + build: + context: . + dockerfile: ./caddy/Dockerfile + container_name: django_caddy + expose: + - 80 + networks: + coolify: + aliases: + - nginx + - nginx_proxy + volumes: + - static_volume:/app/staticfiles:ro + - media_volume:/app/media:ro + - caddy_data:/data + - caddy_config:/config + depends_on: + - web + healthcheck: + test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + labels: + - "coolify.managed=true" + - "coolify.http.port=80" + +volumes: + static_volume: + media_volume: + caddy_data: + caddy_config: + +networks: + coolify: + external: true diff --git a/docker-compose.cool.yml b/docker-compose.cool.yml new file mode 100644 index 0000000..8014635 --- /dev/null +++ b/docker-compose.cool.yml @@ -0,0 +1,58 @@ +services: + web: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_web_prod + command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - static_volume:/app/staticfiles + - media_volume:/app/media + expose: + - 8000 + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-212.64.215.243} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + restart: unless-stopped + + celery: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_celery_prod + command: celery -A core worker -l info + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - media_volume:/app/media + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-212.64.215.243} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + depends_on: + - web + restart: unless-stopped +volumes: + static_volume: + media_volume: diff --git a/docker-compose.d.yml b/docker-compose.d.yml new file mode 100644 index 0000000..c892d31 --- /dev/null +++ b/docker-compose.d.yml @@ -0,0 +1,90 @@ +services: + web: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_web_prod + command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - static_volume:/app/staticfiles + - media_volume:/app/media + expose: + - 8000 + networks: + - dokploy-network + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-10.80.80.50} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + restart: unless-stopped + + celery: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_celery_prod + command: celery -A core worker -l info + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - media_volume:/app/media + networks: + - dokploy-network + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=${USE_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-10.80.80.50} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + - CELERY_BROKER_URL=${CELERY_BROKER_URL} + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} + depends_on: + - web + restart: unless-stopped + + caddy: + build: + context: . + dockerfile: ./caddy/Dockerfile + container_name: django_caddy + expose: + - 80 + networks: + - dokploy-network + volumes: + - static_volume:/app/staticfiles:ro + - media_volume:/app/media:ro + - caddy_data:/data + - caddy_config:/config + depends_on: + - web + restart: unless-stopped + labels: + - "coolify.managed=true" + - "coolify.http.port=80" + +volumes: + static_volume: + media_volume: + caddy_data: + caddy_config: + +networks: + dokploy-network: + external: true diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..8352f6c --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,53 @@ +services: + web: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_web_prod + command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - static_volume:/app/staticfiles + - media_volume:/app/media + expose: + - 8000 + networks: + - dokploy-network + environment: + - DEBUG=0 + - SECRET_KEY=${SECRET_KEY} + - USE_POSTGRES=True + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_HOST=${POSTGRES_HOST:-10.80.80.50} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} + restart: unless-stopped + + nginx: + image: nginx:alpine + container_name: django_nginx + ports: + - "8400:80" + expose: + - 80 + networks: + - dokploy-network + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + - static_volume:/app/staticfiles:ro + - media_volume:/app/media:ro + depends_on: + - web + restart: unless-stopped + +volumes: + static_volume: + media_volume: + +networks: + dokploy-network: + external: true diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d3be0dd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +services: + web: + build: + context: . + dockerfile: ./build/Dockerfile + container_name: django_web + command: python manage.py runserver 0.0.0.0:8000 + dns: + - 8.8.8.8 + - 8.8.4.4 + volumes: + - .:/app + - static_volume:/app/staticfiles + - media_volume:/app/media + ports: + - "8200:8000" + environment: + - DEBUG=1 + - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] + # PostgreSQL ayarları - mevcut sunucunuzu kullanıyor + - USE_POSTGRES=True + - POSTGRES_DB=server_dj + - POSTGRES_USER=server_dj + - POSTGRES_PASSWORD=1234 + - POSTGRES_HOST=10.80.80.70 + - POSTGRES_PORT=5432 + # Mac'te Docker Desktop kullanıyorsanız host.docker.internal kullanabilirsiniz + # extra_hosts: + # - "host.docker.internal:host-gateway" + stdin_open: true + tty: true + +volumes: + static_volume: + media_volume: diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..5ed8490 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Hata durumunda scripti durdur +set -e + +# PostgreSQL bağlantısını kontrol et (mevcut sunucu için) +echo "Checking PostgreSQL connection..." +# Not: Mevcut PostgreSQL sunucunuz zaten çalışıyor olmalı (10.80.80.50:5432) + +# Veritabanı migrasyonlarını uygula +echo "Applying database migrations..." +python manage.py migrate --noinput + +# Superuser oluştur (eğer yoksa) +echo "Creating superuser if it doesn't exist..." +python manage.py shell -c " +from django.contrib.auth import get_user_model +User = get_user_model() +if not User.objects.filter(email='admin@example.com').exists(): + User.objects.create_superuser('admin@example.com', 'admin') + print('Superuser created: admin@example.com / admin') +else: + print('Superuser already exists') +" || true + +# Static dosyaları topla +echo "Collecting static files..." +python manage.py collectstatic --noinput --clear + +echo "Starting server..." +exec "$@" diff --git a/image/__init__.py b/image/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/image/admin.py b/image/admin.py new file mode 100644 index 0000000..c75221a --- /dev/null +++ b/image/admin.py @@ -0,0 +1,27 @@ +from django.contrib import admin + +from .models import PostImages + + +@admin.register(PostImages) +class PostImagesAdmin(admin.ModelAdmin): + list_display = ( + 'id', + 'title', + 'path', + 'processed_path', + 'original_filename', + 'format', + 'width', + 'height', + 'size', + 'quality', + 'slug', + 'created_at', + 'updated_at', + 'is_active', + 'is_front', + ) + list_filter = ('created_at', 'updated_at', 'is_active', 'is_front') + search_fields = ('slug',) + date_hierarchy = 'created_at' \ No newline at end of file diff --git a/image/apps.py b/image/apps.py new file mode 100644 index 0000000..7734360 --- /dev/null +++ b/image/apps.py @@ -0,0 +1,9 @@ +from django.apps import AppConfig + + +class ImageConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'image' + + def ready(self): + import image.signals diff --git a/image/migrations/0001_initial.py b/image/migrations/0001_initial.py new file mode 100644 index 0000000..64c6f40 --- /dev/null +++ b/image/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 5.2.9 on 2025-12-31 01:20 + +import autoslug.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Post', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Resim Başlığı')), + ('path', models.CharField(max_length=254, verbose_name='Resim Yolu')), + ('processed_path', models.CharField(max_length=254, verbose_name='Orijinal Resim Yolu')), + ('original_filename', models.CharField(max_length=254, verbose_name='Orijinal Resim Adı')), + ('format', models.CharField(choices=[('png', 'PNG'), ('webp', 'WebP'), ('jpg', 'JPG'), ('avif', 'AVIF')], default='webp', max_length=254, verbose_name='Resim Formati')), + ('width', models.IntegerField()), + ('height', models.IntegerField()), + ('size', models.IntegerField()), + ('quality', models.IntegerField()), + ('slug', autoslug.fields.AutoSlugField(blank=True, editable=True, max_length=250, populate_from='title', unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?')), + ('is_front', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Önde Görünsünmü ?')), + ], + options={ + 'verbose_name': 'Post', + 'verbose_name_plural': 'Posts', + 'db_table': 'images', + 'ordering': ['created_at'], + 'unique_together': {('slug',)}, + }, + ), + ] diff --git a/image/migrations/0002_rename_post_postimages.py b/image/migrations/0002_rename_post_postimages.py new file mode 100644 index 0000000..df29513 --- /dev/null +++ b/image/migrations/0002_rename_post_postimages.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.9 on 2025-12-31 01:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('image', '0001_initial'), + ] + + operations = [ + migrations.RenameModel( + old_name='Post', + new_name='PostImages', + ), + ] diff --git a/image/migrations/0003_postimages_user.py b/image/migrations/0003_postimages_user.py new file mode 100644 index 0000000..33f2180 --- /dev/null +++ b/image/migrations/0003_postimages_user.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.9 on 2026-01-03 21:07 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('image', '0002_rename_post_postimages'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='postimages', + name='user', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='image_user', to=settings.AUTH_USER_MODEL, verbose_name='Kullanıcı'), + preserve_default=False, + ), + ] diff --git a/image/migrations/0004_alter_postimages_options.py b/image/migrations/0004_alter_postimages_options.py new file mode 100644 index 0000000..74c75c2 --- /dev/null +++ b/image/migrations/0004_alter_postimages_options.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.9 on 2026-01-09 07:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('image', '0003_postimages_user'), + ] + + operations = [ + migrations.AlterModelOptions( + name='postimages', + options={'ordering': ['created_at'], 'verbose_name': 'Resim', 'verbose_name_plural': 'Resimler'}, + ), + ] diff --git a/image/migrations/__init__.py b/image/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/image/models.py b/image/models.py new file mode 100644 index 0000000..d917700 --- /dev/null +++ b/image/models.py @@ -0,0 +1,56 @@ +from autoslug import AutoSlugField +from django.db import models + +# Create your models here. +class PostImages(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + format_choose = ( + ('png', 'PNG'), + ('webp', 'WebP'), + ('jpg', 'JPG'), + ('avif', 'AVIF'), + ) + title = models.CharField(max_length=254, verbose_name="Resim Başlığı") + user = models.ForeignKey('accounts.CustomUser', on_delete=models.CASCADE, related_name='image_user', + verbose_name="Kullanıcı") + path = models.CharField(max_length=254, verbose_name="Resim Yolu") + processed_path = models.CharField(max_length=254, verbose_name="Orijinal Resim Yolu") + original_filename = models.CharField(max_length=254, verbose_name="Orijinal Resim Adı") + format = models.CharField(max_length=254, verbose_name="Resim Formati", choices=format_choose,default='webp') + width = models.IntegerField() + height = models.IntegerField() + size = models.IntegerField() + quality = models.IntegerField() + + slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=True, db_index=True, max_length=250, + blank=True) + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif) + is_front = models.BooleanField(default=True, verbose_name='Önde Görünsünmü ?', choices=aktif) + + class Meta: + ordering = ["created_at"] + db_table = 'images' + verbose_name_plural = "Posts" + verbose_name = "Post" + unique_together = ('slug',) + + def get_slug(self): + slug = self.title.replace('ı', "i").replace('İ', 'i') + number = 1 + while PostImages.objects.filter(slug=slug).exists(): + slug = '{}-{}'.format(slug, number) + number += 1 + return slug + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.get_slug() + super().save(*args, **kwargs) + + def __str__(self): + return f"Resimler: {self.title}" \ No newline at end of file diff --git a/image/serializers.py b/image/serializers.py new file mode 100644 index 0000000..7dc65de --- /dev/null +++ b/image/serializers.py @@ -0,0 +1,108 @@ +import os +import uuid +from io import BytesIO + +from PIL import Image, ImageOps +from django.conf import settings +from django.core.files.base import ContentFile +from rest_framework import serializers + +from .models import PostImages + + +class PostImagesSerializer(serializers.ModelSerializer): + class Meta: + model = PostImages + fields = '__all__' + + +class PostImageCreateSerializer(serializers.Serializer): + """ + Serializer for uploading and processing an image. + """ + image = serializers.ImageField(write_only=True, help_text="Yüklenecek resim dosyası.") + title = serializers.CharField(max_length=254, help_text="Resim için bir başlık.") + width = serializers.IntegerField(help_text="Resmin yeni genişliği (pixel).") + height = serializers.IntegerField(help_text="Resmin yeni yüksekliği (pixel).") + quality = serializers.IntegerField(default=85, min_value=1, max_value=100, help_text="JPG/WebP için kalite (1-100).") + format = serializers.ChoiceField( + choices=['png', 'webp', 'jpg', 'avif'], + default='avif', + help_text="Çıktı resim formatı." + ) + + def create(self, validated_data): + image_file = validated_data.pop('image') + title = validated_data.pop('title') + new_width = validated_data.pop('width') + new_height = validated_data.pop('height') + quality = validated_data.pop('quality') + output_format = validated_data.pop('format') + + # Open the image with Pillow + img = Image.open(image_file) + + # Preserve original metadata for the model + original_filename = image_file.name + original_size = image_file.size + + # Process the image: Resize and crop to fill target dimensions (Center Crop). + # This ensures the image fills the dimensions without distortion or padding. + + # ImageOps.fit resizes and crops the image to the requested size. + img = ImageOps.fit(img, (new_width, new_height), method=Image.Resampling.LANCZOS, centering=(0.5, 0.5)) + + # If output format does not support transparency (like JPG), convert to RGB. + # This also ensures compatibility for formats like JPEG that don't support P or RGBA. + if output_format != 'png' and img.mode != 'RGB': + img = img.convert('RGB') + + # Save the processed image to an in-memory buffer + buffer = BytesIO() + + # Pillow expects 'JPEG' format identifier, not 'jpg' + save_format = output_format.upper() + if save_format == 'JPG': + save_format = 'JPEG' + + save_kwargs = {'format': save_format} + if output_format in ['jpg', 'webp']: + save_kwargs['quality'] = quality + img.save(buffer, **save_kwargs) + buffer.seek(0) + + # Generate a unique filename and path + new_filename = f"processed/{uuid.uuid4()}.{output_format}" + file_path = os.path.join(settings.MEDIA_ROOT, new_filename) + + # Ensure the directory exists + os.makedirs(os.path.dirname(file_path), exist_ok=True) + + # Save the new file to the media directory + with open(file_path, 'wb') as f: + f.write(buffer.getvalue()) + + # Get the size of the new file + new_size = os.path.getsize(file_path) + + # Get user from validated_data if provided (serializer.save(user=...)) + user = validated_data.pop('user', None) + + # Create the PostImages model instance + instance = PostImages.objects.create( + title=title, + user=user, + path=new_filename, # Store the relative path + processed_path=original_filename, # Let's use this field for original name for now + original_filename=original_filename, + format=output_format, + width=new_width, # Use the target width + height=new_height, # Use the target height + size=new_size, + quality=quality, + ) + return instance + + def to_representation(self, instance): + # Use the PostImagesSerializer to represent the created object + return PostImagesSerializer(instance).data diff --git a/image/signals.py b/image/signals.py new file mode 100644 index 0000000..edabcd7 --- /dev/null +++ b/image/signals.py @@ -0,0 +1,22 @@ +import os +from django.conf import settings +from django.db.models.signals import post_delete +from django.dispatch import receiver + +from .models import PostImages + + +@receiver(post_delete, sender=PostImages) +def delete_image_file(sender, instance, **kwargs): + """ + Deletes the associated image file from the filesystem when a PostImages instance is deleted. + """ + # Check if the instance has a path and the path is not empty + if instance.path: + file_path = os.path.join(settings.MEDIA_ROOT, instance.path) + if os.path.exists(file_path): + try: + os.remove(file_path) + except OSError as e: + # Optionally, log the error e.g., print(f"Error deleting file {file_path}: {e}") + pass diff --git a/image/tests.py b/image/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/image/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/image/urls.py b/image/urls.py new file mode 100644 index 0000000..4b84e6b --- /dev/null +++ b/image/urls.py @@ -0,0 +1,8 @@ +from django.urls import path, include +from .views import ImageUploadView, ImageDownloadView, ImageListView # Import ImageDownloadView + +urlpatterns = [ + path('upload/', ImageUploadView.as_view(), name='image-upload'), + path('list/', ImageListView.as_view(), name='image-list'), + path('/download/', ImageDownloadView.as_view(), name='image-download'), # New download URL +] diff --git a/image/views.py b/image/views.py new file mode 100644 index 0000000..7da4cb1 --- /dev/null +++ b/image/views.py @@ -0,0 +1,67 @@ +from rest_framework.parsers import MultiPartParser, FormParser +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework import status +from rest_framework.permissions import IsAdminUser, AllowAny +from rest_framework import generics +import os +from django.conf import settings +from django.http import FileResponse, Http404 +from .serializers import PostImageCreateSerializer, PostImagesSerializer +from .models import PostImages # Make sure to import PostImages model + +class ImageUploadView(APIView): + parser_classes = (MultiPartParser, FormParser) + permission_classes = (IsAdminUser,) + + def post(self, request, *args, **kwargs): + """ + Accepts an image upload and processing parameters. + Processes the image and saves it. + """ + serializer = PostImageCreateSerializer(data=request.data) + if serializer.is_valid(): + instance = serializer.save(user=request.user) + # Return the details of the created object using the representation serializer + return Response(serializer.to_representation(instance), status=status.HTTP_201_CREATED) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class ImageDownloadView(APIView): + """ + API endpoint to download a processed image by its slug. + """ + def get(self, request, slug, *args, **kwargs): + try: + image_instance = PostImages.objects.get(slug=slug) + except PostImages.DoesNotExist: + raise Http404("Image not found.") + + file_path = os.path.join(settings.MEDIA_ROOT, image_instance.path) + + if not os.path.exists(file_path): + raise Http404("File not found on server.") + + # Determine content type based on format + content_type_map = { + 'png': 'image/png', + 'webp': 'image/webp', + 'jpg': 'image/jpeg', + 'avif': 'image/avif', + } + content_type = content_type_map.get(image_instance.format.lower(), 'application/octet-stream') + + # Prepare the filename for download + filename = f"{image_instance.slug}.{image_instance.format.lower()}" + + response = FileResponse(open(file_path, 'rb'), content_type=content_type) + response['Content-Disposition'] = f'attachment; filename="{filename}"' + return response + + +class ImageListView(generics.ListAPIView): + """List all images.""" + queryset = PostImages.objects.all().order_by('-created_at') + serializer_class = PostImagesSerializer + permission_classes = (AllowAny,) diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..f2a662c --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..e0dc8fb --- /dev/null +++ b/nginx.conf @@ -0,0 +1,39 @@ +events { + worker_connections 1024; +} + +http { + upstream django { + server django_web_prod:8000; + } + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + server_name localhost; + client_max_body_size 100M; + + location / { + proxy_pass http://django; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } + + location /static/ { + alias /app/staticfiles/; + expires 30d; + add_header Cache-Control "public, immutable"; + } + + location /media/ { + alias /app/media/; + expires 7d; + add_header Cache-Control "public"; + } + } +} diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..2a95ef9 --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,21 @@ +# Nginx alpine base image +FROM nginx:alpine + +# Remove default nginx config +RUN rm /etc/nginx/conf.d/default.conf + +# Copy our custom nginx config +COPY nginx/default.conf /etc/nginx/conf.d/default.conf + +# Create directories for static and media files +RUN mkdir -p /app/staticfiles /app/media + +# Expose port 80 +EXPOSE 80 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..3ef5b0c --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,38 @@ +upstream django_backend { + server django_web_prod:8000 max_fails=3 fail_timeout=30s; + server web:8000 backup; +} + +server { + listen 80; + server_name _; + client_max_body_size 100M; + + location / { + proxy_pass http://django_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + + # Connection settings + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + location /static/ { + alias /app/staticfiles/; + expires 30d; + add_header Cache-Control "public, immutable"; + } + + location /media/ { + alias /app/media/; + expires 7d; + add_header Cache-Control "public"; + } +} + + diff --git a/req.txt b/req.txt new file mode 100644 index 0000000..d0b75d2 --- /dev/null +++ b/req.txt @@ -0,0 +1,3 @@ +asgiref==3.11.0 +Django==5.2 +sqlparse==0.5.5 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5e6fe8a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,87 @@ +amqp==5.3.1 +asgiref==3.11.0 +attrs==25.4.0 +billiard==4.2.4 +celery==5.6.0 +celery-types==0.23.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 +click==8.3.1 +click-didyoumean==0.3.1 +click-plugins==1.1.1.2 +click-repl==0.3.0 +cron_descriptor==2.0.6 +cryptography==46.0.3 +defusedxml==0.7.1 +Django==5.2.9 +django-appconf==1.2.0 +django-autoslug==1.9.9 +django-celery-beat==2.8.1 +django-ckeditor-5==0.2.18 +django-cleanup==9.0.0 +django-colorfield==0.14.0 +django-cors-headers==4.9.0 +django-cropper-image==1.0.5 +django-environ==0.12.0 +django-extensions==4.1 +django-filter==25.2 +django-imagekit==6.0.0 +django-redis==6.0.0 +django-stubs==5.2.8 +django-stubs-ext==5.2.8 +django-templated-mail==1.1.1 +django-timezone-field==7.2.1 +django-tinymce==5.0.0 +django_celery_results==2.6.0 +djangorestframework==3.16.1 +djangorestframework-stubs==3.16.6 +djangorestframework_simplejwt==5.5.1 +djoser==2.3.3 +drf-spectacular==0.29.0 +exceptiongroup==1.3.1 +flower==2.0.1 +gunicorn==23.0.0 +hiredis==3.3.0 +humanize==4.15.0 +idna==3.11 +inflection==0.5.1 +jsonschema==4.25.1 +jsonschema-specifications==2025.9.1 +kombu==5.6.1 +Markdown==3.10 +oauthlib==3.3.1 +packaging==25.0 +pilkit==3.0 +pillow==12.0.0 +prometheus_client==0.23.1 +prompt_toolkit==3.0.52 +psycopg2-binary==2.9.11 +pycparser==2.23 +PyJWT==2.10.1 +python-crontab==3.3.0 +python-dateutil==2.9.0.post0 +python3-openid==3.2.0 +pytz==2025.2 +PyYAML==6.0.3 +redis==7.1.0 +referencing==0.37.0 +requests==2.32.5 +requests-oauthlib==2.0.0 +rpds-py==0.30.0 +six==1.17.0 +social-auth-app-django==5.7.0 +social-auth-core==4.8.3 +sqlparse==0.5.5 +sweetify==2.3.1 +tornado==6.5.4 +types-PyYAML==6.0.12.20250915 +types-requests==2.32.4.20250913 +typing_extensions==4.15.0 +tzdata==2025.3 +tzlocal==5.3.1 +uritemplate==4.2.0 +urllib3==2.6.2 +vine==5.1.0 +wcwidth==0.2.14 +whitenoise==6.11.0 diff --git a/restore_user_setup.sh b/restore_user_setup.sh new file mode 100644 index 0000000..f499659 --- /dev/null +++ b/restore_user_setup.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Restore sonrası kullanıcı oluşturma scripti + +cd /Users/beyhan/Projeler/Python/dj52 + +echo "===================================" +echo "RESTORE SONRASI KULLANICI OLUŞTURMA" +echo "===================================" + +# Mevcut kullanıcıları kontrol et +python manage.py shell -c " +from accounts.models import CustomUser +users = CustomUser.objects.all() +print(f'\nToplam {users.count()} kullanıcı var') +for user in users: + print(f' - {user.email} (Staff: {user.is_staff}, Superuser: {user.is_superuser})') +" + +echo "" +echo "Yeni superuser oluşturmak ister misiniz? (y/n)" +read -r answer + +if [ "$answer" = "y" ]; then + echo "Email:" + read -r email + echo "Şifre:" + read -rs password + + python manage.py shell -c " +from accounts.models import CustomUser +try: + user = CustomUser.objects.create_superuser(email='$email', password='$password') + print(f'\n✓ Superuser oluşturuldu: {user.email}') +except Exception as e: + print(f'\n✗ Hata: {e}') +" +fi + +echo "" +echo "Mevcut bir kullanıcının şifresini değiştirmek ister misiniz? (y/n)" +read -r answer2 + +if [ "$answer2" = "y" ]; then + echo "Kullanıcı email:" + read -r user_email + echo "Yeni şifre:" + read -rs new_password + + python manage.py shell -c " +from accounts.models import CustomUser +try: + user = CustomUser.objects.get(email='$user_email') + user.set_password('$new_password') + user.save() + print(f'\n✓ Şifre değiştirildi: {user.email}') +except CustomUser.DoesNotExist: + print('\n✗ Kullanıcı bulunamadı') +except Exception as e: + print(f'\n✗ Hata: {e}') +" +fi + +echo "" +echo "İşlem tamamlandı!" + diff --git a/run_spa_server.py b/run_spa_server.py new file mode 100644 index 0000000..a9cf1fc --- /dev/null +++ b/run_spa_server.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python3 +""" +Simple HTTP server to serve SPA test page on port 3000 +This simulates a Nuxt/Next.js frontend +""" +import http.server +import socketserver +import os +from urllib.parse import urlparse, parse_qs +import json + +PORT = 3001 # Using 3001 since 3000 might be in use + +class SPAHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self): + # Parse URL + parsed = urlparse(self.path) + path = parsed.path + + # Serve activation page + if path.startswith('/activate/'): + parts = path.split('/') + if len(parts) >= 4: + uid = parts[2] + token = parts[3] + self.serve_activation_page(uid, token) + return + + # Serve main SPA page + if path == '/' or path == '/index.html': + self.serve_spa_page() + return + + # Default handler + super().do_GET() + + def serve_spa_page(self): + """Serve the main SPA page""" + html = """ + + + + Frontend SPA (Port 3000) + + + +
    +

    🎉 Frontend SPA (Port 3000)

    +

    Bu sayfa Nuxt/Next.js frontend'inizi simüle ediyor.

    + +
    + ✅ Email activation linkleri buraya gelecek! +

    Format: http://localhost:3000/activate/{uid}/{token}/

    +
    + +

    Test için:

    +
      +
    • Backend'de user oluşturun
    • +
    • MailPit'te email'i açın
    • +
    • Activation link'e tıklayın
    • +
    • Bu sayfaya gelecek ve otomatik activate edecek!
    • +
    + +

    Backend SPA Test (Port 8000)

    +
    + + + """ + self.send_response(200) + self.send_header('Content-type', 'text/html') + self.end_headers() + self.wfile.write(html.encode()) + + def serve_activation_page(self, uid, token): + """Serve activation page that calls Django API""" + html = f""" + + + + Activating Account... + + + +
    +
    +
    +

    Activating Your Account...

    +

    Please wait...

    +
    + +
    +
    +

    Account Activated!

    +

    Your account has been successfully activated.

    + Go to Login +
    + +
    +
    +

    Activation Failed

    +

    Something went wrong.

    + Back to Login +
    +
    + + + + + """ + self.send_response(200) + self.send_header('Content-type', 'text/html') + self.end_headers() + self.wfile.write(html.encode()) + +os.chdir('/home/beyhan/Python/server') + +with socketserver.TCPServer(("", PORT), SPAHandler) as httpd: + print(f"🚀 Frontend SPA Server running on http://localhost:{PORT}") + print(f"📧 Email activation links will work here!") + print(f"🔗 Open: http://localhost:{PORT}") + print(f"\nPress Ctrl+C to stop") + httpd.serve_forever() + diff --git a/settings/__init__.py b/settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/settings/admin.py b/settings/admin.py new file mode 100644 index 0000000..4ae1464 --- /dev/null +++ b/settings/admin.py @@ -0,0 +1,19 @@ +from django.contrib import admin +from settings.models import Setting, Banner + + +# Register your models here. +class SettingAdmin(admin.ModelAdmin): + list_display = ('title', 'is_active', 'created_at') + list_editable = ('is_active',) + + +admin.site.register(Setting, SettingAdmin) + + +class BannerAdmin(admin.ModelAdmin): + list_display = ('title', 'is_active', 'created_at') + list_editable = ('is_active',) + + +admin.site.register(Banner, BannerAdmin) diff --git a/settings/apps.py b/settings/apps.py new file mode 100644 index 0000000..e3fbbf0 --- /dev/null +++ b/settings/apps.py @@ -0,0 +1,14 @@ +from django.apps import AppConfig + + +class SettingsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'settings' + verbose_name = 'Site Ayarlar' + + def ready(self): + from . import signals # noqa + """def ready(self): + from core.signal import invalidate_setting_cache + from django.db.models.signals import post_save, post_delete""" + diff --git a/settings/migrations/0001_initial.py b/settings/migrations/0001_initial.py new file mode 100644 index 0000000..be2b445 --- /dev/null +++ b/settings/migrations/0001_initial.py @@ -0,0 +1,68 @@ +# Generated by Django 6.0 on 2025-12-13 15:41 + +import colorfield.fields +import imagekit.models.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Banner', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('color', colorfield.fields.ColorField(default='#FFFFFF', image_field=None, max_length=25, samples=None, verbose_name='Yazı Rengi')), + ('title', models.CharField(max_length=254, null=True, verbose_name='Baner Adı')), + ('text1', models.CharField(max_length=254, null=True, verbose_name='Baner Küçük Yazı 1')), + ('text2', models.CharField(max_length=254, null=True, verbose_name='Baner Büyük Yazı 1')), + ('text4', models.CharField(max_length=254, null=True, verbose_name='Baner Küçük Yazı 2')), + ('text5', models.CharField(max_length=254, null=True, verbose_name='Baner Düğme Yazısı')), + ('image', imagekit.models.fields.ProcessedImageField(upload_to='uploads/banner/%Y')), + ('image_k', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/banner/kucuk/%Y')), + ('image_k_txt', models.CharField(max_length=254, null=True, verbose_name='Küçük Resim Yazisi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ], + options={ + 'verbose_name': 'Banner', + 'verbose_name_plural': 'Bannerler', + 'db_table': 'banners', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='Setting', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Ayar Başlığı')), + ('meta_title', models.CharField(default='Meta Title', max_length=254, verbose_name='Meta Title')), + ('meta_description', models.CharField(default='Meta Description', max_length=254, verbose_name='Meta Description')), + ('phone', models.CharField(max_length=254, verbose_name='Telefon')), + ('url', models.CharField(blank=True, default='https://beyhanogur.com.tr', max_length=254, null=True, verbose_name='Site İnternet Adresi')), + ('email', models.EmailField(max_length=254, verbose_name='E-Posta')), + ('facebook', models.CharField(blank=True, default='https://www.facebook.com', max_length=254, null=True, verbose_name='Facebook')), + ('x', models.CharField(blank=True, default='https://www.twitter.com', max_length=254, null=True, verbose_name='Twitter')), + ('instagram', models.CharField(blank=True, default='https://www.instagram.com', max_length=254, null=True, verbose_name='Instagram')), + ('whatsapp', models.CharField(blank=True, default='https://www.whatsapp.com', max_length=254, null=True, verbose_name='Whatsapp')), + ('slogan', models.CharField(blank=True, default='Dondurma', max_length=254, null=True, verbose_name='Başlık Solaganı')), + ('w_logo', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/logo')), + ('b_logo', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/logo')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=False, verbose_name='Yayındamı')), + ], + options={ + 'verbose_name': 'Site Ayarı', + 'verbose_name_plural': 'Site Ayarları', + 'db_table': 'settings', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/settings/migrations/__init__.py b/settings/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/settings/models.py b/settings/models.py new file mode 100644 index 0000000..b00ce96 --- /dev/null +++ b/settings/models.py @@ -0,0 +1,78 @@ +from django.db import models +from colorfield.fields import ColorField +from imagekit.models import ProcessedImageField +from imagekit.processors import ResizeToFill + +class Setting(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + title = models.CharField(max_length=254, verbose_name="Ayar Başlığı") + meta_title = models.CharField(max_length=254, verbose_name="Meta Title", default='Meta Title') + meta_description = models.CharField(max_length=254, verbose_name="Meta Description", default='Meta Description') + phone = models.CharField(max_length=254, verbose_name="Telefon") + url = models.CharField(max_length=254, verbose_name="Site İnternet Adresi", blank=True, null=True, + default='https://beyhanogur.com.tr') + email = models.EmailField(max_length=254, verbose_name="E-Posta") + facebook = models.CharField(max_length=254, verbose_name="Facebook", default='https://www.facebook.com', null=True, + blank=True) + x = models.CharField(max_length=254, verbose_name="Twitter", default='https://www.twitter.com', null=True, + blank=True) + instagram = models.CharField(max_length=254, verbose_name="Instagram", default='https://www.instagram.com', + null=True, blank=True) + whatsapp = models.CharField(max_length=254, verbose_name="Whatsapp", default='https://www.whatsapp.com', null=True, + blank=True) + slogan = models.CharField(max_length=254, verbose_name="Başlık Solaganı", default='Dondurma', null=True, blank=True) + w_logo = ProcessedImageField(upload_to='uploads/logo', null=True, blank=True, processors=[ResizeToFill(165, 54)], + format='PNG', options={'quality': 85}) + b_logo = ProcessedImageField(upload_to='uploads/logo', null=True, blank=True, processors=[ResizeToFill(165, 54)], + format='PNG', options={'quality': 85}) + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=False, verbose_name='Yayındamı', choices=aktif) + + + class Meta: + ordering = ["-created_at"] + db_table = 'settings' + verbose_name_plural = "Site Ayarları" + verbose_name = "Site Ayarı" + + def __str__(self): + return self.title + + +class Banner(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + color = ColorField(default='#FFFFFF', verbose_name='Yazı Rengi') + title = models.CharField(max_length=254, verbose_name='Baner Adı', null=True) + text1 = models.CharField(max_length=254, verbose_name='Baner Küçük Yazı 1', null=True) + text2 = models.CharField(max_length=254, verbose_name='Baner Büyük Yazı 1', null=True) + text4 = models.CharField(max_length=254, verbose_name='Baner Küçük Yazı 2', null=True) + text5 = models.CharField(max_length=254, verbose_name='Baner Düğme Yazısı', null=True) + image = ProcessedImageField(upload_to='uploads/banner/%Y', + processors=[ResizeToFill(1880, 950)], + format='JPEG', + options={'quality': 90}) + image_k = ProcessedImageField(upload_to='uploads/banner/kucuk/%Y', + processors=[ResizeToFill(48, 48)], + format='PNG', + options={'quality': 90}, null=True, blank=True) + image_k_txt = models.CharField(max_length=254, verbose_name='Küçük Resim Yazisi', null=True) + is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif) + + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + + class Meta: + ordering = ["-created_at"] + db_table = 'banners' + verbose_name_plural = "Bannerler" + verbose_name = "Banner" + + def __str__(self): + return str(self.title) diff --git a/settings/serializers.py b/settings/serializers.py new file mode 100644 index 0000000..c475a57 --- /dev/null +++ b/settings/serializers.py @@ -0,0 +1,98 @@ +from rest_framework import serializers +# from product.models import Category, Product, Images, Tags +from settings.models import Setting + +""" +title +content +categories +keywords +brim +price +tags +gallery +images +thumb +video +slug +created_at +updated_at +is_active +is_front +""" + +""" +class CateSerializer(serializers.ModelSerializer): + class Meta: + model = Category + fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'images', 'keywords', 'description'] + + +class GalSerializer(serializers.ModelSerializer): + class Meta: + model = Images + fields = ['title', 'images'] + + +class TagSerializer(serializers.ModelSerializer): + class Meta: + model = Tags + fields = ['tag', 'slug'] + + +class ProductSerializer(serializers.ModelSerializer): + categories = CateSerializer(read_only=True, many=True) + gallery = GalSerializer(read_only=True, many=True) + tags = TagSerializer(read_only=True, many=True) + + class Meta: + model = Product + fields = ['title', 'content', 'categories', 'keywords', 'brim', 'tags', 'gallery', 'images', 'thumb', 'video', + 'slug', 'created_at', 'updated_at', 'is_active', 'is_front','price'] + # fields = '__all__' + + +class CategorySerializer(serializers.ModelSerializer): + categories = ProductSerializer(read_only=True, many=True) + child = serializers.SerializerMethodField() + + class Meta: + model = Category + fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'images', 'keywords', 'description', + 'categories', 'child'] + + def get_child(self, obj): + serializer = self.__class__(obj.child.all(), many=True, context=self.context) + return serializer.data + +""" + + +class SettingSerializer(serializers.ModelSerializer): + b_logo = serializers.SerializerMethodField() + w_logo = serializers.SerializerMethodField() + + class Meta: + model = Setting + fields = ['title', 'meta_title', 'meta_description', 'phone', 'url', 'email', 'facebook', 'x', + 'instagram', 'whatsapp', 'slogan', 'w_logo', 'b_logo', 'created_at', + 'updated_at', 'is_active'] + + def get_w_logo(self, obj): + if obj.w_logo: + request = self.context.get('request') + if request: + return request.build_absolute_uri(obj.w_logo.url) + else: + # Fallback olarak manuel URL oluşturma + return f"http://127.0.0.1:8000{obj.w_logo.url}" + return None + def get_b_logo(self, obj): + if obj.b_logo: + request = self.context.get('request') + if request: + return request.build_absolute_uri(obj.b_logo.url) + else: + # Fallback olarak manuel URL oluşturma + return f"http://127.0.0.1:8000{obj.b_logo.url}" + return None diff --git a/settings/signals.py b/settings/signals.py new file mode 100644 index 0000000..ec8635d --- /dev/null +++ b/settings/signals.py @@ -0,0 +1,11 @@ +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver +from settings.models import Setting +from django.core.cache import cache + + +@receiver([post_save, post_delete], sender=Setting) +def invalidate_setting_cache(sender, instance, **kwargs): + # Sadece active_setting cache'ini temizle + cache.delete('active_setting') + print('Cache cleared for active_setting') diff --git a/settings/tests.py b/settings/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/settings/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/settings/urls.py b/settings/urls.py new file mode 100644 index 0000000..ee3e3fb --- /dev/null +++ b/settings/urls.py @@ -0,0 +1,7 @@ +from django.urls import path, include +from .views import SettingDetailView + +urlpatterns = [ # Success/Error pages + path('settings/', SettingDetailView.as_view(), name='settings'), + +] diff --git a/settings/views.py b/settings/views.py new file mode 100644 index 0000000..4e7ce65 --- /dev/null +++ b/settings/views.py @@ -0,0 +1,37 @@ +from django.core.cache import cache +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from core.Permission import ReadOnly +from settings.models import Setting +from settings.serializers import SettingSerializer +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_page + + +# Create your views here. +class SettingDetailView(APIView): + permission_classes = [ReadOnly] + + @method_decorator(cache_page(60 * 5)) + def get(self, request): + try: + # Cache'den veri kontrolü + cache_key = 'active_setting' + cached_data = cache.get(cache_key) + + if cached_data: + return Response(cached_data) + + # Cache'de yoksa veritabanından al + setting = Setting.objects.filter(is_active=True).first() + if setting: + serializer = SettingSerializer(setting) + # 5 dakika (300 saniye) cache'le + cache.set(cache_key, serializer.data, timeout=300) + return Response(serializer.data) + else: + return Response({"error": "No settings found"}, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) diff --git a/start_dev.sh b/start_dev.sh new file mode 100644 index 0000000..a0cd54e --- /dev/null +++ b/start_dev.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Hata durumunda durdurma, çünkü ctrl+c ile kapatmak isteyebiliriz +# set -e + +echo "Starting Django Development Server and Celery Worker..." + +# Trap SIGINT (Ctrl+C) to kill all background processes +trap 'kill $(jobs -p)' SIGINT + +# Start Celery Worker in background +echo "Starting Celery Worker..." +celery -A core worker -l info & + +# Wait a bit for Celery to initialize (optional) +sleep 2 + +# Start Django Development Server +echo "Starting Django Server..." +python manage.py runserver 0.0.0.0:8000 + +# Wait for all background processes to finish +wait diff --git a/static/css/bootstrap.min.css b/static/css/bootstrap.min.css new file mode 100644 index 0000000..d65c66b --- /dev/null +++ b/static/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/static/css/font-awesome-4.4.0/css/font-awesome.min.css b/static/css/font-awesome-4.4.0/css/font-awesome.min.css new file mode 100644 index 0000000..ee4e978 --- /dev/null +++ b/static/css/font-awesome-4.4.0/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.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}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.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-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} diff --git a/static/css/font-awesome-4.4.0/fonts/FontAwesome.otf b/static/css/font-awesome-4.4.0/fonts/FontAwesome.otf new file mode 100644 index 0000000..681bdd4 Binary files /dev/null and b/static/css/font-awesome-4.4.0/fonts/FontAwesome.otf differ diff --git a/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.eot b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..a30335d Binary files /dev/null and b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.eot differ diff --git a/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.svg b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..6fd19ab --- /dev/null +++ b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.svg @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.ttf b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..d7994e1 Binary files /dev/null and b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.ttf differ diff --git a/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..6fd4ede Binary files /dev/null and b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff differ diff --git a/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff2 b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..5560193 Binary files /dev/null and b/static/css/font-awesome-4.4.0/fonts/fontawesome-webfont.woff2 differ diff --git a/static/css/style-dark.css b/static/css/style-dark.css new file mode 100644 index 0000000..ad5b1d3 --- /dev/null +++ b/static/css/style-dark.css @@ -0,0 +1,3334 @@ +@charset "utf-8"; +/* CSS Document */ + + +/* + reset + layout + navigation + link style + brackets + preload + frame + skills + countdown + social icons + contact form + newsletter form + center container + owlCarousel + curtains + film grain + weather + snow + particles + clouds + photos + supersized + kenburnsy + YouTube video containment + HTML5 video containment + lines + wordsrotator + dialog + core owlCarousel + core magnificPopup + animate + media queries +*/ + + +/* reset */ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { +margin: 0; +padding: 0; +border: 0; +font-size: 100%; +font: inherit; +vertical-align: baseline; +} + +html, body { +height: 100%; +} + +body { +line-height: 1; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { +display: block; +} + +ol, ul { +list-style: none; +} + +blockquote, q { +quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after { +content: ''; +content: none; +} + +table { +border-collapse: collapse; +border-spacing: 0; +} + +*:focus { +outline: none; +} + +/* remove dotted outline from links, button and input element */ +a:focus, a:active, +button::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner { +border: 0; +outline: 0; +} + + +/* layout */ +body { +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +color: #fff; +background: #000; + -webkit-font-smoothing: antialiased; +-moz-osx-font-smoothing: grayscale; +-webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +width: 100%; +height: 100%; +} + +a { +color: #db0018; +text-decoration: none; +outline: none; +} + +a:hover { +color: #fff; +text-decoration: none; +} + +p a { +text-decoration: none; +outline: none; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +p a:hover { +color: #fff; +text-decoration: none; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +::-moz-selection { background: #555; color: #fff; /* Firefox */ } + ::selection { background: #555; color: #fff; /* Safari */ } + + +.upper-page { +min-height: 100%; +margin: 0; +padding: 0; +background: none; +} + +.upper-content { +margin: 0 auto; +padding: 0; +} + +.lower-page { +min-height: 100%; +margin: 0; +padding: 0; +} + +.lower-content { +margin: 0 auto; +padding: 138px 0 38px 0; +} + +.lower-content p { +padding: 10px; +color: #fff; +text-align: center; +} + +.sections { +position: relative; +z-index: 10; +text-align: center; +} + +#about, #services, #photos, #contact { +display: none; +} + +#intro-wrapper { +position: relative; +width: 100%; +height: auto; +overflow: hidden; +margin: 0 auto; +padding: 0; +} + +.intro-spacer { +position: relative; +width: 100%; +height: 100px; +margin: 0 auto; +} + +.intro-spacer-2 { +position: relative; +width: 100%; +height: 50px; +margin: 0 auto; +} + +h1 { +font-family: 'Oswald', sans-serif; +font-size: 90px; +font-weight: 700; +line-height: .9; +letter-spacing: -0.04em; +color: #fff; +margin: 160px auto 50px auto; +text-align: center; +text-transform: uppercase; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.highlighter { +color: #db0018; +line-height: 1.2; +} + +h2 { +font-family: 'Oswald', sans-serif; +font-size: 70px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #fff; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +} + +h3 { +font-family: 'Oswald', sans-serif; +font-size: 30px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #db0018; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +} + +h4 { +font-family: 'Oswald', sans-serif; +font-size: 30px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #db0018; +margin: 60px auto 15px auto; +text-align: center; +text-transform: uppercase; +} + +h5 { +font-family: 'Montserrat', sans-serif; +font-size: 30px; +font-weight: 700; +line-height: 1; +letter-spacing: -0.08em; +color: #c5c2b8; +margin: 0; +text-align: center; +text-transform: uppercase; +} + +h6 { +font-family: 'Oswald', sans-serif; +font-size: 23px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #fff; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +-webkit-transform: rotate(60deg); + -moz-transform: rotate(60deg); + -ms-transform: rotate(60deg); + -o-transform: rotate(60deg); + transform: rotate(60deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.divider { +margin: 20px auto 40px auto; +} + +.decoration { +position: relative; +margin: 0 auto; +text-align: center; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.decoration-left { +width: 6%; +height: 1px; +background: #fff; +margin: 0 119px 10px 0; +position: relative; +display: inline-block; +} + +.decoration-right { +width: 6%; +height: 1px; +background: #fff; +margin: 0 0 10px 119px; +position: relative; +display: inline-block; +} + +.decoration-effect { +position: absolute; +font-family: 'Oswald', sans-serif; +font-size: 17px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 300; +letter-spacing: 1px; +background: none; +width: 202px; +height: 61px; +padding: 17px 0 0 0; +margin-left: -101px; +left: 50%; +top: -25px; +z-index: 0; +} + +.decoration-effect a, .decoration-effect a:hover { +color: #fff; +text-decoration: none; +} + +.effect-bubba::before, +.effect-bubba::after { +width: 180px; +height: 39px; +position: absolute; +top: 10px; +right: 10px; +bottom: 10px; +left: 10px; +content: ''; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.35s, -webkit-transform 0.35s; + transition: opacity 0.35s, transform 0.35s; +} + +.effect-bubba::before { +border-top: 1px solid #fff; +border-bottom: 1px solid #fff; +-webkit-transform: scale(0,1); + -moz-transform: scale(0,1); + -ms-transform: scale(0,1); + -o-transform: scale(0,1); + transform: scale(0,1); +} + +.effect-bubba::after { +border-left: 1px solid #fff; +border-right: 1px solid #fff; +-webkit-transform: scale(1,0); + -moz-transform: scale(1,0); + -ms-transform: scale(1,0); + -o-transform: scale(1,0); + transform: scale(1,0); +} + +.effect-bubba:hover::before, +.effect-bubba:hover::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.decoration-2 { +position: relative; +margin: 49px auto 74px auto; +text-align: center; +} + +.decoration-left-2 { +width: 6%; +height: 1px; +background: #fff; +margin: 0 119px 10px 0; +position: relative; +display: inline-block; +} + +.decoration-right-2 { +width: 6%; +height: 1px; +background: #fff; +margin: 0 0 10px 119px; +position: relative; +display: inline-block; +} + +.decoration-effect-2 { +position: absolute; +font-family: 'Dosis', sans-serif; +font-size: 17px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +background: none; +width: 202px; +height: 61px; +padding: 17px 0 0 0; +margin-left: -101px; +left: 50%; +top: -25px; +z-index: 0; +} + +.decoration-effect-2 a, .decoration-effect-2 a:hover { +color: #fff; +text-decoration: none; +} + +.effect-bubba-2::before, +.effect-bubba-2::after { +width: 180px; +height: 39px; +position: absolute; +top: 10px; +right: 10px; +bottom: 10px; +left: 10px; +content: ''; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.35s, -webkit-transform 0.35s; + transition: opacity 0.35s, transform 0.35s; +} + +.effect-bubba-2::before { +border-top: 1px solid #fff; +border-bottom: 1px solid #fff; +-webkit-transform: scale(0,1); + -moz-transform: scale(0,1); + -ms-transform: scale(0,1); + -o-transform: scale(0,1); + transform: scale(0,1); +} + +.effect-bubba-2::after { +border-left: 1px solid #fff; +border-right: 1px solid #fff; +-webkit-transform: scale(1,0); + -moz-transform: scale(1,0); + -ms-transform: scale(1,0); + -o-transform: scale(1,0); + transform: scale(1,0); +} + +.effect-bubba-2:hover::before, +.effect-bubba-2:hover::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.quote { +margin: 0 auto; +} + +.quote p { +font-family: 'Raleway',sans-serif; +font-size: 18px; +line-height: 1.5; +font-style: italic; +font-weight: normal; +text-align: center; +color: #fff; +font-weight: 400; +letter-spacing: 1px; +} + +.quote-mark-l { +color: #fff; +padding: 0 10px 0 0; +} + +.quote-mark-r { +color: #fff; +padding: 0 0 0 10px; +} + +.awesome { +color: #fff; +margin: 20px auto; +text-align: center; +display: block; +} + + +/* navigation */ +.menu-toggle { +position: fixed; +display: block; +top: 2px; +left: 14px; +width: 80px; +height: 80px; +padding: 0; +background: none; +line-height: 1; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +z-index: 999; +} + +#main-menu { +position: fixed; +font-family: 'Oswald', sans-serif; +font-style: normal; +text-transform: uppercase; +font-weight: 400; +letter-spacing: 1px; +line-height: 1; +width: 400px; +height: 200%; +left: -760px; +top: -460px; +margin: auto; +background: #fff; +-webkit-transition: left .4s ease-in-out; + -moz-transition: left .4s ease-in-out; + -ms-transition: left .4s ease-in-out; + -o-transition: left .4s ease-in-out; + transition: left .4s ease-in-out; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +z-index: 998; +} + +#main-menu.activated { +left: 98px; +} + +#main-menu ul { +list-style: none outside none; +padding: 0 0 0 37px; +} + +#main-menu ul li { +text-align: left; +line-height: .75; +} + +#main-menu .credits { +font-size: 14px; +line-height: 1; +margin: 15px 0 0 9px; +-webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +-webkit-transform-origin: left; + -moz-transform-origin: left; + -ms-transform-origin: left; + -o-transform-origin: left; + transform-origin: left; +} + +#main-menu .credits a { +color: #444; +text-decoration: none; +} + +#main-menu a { +display: none; +min-width: 10px; +color: #c5c2b8; +text-decoration: none; +-webkit-transition: color .8s ease-in-out; + -moz-transition: color .8s ease-in-out; + -ms-transition: color .8s ease-in-out; + -o-transition: color .8s ease-in-out; + transition: color .8s ease-in-out; +} + +#main-menu li .active { +color: #000; +} + +.menu-nav-wrapper { +display: table; +width: 100%; +height: 100%; +} + +.menu-nav { +display: table-cell; +width: 100%; +height: 100%; +vertical-align: middle; +} + + +/* link style */ +.link { +position: relative; +outline: none; +text-decoration: none; +font-size: 50px; +line-height: 1; +display: inline-block; +width: 326px; +} + +.link--kukuri { +overflow: hidden; +line-height: 1; +} + +.link--kukuri::after { +content: ''; +position: absolute; +height: 16px; +width: 100%; +top: 50%; +margin-top: -8px; +right: 0; +background: #c5c2b8; +-webkit-transform: translate3d(-100%,0,0); + -moz-transform: translate3d(-100%,0,0); + -ms-transform: translate3d(-100%,0,0); + -o-transform: translate3d(-100%,0,0); + transform: translate3d(-100%,0,0); +-webkit-transition: -webkit-transform 0.4s; + transition: transform 0.4s; +-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1); + transition-timing-function: cubic-bezier(0.7,0,0.3,1); +} + +.link--kukuri:hover::after { +-webkit-transform: translate3d(100%,0,0); + -moz-transform: translate3d(100%,0,0); + -ms-transform: translate3d(100%,0,0); + -o-transform: translate3d(100%,0,0); + transform: translate3d(100%,0,0); +} + +.link--kukuri::before { +position: absolute; +content: attr(data-letters); +z-index: 2; +overflow: hidden; +color: #000; +white-space: nowrap; +width: 0%; +-webkit-transition: width 0.6s 0.3s; + -moz-transition: width 0.6s 0.3s; + -ms-transition: width 0.6s 0.3s; + -o-transition: width 0.6s 0.3s; + transition: width 0.6s 0.3s; +} + +.link--kukuri:hover::before { +width: 100%; +} + + +/* brackets */ +.brackets a::before, +.brackets a::after { +display: inline-block; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: -webkit-transform 0.3s, opacity 0.2s; + -moz-transition: -moz-transform 0.3s, opacity 0.2s; + -ms-transition: -ms-transform 0.3s, opacity 0.2s; + -o-transition: -o-transform 0.3s, opacity 0.2s; + transition: transform 0.3s, opacity 0.2s; +} + +.brackets a::before { +content: '['; +margin-right: 10px; +-webkit-transform: translateX(20px); + -moz-transform: translateX(20px); + -ms-transform: translateX(20px); + -o-transform: translateX(20px); + transform: translateX(20px); +} + +.brackets a::after { +content: ']'; +margin-left: 10px; +-webkit-transform: translateX(-20px); + -moz-transform: translateX(-20px); + -ms-transform: translateX(-20px); + -o-transform: translateX(-20px); + transform: translateX(-20px); +} + +.brackets a:hover::before, +.brackets a:hover::after, +.brackets a:focus::before, +.brackets a:focus::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: translateX(0px); + -moz-transform: translateX(0px); + -ms-transform: translateX(0px); + -o-transform: translateX(0px); + transform: translateX(0px); +} + +.brackets ul, li { +list-style: none; +} + +.brackets a { +color: #db0018; +text-decoration: none; +} + +.brackets a:hover { +color: #db0018; +text-decoration: none; +} + +.brackets a:visited { +color: #db0018; +text-decoration: none; +} + + +/* preload */ +#preload { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +right: 0; +bottom: 0; +background: #000; +display: none; +z-index: 10000; +} + +#preload-status { +position: absolute; +width: 40px; +height: 40px; +margin: auto; +padding: 0; +top: 0; +right: 0; +bottom: 0; +left: 0; +display: block; +background: #fff; +border-radius: 100%; +-webkit-animation: scaleout 1.0s infinite ease-in-out; + -moz-animation: scaleout 1.0s infinite ease-in-out; + -ms-animation: scaleout 1.0s infinite ease-in-out; + -o-animation: scaleout 1.0s infinite ease-in-out; + animation: scaleout 1.0s infinite ease-in-out; +} + +@-webkit-keyframes scaleout { + 0% { + -webkit-transform: scale(0.0); + -ms-transform: scale(0.0); + transform: scale(0.0); + } + + 100% { + -webkit-transform: scale(1.0); + -ms-transform: scale(1.0); + transform: scale(1.0); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + } +} + +@keyframes scaleout { + 0% { + -webkit-transform: scale(0.0); + -ms-transform: scale(0.0); + transform: scale(0.0); + } + + 100% { + -webkit-transform: scale(1.0); + -ms-transform: scale(1.0); + transform: scale(1.0); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + } +} + +#preload-status { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + + +/* frame */ +#site-wrapper { +position: relative; +min-width: 100%; +min-height: 100%; +overflow: hidden; +} + +.line { +position: fixed; +display: block; +-webkit-transform: translate3d(0,0,0); + -moz-transform: translate3d(0,0,0); + -ms-transform: translate3d(0,0,0); + -o-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +background: #fff; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +z-index: -1; +} + +.line.line-top { +top: 10px; +left: 10px; +width: 50%; +height: 2px; +-webkit-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -moz-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -ms-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -o-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + transition: width 800ms cubic-bezier(.55,.055,.675,.19); +} + +.line.line-right { +top: 10px; +right: 10px; +width: 2px; +height: 50%; +-webkit-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -moz-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -ms-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -o-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; +} + +.line.line-bottom { +right: 10px; +bottom: 10px; +width: 50%; +height: 2px; +-webkit-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -moz-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -ms-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -o-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + transition: width 800ms cubic-bezier(.55,.055,.675,.19); +} + +.line.line-left { +bottom: 10px; +left: 10px; +width: 2px; +height: 50%; +-webkit-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -moz-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -ms-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -o-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; +} + +.site-opening #ui-layer { +-webkit-transition-delay: 0; + -moz-transition-delay: 0; + -ms-transition-delay: 0; + -o-transition-delay: 0; + transition-delay: 0; +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +#ui-layer { +position: relative; +min-width: 100%; +min-height: 100%; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +z-index: 6; +} + +body[class=page-top] #ui-layer { +/* +-webkit-transition: opacity 1000ms ease 1000ms, -webkit-transform 1000ms ease; + -moz-transition: opacity 1000ms ease 1000ms, -moz-transform 1000ms ease; + -o-transition: opacity 1000ms ease 1000ms, -o-transform 1000ms ease; + transition: opacity 1000ms ease 1000ms, transform 1000ms ease; +*/ +} + +.site-opening #bg-layer { +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +/* +-webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -ms-transform: scale(1.1); + -o-transform: scale(1.1); + transform: scale(1.1); +*/ +-webkit-transform: scale(1.4); + -moz-transform: scale(1.4); + -ms-transform: scale(1.4); + -o-transform: scale(1.4); + transform: scale(1.4); +} + +#bg-layer { +position: absolute; +top: 0; +left: 0; +width: 100%; +height: 100%; +-webkit-transform: scale3d(1); + -moz-transform: scale3d(1); + -ms-transform: scale3d(1); + -o-transform: scale3d(1); + transform: scale3d(1); + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +body[class=page-top] #bg-layer { +-webkit-transition: opacity 2000ms ease, -webkit-transform 2000ms ease; + -moz-transition: opacity 2000ms ease, -moz-transform 2000ms ease; + -ms-transition: opacity 2000ms ease, -ms-transform 2000ms ease; + -o-transition: opacity 2000ms ease, -o-transform 2000ms ease; + transition: opacity 2000ms ease, transform 2000ms ease; +} + +.page-top #bg-layer { +/* +background-image: url(../img/background/bg-layer.jpg); +background-position: 50% 0; +background-repeat: no-repeat; +background-size: cover; +*/ +} + +.main-image { +position: relative; +width: 100%; +height: 100%; +overflow-x: hidden; +overflow-y: auto; +} + +.site-opening .line { +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; +} + +.site-opening .line-top { +width: 0; +} + +.site-opening .line-right { +height: 0; +} + +.site-opening .line-bottom { +width: 0; +} + +.site-opening .line-left { +height: 0; +} + + +/* skills */ +.contentOT { +font-family: 'Dosis', sans-serif; +font-size: 17px; +line-height: 1; +font-style: normal; +text-transform: uppercase; +text-align: left; +font-weight: 400; +letter-spacing: 1px; +position: relative; +width: 100%; +margin: 0; +padding: 40px 10px 0 10px; +float: left; +left: 0; +} + +.colOT { +position: relative; +width: 100%; +float: left; +left: 0; +} + +#skills { +list-style: none; +} + +#skills li { +background: #fff; +height: 3px; +margin: 0 0 50px 0; +} + +#skills li.last { +background: #fff; +height: 3px; +margin: 0; +} + +#skills li .skills-description { +position: relative; +top: -25px; +} + +.expand { +position: absolute; +height: 3px; +margin: 0; +background: #db0018; +} + +.html5 { +width: 70%; +-webkit-animation: html5 2s ease-out; + -moz-animation: html5 2s ease-out; + -ms-animation: html52s ease-out; + -o-animation: html5 2s ease-out; + animation: html5 2s ease-out; +} + +.css3 { +width: 90%; +-webkit-animation: css3 2s ease-out; + -moz-animation: css3 2s ease-out; + -ms-animation: css3 2s ease-out; + -o-animation: css3 2s ease-out; + animation: css3 2s ease-out; +} + +.jquery { +width: 50%; +-webkit-animation: jquery 2s ease-out; + -moz-animation: jquery 2s ease-out; + -ms-animation: jquery 2s ease-out; + -o-animation: jquery 2s ease-out; + animation: jquery 2s ease-out; +} + +.photoshop { +width: 30%; +-webkit-animation: photoshop 2s ease-out; + -moz-animation: photoshop 2s ease-out; + -ms-animation: photoshop 2s ease-out; + -o-animation: photoshop 2s ease-out; + animation: photoshop 2s ease-out; +} + +.dreamweaver { +width: 100%; +-webkit-animation: dreamweaver 2s ease-out; + -moz-animation: dreamweaver 2s ease-out; + -ms-animation: dreamweaver 2s ease-out; + -o-animation: dreamweaver 2s ease-out; + animation: dreamweaver 2s ease-out; +} + +@-moz-keyframes html5 { 0% { width:0px;} 100%{ width:70%;} } +@-moz-keyframes css3 { 0% { width:0px;} 100%{ width:90%;} } +@-moz-keyframes jquery { 0% { width:0px;} 100%{ width:50%;} } +@-moz-keyframes photoshop { 0% { width:0px;} 100%{ width:10%;} } +@-moz-keyframes dreamweaver { 0% { width:0px;} 100%{ width:100%;} } + +@-webkit-keyframes html5 { 0% { width:0px;} 100%{ width:70%;} } +@-webkit-keyframes css3 { 0% { width:0px;} 100%{ width:90%;} } +@-webkit-keyframes jquery { 0% { width:0px;} 100%{ width:50%;} } +@-webkit-keyframes photoshop { 0% { width:0px;} 100%{ width:10%;} } +@-webkit-keyframes dreamweaver { 0% { width:0px;} 100%{ width:100%;} } + + +/* countdown */ +#countdown-wrapper { +position: relative; +margin: 28px auto; +width: 400px; +-webkit-transform: rotate(60deg); + -moz-transform: rotate(60deg); + -ms-transform: rotate(60deg); + -o-transform: rotate(60deg); + transform: rotate(60deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +#countdown { +margin: 0; +padding: 0; +} + +ul#countdown li { +display: inline-block; +width: 115px; +} + +ul#countdown li span { +/* font-family: 'Montserrat', sans-serif; */ +font-family: 'Oswald', sans-serif; +font-size: 70px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #fff; +text-align: center; +margin: 0; +padding: 0; +position: relative; +} + +ul#countdown li span.seconds { +/* font-family: 'Montserrat', sans-serif; */ +font-family: 'Oswald', sans-serif; +font-size: 55px; +font-weight: 400; +line-height: 1.1; +letter-spacing: -0.04em; +color: #db0018; +text-align: left; +margin: 0; +padding: 0 0 0 20px; +position: relative; +/* text-shadow: 1px 1px 2px #222; */ +} + +ul#countdown li span::before { +content: ''; +width: 100%; +height: 1px; +position: absolute; +} + +ul#countdown li p.timeRefDays, +ul#countdown li p.timeRefHours, +ul#countdown li p.timeRefMinutes { +/* font-family: 'Raleway', sans-serif; */ +font-family: 'Oswald', sans-serif; +color: #fff; +text-transform: uppercase; +font-size: 16px; +font-style: normal; +font-weight: 300; +text-align: center; +margin: 0; +padding: 0 0 0 5px; +} + +ul#countdown li p.timeRefSeconds { +/* font-family: 'Raleway', sans-serif; */ +font-family: 'Oswald', sans-serif; +color: #fff; +text-transform: uppercase; +font-size: 16px; +font-style: normal; +font-weight: 300; +text-align: center; +margin: 0; +padding: 0 0 0 24px; +} + + +/* social icons */ +.social-icons-wrapper { +position: relative; +margin: 0 auto; +text-align: center; +} + +.social-icons-wrapper ul { +margin: 0 auto; +padding: 0; +list-style-type: none; +} + +.social-icons-wrapper ul li { +display: inline-block; +margin: 0 auto; +padding: 0 0 0 5px; +} + +ul.social-icons { +font-size: 15px; +margin: 0; +padding: 0; +} + +ul.social-icons a { +padding: 0; +color: #fff; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +ul.social-icons a:hover { +padding: 0; +color: #fff; + opacity: 0.3; + -moz-opacity: 0.3; +-webkit-opacity: 0.3; +filter: alpha(opacity=30); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + + +/* contact form */ +#contact-form { +width: 100%; +margin: 0; +text-align: center; +} + +form { +margin: 0; +padding: 0; +} + +input { +position: relative; +width: 100%; +height: 40px; +border-bottom: 1px solid #fff; +border-left: none; +border-right: none; +border-top: none; +padding: 5px 5px; +background: none; +margin: 5px; +-webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +} + +#form input { +margin: 10px 0 10px 0; +} + +textarea { +position: relative; +width: 100%; +height: 100px; +border-bottom: 1px solid #fff; +border-left: none; +border-right: none; +border-top: none; +padding: 5px 5px; +background: none; +margin: 5px; +-webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +} + +#form textarea { +margin: 10px 0 10px 0; +} + +input:hover, +textarea:hover { +border-color: rgba(255,255,255, .5); +} + +#form input:focus, +#form textarea:focus { +-webkit-animation: glow 900ms ease-out infinite alternate; + -moz-animation: glow 900ms ease-out infinite alternate; + -ms-animation: glow 900ms ease-out infinite alternate; + -o-animation: glow 900ms ease-out infinite alternate; + animation: glow 900ms ease-out infinite alternate; +} + +.success { +font-family: 'Montserrat', sans-serif; +font-size: 13px; +font-weight: 400; +font-style: normal; +text-transform: uppercase; +text-align: center; +color: #fff; +margin: 0; +padding: 20px 0 0 0; +line-height: 1; +} + +#form .error { +position: absolute; +font-size: 10px; +text-transform: uppercase; +text-align: left; +color: #fff; +display: block; +margin: -8px 0 0 1px; +padding: 0; +} + + +@-webkit-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(255,255,255, .2), inset 0 0 5px rgba(255,255,255, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(255,255,255, .6), inset 0 0 10px rgba(255,255,255, .4) + } +} +@-moz-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(255,255,255, .2), inset 0 0 5px rgba(255,255,255, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(255,255,255, .6), inset 0 0 10px rgba(255,255,255, .4) + } +} +@-o-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(255,255,255, .2), inset 0 0 5px rgba(255,255,255, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(255,255,255, .6), inset 0 0 10px rgba(255,255,255, .4) + } +} +@-ms-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(255,255,255, .2), inset 0 0 5px rgba(255,255,255, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(255,255,255, .6), inset 0 0 10px rgba(255,255,255, .4) + } +} +@keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(255,255,255, .2), inset 0 0 5px rgba(255,255,255, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(255,255,255, .6), inset 0 0 10px rgba(255,255,255, .4) + } +} + +::-webkit-input-placeholder { +font-style: italic; +color: #fff; +} + +::-moz-placeholder { +font-style: italic; +color: #fff; +} + +:-ms-input-placeholder { +font-style: italic; +color: #fff; +} + +input:-moz-placeholder { +font-style: italic; +color: #fff; +} + +.submit-button { +position: relative; +font-family: 'Dosis', sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #fff; +display: inline-block; +outline: none; +margin: 21px auto 0 auto; +width: 225px; +padding: 0; +height: 45px; +border: 1px solid #fff; +background: #fff; +overflow: hidden; +cursor: pointer; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +-webkit-transform: translate(0,0); + -moz-transform: translate(0,0); + -ms-transform: translate(0,0); + -o-transform: translate(0,0); + transform: translate(0,0); +} + +.submit-button::before { +position: absolute; +content: ''; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -100%; +bottom: 0%; +width: 200%; +height: 200%; +background: #000; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transform: skewX(-60deg); + -moz-transform: skewX(-60deg); + -ms-transform: skewX(-60deg); + -o-transform: skewX(-60deg); + transform: skewX(-60deg); +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +z-index: -1; +} + +.submit-button::before { +-webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -ms-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +.submit-button:hover { +color: #000; +} + +.submit-button:hover::before { +bottom: -100%; +right: -200%; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + + +/* newsletter form */ +#subscribe-wrapper { +margin: 0 auto 40px auto; +background: none; +width: 225px; +height: 70px; +position: relative; +z-index: 999; +} + +#newsletter { +width: auto; +height: 55px; +padding: 1px 0 0 0; +} + +.newsletter { +position: relative; +clear: both; +width: auto; +border: none; +background: none; +margin: -5px 0 0 0; +padding: 0; +overflow: hidden; +} + +#subscribe .mail { +display: none; +visibility: hidden; +} + +#subscribe input#subscribeemail { +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +color: #000; +width: 225px; +height: 28px; +margin: 0; +padding: 0; +border-top: none; +border-left: none; +border-right: none; +border-bottom: 1px solid #000; +} + +#subscribe input { +background: none; +} + +#subscribe input:focus, #subscribe textarea:focus { +color: #000; +background: none; +} + +.submit-button-2 { +position: relative; +font-family: 'Dosis', sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #fff; +display: inline-block; +outline: none; +margin: 10px auto; +width: 225px; +padding: 0; +height: 45px; +border: none; +background: #000; +overflow: hidden; +cursor: pointer; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +-webkit-transform: translate(0,0); + -moz-transform: translate(0,0); + -ms-transform: translate(0,0); + -o-transform: translate(0,0); + transform: translate(0,0); +} + +.submit-button-2::before { +position: absolute; +content: ''; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -100%; +bottom: 0%; +width: 200%; +height: 200%; +background: #db0018; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transform: skewX(-60deg); + -moz-transform: skewX(-60deg); + -ms-transform: skewX(-60deg); + -o-transform: skewX(-60deg); + transform: skewX(-60deg); +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +z-index: -1; +} + +.submit-button-2::before { +-webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -ms-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +.submit-button-2:hover { +color: #fff; +background: #000; +} + +.submit-button-2:hover::before { +bottom: -100%; +right: -200%; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.subscribesuccess { +font-family: 'Montserrat', sans-serif; +font-size: 13px; +font-weight: 400; +font-style: normal; +text-transform: uppercase; +text-align: center; +color: #000; +margin: 0; +padding: 60px 0 0 0; +line-height: 1; +} + +#subscribe .subscribeerror { +font-size: 10px; +text-transform: uppercase; +text-align: center; +color: #000; +display: block; +margin: 0; +padding: 0; +} + + +/* center container */ +.center-container-home { +position: absolute; +display: table; +height: 100%; +width: 100%; +left: 0; +top: 0; +} + +.center-block-home { +display: table-cell; +vertical-align: middle; +} + +.center-container { +position: absolute; +display: table; +/* display: block; */ +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(0,0,0, .6); +} + +.center-container-videos { +position: absolute; +display: table; +/* display: block; */ +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(0,0,0, .4); +} + +.center-block { +display: table-cell; +/* display: block; */ +vertical-align: middle; +} + +.cover-all { +position: fixed; +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(0,0,0, .6); +z-index: 1; +} + +.cover-all-videos { +position: fixed; +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(0,0,0, .4); +z-index: 1; +} + + +/* owlCarousel */ +.owl-carousel { +overflow: hidden; +} + +.owl-buttons { +position: static; +} + +.owl-prev, +.owl-next { +position: absolute; +display: block; +top: 50%; +margin-top: -50px; +width: 105px; +height: 105px; +line-height: 105px; +font-size: 30px; +text-align: center; +color: #fff; +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +z-index: 6; +} + +.owl-prev { +left: -50px; +} + +.owl-next { +right: -50px; +} + +.owl-prev:before, +.owl-next:before { +content: ""; +display: block; +width: 66%; +height: 66%; +position: absolute; +left: 0; +top: 17px; +background: none; +/* +-webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +-webkit-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + -moz-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + box-shadow: 1px 1px 0px rgba(0,0,0, .1); +-webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +*/ +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); +} + +.owl-next:before { +left: auto; +right: 0; +} + +.owl-prev .fa, +.owl-next .fa { +position: relative; +} + +.owl-prev:hover, +.owl-next:hover { +-webkit-transition: 0 none !important; + -moz-transition: 0 none !important; + -ms-transition: 0 none !important; + -o-transition: 0 none !important; + transition: 0 none !important; +} + +.owl-prev:hover:before, +.owl-next:hover:before { + opacity: 0.8; + -moz-opacity: 0.8; +-webkit-opacity: 0.8; +filter: alpha(opacity=80); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; +} + +.owl-prev:active:before, +.owl-next:active:before { + opacity: 0.6; + -moz-opacity: 0.6; +-webkit-opacity: 0.6; +filter: alpha(opacity=60); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; +} + +.owl-carousel:hover .owl-prev { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +left: -35px; +} + +.owl-carousel:hover .owl-next { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -35px; +} + +.owl-pagination { +display: block; +width: 100%; +height: auto; +position: absolute; +bottom: 20px; +left: 0; +text-align: center; +} + +.owl-page { +position: relative; +display: inline-block; +padding: 6px 4px; +} + +.owl-page span { +width: 15px; +height: 2px; +display: block; +background: rgba(255,255,255, .7); +position: relative; +/* +-webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +*/ +-webkit-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + -moz-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + box-shadow: 1px 1px 0px rgba(0,0,0, .1); +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); +z-index: 1000 !important; +} + +.owl-page:hover span { +background: rgba(255,255,255, 1); +} + +.owl-page.active span { +background: #db0018; +-webkit-transform: scale(1.3333333); + -moz-transform: scale(1.3333333); + -ms-transform: scale(1.3333333); + -o-transform: scale(1.3333333); + transform: scale(1.3333333); +} + +.services-gallery { +margin: 16px 0 0 0; +} + +.services-gallery img { +max-width: 100%; +height: auto; +} + + +/* curtains */ +#curtains { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +/* background: url(../img/curtains.png) repeat top left; */ +z-index: 1; +} + + +/* film grain */ +#film-grain { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +background: url(../img/film-grain.gif) repeat top left; + opacity: 0.1; + -moz-opacity: 0.1; +-webkit-opacity: 0.1; +filter: alpha(opacity=10); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; +z-index: 5; +} + + +/* weather */ +/* main element */ +.weather { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +z-index: 5; +} + +/* pseudo elements: positioning and setup */ +.weather:before, .weather:after { +content: ""; +position: absolute; +left: -60%; +top: -60%; +right: -60%; +bottom: -60%; +pointer-events: none; +background: transparent repeat; +-webkit-transform: rotate(-40deg); + -moz-transform: rotate(-40deg); + -ms-transform: rotate(-40deg); + -o-transform: rotate(-40deg); + transform: rotate(-40deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +-webkit-animation-timing-function: linear; +-webkit-animation-iteration-count: infinite; +-webkit-animation-name: weather; + animation-name: weather; +animation-timing-function: linear; +animation-iteration-count: infinite; +z-index: 1; +} + +.weather:after { +-webkit-animation-name: weather2; + animation-name: weather2; +} + +/* rain */ +.weather.rain:before, .weather.rain:after { +background: url(../img/rain.png) left top; + opacity: 0.6; + -moz-opacity: 0.6; +-webkit-opacity: 0.6; +filter: alpha(opacity=60); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; +-webkit-animation-duration: 2s; + animation-duration: 2s; +} + +.weather.rain:after { +-webkit-animation-duration: 1.5s; + animation-duration: 1.5s; +} + +/* animation keyframes */ +@-webkit-keyframes weather { + from { background-position: 0 0px; } + to { background-position: 0 1024px; } +} +@keyframes weather { + from { background-position: 0 0px; } + to { background-position: 0 1024px; } +} +@-webkit-keyframes weather2 { + from { background-position: 64px 64px; } + to { background-position: 64px 1088px; } +} +@keyframes weather2 { + from { background-position: 64px 64px; } + to { background-position: 64px 1088px; } +} + + +/* snow */ +#snow { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +left: 0; +top: 0; +z-index: 5; +} + + +/* particles */ +#particles-holder { +position: absolute; +top: 0; +left: 0; +width: 100%; +height: 100%!important; +overflow: hidden; +z-index: 5; +} + +#particles-js { +width: 100%; +height: 100%; +overflow: hidden; +background: none; +} + +@media only screen and (max-width: 640px) { + #particles-holder, + #particles-js { + display: none; + visibility: hidden; + } +} + + +/* clouds */ +.clouds { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +background: none; +top: 0; +z-index: 5; +} + +.cloud-1 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-1.png); +background-repeat: repeat-x; +-webkit-animation: cloud-1 50s linear infinite; + -moz-animation: cloud-1 50s linear infinite; + -ms-animation: cloud-1 50s linear infinite; + -o-animation: cloud-1 50s linear infinite; + animation: cloud-1 50s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +.cloud-2 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-2.png); +background-repeat: repeat-x; +-webkit-animation: cloud-2 90s linear infinite; + -moz-animation: cloud-2 90s linear infinite; + -ms-animation: cloud-2 90s linear infinite; + -o-animation: cloud-2 90s linear infinite; + animation: cloud-2 90s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +.cloud-3 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-3.png); +background-repeat: repeat-x; +-webkit-animation: cloud-3 70s linear infinite; + -moz-animation: cloud-3 70s linear infinite; + -ms-animation: cloud-3 70s linear infinite; + -o-animation: cloud-3 70s linear infinite; + animation: cloud-3 70s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +@-webkit-keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-webkit-keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-webkit-keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + + +/* photos */ +.photos-section .photos-container { +position: relative; +display: block; +width: 100%; +float: left; +margin: 16px auto 0 auto; +-webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; +-webkit-column-gap: 5px; + -moz-column-gap: 5px; + column-gap: 5px; +} + +.photos-container .photo-gallery { +position: relative; +display: inline-block; +width: 100%; +height: 100%; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.photos-container .photo-gallery.portrait { +height: 465px; +filter: grayscale(100%); +-webkit-filter: grayscale(100%); /* Webkit browsers */ +filter: gray; /* IE 6 - 9 */ +filter: url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 10+, Firefox on Android */ +} + +.photos-container .photo-gallery.portrait:hover { +filter: grayscale(0%); +-webkit-filter: grayscale(0%); +filter: url("data:image/svg+xml;utf8,#grayscale"); +} + +.photos-container .photo-gallery.landscape { +height: 230px; +filter: grayscale(100%); +-webkit-filter: grayscale(100%); /* Webkit browsers */ +filter: gray; /* IE 6 - 9 */ +filter: url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 10+, Firefox on Android */ +} + +.photos-container .photo-gallery.landscape:hover { +filter: grayscale(0%); +-webkit-filter: grayscale(0%); +filter: url("data:image/svg+xml;utf8,#grayscale"); +} + +.photo-gallery .photo-container { +position: relative; +float: left; +display: block; +width: 100%; +height: 100%; +overflow: hidden; +} + +.photo-gallery .photo-container::before { +position: absolute; +display: block; +width: 100%; +height: 100%; +left: 0; +top: 0; +z-index: 1; +} + +.photo-gallery .photo-container::before { +content:''; +} + +.photo-gallery .photo-container img { +position: absolute; +display: block; +width: 100%; +height: auto; +left: 0; +top: 0; +-webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); +-webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); +} + +.photo-gallery .button-container { +position: absolute; +display: block; +width: 100%; +height: 50px; +text-align: center; +z-index: 2; +} + +.photo-gallery .button-zoom { +display: inline-block; +font-size: 32px; +line-height: 50px; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transform: scale(0,0); + -moz-transform: scale(0,0); + -ms-transform: scale(0,0); + -o-transform: scale(0,0); + transform: scale(0,0); +z-index: 2; +} + +.photo-gallery .button-zoom::before { +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.photo-gallery .button-zoom:hover { +color: inherit; +} + +.photo-gallery:hover .button-zoom { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1,1); + -moz-transform: scale(1,1); + -ms-transform: scale(1,1); + -o-transform: scale(1,1); + transform: scale(1,1); +} + +.button-square { +position: relative; +display: inline-block; +width: 50px; +height: 50px; +line-height: 45px; +font-size: 25px; +text-align: center; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.button-square::before { +position: absolute; +content: ''; +width: 100%; +height: 100%; +left: 0; +top: 0; +-webkit-box-shadow: inset 0 0 0 25px #fff; + -moz-box-shadow: inset 0 0 0 25px #fff; + -ms-box-shadow: inset 0 0 0 25px #fff; + -o-box-shadow: inset 0 0 0 25px #fff; + box-shadow: inset 0 0 0 25px #fff; +-webkit-transform: scale(1, 1); + -moz-transform: scale(1, 1); + -ms-transform: scale(1, 1); + -o-transform: scale(1, 1); + transform: scale(1, 1); +z-index:-1; +} + +.button-square:hover::before { +-webkit-box-shadow: inset 0 0 0 2px #fff; + -moz-box-shadow: inset 0 0 0 2px #fff; + -ms-box-shadow: inset 0 0 0 2px #fff; + -o-box-shadow: inset 0 0 0 2px #fff; + box-shadow: inset 0 0 0 2px #fff; +-webkit-transform: scale(1.1, 1.1); + -moz-transform: scale(1.1, 1.1); + -ms-transform: scale(1.1, 1.1); + -o-transform: scale(1.1, 1.1); + transform: scale(1.1, 1.1); +} + +.photo-gallery .photo-container::before { +background: none; +} + +.photo-gallery .button-zoom { +color: #000; +} + +.photo-gallery .button-zoom:hover { +color: #fff; +} + +.photo-gallery:hover .photo-container::before { +background: rgba(0,0,0, .3); +} + +.button-square, +.button-square::before, +.photo-gallery .photo-container::before, +.photo-gallery .photo-container img { +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +} + +.centering-y { +position: absolute; +top: 50%; +display: inline-block; +-webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); +} + + +/* supersized */ +img { border: none; } +#supersized-loader { position: absolute; top: 50%; left: 50%; width: 60px; height: 60px; margin: -30px 0 0 -30px; text-indent: -999em; background: none; z-index: -1; } +#supersized { display: block; position: fixed; left: 0; top: 0; overflow: hidden; height: 100%; width: 100%; z-index: -999; } +#supersized img { width: auto; height: auto; position: relative; display: none; outline: none; border: none; } +#supersized.speed img { -ms-interpolation-mode: nearest-neighbor; image-rendering: -moz-crisp-edges; } /* Speed */ +#supersized.quality img { -ms-interpolation-mode: bicubic; image-rendering: optimizeQuality; } /* Quality */ +#supersized li { display: block; list-style: none; position: fixed; overflow: hidden; top: 0; left: 0; width: 100%; height: 100%; background: none; z-index: -30; } +#supersized a { width: 100%; height: 100%; display: block; } +#supersized li.prevslide { z-index: -20; } +#supersized li.activeslide { z-index: -10; } +#supersized li.image-loading { background: none; width: 100%; height: 100%; } +#supersized li.image-loading img { visibility: hidden; } +#supersized li.prevslide img, #supersized li.activeslide img { display: inline; } + + +/* kenburnsy */ +.kenburnsy { +position: relative; +width: 100%; +height: auto; +overflow: hidden; +} + +.kenburnsy.fullscreen { +position: fixed; +top: 0; +right: 0; +bottom: 0; +left: 0; +z-index: 0; +} + +.kenburnsy img { +display: none; +} + +.kenburnsy .slide { +position: absolute; +top: 0; +right: 0; +bottom: 0; +left: 0; +background-position: center center; +-webkit-background-size: cover; + background-size: cover; +background-repeat: no-repeat; +-webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +-webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; +} + +#kenburnsy-bg { +overflow: hidden; +} + + +/* YouTube video containment */ +#videoContainment { +position: fixed; +width: 100%; +height: 100%; +left: 0; +top: 0; +overflow: hidden; +} + + +/* HTML5 video containment */ +#video-bg { +position: fixed; +width: 100%; +height: 100%; +left: 0; +top: 0; +overflow: hidden; +} + + +/* lines */ +.lines-button{padding:2rem 1rem;transition:.3s;cursor:pointer;user-select:none;}.lines-button:hover{opacity:1}.lines-button:active{transition:0}.lines{display:inline-block;width:3rem;height:.3rem;background:#db0018;transition:.3s;position:relative}.lines:after,.lines:before{display:inline-block;width:3rem;height:.3rem;background:#db0018;transition:.3s;position:absolute;left:0;content:'';-webkit-transform-origin:.28571rem center;transform-origin:.28571rem center}.lines:before{top:0.8rem}.lines:after{top:-0.8rem}.lines-button.arrow.lines-close .lines:after,.lines-button.arrow.lines-close .lines:before{top:0;width:2.22222rem}.lines-button.arrow.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,40deg);transform:rotate3d(0,0,1,40deg)}.lines-button.arrow.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-40deg);transform:rotate3d(0,0,1,-40deg)}.lines-button.arrow-up.lines-close{-webkit-transform:scale3d(0.8,.8,.8) rotate3d(0,0,1,90deg);transform:scale3d(0.8,.8,.8) rotate3d(0,0,1,90deg)}.lines-button.minus.lines-close .lines:after,.lines-button.minus.lines-close .lines:before{-webkit-transform:none;transform:none;top:0;width:3rem}.lines-button.x.lines-close .lines{background:0 0}.lines-button.x.lines-close .lines:after,.lines-button.x.lines-close .lines:before{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;top:0;width:3rem}.lines-button.x.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}.lines-button.x.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)}.lines-button.x2 .lines{transition:background .3s .5s ease}.lines-button.x2 .lines:after,.lines-button.x2 .lines:before{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;transition:top .3s .6s ease,-webkit-transform .3s ease;transition:top .3s .6s ease,transform .3s ease}.lines-button.x2.lines-close .lines{transition:background .3s 0s ease;background:0 0}.lines-button.x2.lines-close .lines:after,.lines-button.x2.lines-close .lines:before{transition:top .3s ease,-webkit-transform .3s .5s ease;transition:top .3s ease,transform .3s .5s ease;top:0;width:3rem}.lines-button.x2.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}.lines-button.x2.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)} + + +/* wordsrotator */ +.wordsrotator_words{display:inline-block; position:relative; white-space:nowrap; -webkit-transition:width 1s; -moz-transition:width 1s; -o-transition:width 1s; transition:width 1s} +.wordsrotator_words .wordsrotator_wordOut, .wordsrotator_words .wordsrotator_wordIn{position:relative; display:inline-block; -webkit-animation-duration:1s; -webkit-animation-timing-function:ease; -webkit-animation-fill-mode:both; -moz-animation-duration:1s; -moz-animation-timing-function:ease; -moz-animation-fill-mode:both; -ms-animation-duration:1s; -ms-animation-timing-function:ease; -ms-animation-fill-mode:both} +.wordsrotator_words .wordsrotator_wordOut{left:0; top:0; position:absolute; display:inline-block} +.wordsrotator_words .wordsrotator_wordOut span{width:auto; position:relative} +.wordsrotator_words .wordsrotator_wordIn{opacity:0} +#wordrotator { +overflow: hidden; +} + + +/* dialog */ +a:hover, a:focus { +color: #c94e50; +outline: none; +} + +button { +position: absolute; +left: 0; +top: 0; +padding: 10px 20px 10px 20px; +outline: none; +border: none; +color: #fff; +background: #000; +} + +.content { +max-width: 1000px; +padding: 0 1em; +margin: 0 auto; +text-align: center; +-webkit-touch-callout: none; +-webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.button-wrap { +padding: 0; +} + +button.trigger { +background: #c94e50; +color: #fff; +border: none; +} + +/* dialog */ +.dialog, +.dialog__overlay { +width: 100%; +height: 100%; +top: 0; +left: 0; +} + +.dialog { +position: fixed; +display: -webkit-flex; +display: flex; +-webkit-align-items: center; + align-items: center; +-webkit-justify-content: center; + justify-content: center; +pointer-events: none; +z-index: 999; +} + +.dialog__overlay { +position: absolute; +background: rgba(0,0,0,0.7); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.3s; + transition: opacity 0.3s; +-webkit-backface-visibility: hidden; +z-index: 10; +} + +.dialog--open .dialog__overlay { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +pointer-events: auto; +} + +.dialog__content { +position: relative; +width: 50%; +max-width: 560px; +min-width: 290px; +background: #fff; +padding: 4em; +text-align: center; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +z-index: 15; +} + +.dialog--open .dialog__content { +pointer-events: auto; +} + +.dialog p { +font-family: 'Dosis', sans-serif; +font-size: 15px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #000; +margin: 0 auto 40px auto; +} + +/* wilma */ +.dialog--open .dialog__overlay { +-webkit-transition-duration: 0.8s; + -moz-transition-duration: 0.8s; + -ms-transition-duration: 0.8s; + -o-transition-duration: 0.8s; + transition-duration: 0.8s; +} + +.dialog--close .dialog__overlay { +-webkit-transition-duration: 0.5s; + -moz-transition-duration: 0.5s; + -ms-transition-duration: 0.5s; + -o-transition-duration: 0.5s; + transition-duration: 0.5s; +} + +.dialog__content { +padding: 0; +background: transparent; +} + +.dialog.dialog--open .dialog__content { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +.morph-shape { +position: absolute; +width: calc(100% + 4px); +height: calc(100% + 4px); +top: -2px; +left: -2px; +z-index: -1; +} + +.morph-shape svg rect { +stroke: #fff; +stroke-width: 2px; +stroke-dasharray: 1680; +} + +.dialog--open .morph-shape svg rect { +-webkit-animation: anim-dash 0.6s forwards; + -moz-animation: anim-dash 0.6s forwards; + -ms-animation: anim-dash 0.6s forwards; + -o-animation: anim-dash 0.6s forwards; + animation: anim-dash 0.6s forwards; +} + +.dialog-inner { +background: #fff; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.dialog--open .dialog-inner { +padding: 55px 0 15px 0; +-webkit-transition: opacity 0.85s 0.35s; + -moz-transition: opacity 0.85s 0.35s; + -ms-transition: opacity 0.85s 0.35s; + -o-transition: opacity 0.85s 0.35s; + transition: opacity 0.85s 0.35s; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + + +.dialog.dialog--open h5 { +-webkit-animation: anim-elem-1 0.7s ease-out both; + -moz-animation: anim-elem-1 0.7s ease-out both; + -ms-animation: anim-elem-1 0.7s ease-out both; + -o-animation: anim-elem-1 0.7s ease-out both; + animation: anim-elem-1 0.7s ease-out both; +} + +.dialog.dialog--open p { +-webkit-animation: anim-elem-2 0.7s ease-out both; + -moz-animation: anim-elem-2 0.7s ease-out both; + -ms-animation: anim-elem-2 0.7s ease-out both; + -o-animation: anim-elem-2 0.7s ease-out both; + animation: anim-elem-2 0.7s ease-out both; +} + +@keyframes anim-dash { + 0% { + stroke-dashoffset: 1680; + } + 100% { + stroke-dashoffset: 0; + } +} + +@-webkit-keyframes anim-dash { + 0% { + stroke-dashoffset: 1680; + } + 100% { + stroke-dashoffset: 0; + } +} + +/* inner elements animations */ +@-webkit-keyframes anim-elem-1 { + 0% { opacity: 0; -webkit-transform: translate3d(-150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); } +} + +@keyframes anim-elem-1 { + 0% { opacity: 0; -webkit-transform: translate3d(-150px, 0, 0); transform: translate3d(-150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } +} + +@-webkit-keyframes anim-elem-2 { + 0% { opacity: 0; -webkit-transform: translate3d(150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); } +} + +@keyframes anim-elem-2 { + 0% { opacity: 0; -webkit-transform: translate3d(150px, 0, 0); transform: translate3d(150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } +} + + +/* core owlCarousel */ +/* Core Owl Carousel CSS File v1.3.3 */ +/* clearfix */ +.owl-carousel .owl-wrapper:after { +content: "."; +display: block; +clear: both; +visibility: hidden; +line-height: 0; +height: 0; +} + +/* display none until init */ +.owl-carousel { +position: relative; +display: none; +width: 100%; +-ms-touch-action: pan-y; +} + +.owl-carousel .owl-wrapper { +display: none; +position: relative; +-webkit-transform: translate3d(0px, 0px, 0px); + -moz-transform: translate3d(0px, 0px, 0px); + -ms-transform: translate3d(0px, 0px, 0px); + -o-transform: translate3d(0px, 0px, 0px); + transform: translate3d(0px, 0px, 0px); +} + +.owl-carousel .owl-wrapper-outer { +overflow: hidden; +position: relative; +width: 100%; +} + +.owl-carousel .owl-wrapper-outer.autoHeight { +-webkit-transition: height 500ms ease-in-out; + -moz-transition: height 500ms ease-in-out; + -ms-transition: height 500ms ease-in-out; + -o-transition: height 500ms ease-in-out; + transition: height 500ms ease-in-out; +} + +.owl-carousel .owl-item { +float: left; +} + +.owl-controls .owl-page, +.owl-controls .owl-buttons div { +cursor: pointer; +} + +.owl-controls { +-webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +-webkit-tap-highlight-color: rgba(0,0,0, 0); +} + +/* mouse grab icon */ +.grabbing { +cursor: url(../img/grabbing.png) 8 8, move; +} + +/* fix */ +.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); + -o-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +} + + +/* core magnificPopup */ +/* Magnific Popup CSS */ +.mfp-bg,.mfp-wrap{left:0;top:0;position:fixed}.mfp-bg,.mfp-container,.mfp-wrap{width:100%;height:100%}.mfp-bg{z-index:1042;overflow:hidden;background:#0b0b0b;opacity:.9;filter:alpha(opacity=90)}.mfp-wrap{z-index:1043;outline:0!important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;left:0;top:0;padding:0 8px;box-sizing:border-box}.mfp-container,img.mfp-img{-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder{cursor:crosshair}.mfp-close,.mfp-zoom{cursor:pointer}.mfp-zoom{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-arrow,.mfp-close,.mfp-counter,.mfp-preloader{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none!important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-close,.mfp-close-btn-in .mfp-close{color:#fff}.mfp-s-error .mfp-content,.mfp-s-ready .mfp-preloader{display:none}button.mfp-arrow,button.mfp-close{overflow:visible;cursor:pointer;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;-webkit-box-shadow:none;box-shadow:none}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:60px!important;height:60px!important;display:block;position:absolute;right:-60px;top:40px;text-decoration:none;text-align:center!important;padding:0;font-style:normal;font-size:24px;font-weight:300;background:#000;line-height:54px}button.mfp-close{background:#000;line-height:10px;opacity:.8}.mfp-close:hover{opacity:1}.mfp-iframe-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-arrow,.mfp-counter{background:#000;opacity:.5;bottom:4px;width:60px;height:60px;text-align:center}.mfp-arrow:before,.mfp-counter{position:absolute;display:block;color:#fff}.mfp-counter{right:60px;font-size:12px;line-height:60px;white-space:nowrap;left:60px}.mfp-figure,img.mfp-img{line-height:0}.mfp-arrow{position:absolute;margin:0;padding:0;-webkit-tap-highlight-color:transparent}.mfp-arrow:focus,.mfp-arrow:hover{opacity:1}.mfp-arrow:before{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:30px;margin-left:-1px;margin-top:-1px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%)}.mfp-arrow-left{right:0;top:-64px;position:absolute}.mfp-arrow-left::before{content:"\f104"}.mfp-arrow-right{left:120px;top:-64px;position:absolute}.mfp-arrow-right::before{content:"\f105"}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-image-holder .mfp-content,img.mfp-img{max-width:100%}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,.6);background:#000}.mfp-figure:after,img.mfp-img{display:block;width:auto;height:auto}img.mfp-img{box-sizing:border-box;padding:40px 0;margin:0 auto}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;right:0;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,.6);background:#444}.mfp-figure small{color:#BDBDBD;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#F3F3F3;word-wrap:break-word;padding-right:36px}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,.6);position:fixed;text-align:center;padding:0}}.mfp-ie7 .mfp-img{padding:0}.mfp-ie7 .mfp-bottom-bar{width:600px;left:50%;margin-left:-300px;margin-top:5px;padding-bottom:5px}.mfp-ie7 .mfp-container{padding:0}.mfp-ie7 .mfp-content{padding-top:44px}.mfp-ie7 .mfp-close{top:0;right:0;padding-top:0}.mfp-with-zoom .mfp-container,.mfp-with-zoom.mfp-bg{opacity:0;-webkit-backface-visibility:hidden;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.mfp-with-zoom.mfp-ready .mfp-container{opacity:1}.mfp-with-zoom.mfp-ready.mfp-bg{opacity:.9}.mfp-with-zoom.mfp-removing .mfp-container,.mfp-with-zoom.mfp-removing.mfp-bg{opacity:0}.mfp-fade.mfp-bg{opacity:0;transition:all .3s ease-out}.mfp-fade.mfp-bg,.mfp-fade.mfp-wrap .mfp-content{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out}.mfp-fade.mfp-bg.mfp-ready{opacity:.9}.mfp-fade.mfp-bg.mfp-removing{opacity:0}.mfp-fade.mfp-wrap .mfp-content{opacity:0;transition:all .3s ease-out}.mfp-fade.mfp-wrap.mfp-ready .mfp-content{opacity:1}.mfp-fade.mfp-wrap.mfp-removing .mfp-content{opacity:0}@media all and (max-width:1199px){.mfp-close{right:0;top:40px}} + + +/* animate */ +/*!Animate.css - http://daneden.me/animate Licensed under the MIT license -http://opensource.org/licenses/MIT Copyright (c) 2015 Daniel Eden*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut{-webkit-animation-duration:.75s;animation-duration:.75s}.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,20%,53%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,0.75,1);transform:scale3d(1.25,0.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,0.85,1);transform:scale3d(1.15,0.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,0.75,1);transform:scale3d(1.25,0.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,0.85,1);transform:scale3d(1.15,0.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{11.1%{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-0.78125deg) skewY(-0.78125deg);transform:skewX(-0.78125deg) skewY(-0.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-0.1953125deg) skewY(-0.1953125deg);transform:skewX(-0.1953125deg) skewY(-0.1953125deg)}100%{-webkit-transform:none;transform:none}}@keyframes jello{11.1%{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-0.78125deg) skewY(-0.78125deg);transform:skewX(-0.78125deg) skewY(-0.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-0.1953125deg) skewY(-0.1953125deg);transform:skewX(-0.1953125deg) skewY(-0.1953125deg)}100%{-webkit-transform:none;transform:none}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} + + +/* media queries */ +/* 880px */ +@media only screen and (max-width: 880px) { + +/* navigation */ +#main-menu { +width: 400px; +left: -660px; +top: -400px; +} + +/* skills */ +.contentOT { +padding: 40px 10px 68px 10px; +} + +/* owlCarousel */ +.services-gallery { +margin: 54px 0 6px 0; +} + +/* clouds */ +.clouds { +height: 200%; +top: -250px; +} + +.cloud-1 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-2 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-3 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +/* photos */ +.photos-section .photos-container { +-webkit-column-count: 2; + -moz-column-count: 2; + column-count: 2; +} + +} + + +/* 640px */ +@media only screen and (max-width: 640px) { + +/* layout */ +h1 { +/* font-size: 60px; */ +font-size: 57px; +margin: 37px auto 34px auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +h2 { +/* font-size: 60px; */ +font-size: 57px; +} + +h6 { +margin: 45px auto 0 auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +.decoration { +margin: 0 auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +.decoration-left { +width: 3%; +} + +.decoration-right { +width: 3%; +} + +.decoration-2 { +margin: 34px auto 44px auto; +} + +.decoration-left-2 { +width: 3%; +} + +.decoration-right-2 { +width: 3%; +} + +/* navigation */ +.menu-toggle { +position: absolute; +} + +#main-menu { +width: 280px; +height: 100%; +left: -280px; +top: 0; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +#main-menu.activated { +left: 108px; +} + +#main-menu .credits { +font-size: 12px; +margin: 28px 0 0 -14px; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +/* link style */ +.link { +font-size: 40px; +width: 206px; +} + +/* frame */ +.line { +visibility: hidden; +display: none; +} + +/* skills */ +.contentOT { +padding: 40px 10px 68px 10px; +} + +/* countdown */ +#countdown-wrapper { +margin: -13px auto -6px auto; +width: auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +ul#countdown li { +width: 90px; +} + +ul#countdown li span { +font-size: 50px; +} + +ul#countdown li span.seconds { +font-size: 35px; +} + +ul#countdown li span.seconds { +padding: 0 0 0 20px; +} + +ul#countdown li p.timeRefDays, +ul#countdown li p.timeRefHours, +ul#countdown li p.timeRefMinutes { +padding: 0 0 0 3px; +} + +ul#countdown li p.timeRefSeconds { +padding: 0 0 0 18px; +} + +/* social icons */ +.social-icons-wrapper { +margin: 0 auto 13px auto; +} + +/* center container */ +.center-container-home { +position: relative; +display: block; +} + +.center-block-home { +display: block; +} + +.center-container { +position: relative; +display: block; +} + +.center-container-videos { +position: relative; +display: block; +} + +.center-block { +display: block; +} + +/* owlCarousel */ +.services-gallery { +margin: 54px 0 6px 0; +} + +/* clouds */ +.clouds { +height: 200%; +top: -250px; +} + +.cloud-1 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-2 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-3 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +/* photos */ +.photos-section .photos-container { +margin: 16px auto 10px auto; +-webkit-column-count: 1; + -moz-column-count: 1; + column-count: 1; +} + +} + + +/* landscape */ +@media only screen and (max-width: 640px) and (orientation: landscape) { + +/* slides */ +#slidePositionIndicator { +display: none; +visibility: hidden; +} + +/* clouds */ +.clouds { +height: 300%; +} + +} + + +/* 480px */ +@media only screen and (max-width: 480px) { +} \ No newline at end of file diff --git a/static/css/style-light.css b/static/css/style-light.css new file mode 100644 index 0000000..17d6cfb --- /dev/null +++ b/static/css/style-light.css @@ -0,0 +1,3334 @@ +@charset "utf-8"; +/* CSS Document */ + + +/* + reset + layout + navigation + link style + brackets + preload + frame + skills + countdown + social icons + contact form + newsletter form + center container + owlCarousel + curtains + film grain + weather + snow + particles + clouds + photos + supersized + kenburnsy + YouTube video containment + HTML5 video containment + lines + wordsrotator + dialog + core owlCarousel + core magnificPopup + animate + media queries +*/ + + +/* reset */ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { +margin: 0; +padding: 0; +border: 0; +font-size: 100%; +font: inherit; +vertical-align: baseline; +} + +html, body { +height: 100%; +} + +body { +line-height: 1; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { +display: block; +} + +ol, ul { +list-style: none; +} + +blockquote, q { +quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after { +content: ''; +content: none; +} + +table { +border-collapse: collapse; +border-spacing: 0; +} + +*:focus { +outline: none; +} + +/* remove dotted outline from links, button and input element */ +a:focus, a:active, +button::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner { +border: 0; +outline: 0; +} + + +/* layout */ +body { +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +color: #000; +background: #fff; + -webkit-font-smoothing: antialiased; +-moz-osx-font-smoothing: grayscale; +-webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +width: 100%; +height: 100%; +} + +a { +color: #db0018; +text-decoration: none; +outline: none; +} + +a:hover { +color: #000; +text-decoration: none; +} + +p a { +text-decoration: none; +outline: none; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +p a:hover { +color: #000; +text-decoration: none; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +::-moz-selection { background: #555; color: #fff; /* Firefox */ } + ::selection { background: #555; color: #fff; /* Safari */ } + + +.upper-page { +min-height: 100%; +margin: 0; +padding: 0; +background: none; +} + +.upper-content { +margin: 0 auto; +padding: 0; +} + +.lower-page { +min-height: 100%; +margin: 0; +padding: 0; +} + +.lower-content { +margin: 0 auto; +padding: 138px 0 38px 0; +} + +.lower-content p { +padding: 10px; +color: #000; +text-align: center; +} + +.sections { +position: relative; +z-index: 10; +text-align: center; +} + +#about, #services, #photos, #contact { +display: none; +} + +#intro-wrapper { +position: relative; +width: 100%; +height: auto; +overflow: hidden; +margin: 0 auto; +padding: 0; +} + +.intro-spacer { +position: relative; +width: 100%; +height: 100px; +margin: 0 auto; +} + +.intro-spacer-2 { +position: relative; +width: 100%; +height: 50px; +margin: 0 auto; +} + +h1 { +font-family: 'Oswald', sans-serif; +font-size: 90px; +font-weight: 700; +line-height: .9; +letter-spacing: -0.04em; +color: #000; +margin: 160px auto 50px auto; +text-align: center; +text-transform: uppercase; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.highlighter { +color: #db0018; +line-height: 1.2; +} + +h2 { +font-family: 'Oswald', sans-serif; +font-size: 70px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #000; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +} + +h3 { +font-family: 'Oswald', sans-serif; +font-size: 30px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #db0018; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +} + +h4 { +font-family: 'Oswald', sans-serif; +font-size: 30px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #db0018; +margin: 60px auto 15px auto; +text-align: center; +text-transform: uppercase; +} + +h5 { +font-family: 'Montserrat', sans-serif; +font-size: 30px; +font-weight: 700; +line-height: 1; +letter-spacing: -0.08em; +color: #c5c2b8; +margin: 0; +text-align: center; +text-transform: uppercase; +} + +h6 { +font-family: 'Oswald', sans-serif; +font-size: 23px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #000; +margin: 0 auto; +text-align: center; +text-transform: uppercase; +-webkit-transform: rotate(60deg); + -moz-transform: rotate(60deg); + -ms-transform: rotate(60deg); + -o-transform: rotate(60deg); + transform: rotate(60deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.divider { +margin: 20px auto 40px auto; +} + +.decoration { +position: relative; +margin: 0 auto; +text-align: center; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +.decoration-left { +width: 6%; +height: 1px; +background: #000; +margin: 0 119px 10px 0; +position: relative; +display: inline-block; +} + +.decoration-right { +width: 6%; +height: 1px; +background: #000; +margin: 0 0 10px 119px; +position: relative; +display: inline-block; +} + +.decoration-effect { +position: absolute; +font-family: 'Oswald', sans-serif; +font-size: 17px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 300; +letter-spacing: 1px; +background: none; +width: 202px; +height: 61px; +padding: 17px 0 0 0; +margin-left: -101px; +left: 50%; +top: -25px; +z-index: 0; +} + +.decoration-effect a, .decoration-effect a:hover { +color: #000; +text-decoration: none; +} + +.effect-bubba::before, +.effect-bubba::after { +width: 180px; +height: 39px; +position: absolute; +top: 10px; +right: 10px; +bottom: 10px; +left: 10px; +content: ''; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.35s, -webkit-transform 0.35s; + transition: opacity 0.35s, transform 0.35s; +} + +.effect-bubba::before { +border-top: 1px solid #000; +border-bottom: 1px solid #000; +-webkit-transform: scale(0,1); + -moz-transform: scale(0,1); + -ms-transform: scale(0,1); + -o-transform: scale(0,1); + transform: scale(0,1); +} + +.effect-bubba::after { +border-left: 1px solid #000; +border-right: 1px solid #000; +-webkit-transform: scale(1,0); + -moz-transform: scale(1,0); + -ms-transform: scale(1,0); + -o-transform: scale(1,0); + transform: scale(1,0); +} + +.effect-bubba:hover::before, +.effect-bubba:hover::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.decoration-2 { +position: relative; +margin: 49px auto 74px auto; +text-align: center; +} + +.decoration-left-2 { +width: 6%; +height: 1px; +background: #000; +margin: 0 119px 10px 0; +position: relative; +display: inline-block; +} + +.decoration-right-2 { +width: 6%; +height: 1px; +background: #000; +margin: 0 0 10px 119px; +position: relative; +display: inline-block; +} + +.decoration-effect-2 { +position: absolute; +font-family: 'Dosis', sans-serif; +font-size: 17px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +background: none; +width: 202px; +height: 61px; +padding: 17px 0 0 0; +margin-left: -101px; +left: 50%; +top: -25px; +z-index: 0; +} + +.decoration-effect-2 a, .decoration-effect-2 a:hover { +color: #000; +text-decoration: none; +} + +.effect-bubba-2::before, +.effect-bubba-2::after { +width: 180px; +height: 39px; +position: absolute; +top: 10px; +right: 10px; +bottom: 10px; +left: 10px; +content: ''; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.35s, -webkit-transform 0.35s; + transition: opacity 0.35s, transform 0.35s; +} + +.effect-bubba-2::before { +border-top: 1px solid #000; +border-bottom: 1px solid #000; +-webkit-transform: scale(0,1); + -moz-transform: scale(0,1); + -ms-transform: scale(0,1); + -o-transform: scale(0,1); + transform: scale(0,1); +} + +.effect-bubba-2::after { +border-left: 1px solid #000; +border-right: 1px solid #000; +-webkit-transform: scale(1,0); + -moz-transform: scale(1,0); + -ms-transform: scale(1,0); + -o-transform: scale(1,0); + transform: scale(1,0); +} + +.effect-bubba-2:hover::before, +.effect-bubba-2:hover::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.quote { +margin: 0 auto; +} + +.quote p { +font-family: 'Raleway',sans-serif; +font-size: 18px; +line-height: 1.5; +font-style: italic; +font-weight: normal; +text-align: center; +color: #000; +font-weight: 400; +letter-spacing: 1px; +} + +.quote-mark-l { +color: #000; +padding: 0 10px 0 0; +} + +.quote-mark-r { +color: #000; +padding: 0 0 0 10px; +} + +.awesome { +color: #000; +margin: 20px auto; +text-align: center; +display: block; +} + + +/* navigation */ +.menu-toggle { +position: fixed; +display: block; +top: 2px; +left: 14px; +width: 80px; +height: 80px; +padding: 0; +background: none; +line-height: 1; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +z-index: 999; +} + +#main-menu { +position: fixed; +font-family: 'Oswald', sans-serif; +font-style: normal; +text-transform: uppercase; +font-weight: 400; +letter-spacing: 1px; +line-height: 1; +width: 400px; +height: 200%; +left: -760px; +top: -460px; +margin: auto; +background: #fff; +-webkit-transition: left .4s ease-in-out; + -moz-transition: left .4s ease-in-out; + -ms-transition: left .4s ease-in-out; + -o-transition: left .4s ease-in-out; + transition: left .4s ease-in-out; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +z-index: 998; +} + +#main-menu.activated { +left: 98px; +} + +#main-menu ul { +list-style: none outside none; +padding: 0 0 0 37px; +} + +#main-menu ul li { +text-align: left; +line-height: .75; +} + +#main-menu .credits { +font-size: 14px; +line-height: 1; +margin: 15px 0 0 9px; +-webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +-webkit-transform-origin: left; + -moz-transform-origin: left; + -ms-transform-origin: left; + -o-transform-origin: left; + transform-origin: left; +} + +#main-menu .credits a { +color: #444; +text-decoration: none; +} + +#main-menu a { +display: none; +min-width: 10px; +color: #c5c2b8; +text-decoration: none; +-webkit-transition: color .8s ease-in-out; + -moz-transition: color .8s ease-in-out; + -ms-transition: color .8s ease-in-out; + -o-transition: color .8s ease-in-out; + transition: color .8s ease-in-out; +} + +#main-menu li .active { +color: #000; +} + +.menu-nav-wrapper { +display: table; +width: 100%; +height: 100%; +} + +.menu-nav { +display: table-cell; +width: 100%; +height: 100%; +vertical-align: middle; +} + + +/* link style */ +.link { +position: relative; +outline: none; +text-decoration: none; +font-size: 50px; +line-height: 1; +display: inline-block; +width: 326px; +} + +.link--kukuri { +overflow: hidden; +line-height: 1; +} + +.link--kukuri::after { +content: ''; +position: absolute; +height: 16px; +width: 100%; +top: 50%; +margin-top: -8px; +right: 0; +background: #c5c2b8; +-webkit-transform: translate3d(-100%,0,0); + -moz-transform: translate3d(-100%,0,0); + -ms-transform: translate3d(-100%,0,0); + -o-transform: translate3d(-100%,0,0); + transform: translate3d(-100%,0,0); +-webkit-transition: -webkit-transform 0.4s; + transition: transform 0.4s; +-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1); + transition-timing-function: cubic-bezier(0.7,0,0.3,1); +} + +.link--kukuri:hover::after { +-webkit-transform: translate3d(100%,0,0); + -moz-transform: translate3d(100%,0,0); + -ms-transform: translate3d(100%,0,0); + -o-transform: translate3d(100%,0,0); + transform: translate3d(100%,0,0); +} + +.link--kukuri::before { +position: absolute; +content: attr(data-letters); +z-index: 2; +overflow: hidden; +color: #000; +white-space: nowrap; +width: 0%; +-webkit-transition: width 0.6s 0.3s; + -moz-transition: width 0.6s 0.3s; + -ms-transition: width 0.6s 0.3s; + -o-transition: width 0.6s 0.3s; + transition: width 0.6s 0.3s; +} + +.link--kukuri:hover::before { +width: 100%; +} + + +/* brackets */ +.brackets a::before, +.brackets a::after { +display: inline-block; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: -webkit-transform 0.3s, opacity 0.2s; + -moz-transition: -moz-transform 0.3s, opacity 0.2s; + -ms-transition: -ms-transform 0.3s, opacity 0.2s; + -o-transition: -o-transform 0.3s, opacity 0.2s; + transition: transform 0.3s, opacity 0.2s; +} + +.brackets a::before { +content: '['; +margin-right: 10px; +-webkit-transform: translateX(20px); + -moz-transform: translateX(20px); + -ms-transform: translateX(20px); + -o-transform: translateX(20px); + transform: translateX(20px); +} + +.brackets a::after { +content: ']'; +margin-left: 10px; +-webkit-transform: translateX(-20px); + -moz-transform: translateX(-20px); + -ms-transform: translateX(-20px); + -o-transform: translateX(-20px); + transform: translateX(-20px); +} + +.brackets a:hover::before, +.brackets a:hover::after, +.brackets a:focus::before, +.brackets a:focus::after { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: translateX(0px); + -moz-transform: translateX(0px); + -ms-transform: translateX(0px); + -o-transform: translateX(0px); + transform: translateX(0px); +} + +.brackets ul, li { +list-style: none; +} + +.brackets a { +color: #db0018; +text-decoration: none; +} + +.brackets a:hover { +color: #db0018; +text-decoration: none; +} + +.brackets a:visited { +color: #db0018; +text-decoration: none; +} + + +/* preload */ +#preload { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +right: 0; +bottom: 0; +background: #fff; +display: none; +z-index: 10000; +} + +#preload-status { +position: absolute; +width: 40px; +height: 40px; +margin: auto; +padding: 0; +top: 0; +right: 0; +bottom: 0; +left: 0; +display: block; +background: #000; +border-radius: 100%; +-webkit-animation: scaleout 1.0s infinite ease-in-out; + -moz-animation: scaleout 1.0s infinite ease-in-out; + -ms-animation: scaleout 1.0s infinite ease-in-out; + -o-animation: scaleout 1.0s infinite ease-in-out; + animation: scaleout 1.0s infinite ease-in-out; +} + +@-webkit-keyframes scaleout { + 0% { + -webkit-transform: scale(0.0); + -ms-transform: scale(0.0); + transform: scale(0.0); + } + + 100% { + -webkit-transform: scale(1.0); + -ms-transform: scale(1.0); + transform: scale(1.0); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + } +} + +@keyframes scaleout { + 0% { + -webkit-transform: scale(0.0); + -ms-transform: scale(0.0); + transform: scale(0.0); + } + + 100% { + -webkit-transform: scale(1.0); + -ms-transform: scale(1.0); + transform: scale(1.0); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + } +} + +#preload-status { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + + +/* frame */ +#site-wrapper { +position: relative; +min-width: 100%; +min-height: 100%; +overflow: hidden; +} + +.line { +position: fixed; +display: block; +-webkit-transform: translate3d(0,0,0); + -moz-transform: translate3d(0,0,0); + -ms-transform: translate3d(0,0,0); + -o-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +background: #000; +-webkit-transform: rotate(-30deg); + -moz-transform: rotate(-30deg); + -ms-transform: rotate(-30deg); + -o-transform: rotate(-30deg); + transform: rotate(-30deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +z-index: -1; +} + +.line.line-top { +top: 10px; +left: 10px; +width: 50%; +height: 2px; +-webkit-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -moz-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -ms-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -o-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + transition: width 800ms cubic-bezier(.55,.055,.675,.19); +} + +.line.line-right { +top: 10px; +right: 10px; +width: 2px; +height: 50%; +-webkit-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -moz-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -ms-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -o-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; +} + +.line.line-bottom { +right: 10px; +bottom: 10px; +width: 50%; +height: 2px; +-webkit-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -moz-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -ms-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + -o-transition: width 800ms cubic-bezier(.55,.055,.675,.19); + transition: width 800ms cubic-bezier(.55,.055,.675,.19); +} + +.line.line-left { +bottom: 10px; +left: 10px; +width: 2px; +height: 50%; +-webkit-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -moz-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -ms-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + -o-transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; + transition: height 1000ms cubic-bezier(.215,.61,.355,1) 800ms; +} + +.site-opening #ui-layer { +-webkit-transition-delay: 0; + -moz-transition-delay: 0; + -ms-transition-delay: 0; + -o-transition-delay: 0; + transition-delay: 0; +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +#ui-layer { +position: relative; +min-width: 100%; +min-height: 100%; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +z-index: 6; +} + +body[class=page-top] #ui-layer { +/* +-webkit-transition: opacity 1000ms ease 1000ms, -webkit-transform 1000ms ease; + -moz-transition: opacity 1000ms ease 1000ms, -moz-transform 1000ms ease; + -o-transition: opacity 1000ms ease 1000ms, -o-transform 1000ms ease; + transition: opacity 1000ms ease 1000ms, transform 1000ms ease; +*/ +} + +.site-opening #bg-layer { +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +/* +-webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -ms-transform: scale(1.1); + -o-transform: scale(1.1); + transform: scale(1.1); +*/ +-webkit-transform: scale(1.4); + -moz-transform: scale(1.4); + -ms-transform: scale(1.4); + -o-transform: scale(1.4); + transform: scale(1.4); +} + +#bg-layer { +position: absolute; +top: 0; +left: 0; +width: 100%; +height: 100%; +-webkit-transform: scale3d(1); + -moz-transform: scale3d(1); + -ms-transform: scale3d(1); + -o-transform: scale3d(1); + transform: scale3d(1); + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +body[class=page-top] #bg-layer { +-webkit-transition: opacity 2000ms ease, -webkit-transform 2000ms ease; + -moz-transition: opacity 2000ms ease, -moz-transform 2000ms ease; + -ms-transition: opacity 2000ms ease, -ms-transform 2000ms ease; + -o-transition: opacity 2000ms ease, -o-transform 2000ms ease; + transition: opacity 2000ms ease, transform 2000ms ease; +} + +.page-top #bg-layer { +/* +background-image: url(../img/background/bg-layer.jpg); +background-position: 50% 0; +background-repeat: no-repeat; +background-size: cover; +*/ +} + +.main-image { +position: relative; +width: 100%; +height: 100%; +overflow-x: hidden; +overflow-y: auto; +} + +.site-opening .line { +-webkit-transition-duration: 0; + -moz-transition-duration: 0; + -ms-transition-duration: 0; + -o-transition-duration: 0; + transition-duration: 0; +} + +.site-opening .line-top { +width: 0; +} + +.site-opening .line-right { +height: 0; +} + +.site-opening .line-bottom { +width: 0; +} + +.site-opening .line-left { +height: 0; +} + + +/* skills */ +.contentOT { +font-family: 'Dosis', sans-serif; +font-size: 17px; +line-height: 1; +font-style: normal; +text-transform: uppercase; +text-align: left; +font-weight: 400; +letter-spacing: 1px; +position: relative; +width: 100%; +margin: 0; +padding: 40px 10px 0 10px; +float: left; +left: 0; +} + +.colOT { +position: relative; +width: 100%; +float: left; +left: 0; +} + +#skills { +list-style: none; +} + +#skills li { +background: #000; +height: 3px; +margin: 0 0 50px 0; +} + +#skills li.last { +background: #000; +height: 3px; +margin: 0; +} + +#skills li .skills-description { +position: relative; +top: -25px; +} + +.expand { +position: absolute; +height: 3px; +margin: 0; +background: #db0018; +} + +.html5 { +width: 70%; +-webkit-animation: html5 2s ease-out; + -moz-animation: html5 2s ease-out; + -ms-animation: html52s ease-out; + -o-animation: html5 2s ease-out; + animation: html5 2s ease-out; +} + +.css3 { +width: 90%; +-webkit-animation: css3 2s ease-out; + -moz-animation: css3 2s ease-out; + -ms-animation: css3 2s ease-out; + -o-animation: css3 2s ease-out; + animation: css3 2s ease-out; +} + +.jquery { +width: 50%; +-webkit-animation: jquery 2s ease-out; + -moz-animation: jquery 2s ease-out; + -ms-animation: jquery 2s ease-out; + -o-animation: jquery 2s ease-out; + animation: jquery 2s ease-out; +} + +.photoshop { +width: 30%; +-webkit-animation: photoshop 2s ease-out; + -moz-animation: photoshop 2s ease-out; + -ms-animation: photoshop 2s ease-out; + -o-animation: photoshop 2s ease-out; + animation: photoshop 2s ease-out; +} + +.dreamweaver { +width: 100%; +-webkit-animation: dreamweaver 2s ease-out; + -moz-animation: dreamweaver 2s ease-out; + -ms-animation: dreamweaver 2s ease-out; + -o-animation: dreamweaver 2s ease-out; + animation: dreamweaver 2s ease-out; +} + +@-moz-keyframes html5 { 0% { width:0px;} 100%{ width:70%;} } +@-moz-keyframes css3 { 0% { width:0px;} 100%{ width:90%;} } +@-moz-keyframes jquery { 0% { width:0px;} 100%{ width:50%;} } +@-moz-keyframes photoshop { 0% { width:0px;} 100%{ width:10%;} } +@-moz-keyframes dreamweaver { 0% { width:0px;} 100%{ width:100%;} } + +@-webkit-keyframes html5 { 0% { width:0px;} 100%{ width:70%;} } +@-webkit-keyframes css3 { 0% { width:0px;} 100%{ width:90%;} } +@-webkit-keyframes jquery { 0% { width:0px;} 100%{ width:50%;} } +@-webkit-keyframes photoshop { 0% { width:0px;} 100%{ width:10%;} } +@-webkit-keyframes dreamweaver { 0% { width:0px;} 100%{ width:100%;} } + + +/* countdown */ +#countdown-wrapper { +position: relative; +margin: 28px auto; +width: 400px; +-webkit-transform: rotate(60deg); + -moz-transform: rotate(60deg); + -ms-transform: rotate(60deg); + -o-transform: rotate(60deg); + transform: rotate(60deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +text-shadow: 1px 1px 2px #000; +} + +#countdown { +margin: 0; +padding: 0; +} + +ul#countdown li { +display: inline-block; +width: 115px; +} + +ul#countdown li span { +/* font-family: 'Montserrat', sans-serif; */ +font-family: 'Oswald', sans-serif; +font-size: 70px; +font-weight: 400; +line-height: 1; +letter-spacing: -0.04em; +color: #000; +text-align: center; +margin: 0; +padding: 0; +position: relative; +} + +ul#countdown li span.seconds { +/* font-family: 'Montserrat', sans-serif; */ +font-family: 'Oswald', sans-serif; +font-size: 55px; +font-weight: 400; +line-height: 1.1; +letter-spacing: -0.04em; +color: #db0018; +text-align: left; +margin: 0; +padding: 0 0 0 20px; +position: relative; +/* text-shadow: 1px 1px 2px #222; */ +} + +ul#countdown li span::before { +content: ''; +width: 100%; +height: 1px; +position: absolute; +} + +ul#countdown li p.timeRefDays, +ul#countdown li p.timeRefHours, +ul#countdown li p.timeRefMinutes { +/* font-family: 'Raleway', sans-serif; */ +font-family: 'Oswald', sans-serif; +color: #000; +text-transform: uppercase; +font-size: 16px; +font-style: normal; +font-weight: 300; +text-align: center; +margin: 0; +padding: 0 0 0 5px; +} + +ul#countdown li p.timeRefSeconds { +/* font-family: 'Raleway', sans-serif; */ +font-family: 'Oswald', sans-serif; +color: #000; +text-transform: uppercase; +font-size: 16px; +font-style: normal; +font-weight: 300; +text-align: center; +margin: 0; +padding: 0 0 0 24px; +} + + +/* social icons */ +.social-icons-wrapper { +position: relative; +margin: 0 auto; +text-align: center; +} + +.social-icons-wrapper ul { +margin: 0 auto; +padding: 0; +list-style-type: none; +} + +.social-icons-wrapper ul li { +display: inline-block; +margin: 0 auto; +padding: 0 0 0 5px; +} + +ul.social-icons { +font-size: 15px; +margin: 0; +padding: 0; +} + +ul.social-icons a { +padding: 0; +color: #000; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + +ul.social-icons a:hover { +padding: 0; +color: #000; + opacity: 0.3; + -moz-opacity: 0.3; +-webkit-opacity: 0.3; +filter: alpha(opacity=30); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; +-webkit-transition: all 0.5s linear; + -moz-transition: all 0.5s linear; + -ms-transition: all 0.5s linear; + -o-transition: all 0.5s linear; + transition: all 0.5s linear; +} + + +/* contact form */ +#contact-form { +width: 100%; +margin: 0; +text-align: center; +} + +form { +margin: 0; +padding: 0; +} + +input { +position: relative; +width: 100%; +height: 40px; +border-bottom: 1px solid #000; +border-left: none; +border-right: none; +border-top: none; +padding: 5px 5px; +background: none; +margin: 5px; +-webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +} + +#form input { +margin: 10px 0 10px 0; +} + +textarea { +position: relative; +width: 100%; +height: 100px; +border-bottom: 1px solid #000; +border-left: none; +border-right: none; +border-top: none; +padding: 5px 5px; +background: none; +margin: 5px; +-webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +} + +#form textarea { +margin: 10px 0 10px 0; +} + +input:hover, +textarea:hover { +border-color: rgba(0,0,0, .5); +} + +#form input:focus, +#form textarea:focus { +-webkit-animation: glow 900ms ease-out infinite alternate; + -moz-animation: glow 900ms ease-out infinite alternate; + -ms-animation: glow 900ms ease-out infinite alternate; + -o-animation: glow 900ms ease-out infinite alternate; + animation: glow 900ms ease-out infinite alternate; +} + +.success { +font-family: 'Montserrat', sans-serif; +font-size: 13px; +font-weight: 400; +font-style: normal; +text-transform: uppercase; +text-align: center; +color: #000; +margin: 0; +padding: 20px 0 0 0; +line-height: 1; +} + +#form .error { +position: absolute; +font-size: 10px; +text-transform: uppercase; +text-align: left; +color: #000; +display: block; +margin: -8px 0 0 1px; +padding: 0; +} + + +@-webkit-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(0,0,0, .2), inset 0 0 5px rgba(0,0,0, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(0,0,0, .6), inset 0 0 10px rgba(0,0,0, .4) + } +} +@-moz-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(0,0,0, .2), inset 0 0 5px rgba(0,0,0, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(0,0,0, .6), inset 0 0 10px rgba(0,0,0, .4) + } +} +@-o-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(0,0,0, .2), inset 0 0 5px rgba(0,0,0, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(0,0,0, .6), inset 0 0 10px rgba(0,0,0, .4) + } +} +@-ms-keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(0,0,0, .2), inset 0 0 5px rgba(0,0,0, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(0,0,0, .6), inset 0 0 10px rgba(0,0,0, .4) + } +} +@keyframes glow { + 0% { + border-color: #db0018; + box-shadow: 0 0 5px rgba(0,0,0, .2), inset 0 0 5px rgba(0,0,0, .1) + } + 100% { + border-color: #db0018; + box-shadow: 0 0 20px rgba(0,0,0, .6), inset 0 0 10px rgba(0,0,0, .4) + } +} + +::-webkit-input-placeholder { +font-style: italic; +color: #000; +} + +::-moz-placeholder { +font-style: italic; +color: #000; +} + +:-ms-input-placeholder { +font-style: italic; +color: #000; +} + +input:-moz-placeholder { +font-style: italic; +color: #000; +} + +.submit-button { +position: relative; +font-family: 'Dosis', sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #fff; +display: inline-block; +outline: none; +margin: 21px auto 0 auto; +width: 225px; +padding: 0; +height: 45px; +border: 1px solid #fff; +background: #fff; +overflow: hidden; +cursor: pointer; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +-webkit-transform: translate(0,0); + -moz-transform: translate(0,0); + -ms-transform: translate(0,0); + -o-transform: translate(0,0); + transform: translate(0,0); +} + +.submit-button::before { +position: absolute; +content: ''; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -100%; +bottom: 0%; +width: 200%; +height: 200%; +background: #000; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transform: skewX(-60deg); + -moz-transform: skewX(-60deg); + -ms-transform: skewX(-60deg); + -o-transform: skewX(-60deg); + transform: skewX(-60deg); +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +z-index: -1; +} + +.submit-button::before { +-webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -ms-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +.submit-button:hover { +color: #000; +} + +.submit-button:hover::before { +bottom: -100%; +right: -200%; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + + +/* newsletter form */ +#subscribe-wrapper { +margin: 0 auto 40px auto; +background: none; +width: 225px; +height: 70px; +position: relative; +z-index: 999; +} + +#newsletter { +width: auto; +height: 55px; +padding: 1px 0 0 0; +} + +.newsletter { +position: relative; +clear: both; +width: auto; +border: none; +background: none; +margin: -5px 0 0 0; +padding: 0; +overflow: hidden; +} + +#subscribe .mail { +display: none; +visibility: hidden; +} + +#subscribe input#subscribeemail { +font-family: 'Raleway',sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +font-weight: normal; +text-align: center; +color: #000; +width: 225px; +height: 28px; +margin: 0; +padding: 0; +border-top: none; +border-left: none; +border-right: none; +border-bottom: 1px solid #000; +} + +#subscribe input { +background: none; +} + +#subscribe input:focus, #subscribe textarea:focus { +color: #000; +background: none; +} + +.submit-button-2 { +position: relative; +font-family: 'Dosis', sans-serif; +font-size: 14px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #fff; +display: inline-block; +outline: none; +margin: 10px auto; +width: 225px; +padding: 0; +height: 45px; +border: none; +background: #000; +overflow: hidden; +cursor: pointer; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +-webkit-transform: translate(0,0); + -moz-transform: translate(0,0); + -ms-transform: translate(0,0); + -o-transform: translate(0,0); + transform: translate(0,0); +} + +.submit-button-2::before { +position: absolute; +content: ''; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -100%; +bottom: 0%; +width: 200%; +height: 200%; +background: #db0018; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +-webkit-transform: skewX(-60deg); + -moz-transform: skewX(-60deg); + -ms-transform: skewX(-60deg); + -o-transform: skewX(-60deg); + transform: skewX(-60deg); +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +z-index: -1; +} + +.submit-button-2::before { +-webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -ms-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; +} + +.submit-button-2:hover { +color: #fff; +background: #000; +} + +.submit-button-2:hover::before { +bottom: -100%; +right: -200%; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.subscribesuccess { +font-family: 'Montserrat', sans-serif; +font-size: 13px; +font-weight: 400; +font-style: normal; +text-transform: uppercase; +text-align: center; +color: #000; +margin: 0; +padding: 60px 0 0 0; +line-height: 1; +} + +#subscribe .subscribeerror { +font-size: 10px; +text-transform: uppercase; +text-align: center; +color: #000; +display: block; +margin: 0; +padding: 0; +} + + +/* center container */ +.center-container-home { +position: absolute; +display: table; +height: 100%; +width: 100%; +left: 0; +top: 0; +} + +.center-block-home { +display: table-cell; +vertical-align: middle; +} + +.center-container { +position: absolute; +display: table; +/* display: block; */ +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(225,225,225, .6); +} + +.center-container-videos { +position: absolute; +display: table; +/* display: block; */ +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(225,225,225, .4); +} + +.center-block { +display: table-cell; +/* display: block; */ +vertical-align: middle; +} + +.cover-all { +position: fixed; +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(225,225,225, .6); +z-index: 1; +} + +.cover-all-videos { +position: fixed; +height: 100%; +width: 100%; +left: 0; +top: 0; +background: rgba(255,255,255, .4); +z-index: 1; +} + + +/* owlCarousel */ +.owl-carousel { +overflow: hidden; +} + +.owl-buttons { +position: static; +} + +.owl-prev, +.owl-next { +position: absolute; +display: block; +top: 50%; +margin-top: -50px; +width: 105px; +height: 105px; +line-height: 105px; +font-size: 30px; +text-align: center; +color: #000; +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +z-index: 6; +} + +.owl-prev { +left: -50px; +} + +.owl-next { +right: -50px; +} + +.owl-prev:before, +.owl-next:before { +content: ""; +display: block; +width: 66%; +height: 66%; +position: absolute; +left: 0; +top: 17px; +background: none; +/* +-webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +-webkit-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + -moz-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + box-shadow: 1px 1px 0px rgba(0,0,0, .1); +-webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +*/ +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); +} + +.owl-next:before { +left: auto; +right: 0; +} + +.owl-prev .fa, +.owl-next .fa { +position: relative; +} + +.owl-prev:hover, +.owl-next:hover { +-webkit-transition: 0 none !important; + -moz-transition: 0 none !important; + -ms-transition: 0 none !important; + -o-transition: 0 none !important; + transition: 0 none !important; +} + +.owl-prev:hover:before, +.owl-next:hover:before { + opacity: 0.8; + -moz-opacity: 0.8; +-webkit-opacity: 0.8; +filter: alpha(opacity=80); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; +} + +.owl-prev:active:before, +.owl-next:active:before { + opacity: 0.6; + -moz-opacity: 0.6; +-webkit-opacity: 0.6; +filter: alpha(opacity=60); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; +} + +.owl-carousel:hover .owl-prev { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +left: -35px; +} + +.owl-carousel:hover .owl-next { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +right: -35px; +} + +.owl-pagination { +display: block; +width: 100%; +height: auto; +position: absolute; +bottom: 20px; +left: 0; +text-align: center; +} + +.owl-page { +position: relative; +display: inline-block; +padding: 6px 4px; +} + +.owl-page span { +width: 15px; +height: 2px; +display: block; +background: rgba(0,0,0, .7); +position: relative; +/* +-webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +*/ +-webkit-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + -moz-box-shadow: 1px 1px 0px rgba(0,0,0, .1); + box-shadow: 1px 1px 0px rgba(0,0,0, .1); +-webkit-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -moz-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -ms-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + -o-transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); + transition: all 0.27s cubic-bezier(0.000, 0.000, 0.580, 1.000); +z-index: 1000 !important; +} + +.owl-page:hover span { +background: rgba(0,0,0, 1); +} + +.owl-page.active span { +background: #db0018; +-webkit-transform: scale(1.3333333); + -moz-transform: scale(1.3333333); + -ms-transform: scale(1.3333333); + -o-transform: scale(1.3333333); + transform: scale(1.3333333); +} + +.services-gallery { +margin: 16px 0 0 0; +} + +.services-gallery img { +max-width: 100%; +height: auto; +} + + +/* curtains */ +#curtains { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +/* background: url(../img/curtains.png) repeat top left; */ +z-index: 1; +} + + +/* film grain */ +#film-grain { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +background: url(../img/film-grain.gif) repeat top left; + opacity: 0.1; + -moz-opacity: 0.1; +-webkit-opacity: 0.1; +filter: alpha(opacity=10); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; +z-index: 5; +} + + +/* weather */ +/* main element */ +.weather { +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +z-index: 5; +} + +/* pseudo elements: positioning and setup */ +.weather:before, .weather:after { +content: ""; +position: absolute; +left: -60%; +top: -60%; +right: -60%; +bottom: -60%; +pointer-events: none; +background: transparent repeat; +-webkit-transform: rotate(-40deg); + -moz-transform: rotate(-40deg); + -ms-transform: rotate(-40deg); + -o-transform: rotate(-40deg); + transform: rotate(-40deg); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +-webkit-animation-timing-function: linear; +-webkit-animation-iteration-count: infinite; +-webkit-animation-name: weather; + animation-name: weather; +animation-timing-function: linear; +animation-iteration-count: infinite; +z-index: 1; +} + +.weather:after { +-webkit-animation-name: weather2; + animation-name: weather2; +} + +/* rain */ +.weather.rain:before, .weather.rain:after { +background: url(../img/rain.png) left top; + opacity: 0.6; + -moz-opacity: 0.6; +-webkit-opacity: 0.6; +filter: alpha(opacity=60); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; +-webkit-animation-duration: 2s; + animation-duration: 2s; +} + +.weather.rain:after { +-webkit-animation-duration: 1.5s; + animation-duration: 1.5s; +} + +/* animation keyframes */ +@-webkit-keyframes weather { + from { background-position: 0 0px; } + to { background-position: 0 1024px; } +} +@keyframes weather { + from { background-position: 0 0px; } + to { background-position: 0 1024px; } +} +@-webkit-keyframes weather2 { + from { background-position: 64px 64px; } + to { background-position: 64px 1088px; } +} +@keyframes weather2 { + from { background-position: 64px 64px; } + to { background-position: 64px 1088px; } +} + + +/* snow */ +#snow { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +left: 0; +top: 0; +z-index: 5; +} + + +/* particles */ +#particles-holder { +position: absolute; +top: 0; +left: 0; +width: 100%; +height: 100%!important; +overflow: hidden; +z-index: 5; +} + +#particles-js { +width: 100%; +height: 100%; +overflow: hidden; +background: none; +} + +@media only screen and (max-width: 640px) { + #particles-holder, + #particles-js { + display: none; + visibility: hidden; + } +} + + +/* clouds */ +.clouds { +position: fixed; +width: 100%; +height: 100%; +overflow: hidden; +background: none; +top: 0; +z-index: 5; +} + +.cloud-1 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-1.png); +background-repeat: repeat-x; +-webkit-animation: cloud-1 50s linear infinite; + -moz-animation: cloud-1 50s linear infinite; + -ms-animation: cloud-1 50s linear infinite; + -o-animation: cloud-1 50s linear infinite; + animation: cloud-1 50s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +.cloud-2 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-2.png); +background-repeat: repeat-x; +-webkit-animation: cloud-2 90s linear infinite; + -moz-animation: cloud-2 90s linear infinite; + -ms-animation: cloud-2 90s linear infinite; + -o-animation: cloud-2 90s linear infinite; + animation: cloud-2 90s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +.cloud-3 { +position: absolute; +left: 0; +top: 0; +width: 300%; +height: 100%; +background-image: url(../img/cloud-3.png); +background-repeat: repeat-x; +-webkit-animation: cloud-3 70s linear infinite; + -moz-animation: cloud-3 70s linear infinite; + -ms-animation: cloud-3 70s linear infinite; + -o-animation: cloud-3 70s linear infinite; + animation: cloud-3 70s linear infinite; +-webkit-transform: scale(1,1) translate3d(0,0,0); + -moz-transform: scale(1,1) translate3d(0,0,0); + -ms-transform: scale(1,1) translate3d(0,0,0); + -o-transform: scale(1,1) translate3d(0,0,0); + transform: scale(1,1) translate3d(0,0,0); +} + +@-webkit-keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-1 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-webkit-keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-2 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-webkit-keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@-moz-keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + +@keyframes cloud-3 { +0% { + left: 0; +} + +100% { + left: -200%; +} +} + + +/* photos */ +.photos-section .photos-container { +position: relative; +display: block; +width: 100%; +float: left; +margin: 16px auto 0 auto; +-webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; +-webkit-column-gap: 5px; + -moz-column-gap: 5px; + column-gap: 5px; +} + +.photos-container .photo-gallery { +position: relative; +display: inline-block; +width: 100%; +height: 100%; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.photos-container .photo-gallery.portrait { +height: 465px; +filter: grayscale(100%); +-webkit-filter: grayscale(100%); /* Webkit browsers */ +filter: gray; /* IE 6 - 9 */ +filter: url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 10+, Firefox on Android */ +} + +.photos-container .photo-gallery.portrait:hover { +filter: grayscale(0%); +-webkit-filter: grayscale(0%); +filter: url("data:image/svg+xml;utf8,#grayscale"); +} + +.photos-container .photo-gallery.landscape { +height: 230px; +filter: grayscale(100%); +-webkit-filter: grayscale(100%); /* Webkit browsers */ +filter: gray; /* IE 6 - 9 */ +filter: url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 10+, Firefox on Android */ +} + +.photos-container .photo-gallery.landscape:hover { +filter: grayscale(0%); +-webkit-filter: grayscale(0%); +filter: url("data:image/svg+xml;utf8,#grayscale"); +} + +.photo-gallery .photo-container { +position: relative; +float: left; +display: block; +width: 100%; +height: 100%; +overflow: hidden; +} + +.photo-gallery .photo-container::before { +position: absolute; +display: block; +width: 100%; +height: 100%; +left: 0; +top: 0; +z-index: 1; +} + +.photo-gallery .photo-container::before { +content:''; +} + +.photo-gallery .photo-container img { +position: absolute; +display: block; +width: 100%; +height: auto; +left: 0; +top: 0; +-webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); +-webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); +} + +.photo-gallery .button-container { +position: absolute; +display: block; +width: 100%; +height: 50px; +text-align: center; +z-index: 2; +} + +.photo-gallery .button-zoom { +display: inline-block; +font-size: 32px; +line-height: 50px; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transform: scale(0,0); + -moz-transform: scale(0,0); + -ms-transform: scale(0,0); + -o-transform: scale(0,0); + transform: scale(0,0); +z-index: 2; +} + +.photo-gallery .button-zoom::before { +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.photo-gallery .button-zoom:hover { +color: inherit; +} + +.photo-gallery:hover .button-zoom { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +-webkit-transform: scale(1,1); + -moz-transform: scale(1,1); + -ms-transform: scale(1,1); + -o-transform: scale(1,1); + transform: scale(1,1); +} + +.button-square { +position: relative; +display: inline-block; +width: 50px; +height: 50px; +line-height: 45px; +font-size: 25px; +text-align: center; +-webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.button-square::before { +position: absolute; +content: ''; +width: 100%; +height: 100%; +left: 0; +top: 0; +-webkit-box-shadow: inset 0 0 0 25px #fff; + -moz-box-shadow: inset 0 0 0 25px #fff; + -ms-box-shadow: inset 0 0 0 25px #fff; + -o-box-shadow: inset 0 0 0 25px #fff; + box-shadow: inset 0 0 0 25px #fff; +-webkit-transform: scale(1, 1); + -moz-transform: scale(1, 1); + -ms-transform: scale(1, 1); + -o-transform: scale(1, 1); + transform: scale(1, 1); +z-index:-1; +} + +.button-square:hover::before { +-webkit-box-shadow: inset 0 0 0 2px #fff; + -moz-box-shadow: inset 0 0 0 2px #fff; + -ms-box-shadow: inset 0 0 0 2px #fff; + -o-box-shadow: inset 0 0 0 2px #fff; + box-shadow: inset 0 0 0 2px #fff; +-webkit-transform: scale(1.1, 1.1); + -moz-transform: scale(1.1, 1.1); + -ms-transform: scale(1.1, 1.1); + -o-transform: scale(1.1, 1.1); + transform: scale(1.1, 1.1); +} + +.photo-gallery .photo-container::before { +background: none; +} + +.photo-gallery .button-zoom { +color: #000; +} + +.photo-gallery .button-zoom:hover { +color: #fff; +} + +.photo-gallery:hover .photo-container::before { +background: rgba(0,0,0, .3); +} + +.button-square, +.button-square::before, +.photo-gallery .photo-container::before, +.photo-gallery .photo-container img { +-webkit-transition: all 0.4s ease; + -moz-transition: all 0.4s ease; + -ms-transition: all 0.4s ease; + -o-transition: all 0.4s ease; + transition: all 0.4s ease; +} + +.centering-y { +position: absolute; +top: 50%; +display: inline-block; +-webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); +} + + +/* supersized */ +img { border: none; } +#supersized-loader { position: absolute; top: 50%; left: 50%; width: 60px; height: 60px; margin: -30px 0 0 -30px; text-indent: -999em; background: none; z-index: -1; } +#supersized { display: block; position: fixed; left: 0; top: 0; overflow: hidden; height: 100%; width: 100%; z-index: -999; } +#supersized img { width: auto; height: auto; position: relative; display: none; outline: none; border: none; } +#supersized.speed img { -ms-interpolation-mode: nearest-neighbor; image-rendering: -moz-crisp-edges; } /* Speed */ +#supersized.quality img { -ms-interpolation-mode: bicubic; image-rendering: optimizeQuality; } /* Quality */ +#supersized li { display: block; list-style: none; position: fixed; overflow: hidden; top: 0; left: 0; width: 100%; height: 100%; background: none; z-index: -30; } +#supersized a { width: 100%; height: 100%; display: block; } +#supersized li.prevslide { z-index: -20; } +#supersized li.activeslide { z-index: -10; } +#supersized li.image-loading { background: none; width: 100%; height: 100%; } +#supersized li.image-loading img { visibility: hidden; } +#supersized li.prevslide img, #supersized li.activeslide img { display: inline; } + + +/* kenburnsy */ +.kenburnsy { +position: relative; +width: 100%; +height: auto; +overflow: hidden; +} + +.kenburnsy.fullscreen { +position: fixed; +top: 0; +right: 0; +bottom: 0; +left: 0; +z-index: 0; +} + +.kenburnsy img { +display: none; +} + +.kenburnsy .slide { +position: absolute; +top: 0; +right: 0; +bottom: 0; +left: 0; +background-position: center center; +-webkit-background-size: cover; + background-size: cover; +background-repeat: no-repeat; +-webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +-webkit-transform-origin: center; + -ms-transform-origin: center; + transform-origin: center; +} + +#kenburnsy-bg { +overflow: hidden; +} + + +/* YouTube video containment */ +#videoContainment { +position: fixed; +width: 100%; +height: 100%; +left: 0; +top: 0; +overflow: hidden; +} + + +/* HTML5 video containment */ +#video-bg { +position: fixed; +width: 100%; +height: 100%; +left: 0; +top: 0; +overflow: hidden; +} + + +/* lines */ +.lines-button{padding:2rem 1rem;transition:.3s;cursor:pointer;user-select:none;}.lines-button:hover{opacity:1}.lines-button:active{transition:0}.lines{display:inline-block;width:3rem;height:.3rem;background:#db0018;transition:.3s;position:relative}.lines:after,.lines:before{display:inline-block;width:3rem;height:.3rem;background:#db0018;transition:.3s;position:absolute;left:0;content:'';-webkit-transform-origin:.28571rem center;transform-origin:.28571rem center}.lines:before{top:0.8rem}.lines:after{top:-0.8rem}.lines-button.arrow.lines-close .lines:after,.lines-button.arrow.lines-close .lines:before{top:0;width:2.22222rem}.lines-button.arrow.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,40deg);transform:rotate3d(0,0,1,40deg)}.lines-button.arrow.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-40deg);transform:rotate3d(0,0,1,-40deg)}.lines-button.arrow-up.lines-close{-webkit-transform:scale3d(0.8,.8,.8) rotate3d(0,0,1,90deg);transform:scale3d(0.8,.8,.8) rotate3d(0,0,1,90deg)}.lines-button.minus.lines-close .lines:after,.lines-button.minus.lines-close .lines:before{-webkit-transform:none;transform:none;top:0;width:3rem}.lines-button.x.lines-close .lines{background:0 0}.lines-button.x.lines-close .lines:after,.lines-button.x.lines-close .lines:before{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;top:0;width:3rem}.lines-button.x.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}.lines-button.x.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)}.lines-button.x2 .lines{transition:background .3s .5s ease}.lines-button.x2 .lines:after,.lines-button.x2 .lines:before{-webkit-transform-origin:50% 50%;transform-origin:50% 50%;transition:top .3s .6s ease,-webkit-transform .3s ease;transition:top .3s .6s ease,transform .3s ease}.lines-button.x2.lines-close .lines{transition:background .3s 0s ease;background:0 0}.lines-button.x2.lines-close .lines:after,.lines-button.x2.lines-close .lines:before{transition:top .3s ease,-webkit-transform .3s .5s ease;transition:top .3s ease,transform .3s .5s ease;top:0;width:3rem}.lines-button.x2.lines-close .lines:before{-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}.lines-button.x2.lines-close .lines:after{-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)} + + +/* wordsrotator */ +.wordsrotator_words{display:inline-block; position:relative; white-space:nowrap; -webkit-transition:width 1s; -moz-transition:width 1s; -o-transition:width 1s; transition:width 1s} +.wordsrotator_words .wordsrotator_wordOut, .wordsrotator_words .wordsrotator_wordIn{position:relative; display:inline-block; -webkit-animation-duration:1s; -webkit-animation-timing-function:ease; -webkit-animation-fill-mode:both; -moz-animation-duration:1s; -moz-animation-timing-function:ease; -moz-animation-fill-mode:both; -ms-animation-duration:1s; -ms-animation-timing-function:ease; -ms-animation-fill-mode:both} +.wordsrotator_words .wordsrotator_wordOut{left:0; top:0; position:absolute; display:inline-block} +.wordsrotator_words .wordsrotator_wordOut span{width:auto; position:relative} +.wordsrotator_words .wordsrotator_wordIn{opacity:0} +#wordrotator { +overflow: hidden; +} + + +/* dialog */ +a:hover, a:focus { +color: #c94e50; +outline: none; +} + +button { +position: absolute; +left: 0; +top: 0; +padding: 10px 20px 10px 20px; +outline: none; +border: none; +color: #fff; +background: #000; +} + +.content { +max-width: 1000px; +padding: 0 1em; +margin: 0 auto; +text-align: center; +-webkit-touch-callout: none; +-webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.button-wrap { +padding: 0; +} + +button.trigger { +background: #c94e50; +color: #fff; +border: none; +} + +/* dialog */ +.dialog, +.dialog__overlay { +width: 100%; +height: 100%; +top: 0; +left: 0; +} + +.dialog { +position: fixed; +display: -webkit-flex; +display: flex; +-webkit-align-items: center; + align-items: center; +-webkit-justify-content: center; + justify-content: center; +pointer-events: none; +z-index: 999; +} + +.dialog__overlay { +position: absolute; +background: rgba(0,0,0,0.7); + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +-webkit-transition: opacity 0.3s; + transition: opacity 0.3s; +-webkit-backface-visibility: hidden; +z-index: 10; +} + +.dialog--open .dialog__overlay { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +pointer-events: auto; +} + +.dialog__content { +position: relative; +width: 50%; +max-width: 560px; +min-width: 290px; +background: #fff; +padding: 4em; +text-align: center; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +z-index: 15; +} + +.dialog--open .dialog__content { +pointer-events: auto; +} + +.dialog p { +font-family: 'Dosis', sans-serif; +font-size: 15px; +line-height: 1.5; +font-style: normal; +text-transform: uppercase; +text-align: center; +font-weight: 400; +letter-spacing: 1px; +color: #000; +margin: 0 auto 40px auto; +} + +/* wilma */ +.dialog--open .dialog__overlay { +-webkit-transition-duration: 0.8s; + -moz-transition-duration: 0.8s; + -ms-transition-duration: 0.8s; + -o-transition-duration: 0.8s; + transition-duration: 0.8s; +} + +.dialog--close .dialog__overlay { +-webkit-transition-duration: 0.5s; + -moz-transition-duration: 0.5s; + -ms-transition-duration: 0.5s; + -o-transition-duration: 0.5s; + transition-duration: 0.5s; +} + +.dialog__content { +padding: 0; +background: transparent; +} + +.dialog.dialog--open .dialog__content { + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +.morph-shape { +position: absolute; +width: calc(100% + 4px); +height: calc(100% + 4px); +top: -2px; +left: -2px; +z-index: -1; +} + +.morph-shape svg rect { +stroke: #fff; +stroke-width: 2px; +stroke-dasharray: 1680; +} + +.dialog--open .morph-shape svg rect { +-webkit-animation: anim-dash 0.6s forwards; + -moz-animation: anim-dash 0.6s forwards; + -ms-animation: anim-dash 0.6s forwards; + -o-animation: anim-dash 0.6s forwards; + animation: anim-dash 0.6s forwards; +} + +.dialog-inner { +background: #fff; + opacity: 0; + -moz-opacity: 0; +-webkit-opacity: 0; +filter: alpha(opacity=0); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.dialog--open .dialog-inner { +padding: 55px 0 15px 0; +-webkit-transition: opacity 0.85s 0.35s; + -moz-transition: opacity 0.85s 0.35s; + -ms-transition: opacity 0.85s 0.35s; + -o-transition: opacity 0.85s 0.35s; + transition: opacity 0.85s 0.35s; + opacity: 1; + -moz-opacity: 1; +-webkit-opacity: 1; +filter: alpha(opacity=100); +-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + + +.dialog.dialog--open h5 { +-webkit-animation: anim-elem-1 0.7s ease-out both; + -moz-animation: anim-elem-1 0.7s ease-out both; + -ms-animation: anim-elem-1 0.7s ease-out both; + -o-animation: anim-elem-1 0.7s ease-out both; + animation: anim-elem-1 0.7s ease-out both; +} + +.dialog.dialog--open p { +-webkit-animation: anim-elem-2 0.7s ease-out both; + -moz-animation: anim-elem-2 0.7s ease-out both; + -ms-animation: anim-elem-2 0.7s ease-out both; + -o-animation: anim-elem-2 0.7s ease-out both; + animation: anim-elem-2 0.7s ease-out both; +} + +@keyframes anim-dash { + 0% { + stroke-dashoffset: 1680; + } + 100% { + stroke-dashoffset: 0; + } +} + +@-webkit-keyframes anim-dash { + 0% { + stroke-dashoffset: 1680; + } + 100% { + stroke-dashoffset: 0; + } +} + +/* inner elements animations */ +@-webkit-keyframes anim-elem-1 { + 0% { opacity: 0; -webkit-transform: translate3d(-150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); } +} + +@keyframes anim-elem-1 { + 0% { opacity: 0; -webkit-transform: translate3d(-150px, 0, 0); transform: translate3d(-150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } +} + +@-webkit-keyframes anim-elem-2 { + 0% { opacity: 0; -webkit-transform: translate3d(150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); } +} + +@keyframes anim-elem-2 { + 0% { opacity: 0; -webkit-transform: translate3d(150px, 0, 0); transform: translate3d(150px, 0, 0); } + 100% { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } +} + + +/* core owlCarousel */ +/* Core Owl Carousel CSS File v1.3.3 */ +/* clearfix */ +.owl-carousel .owl-wrapper:after { +content: "."; +display: block; +clear: both; +visibility: hidden; +line-height: 0; +height: 0; +} + +/* display none until init */ +.owl-carousel { +position: relative; +display: none; +width: 100%; +-ms-touch-action: pan-y; +} + +.owl-carousel .owl-wrapper { +display: none; +position: relative; +-webkit-transform: translate3d(0px, 0px, 0px); + -moz-transform: translate3d(0px, 0px, 0px); + -ms-transform: translate3d(0px, 0px, 0px); + -o-transform: translate3d(0px, 0px, 0px); + transform: translate3d(0px, 0px, 0px); +} + +.owl-carousel .owl-wrapper-outer { +overflow: hidden; +position: relative; +width: 100%; +} + +.owl-carousel .owl-wrapper-outer.autoHeight { +-webkit-transition: height 500ms ease-in-out; + -moz-transition: height 500ms ease-in-out; + -ms-transition: height 500ms ease-in-out; + -o-transition: height 500ms ease-in-out; + transition: height 500ms ease-in-out; +} + +.owl-carousel .owl-item { +float: left; +} + +.owl-controls .owl-page, +.owl-controls .owl-buttons div { +cursor: pointer; +} + +.owl-controls { +-webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +-webkit-tap-highlight-color: rgba(0,0,0, 0); +} + +/* mouse grab icon */ +.grabbing { +cursor: url(../img/grabbing.png) 8 8, move; +} + +/* fix */ +.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); + -o-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); +-webkit-transform-origin: center; + -moz-transform-origin: center; + -ms-transform-origin: center; + -o-transform-origin: center; + transform-origin: center; +} + + +/* core magnificPopup */ +/* Magnific Popup CSS */ +.mfp-bg,.mfp-wrap{left:0;top:0;position:fixed}.mfp-bg,.mfp-container,.mfp-wrap{width:100%;height:100%}.mfp-bg{z-index:1042;overflow:hidden;background:#0b0b0b;opacity:.9;filter:alpha(opacity=90)}.mfp-wrap{z-index:1043;outline:0!important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;left:0;top:0;padding:0 8px;box-sizing:border-box}.mfp-container,img.mfp-img{-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-ajax-holder .mfp-content,.mfp-inline-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder{cursor:crosshair}.mfp-close,.mfp-zoom{cursor:pointer}.mfp-zoom{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-arrow,.mfp-close,.mfp-counter,.mfp-preloader{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none!important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-close,.mfp-close-btn-in .mfp-close{color:#fff}.mfp-s-error .mfp-content,.mfp-s-ready .mfp-preloader{display:none}button.mfp-arrow,button.mfp-close{overflow:visible;cursor:pointer;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;-webkit-box-shadow:none;box-shadow:none}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:60px!important;height:60px!important;display:block;position:absolute;right:-60px;top:40px;text-decoration:none;text-align:center!important;padding:0;font-style:normal;font-size:24px;font-weight:300;background:#000;line-height:54px}button.mfp-close{background:#000;line-height:10px;opacity:.8}.mfp-close:hover{opacity:1}.mfp-iframe-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-arrow,.mfp-counter{background:#000;opacity:.5;bottom:4px;width:60px;height:60px;text-align:center}.mfp-arrow:before,.mfp-counter{position:absolute;display:block;color:#fff}.mfp-counter{right:60px;font-size:12px;line-height:60px;white-space:nowrap;left:60px}.mfp-figure,img.mfp-img{line-height:0}.mfp-arrow{position:absolute;margin:0;padding:0;-webkit-tap-highlight-color:transparent}.mfp-arrow:focus,.mfp-arrow:hover{opacity:1}.mfp-arrow:before{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:30px;margin-left:-1px;margin-top:-1px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%)}.mfp-arrow-left{right:0;top:-64px;position:absolute}.mfp-arrow-left::before{content:"\f104"}.mfp-arrow-right{left:120px;top:-64px;position:absolute}.mfp-arrow-right::before{content:"\f105"}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-image-holder .mfp-content,img.mfp-img{max-width:100%}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,.6);background:#000}.mfp-figure:after,img.mfp-img{display:block;width:auto;height:auto}img.mfp-img{box-sizing:border-box;padding:40px 0;margin:0 auto}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;right:0;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,.6);background:#444}.mfp-figure small{color:#BDBDBD;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#F3F3F3;word-wrap:break-word;padding-right:36px}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,.6);position:fixed;text-align:center;padding:0}}.mfp-ie7 .mfp-img{padding:0}.mfp-ie7 .mfp-bottom-bar{width:600px;left:50%;margin-left:-300px;margin-top:5px;padding-bottom:5px}.mfp-ie7 .mfp-container{padding:0}.mfp-ie7 .mfp-content{padding-top:44px}.mfp-ie7 .mfp-close{top:0;right:0;padding-top:0}.mfp-with-zoom .mfp-container,.mfp-with-zoom.mfp-bg{opacity:0;-webkit-backface-visibility:hidden;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.mfp-with-zoom.mfp-ready .mfp-container{opacity:1}.mfp-with-zoom.mfp-ready.mfp-bg{opacity:.9}.mfp-with-zoom.mfp-removing .mfp-container,.mfp-with-zoom.mfp-removing.mfp-bg{opacity:0}.mfp-fade.mfp-bg{opacity:0;transition:all .3s ease-out}.mfp-fade.mfp-bg,.mfp-fade.mfp-wrap .mfp-content{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out}.mfp-fade.mfp-bg.mfp-ready{opacity:.9}.mfp-fade.mfp-bg.mfp-removing{opacity:0}.mfp-fade.mfp-wrap .mfp-content{opacity:0;transition:all .3s ease-out}.mfp-fade.mfp-wrap.mfp-ready .mfp-content{opacity:1}.mfp-fade.mfp-wrap.mfp-removing .mfp-content{opacity:0}@media all and (max-width:1199px){.mfp-close{right:0;top:40px}} + + +/* animate */ +/*!Animate.css - http://daneden.me/animate Licensed under the MIT license -http://opensource.org/licenses/MIT Copyright (c) 2015 Daniel Eden*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut{-webkit-animation-duration:.75s;animation-duration:.75s}.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,20%,53%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);animation-timing-function:cubic-bezier(0.755,0.050,0.855,0.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,0.75,1);transform:scale3d(1.25,0.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,0.85,1);transform:scale3d(1.15,0.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,0.75,1);transform:scale3d(1.25,0.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,0.85,1);transform:scale3d(1.15,0.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{11.1%{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-0.78125deg) skewY(-0.78125deg);transform:skewX(-0.78125deg) skewY(-0.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-0.1953125deg) skewY(-0.1953125deg);transform:skewX(-0.1953125deg) skewY(-0.1953125deg)}100%{-webkit-transform:none;transform:none}}@keyframes jello{11.1%{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-0.78125deg) skewY(-0.78125deg);transform:skewX(-0.78125deg) skewY(-0.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-0.1953125deg) skewY(-0.1953125deg);transform:skewX(-0.1953125deg) skewY(-0.1953125deg)}100%{-webkit-transform:none;transform:none}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,60%,75%,90%,100%{-webkit-animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000);animation-timing-function:cubic-bezier(0.215,0.610,0.355,1.000)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190);animation-timing-function:cubic-bezier(0.550,0.055,0.675,0.190)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,0.885,0.320,1);animation-timing-function:cubic-bezier(0.175,0.885,0.320,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} + + +/* media queries */ +/* 880px */ +@media only screen and (max-width: 880px) { + +/* navigation */ +#main-menu { +width: 400px; +left: -660px; +top: -400px; +} + +/* skills */ +.contentOT { +padding: 40px 10px 68px 10px; +} + +/* owlCarousel */ +.services-gallery { +margin: 54px 0 6px 0; +} + +/* clouds */ +.clouds { +height: 200%; +top: -250px; +} + +.cloud-1 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-2 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-3 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +/* photos */ +.photos-section .photos-container { +-webkit-column-count: 2; + -moz-column-count: 2; + column-count: 2; +} + +} + + +/* 640px */ +@media only screen and (max-width: 640px) { + +/* layout */ +h1 { +/* font-size: 60px; */ +font-size: 57px; +margin: 37px auto 34px auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +h2 { +/* font-size: 60px; */ +font-size: 57px; +} + +h6 { +margin: 45px auto 0 auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +.decoration { +margin: 0 auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +.decoration-left { +width: 3%; +} + +.decoration-right { +width: 3%; +} + +.decoration-2 { +margin: 34px auto 44px auto; +} + +.decoration-left-2 { +width: 3%; +} + +.decoration-right-2 { +width: 3%; +} + +/* navigation */ +.menu-toggle { +position: absolute; +} + +#main-menu { +width: 280px; +height: 100%; +left: -280px; +top: 0; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +#main-menu.activated { +left: 108px; +} + +#main-menu .credits { +font-size: 12px; +margin: 28px 0 0 -14px; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +/* link style */ +.link { +font-size: 40px; +width: 206px; +} + +/* frame */ +.line { +visibility: hidden; +display: none; +} + +/* skills */ +.contentOT { +padding: 40px 10px 68px 10px; +} + +/* countdown */ +#countdown-wrapper { +margin: -13px auto -6px auto; +width: auto; +-webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +ul#countdown li { +width: 90px; +} + +ul#countdown li span { +font-size: 50px; +} + +ul#countdown li span.seconds { +font-size: 35px; +} + +ul#countdown li span.seconds { +padding: 0 0 0 20px; +} + +ul#countdown li p.timeRefDays, +ul#countdown li p.timeRefHours, +ul#countdown li p.timeRefMinutes { +padding: 0 0 0 3px; +} + +ul#countdown li p.timeRefSeconds { +padding: 0 0 0 18px; +} + +/* social icons */ +.social-icons-wrapper { +margin: 0 auto 13px auto; +} + +/* center container */ +.center-container-home { +position: relative; +display: block; +} + +.center-block-home { +display: block; +} + +.center-container { +position: relative; +display: block; +} + +.center-container-videos { +position: relative; +display: block; +} + +.center-block { +display: block; +} + +/* owlCarousel */ +.services-gallery { +margin: 54px 0 6px 0; +} + +/* clouds */ +.clouds { +height: 200%; +top: -250px; +} + +.cloud-1 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-2 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +.cloud-3 { +width: 400%; +-webkit-transform: scale(0.5,0.5) translate3d(0,0,0); + -moz-transform: scale(0.5,0.5) translate3d(0,0,0); + -ms-transform: scale(0.5,0.5) translate3d(0,0,0); + -o-transform: scale(0.5,0.5) translate3d(0,0,0); + transform: scale(0.5,0.5) translate3d(0,0,0); +} + +/* photos */ +.photos-section .photos-container { +margin: 16px auto 10px auto; +-webkit-column-count: 1; + -moz-column-count: 1; + column-count: 1; +} + +} + + +/* landscape */ +@media only screen and (max-width: 640px) and (orientation: landscape) { + +/* slides */ +#slidePositionIndicator { +display: none; +visibility: hidden; +} + +/* clouds */ +.clouds { +height: 300%; +} + +} + + +/* 480px */ +@media only screen and (max-width: 480px) { +} \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..18993ad Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/img/background/1.jpg b/static/img/background/1.jpg new file mode 100644 index 0000000..499e3d8 Binary files /dev/null and b/static/img/background/1.jpg differ diff --git a/static/img/background/2.jpg b/static/img/background/2.jpg new file mode 100644 index 0000000..267669b Binary files /dev/null and b/static/img/background/2.jpg differ diff --git a/static/img/background/3.jpg b/static/img/background/3.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/background/3.jpg differ diff --git a/static/img/background/4.jpg b/static/img/background/4.jpg new file mode 100644 index 0000000..267669b Binary files /dev/null and b/static/img/background/4.jpg differ diff --git a/static/img/background/back.avif b/static/img/background/back.avif new file mode 100644 index 0000000..8afafb3 Binary files /dev/null and b/static/img/background/back.avif differ diff --git a/static/img/background/bg-layer.jpg b/static/img/background/bg-layer.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/background/bg-layer.jpg differ diff --git a/static/img/background/video-HTML5.jpg b/static/img/background/video-HTML5.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/background/video-HTML5.jpg differ diff --git a/static/img/background/video.jpg b/static/img/background/video.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/background/video.jpg differ diff --git a/static/img/cloud-1.png b/static/img/cloud-1.png new file mode 100644 index 0000000..9b34489 Binary files /dev/null and b/static/img/cloud-1.png differ diff --git a/static/img/cloud-2.png b/static/img/cloud-2.png new file mode 100644 index 0000000..2db4eb3 Binary files /dev/null and b/static/img/cloud-2.png differ diff --git a/static/img/cloud-3.png b/static/img/cloud-3.png new file mode 100644 index 0000000..3b0d3f0 Binary files /dev/null and b/static/img/cloud-3.png differ diff --git a/static/img/curtains.png b/static/img/curtains.png new file mode 100644 index 0000000..97ffd50 Binary files /dev/null and b/static/img/curtains.png differ diff --git a/static/img/film-grain.gif b/static/img/film-grain.gif new file mode 100644 index 0000000..f78fd88 Binary files /dev/null and b/static/img/film-grain.gif differ diff --git a/static/img/grabbing.png b/static/img/grabbing.png new file mode 100644 index 0000000..85491df Binary files /dev/null and b/static/img/grabbing.png differ diff --git a/static/img/photos/large/1.jpg b/static/img/photos/large/1.jpg new file mode 100644 index 0000000..499e3d8 Binary files /dev/null and b/static/img/photos/large/1.jpg differ diff --git a/static/img/photos/large/2.jpg b/static/img/photos/large/2.jpg new file mode 100644 index 0000000..267669b Binary files /dev/null and b/static/img/photos/large/2.jpg differ diff --git a/static/img/photos/large/3.jpg b/static/img/photos/large/3.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/photos/large/3.jpg differ diff --git a/static/img/photos/large/4.jpg b/static/img/photos/large/4.jpg new file mode 100644 index 0000000..267669b Binary files /dev/null and b/static/img/photos/large/4.jpg differ diff --git a/static/img/photos/large/5.jpg b/static/img/photos/large/5.jpg new file mode 100644 index 0000000..27279ec Binary files /dev/null and b/static/img/photos/large/5.jpg differ diff --git a/static/img/photos/small/1.jpg b/static/img/photos/small/1.jpg new file mode 100644 index 0000000..5032cfd Binary files /dev/null and b/static/img/photos/small/1.jpg differ diff --git a/static/img/photos/small/2.jpg b/static/img/photos/small/2.jpg new file mode 100644 index 0000000..a795b41 Binary files /dev/null and b/static/img/photos/small/2.jpg differ diff --git a/static/img/photos/small/3.jpg b/static/img/photos/small/3.jpg new file mode 100644 index 0000000..328b569 Binary files /dev/null and b/static/img/photos/small/3.jpg differ diff --git a/static/img/photos/small/4.jpg b/static/img/photos/small/4.jpg new file mode 100644 index 0000000..a795b41 Binary files /dev/null and b/static/img/photos/small/4.jpg differ diff --git a/static/img/photos/small/5.jpg b/static/img/photos/small/5.jpg new file mode 100644 index 0000000..328b569 Binary files /dev/null and b/static/img/photos/small/5.jpg differ diff --git a/static/img/rain.png b/static/img/rain.png new file mode 100644 index 0000000..b67c854 Binary files /dev/null and b/static/img/rain.png differ diff --git a/static/img/sky-image-dark.png b/static/img/sky-image-dark.png new file mode 100644 index 0000000..d295cf0 Binary files /dev/null and b/static/img/sky-image-dark.png differ diff --git a/static/img/sky-image-light.png b/static/img/sky-image-light.png new file mode 100644 index 0000000..8d42370 Binary files /dev/null and b/static/img/sky-image-light.png differ diff --git a/static/img/snowflake.png b/static/img/snowflake.png new file mode 100644 index 0000000..bb65c62 Binary files /dev/null and b/static/img/snowflake.png differ diff --git a/static/img/the-sea-image-dark.png b/static/img/the-sea-image-dark.png new file mode 100644 index 0000000..eab3877 Binary files /dev/null and b/static/img/the-sea-image-dark.png differ diff --git a/static/img/the-sea-image-light.png b/static/img/the-sea-image-light.png new file mode 100644 index 0000000..b66ba64 Binary files /dev/null and b/static/img/the-sea-image-light.png differ diff --git a/static/js/jquery-1.11.3.min.js b/static/js/jquery-1.11.3.min.js new file mode 100644 index 0000000..0f60b7b --- /dev/null +++ b/static/js/jquery-1.11.3.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){t.types.push(R),I("BeforeChange",function(e,t,n){t!==n&&(t===R?q():n===R&&q(!0))}),I(s+"."+R,function(){q()})},getIframe:function(n,i){var o=n.src,r=t.st.iframe;e.each(r.patterns,function(){return o.indexOf(this.index)>-1?(this.id&&(o="string"==typeof this.id?o.substr(o.lastIndexOf(this.id)+this.id.length,o.length):this.id.call(this,o)),o=this.src.replace("%id%",o),!1):void 0});var a={};return r.srcAction&&(a[r.srcAction]=o),t._parseMarkup(i,a,n),t.updateStatus("ready"),i}}});var D=function(e){var n=t.items.length;return e>n-1?e-n:0>e?n+e:e},K=function(e,t,n){return e.replace(/%curr%/gi,t+1).replace(/%total%/gi,n)};e.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var n=t.st.gallery,o=".mfp-gallery",a=Boolean(e.fn.mfpFastClick);return t.direction=!0,n&&n.enabled?(r+=" mfp-gallery",I(p+o,function(){n.navigateByImgClick&&t.wrap.on("click"+o,".mfp-img",function(){return t.items.length>1?(t.next(),!1):void 0}),i.on("keydown"+o,function(e){37===e.keyCode?t.prev():39===e.keyCode&&t.next()})}),I("UpdateStatus"+o,function(e,n){n.text&&(n.text=K(n.text,t.currItem.index,t.items.length))}),I(u+o,function(e,i,o,r){var a=t.items.length;o.counter=a>1?K(n.tCounter,r.index,a):""}),I("BuildControls"+o,function(){if(t.items.length>1&&n.arrows&&!t.arrowLeft){var i=n.arrowMarkup,o=t.arrowLeft=e(i.replace(/%title%/gi,n.tPrev).replace(/%dir%/gi,"left")).addClass(C),r=t.arrowRight=e(i.replace(/%title%/gi,n.tNext).replace(/%dir%/gi,"right")).addClass(C),s=a?"mfpFastClick":"click";o[s](function(){t.prev()}),r[s](function(){t.next()}),t.isIE7&&(x("b",o[0],!1,!0),x("a",o[0],!1,!0),x("b",r[0],!1,!0),x("a",r[0],!1,!0)),t.container.find('.mfp-bottom-bar').append(o.add(r))}}),I(f+o,function(){t._preloadTimeout&&clearTimeout(t._preloadTimeout),t._preloadTimeout=setTimeout(function(){t.preloadNearbyImages(),t._preloadTimeout=null},16)}),void I(s+o,function(){i.off(o),t.wrap.off("click"+o),t.arrowLeft&&a&&t.arrowLeft.add(t.arrowRight).destroyMfpFastClick(),t.arrowRight=t.arrowLeft=null})):!1},next:function(){t.direction=!0,t.index=D(t.index+1),t.updateItemHTML()},prev:function(){t.direction=!1,t.index=D(t.index-1),t.updateItemHTML()},goTo:function(e){t.direction=e>=t.index,t.index=e,t.updateItemHTML()},preloadNearbyImages:function(){var e,n=t.st.gallery.preload,i=Math.min(n[0],t.items.length),o=Math.min(n[1],t.items.length);for(e=1;e<=(t.direction?o:i);e++)t._preloadItem(t.index+e);for(e=1;e<=(t.direction?i:o);e++)t._preloadItem(t.index-e)},_preloadItem:function(n){if(n=D(n),!t.items[n].preloaded){var i=t.items[n];i.parsed||(i=t.parseEl(n)),k("LazyLoad",i),"image"===i.type&&(i.img=e('').on("load.mfploader",function(){i.hasSize=!0}).on("error.mfploader",function(){i.hasSize=!0,i.loadError=!0,k("LazyLoadError",i)}).attr("src",i.src)),i.preloaded=!0}}}});var Y="retina";e.magnificPopup.registerModule(Y,{options:{replaceSrc:function(e){return e.src.replace(/\.\w+$/,function(e){return"@2x"+e})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var e=t.st.retina,n=e.ratio;n=isNaN(n)?n():n,n>1&&(I("ImageHasSize."+Y,function(e,t){t.img.css({"max-width":t.img[0].naturalWidth/n,width:"100%"})}),I("ElementParse."+Y,function(t,i){i.src=e.replaceSrc(i,n)}))}}}}),function(){var t=1e3,n="ontouchstart"in window,i=function(){b.off("touchmove"+r+" touchend"+r)},o="mfpFastClick",r="."+o;e.fn.mfpFastClick=function(o){return e(this).each(function(){var a,s=e(this);if(n){var l,c,d,u,p,f;s.on("touchstart"+r,function(e){u=!1,f=1,p=e.originalEvent?e.originalEvent.touches[0]:e.touches[0],c=p.clientX,d=p.clientY,b.on("touchmove"+r,function(e){p=e.originalEvent?e.originalEvent.touches:e.touches,f=p.length,p=p[0],(Math.abs(p.clientX-c)>10||Math.abs(p.clientY-d)>10)&&(u=!0,i())}).on("touchend"+r,function(e){i(),u||f>1||(a=!0,e.preventDefault(),clearTimeout(l),l=setTimeout(function(){a=!1},t),o())})})}s.on("click"+r,function(){a||o()})})},e.fn.destroyMfpFastClick=function(){e(this).off("touchstart"+r+" click"+r),n&&b.off("touchmove"+r+" touchend"+r)}}(),E()}); + + +/* snow */ +// +var THREE=THREE||{};if(!self.Int32Array)self.Int32Array=Array,self.Float32Array=Array;THREE.Color=function(a){a!==void 0&&this.setHex(a);return this};THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSV:function(a,b,c){var d,f,e;if(c===0)this.r=this.g=this.b=0;else switch(d=Math.floor(a*6),f=a*6-d,a=c*(1-b),e=c*(1- +b*f),b=c*(1-b*(1-f)),d){case 1:this.r=e;this.g=c;this.b=a;break;case 2:this.r=a;this.g=c;this.b=b;break;case 3:this.r=a;this.g=e;this.b=c;break;case 4:this.r=b;this.g=a;this.b=c;break;case 5:this.r=c;this.g=a;this.b=e;break;case 6:case 0:this.r=c,this.g=b,this.b=a}return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},getHex:function(){return~~(this.r*255)<<16^~~(this.g*255)<<8^~~(this.b*255)},getContextStyle:function(){return"rgb("+ +Math.floor(this.r*255)+","+Math.floor(this.g*255)+","+Math.floor(this.b*255)+")"},clone:function(){return(new THREE.Color).setRGB(this.r,this.g,this.b)}};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0};THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},copy:function(a){this.x=a.x;this.y=a.y;return this},clone:function(){return new THREE.Vector2(this.x,this.y)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a):this.set(0,0);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.lengthSq())},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.normalize().multiplyScalar(a)},equals:function(a){return a.x===this.x&&a.y===this.y}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0};THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},multiply:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},multiplySelf:function(a){this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},divideSelf:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a):this.z=this.y=this.x=0;return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.lengthSq())},lengthManhattan:function(){return this.x+this.y+this.z},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},cross:function(a,b){this.x=a.y*b.z-a.z*b.y;this.y=a.z*b.x-a.x*b.z;this.z=a.x*b.y-a.y*b.x;return this},crossSelf:function(a){var b=this.x,c=this.y,d=this.z;this.x=c*a.z-d*a.y;this.y=d*a.x-b*a.z;this.z=b*a.y-c*a.x;return this},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){return(new THREE.Vector3).sub(this,a).lengthSq()},setPositionFromMatrix:function(a){this.x=a.n14;this.y=a.n24;this.z=a.n34},setRotationFromMatrix:function(a){var b=Math.cos(this.y);this.y=Math.asin(a.n13);Math.abs(b)>1.0E-5?(this.x=Math.atan2(-a.n23/b,a.n33/b),this.z=Math.atan2(-a.n12/b,a.n11/b)):(this.x=0,this.z=Math.atan2(a.n21,a.n22))},isZero:function(){return this.lengthSq()<1.0E-4}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=d!==void 0?d:1};THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w!==void 0?a.w:1},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z- +b.z;this.w=a.w-b.w;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.dot(this)},length:function(){return Math.sqrt(this.lengthSq())},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this}};THREE.Ray=function(a,b){function c(a,b,c){i.sub(c,a);p=i.dot(b);if(p<=0)return null;k=n.add(a,o.copy(b).multiplyScalar(p));return s=c.distanceTo(k)}function d(a,b,c,d){i.sub(d,b);n.sub(c,b);o.sub(a,b);K=i.dot(i);C=i.dot(n);Q=i.dot(o);O=n.dot(n);w=n.dot(o);F=1/(K*O-C*C);z=(O*Q-C*w)*F;D=(K*w-C*Q)*F;return z>=0&&D>=0&&z+D<1}this.origin=a||new THREE.Vector3;this.direction=b||new THREE.Vector3;this.intersectScene=function(a){return this.intersectObjects(a.children)};this.intersectObjects=function(a){var b,c,d=[];b=0;for(c=a.length;bk.scale.x)return[];i={distance:n,point:k.position,face:null,object:k};o.push(i)}else if(k instanceof THREE.Mesh){n=c(this.origin,this.direction,k.matrixWorld.getPosition());if(n===null||n>k.geometry.boundingSphere.radius*Math.max(k.scale.x,Math.max(k.scale.y,k.scale.z)))return o;var p,G=k.geometry,H=G.vertices,I;k.matrixRotationWorld.extractRotation(k.matrixWorld);n=0;for(W=G.faces.length;n0:p<0)))if(p=l.dot(m.sub(f,a))/p,j.add(a,b.multiplyScalar(p)),i instanceof THREE.Face3)d(j,f,e,g)&&(i={distance:a.distanceTo(j),point:j.clone(),face:i,object:k},o.push(i));else if(i instanceof THREE.Face4&&(d(j,f,e,h)||d(j,e,g,h)))i={distance:a.distanceTo(j),point:j.clone(),face:i,object:k},o.push(i)}return o};var i=new THREE.Vector3,n=new THREE.Vector3,o=new THREE.Vector3,p,k,s,K,C,Q,O,w,F,z,D};THREE.Rectangle=function(){function a(){e=d-b;g=f-c}var b,c,d,f,e,g,h=!0;this.getX=function(){return b};this.getY=function(){return c};this.getWidth=function(){return e};this.getHeight=function(){return g};this.getLeft=function(){return b};this.getTop=function(){return c};this.getRight=function(){return d};this.getBottom=function(){return f};this.set=function(e,g,j,i){h=!1;b=e;c=g;d=j;f=i;a()};this.addPoint=function(e,g){h?(h=!1,b=e,c=g,d=e,f=g):(b=be?d:e,f=f>g?f:g);a()};this.add3Points=function(e,g,j,i,n,o){h?(h=!1,b=ej?e>n?e:n:j>n?j:n,f=g>i?g>o?g:o:i>o?i:o):(b=ej?e>n?e>d?e:d:n>d?n:d:j>n?j>d?j:d:n>d?n:d,f=g>i?g>o?g>f?g:f:o>f?o:f:i>o?i>f?i:f:o>f?o:f);a()};this.addRectangle=function(e){h?(h=!1,b=e.getLeft(),c=e.getTop(),d=e.getRight(),f=e.getBottom()):(b=be.getRight()?d:e.getRight(),f=f>e.getBottom()?f:e.getBottom());a()};this.inflate=function(e){b-=e;c-=e;d+=e;f+=e;a()};this.minSelf=function(e){b=b>e.getLeft()?b:e.getLeft();c=c>e.getTop()?c:e.getTop();d=d=0&&Math.min(f,a.getBottom())-Math.max(c,a.getTop())>=0};this.empty=function(){h=!0;f=d=c=b=0;a()};this.isEmpty=function(){return h}};THREE.Math={clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=0&&f>=0&&g>=0&&h>=0?!0:e<0&&f<0||g<0&&h<0?!1:(e<0?c=Math.max(c,e/(e-f)):f<0&&(d=Math.min(d,e/(e-f))),g<0?c=Math.max(c,g/(g-h)):h<0&&(d=Math.min(d,g/(g-h))),dg&&h.positionScreen.z0&&z.z<1))g=O[Q]=O[Q]||new THREE.RenderableParticle,Q++,C=g,C.x=z.x/z.w,C.y=z.y/z.w,C.z=z.z,C.rotation=J.rotation.z,C.scale.x=J.scale.x*Math.abs(C.x-(z.x+e.projectionMatrix.n11)/(z.w+e.projectionMatrix.n14)),C.scale.y=J.scale.y*Math.abs(C.y-(z.y+e.projectionMatrix.n22)/(z.w+e.projectionMatrix.n24)),C.material=J.material,w.elements.push(C);f&&w.elements.sort(c);return w}};THREE.Quaternion=function(a,b,c,d){this.set(a||0,b||0,c||0,d!==void 0?d:1)};THREE.Quaternion.prototype={constructor:THREE.Quaternion,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w;return this},setFromEuler:function(a){var b=Math.PI/360,c=a.x*b,d=a.y*b,f=a.z*b,a=Math.cos(d),d=Math.sin(d),b=Math.cos(-f),f=Math.sin(-f),e=Math.cos(c),c=Math.sin(c),g=a*b,h=d*f;this.w=g*e-h*c;this.x=g*c+h*e;this.y=d*b*e+a*f*c;this.z=a*f*e-d*b*c;return this},setFromAxisAngle:function(a,b){var c=b/2,d=Math.sin(c);this.x=a.x*d;this.y=a.y*d;this.z=a.z*d;this.w=Math.cos(c);return this},setFromRotationMatrix:function(a){var b=Math.pow(a.determinant(),1/3);this.w=Math.sqrt(Math.max(0,b+a.n11+a.n22+a.n33))/2;this.x=Math.sqrt(Math.max(0,b+a.n11-a.n22-a.n33))/2;this.y=Math.sqrt(Math.max(0,b-a.n11+a.n22-a.n33))/2;this.z=Math.sqrt(Math.max(0,b-a.n11-a.n22+a.n33))/2;this.x=a.n32-a.n23<0?-Math.abs(this.x):Math.abs(this.x);this.y=a.n13-a.n31<0?-Math.abs(this.y):Math.abs(this.y);this.z=a.n21-a.n12<0?-Math.abs(this.z):Math.abs(this.z);this.normalize();return this},calculateW:function(){this.w=-Math.sqrt(Math.abs(1-this.x*this.x-this.y*this.y-this.z*this.z));return this},inverse:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);a===0?this.w=this.z=this.y=this.x=0:(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiplySelf:function(a){var b=this.x,c=this.y,d=this.z,f=this.w,e=a.x,g=a.y,h=a.z,a=a.w;this.x=b*a+f*e+c*h-d*g;this.y=c*a+f*g+d*e-b*h;this.z=d*a+f*h+b*g-c*e;this.w=f*a-b*e-c*g-d*h;return this},multiply:function(a,b){this.x=a.x*b.w+a.y*b.z-a.z*b.y+a.w*b.x;this.y=-a.x*b.z+a.y*b.w+a.z*b.x+a.w*b.y;this.z=a.x*b.y-a.y*b.x+a.z*b.w+a.w*b.z;this.w=-a.x*b.x-a.y*b.y-a.z*b.z+a.w*b.w;return this},multiplyVector3:function(a,b){b||(b=a);var c=a.x,d=a.y,f=a.z,e=this.x,g=this.y,h=this.z,m=this.w,l=m*c+g*f-h*d,j=m*d+h*c-e*f,i=m*f+e*d-g*c,c=-e*c-g*d-h*f;b.x=l*m+c*-e+j*-h-i*-g;b.y=j*m+c*-g+i*-e-l*-h;b.z=i*m+c*-h+l*-g-j*-e;return b}};THREE.Quaternion.slerp=function(a,b,c,d){var f=a.w*b.w+a.x*b.x+a.y*b.y+a.z*b.z;f<0?(c.w=-b.w,c.x=-b.x,c.y=-b.y,c.z=-b.z,f=-f):c.copy(b);if(Math.abs(f)>=1)return c.w=a.w,c.x=a.x,c.y=a.y,c.z=a.z,c;var e=Math.acos(f),f=Math.sqrt(1-f*f);if(Math.abs(f)<0.001)return c.w=0.5*(a.w+b.w),c.x=0.5*(a.x+b.x),c.y=0.5*(a.y+b.y),c.z=0.5*(a.z+b.z),c;b=Math.sin((1-d)*e)/f;d=Math.sin(d*e)/f;c.w=a.w*b+c.w*d;c.x=a.x*b+c.x*d;c.y=a.y*b+c.y*d;c.z=a.z*b+c.z*d;return c};THREE.Vertex=function(a){this.position=a||new THREE.Vector3};THREE.Face3=function(a,b,c,d,f,e){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=f instanceof THREE.Color?f:new THREE.Color;this.vertexColors=f instanceof Array?f:[];this.vertexTangents=[];this.materialIndex=e;this.centroid=new THREE.Vector3};THREE.Face4=function(a,b,c,d,f,e,g){this.a=a;this.b=b;this.c=c;this.d=d;this.normal=f instanceof THREE.Vector3?f:new THREE.Vector3;this.vertexNormals=f instanceof Array?f:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=g;this.centroid=new THREE.Vector3};THREE.UV=function(a,b){this.u=a||0;this.v=b||0};THREE.UV.prototype={constructor:THREE.UV,set:function(a,b){this.u=a;this.v=b;return this},copy:function(a){this.u=a.u;this.v=a.v;return this},clone:function(){return new THREE.UV(this.u,this.v)}};THREE.Geometry=function(){this.id=THREE.GeometryCount++;this.vertices=[];this.colors=[];this.materials=[];this.faces=[];this.faceUvs=[[]];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphColors=[];this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.dynamic=this.hasTangents=!1};THREE.Geometry.prototype={constructor:THREE.Geometry,applyMatrix:function(a){var b=new THREE.Matrix4;b.extractRotation(a,new THREE.Vector3(1,1,1));for(var c=0,d=this.vertices.length;c0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x],y:[this.vertices[0].position.y,this.vertices[0].position.y],z:[this.vertices[0].position.z,this.vertices[0].position.z]};for(var b=1,c=this.vertices.length;bthis.boundingBox.x[1])this.boundingBox.x[1]=a.position.x;if(a.position.ythis.boundingBox.y[1])this.boundingBox.y[1]=a.position.y;if(a.position.zthis.boundingBox.z[1])this.boundingBox.z[1]=a.position.z}}},computeBoundingSphere:function(){for(var a=0,b=0,c=this.vertices.length;b0&&(c(THREE.NormalBlending),b(1),f("rgba("+Math.floor(s.r*255)+","+Math.floor(s.g*255)+","+Math.floor(s.b*255)+","+K+")"),k.fillRect(Math.floor(Z.getX()),Math.floor(Z.getY()),Math.floor(Z.getWidth()),Math.floor(Z.getHeight()))),Z.empty())};this.render=function(a,j){function i(a){var b,c,d,e;$.setRGB(0,0,0);ta.setRGB(0,0,0);ua.setRGB(0,0,0);b=0;for(c=a.length;b>1,n=m.height>>1,g=e.scale.x*o,i=e.scale.y*p,h=g*q,j=i*n,X.set(a.x-h,a.y-j,a.x+h,a.y+j),ma.intersects(X)&&(k.save(),k.translate(a.x,a.y),k.rotate(-e.rotation),k.scale(g,-i),k.translate(-q,-n),k.drawImage(m,0,0),k.restore())}else g instanceof THREE.ParticleCanvasMaterial&&(h=e.scale.x*o,j=e.scale.y*p,X.set(a.x-h,a.y-j,a.x+h,a.y+j),ma.intersects(X)&&(d(g.color.getContextStyle()),f(g.color.getContextStyle()),k.save(),k.translate(a.x,a.y),k.rotate(-e.rotation),k.scale(h,j),g.program(k),k.restore()))}function w(a,e,f,g){b(g.opacity);c(g.blending);k.beginPath();k.moveTo(a.positionScreen.x,a.positionScreen.y);k.lineTo(e.positionScreen.x,e.positionScreen.y);k.closePath();if(g instanceof THREE.LineBasicMaterial){a=g.linewidth;if(F!=a)k.lineWidth=F=a;a=g.linecap;if(z!=a)k.lineCap=z=a;a=g.linejoin;if(D!=a)k.lineJoin=D=a;d(g.color.getContextStyle());k.stroke();X.inflate(g.linewidth*2)}}function C(a,d,f,g,h,k,i,q){e.info.render.vertices+=3;e.info.render.faces++;b(q.opacity);c(q.blending);G=a.positionScreen.x;H=a.positionScreen.y;I=d.positionScreen.x;Y=d.positionScreen.y;L=f.positionScreen.x;B=f.positionScreen.y;K(G,H,I,Y,L,B);if(q instanceof THREE.MeshBasicMaterial)if(q.map)q.map.mapping instanceof THREE.UVMapping&&(aa=i.uvs[0],Aa(G,H,I,Y,L,B,aa[g].u,aa[g].v,aa[h].u,aa[h].v,aa[k].u,aa[k].v,q.map));else if(q.envMap){if(q.envMap.mapping instanceof THREE.SphericalReflectionMapping)a=j.matrixWorldInverse,T.copy(i.vertexNormalsWorld[g]),Ba=(T.x*a.n11+T.y*a.n12+T.z*a.n13)*0.5+0.5,Ca=-(T.x*a.n21+T.y*a.n22+T.z*a.n23)*0.5+0.5,T.copy(i.vertexNormalsWorld[h]),Da=(T.x*a.n11+T.y*a.n12+T.z*a.n13)*0.5+0.5,Ea=-(T.x*a.n21+T.y*a.n22+T.z*a.n23)*0.5+0.5,T.copy(i.vertexNormalsWorld[k]),Fa=(T.x*a.n11+T.y*a.n12+T.z*a.n13)*0.5+0.5,Ga=-(T.x*a.n21+T.y*a.n22+T.z*a.n23)*0.5+0.5,Aa(G,H,I,Y,L,B,Ba,Ca,Da,Ea,Fa,Ga,q.envMap)}else q.wireframe?ja(q.color,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(q.color);else if(q instanceof THREE.MeshLambertMaterial)q.map&&!q.wireframe&&(q.map.mapping instanceof THREE.UVMapping&&(aa=i.uvs[0],Aa(G,H,I,Y,L,B,aa[g].u,aa[g].v,aa[h].u,aa[h].v,aa[k].u,aa[k].v,q.map)),c(THREE.SubtractiveBlending)),ya?!q.wireframe&&q.shading==THREE.SmoothShading&&i.vertexNormalsWorld.length==3?(A.r=x.r=y.r=$.r,A.g=x.g=y.g=$.g,A.b=x.b=y.b=$.b,n(m,i.v1.positionWorld,i.vertexNormalsWorld[0],A),n(m,i.v2.positionWorld,i.vertexNormalsWorld[1],x),n(m,i.v3.positionWorld,i.vertexNormalsWorld[2],y),A.r=Math.max(0,Math.min(q.color.r*A.r,1)),A.g=Math.max(0,Math.min(q.color.g*A.g,1)),A.b=Math.max(0,Math.min(q.color.b*A.b,1)),x.r=Math.max(0,Math.min(q.color.r*x.r,1)),x.g=Math.max(0,Math.min(q.color.g*x.g,1)),x.b=Math.max(0,Math.min(q.color.b*x.b,1)),y.r=Math.max(0,Math.min(q.color.r*y.r,1)),y.g=Math.max(0,Math.min(q.color.g*y.g,1)),y.b=Math.max(0,Math.min(q.color.b*y.b,1)),M.r=(x.r+y.r)*0.5,M.g=(x.g+y.g)*0.5,M.b=(x.b+y.b)*0.5,ea=wa(A,x,y,M),oa(G,H,I,Y,L,B,0,0,1,0,0,1,ea)):(t.r=$.r,t.g=$.g,t.b=$.b,n(m,i.centroidWorld,i.normalWorld,t),t.r=Math.max(0,Math.min(q.color.r*t.r,1)),t.g=Math.max(0,Math.min(q.color.g*t.g,1)),t.b=Math.max(0,Math.min(q.color.b*t.b,1)),q.wireframe?ja(t,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(t)):q.wireframe?ja(q.color,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(q.color);else if(q instanceof THREE.MeshDepthMaterial)ga=j.near,ha=j.far,A.r=A.g=A.b=1-na(a.positionScreen.z,ga,ha),x.r=x.g=x.b=1-na(d.positionScreen.z,ga,ha),y.r=y.g=y.b=1-na(f.positionScreen.z,ga,ha),M.r=(x.r+y.r)*0.5,M.g=(x.g+y.g)*0.5,M.b=(x.b+y.b)*0.5,ea=wa(A,x,y,M),oa(G,H,I,Y,L,B,0,0,1,0,0,1,ea);else if(q instanceof THREE.MeshNormalMaterial)t.r=pa(i.normalWorld.x),t.g=pa(i.normalWorld.y),t.b=pa(i.normalWorld.z),q.wireframe?ja(t,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(t)}function Q(a,d,f,g,h,k,i,q,o){e.info.render.vertices+=4;e.info.render.faces++;b(q.opacity);c(q.blending);if(q.map||q.envMap)C(a,d,g,0,1,3,i,q,o),C(h,f,k,1,2,3,i,q,o);else if(G=a.positionScreen.x,H=a.positionScreen.y,I=d.positionScreen.x,Y=d.positionScreen.y,L=f.positionScreen.x,B=f.positionScreen.y,S=g.positionScreen.x,v=g.positionScreen.y,R=h.positionScreen.x,P=h.positionScreen.y,V=k.positionScreen.x,J=k.positionScreen.y,q instanceof THREE.MeshBasicMaterial)O(G,H,I,Y,L,B,S,v),q.wireframe?ja(q.color,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(q.color);else if(q instanceof THREE.MeshLambertMaterial)ya?!q.wireframe&&q.shading==THREE.SmoothShading&&i.vertexNormalsWorld.length==4?(A.r=x.r=y.r=M.r=$.r,A.g=x.g=y.g=M.g=$.g,A.b=x.b=y.b=M.b=$.b,n(m,i.v1.positionWorld,i.vertexNormalsWorld[0],A),n(m,i.v2.positionWorld,i.vertexNormalsWorld[1],x),n(m,i.v4.positionWorld,i.vertexNormalsWorld[3],y),n(m,i.v3.positionWorld,i.vertexNormalsWorld[2],M),A.r=Math.max(0,Math.min(q.color.r*A.r,1)),A.g=Math.max(0,Math.min(q.color.g*A.g,1)),A.b=Math.max(0,Math.min(q.color.b*A.b,1)),x.r=Math.max(0,Math.min(q.color.r*x.r,1)),x.g=Math.max(0,Math.min(q.color.g*x.g,1)),x.b=Math.max(0,Math.min(q.color.b*x.b,1)),y.r=Math.max(0,Math.min(q.color.r*y.r,1)),y.g=Math.max(0,Math.min(q.color.g*y.g,1)),y.b=Math.max(0,Math.min(q.color.b*y.b,1)),M.r=Math.max(0,Math.min(q.color.r*M.r,1)),M.g=Math.max(0,Math.min(q.color.g*M.g,1)),M.b=Math.max(0,Math.min(q.color.b*M.b,1)),ea=wa(A,x,y,M),K(G,H,I,Y,S,v),oa(G,H,I,Y,S,v,0,0,1,0,0,1,ea),K(R,P,L,B,V,J),oa(R,P,L,B,V,J,1,0,1,1,0,1,ea)):(t.r=$.r,t.g=$.g,t.b=$.b,n(m,i.centroidWorld,i.normalWorld,t),t.r=Math.max(0,Math.min(q.color.r*t.r,1)),t.g=Math.max(0,Math.min(q.color.g*t.g,1)),t.b=Math.max(0,Math.min(q.color.b*t.b,1)),O(G,H,I,Y,L,B,S,v),q.wireframe?ja(t,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(t)):(O(G,H,I,Y,L,B,S,v),q.wireframe?ja(q.color,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(q.color));else if(q instanceof THREE.MeshNormalMaterial)t.r=pa(i.normalWorld.x),t.g=pa(i.normalWorld.y),t.b=pa(i.normalWorld.z),O(G,H,I,Y,L,B,S,v),q.wireframe?ja(t,q.wireframeLinewidth,q.wireframeLinecap,q.wireframeLinejoin):ia(t);else if(q instanceof THREE.MeshDepthMaterial)ga=j.near,ha=j.far,A.r=A.g=A.b=1-na(a.positionScreen.z,ga,ha),x.r=x.g=x.b=1-na(d.positionScreen.z,ga,ha),y.r=y.g=y.b=1-na(g.positionScreen.z,ga,ha),M.r=M.g=M.b=1-na(f.positionScreen.z,ga,ha),ea=wa(A,x,y,M),K(G,H,I,Y,S,v),oa(G,H,I,Y,S,v,0,0,1,0,0,1,ea),K(R,P,L,B,V,J),oa(R,P,L,B,V,J,1,0,1,1,0,1,ea)}function K(a,b,c,d,e,f){k.beginPath();k.moveTo(a,b);k.lineTo(c,d);k.lineTo(e,f);k.lineTo(a,b);k.closePath()}function O(a,b,c,d,e,f,g,h){k.beginPath();k.moveTo(a,b);k.lineTo(c,d);k.lineTo(e,f);k.lineTo(g,h);k.lineTo(a,b);k.closePath()}function ja(a,b,c,e){if(F!=b)k.lineWidth=F=b;if(z!=c)k.lineCap=z=c;if(D!=e)k.lineJoin=D=e;d(a.getContextStyle());k.stroke();X.inflate(b*2)}function ia(a){f(a.getContextStyle());k.fill()}function Aa(a,b,c,d,e,g,h,i,j,m,o,n,l){if(l.image.width!=0){if(l.needsUpdate==!0||la[l.id]==void 0){var p=l.wrapS==THREE.RepeatWrapping,r=l.wrapT==THREE.RepeatWrapping;la[l.id]=k.createPattern(l.image,p&&r?"repeat":p&&!r?"repeat-x":!p&&r?"repeat-y":"no-repeat");l.needsUpdate=!1}f(la[l.id]);var p=l.offset.x/l.repeat.x,r=l.offset.y/l.repeat.y,s=l.image.width*l.repeat.x,u=l.image.height*l.repeat.y,h=(h+p)*s,i=(i+r)*u,j=(j+p)*s,m=(m+r)*u,o=(o+p)*s,n=(n+r)*u;c-=a;d-=b;e-=a;g-=b;j-=h;m-=i;o-=h;n-=i;p=j*n-o*m;if(p==0){if(fa[l.id]==void 0)b=document.createElement("canvas"),b.width=l.image.width,b.height=l.image.height,a=b.getContext("2d"),a.drawImage(l.image,0,0),fa[l.id]=a.getImageData(0,0,l.image.width,l.image.height).data,delete b;b=fa[l.id];h=(Math.floor(h)+Math.floor(i)*l.image.width)*4;t.setRGB(b[h]/255,b[h+1]/255,b[h+2]/255);ia(t)}else p=1/p,l=(n*c-m*e)*p,m=(n*d-m*g)*p,c=(j*e-o*c)*p,d=(j*g-o*d)*p,a=a-l*h-c*i,h=b-m*h- +d*i,k.save(),k.transform(l,m,c,d,a,h),k.fill(),k.restore()}}function oa(a,b,c,d,e,f,g,h,i,j,l,m,o){var n,p;n=o.width-1;p=o.height-1;g*=n;h*=p;i*=n;j*=p;l*=n;m*=p;c-=a;d-=b;e-=a;f-=b;i-=g;j-=h;l-=g;m-=h;p=1/(i*m-l*j);n=(m*c-j*e)*p;j=(m*d-j*f)*p;c=(i*e-l*c)*p;d=(i*f-l*d)*p;a=a-n*g-c*h;b=b-j*g-d*h;k.save();k.transform(n,j,c,d,a,b);k.clip();k.drawImage(o,0,0);k.restore()}function wa(a,b,c,d){var e=~~(a.r*255),f=~~(a.g*255),a=~~(a.b*255),g=~~(b.r*255),h=~~(b.g*255),b=~~(b.b*255),i=~~(c.r*255),j=~~(c.g*255),c=~~(c.b*255),k=~~(d.r*255),l=~~(d.g*255),d=~~(d.b*255);ba[0]=e<0?0:e>255?255:e;ba[1]=f<0?0:f>255?255:f;ba[2]=a<0?0:a>255?255:a;ba[4]=g<0?0:g>255?255:g;ba[5]=h<0?0:h>255?255:h;ba[6]=b<0?0:b>255?255:b;ba[8]=i<0?0:i>255?255:i;ba[9]=j<0?0:j>255?255:j;ba[10]=c<0?0:c>255?255:c;ba[12]=k<0?0:k>255?255:k;ba[13]=l<0?0:l>255?255:l;ba[14]=d<0?0:d>255?255:d;ra.putImageData(za,0,0);va.drawImage(qa,0,0);return sa}function na(a,b,c){a=(a-b)/(c-b);return a*a*(3-2*a)}function pa(a){a=(a+1)*0.5;return a<0?0:a>1?1:a}function ka(a,b){var c=b.x-a.x,d=b.y-a.y,e=c*c+d*d;e!=0&&(e=1/Math.sqrt(e),c*=e,d*=e,b.x+=c,b.y+=d,a.x-=c,a.y-=d)}var xa,Ha,U,ca;this.autoClear?this.clear():k.setTransform(1,0,0,-1,o,p);e.info.render.vertices=0;e.info.render.faces=0;g=l.projectScene(a,j,this.sortElements);h=g.elements;m=g.lights;(ya=m.length>0)&&i(m);xa=0;for(Ha=h.length;xa1000)x-=2000;else if(x<-1000)x+=2000;if(z>1000)z-=2000;else if(z<-1000)z+=2000}}camera.position.x+=(mouseX-camera.position.x)*0.05;camera.position.y+=(-mouseY-camera.position.y)*0.05;camera.lookAt(scene.position);renderer.render(scene,camera)} + + +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/static/js/supersized.3.2.7.bg-single-image.js b/static/js/supersized.3.2.7.bg-single-image.js new file mode 100644 index 0000000..bc67285 --- /dev/null +++ b/static/js/supersized.3.2.7.bg-single-image.js @@ -0,0 +1,40 @@ +// JavaScript Document + + +// supersized +jQuery(function($){ + $.supersized({ + + // Functionality + slideshow : 1, // Slideshow on/off + autoplay : 1, // Slideshow starts playing automatically + start_slide : 1, // Start slide (0 is random) + stop_loop : 1, // Pauses slideshow on last slide + random : 0, // Randomize slide order (Ignores start slide) + slide_interval : 6000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 2000, // Speed of transition + new_window : 0, // Image links open in new window/tab + pause_hover : 0, // Pause slideshow on hover + keyboard_nav : 1, // Keyboard navigation on/off + performance : 2, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) + image_protect : 1, // Disables image dragging and right click with Javascript + + // Size || Position + min_width : 0, // Min width allowed (in pixels) + min_height : 0, // Min height allowed (in pixels) + vertical_center : 1, // Vertically center background + horizontal_center : 1, // Horizontally center background + fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) + fit_portrait : 1, // Portrait images will not exceed browser height + fit_landscape : 0, // Landscape images will not exceed browser width + + // Components + slide_links : 'false', // Individual links for each slide (Options: false, 'number', 'name', 'blank') + thumb_links : 0, // Individual thumb links for each slide + thumbnail_navigation : 0, // Thumbnail navigation + slides : [ // Slideshow Images +{image: "static/img/background/back.avif", title: '', thumb: '', url: ''} ] + + }); + }); \ No newline at end of file diff --git a/static/js/supersized.3.2.7.bg-slideshow-image.js b/static/js/supersized.3.2.7.bg-slideshow-image.js new file mode 100644 index 0000000..b43a60d --- /dev/null +++ b/static/js/supersized.3.2.7.bg-slideshow-image.js @@ -0,0 +1,44 @@ +// JavaScript Document + + +// supersized +jQuery(function($){ + $.supersized({ + + // Functionality + slideshow : 1, // Slideshow on/off + autoplay : 1, // Slideshow starts playing automatically + start_slide : 1, // Start slide (0 is random) + stop_loop : 0, // Pauses slideshow on last slide + random : 0, // Randomize slide order (Ignores start slide) + slide_interval : 6000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 2000, // Speed of transition + new_window : 0, // Image links open in new window/tab + pause_hover : 0, // Pause slideshow on hover + keyboard_nav : 1, // Keyboard navigation on/off + performance : 2, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) + image_protect : 1, // Disables image dragging and right click with Javascript + + // Size || Position + min_width : 0, // Min width allowed (in pixels) + min_height : 0, // Min height allowed (in pixels) + vertical_center : 1, // Vertically center background + horizontal_center : 1, // Horizontally center background + fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) + fit_portrait : 1, // Portrait images will not exceed browser height + fit_landscape : 0, // Landscape images will not exceed browser width + + // Components + slide_links : 'false', // Individual links for each slide (Options: false, 'number', 'name', 'blank') + thumb_links : 0, // Individual thumb links for each slide + thumbnail_navigation : 0, // Thumbnail navigation + slides : [ // Slideshow Images + {image : 'img/background/1.jpg', title : '', thumb : '', url : ''}, + {image : 'img/background/2.jpg', title : '', thumb : '', url : ''}, + {image : 'img/background/3.jpg', title : '', thumb : '', url : ''}, + {image : 'img/background/4.jpg', title : '', thumb : '', url : ''} + ] + + }); + }); \ No newline at end of file diff --git a/static/js/supersized.3.2.7.bg-video-HTML5.js b/static/js/supersized.3.2.7.bg-video-HTML5.js new file mode 100644 index 0000000..33ba854 --- /dev/null +++ b/static/js/supersized.3.2.7.bg-video-HTML5.js @@ -0,0 +1,41 @@ +// JavaScript Document + + +// supersized +jQuery(function($){ + $.supersized({ + + // Functionality + slideshow : 1, // Slideshow on/off + autoplay : 1, // Slideshow starts playing automatically + start_slide : 1, // Start slide (0 is random) + stop_loop : 1, // Pauses slideshow on last slide + random : 0, // Randomize slide order (Ignores start slide) + slide_interval : 6000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 2000, // Speed of transition + new_window : 0, // Image links open in new window/tab + pause_hover : 0, // Pause slideshow on hover + keyboard_nav : 1, // Keyboard navigation on/off + performance : 2, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) + image_protect : 1, // Disables image dragging and right click with Javascript + + // Size || Position + min_width : 0, // Min width allowed (in pixels) + min_height : 0, // Min height allowed (in pixels) + vertical_center : 1, // Vertically center background + horizontal_center : 1, // Horizontally center background + fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) + fit_portrait : 1, // Portrait images will not exceed browser height + fit_landscape : 0, // Landscape images will not exceed browser width + + // Components + slide_links : 'false', // Individual links for each slide (Options: false, 'number', 'name', 'blank') + thumb_links : 0, // Individual thumb links for each slide + thumbnail_navigation : 0, // Thumbnail navigation + slides : [ // Slideshow Images + {image : 'img/background/video-HTML5.jpg', title : '', thumb : '', url : ''} + ] + + }); + }); \ No newline at end of file diff --git a/static/js/supersized.3.2.7.bg-video.js b/static/js/supersized.3.2.7.bg-video.js new file mode 100644 index 0000000..08060b8 --- /dev/null +++ b/static/js/supersized.3.2.7.bg-video.js @@ -0,0 +1,41 @@ +// JavaScript Document + + +// supersized +jQuery(function($){ + $.supersized({ + + // Functionality + slideshow : 1, // Slideshow on/off + autoplay : 1, // Slideshow starts playing automatically + start_slide : 1, // Start slide (0 is random) + stop_loop : 1, // Pauses slideshow on last slide + random : 0, // Randomize slide order (Ignores start slide) + slide_interval : 6000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 2000, // Speed of transition + new_window : 0, // Image links open in new window/tab + pause_hover : 0, // Pause slideshow on hover + keyboard_nav : 1, // Keyboard navigation on/off + performance : 2, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) + image_protect : 1, // Disables image dragging and right click with Javascript + + // Size || Position + min_width : 0, // Min width allowed (in pixels) + min_height : 0, // Min height allowed (in pixels) + vertical_center : 1, // Vertically center background + horizontal_center : 1, // Horizontally center background + fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) + fit_portrait : 1, // Portrait images will not exceed browser height + fit_landscape : 0, // Landscape images will not exceed browser width + + // Components + slide_links : 'false', // Individual links for each slide (Options: false, 'number', 'name', 'blank') + thumb_links : 0, // Individual thumb links for each slide + thumbnail_navigation : 0, // Thumbnail navigation + slides : [ // Slideshow Images + {image : 'img/background/video.jpg', title : '', thumb : '', url : ''} + ] + + }); + }); \ No newline at end of file diff --git a/static/js/the-outskirts.js b/static/js/the-outskirts.js new file mode 100644 index 0000000..ae93477 --- /dev/null +++ b/static/js/the-outskirts.js @@ -0,0 +1,204 @@ +(function($) { + + + // WINDOW.LOAD FUNCTION start + $(window).load(function() { + "use strict"; + + // screen loader + $('.screen-loader').fadeOut('slow'); + + }); + // WINDOW.LOAD FUNCTION end + + + // DOCUMENT.READY FUNCTION start + $(document).ready(function() { + "use strict"; + + // preload + $('#preload').css({ + display: 'table' + }); + + // preload.Timeout + setTimeout(function() { + $('#preload').delay(250).fadeOut(1400); + $('#intro-wrapper').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('#menu-wrapper').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('#countdown-wrapper').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('#film-grain').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('.weather').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('#snow').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('#particles-holder').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + $('.clouds').delay(1400).css({ + display: 'none' + }).fadeIn(2400); + }); + + // kenburnsy + $("#kenburnsy-bg").kenburnsy({ + fullscreen: true + }); + + // magnificPopup + $('.popup-photo').magnificPopup({ + type: 'image', + gallery: { + enabled: true, + tPrev: '', + tNext: '', + tCounter: '%curr% / %total%' + }, + removalDelay: 300, + mainClass: 'mfp-fade' + }); + + // countdown setup start + $("#countdown").countdown({ + date: "15 August 2019 12:00:00", // countdown target date settings + format: "on" + }, function() { + // callback function + }); + + // snow + $(function() { + $("#snow").each(function() { + snowBind(); + }); + }); + + // fire + // fire home + $("#fire-home").on("click", function(e) { + e.preventDefault(); + $(".current").fadeOut(1200, function() { + $("#home").fadeIn(2200); + $(".current").removeClass("current"); + $("#home").addClass("current"); + }); + }); + // fire about + $("#fire-about").on("click", function(e) { + e.preventDefault(); + $(".current").fadeOut(1200, function() { + $("#about").fadeIn(2200); + $(".current").removeClass("current"); + $("#about").addClass("current"); + }); + }); + // fire services + $("#fire-services").on("click", function(e) { + e.preventDefault(); + $(".current").fadeOut(1200, function() { + $("#services").fadeIn(2200); + $(".current").removeClass("current"); + $("#services").addClass("current"); + }); + }); + // fire photos + $("#fire-photos").on("click", function(e) { + e.preventDefault(); + $(".current").fadeOut(1200, function() { + $("#photos").fadeIn(2200); + $(".current").removeClass("current"); + $("#photos").addClass("current"); + }); + }); + // fire contact + $("#fire-contact").on("click", function(e) { + e.preventDefault(); + $(".current").fadeOut(1200, function() { + $("#contact").fadeIn(2200); + $(".current").removeClass("current"); + $("#contact").addClass("current"); + }); + }); + + // menu active state + $('a.menu-state').on("click", function() { + $('a.menu-state').removeClass("active"); + $(this).addClass("active"); + }); + + // owlCarousel + $(".services-gallery-slider").owlCarousel({ + slideSpeed: 350, + singleItem: true, + autoHeight: true, + navigation: true, + navigationText: ["", ""] + }); + + // wordRotator + $("#wordrotator").wordsrotator({ + autoLoop: true, // auto rotate words + randomize: false, // show random entries from the words array + stopOnHover: false, // stop animation on hover + changeOnClick: false, // force animation run on click + animationIn: "fadeInLeft", // css class for entrace animation + animationOut: "fadeOutRight", // css class for exit animation + speed: 4000, // delay in milliseconds between two words + words: ['the
    Outskirts', 'where the
    city ends', + 'and the
    suburbs begin' + ] + // Array of words, it may contain HTML values + }); + + // dialog + (function() { + var dlgtrigger = document.querySelector('[data-dialog]'), + somedialog = document.getElementById(dlgtrigger.getAttribute('data-dialog')), + dlg = new DialogFx(somedialog); + dlgtrigger.addEventListener('click', dlg.toggle.bind(dlg)); + })(); + + // YTPlayer + $(function() { + $(".player").mb_YTPlayer(); + }); + + }); + // DOCUMENT.READY FUNCTION end + + + // MOBILE DETECT start + var isMobile = { + Android: function() { + return navigator.userAgent.match(/Android/i); + }, + BlackBerry: function() { + return navigator.userAgent.match(/BlackBerry/i); + }, + iOS: function() { + return navigator.userAgent.match(/iPhone|iPad|iPod/i); + }, + Opera: function() { + return navigator.userAgent.match(/Opera Mini/i); + }, + Windows: function() { + return navigator.userAgent.match(/IEMobile/i); + }, + any: function() { + return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); + } + }; + // MOBILE DETECT end + + +})(jQuery); \ No newline at end of file diff --git a/static/temp.ts b/static/temp.ts new file mode 100644 index 0000000..e69de29 diff --git a/templates/home/index.html b/templates/home/index.html new file mode 100644 index 0000000..1afa9cc --- /dev/null +++ b/templates/home/index.html @@ -0,0 +1,578 @@ +{% extends 'layouts/app.html' %} +{% load static %} +{% block content %} + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + + {% comment %}{% endcomment %} + +
    +
    +
    +
    + + + +
    +
    +
    + Newsletter sign up +
    +

    + Subscribe today to receive the latest news +

    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + {% comment %} {% endcomment %} +
    + +

    +
    + +
    +
    +
    + Site +
    +
    +
    + +
    + +
    +
      + +
    • + 00 +

      + Seconds +

      +
    • + +
    • + 00 +

      + Days +

      +
    • +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + About +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +

    + Lorem ipsum dolor + sit + amet, consectetur adipiscing elit. Fusce dictum pharetra + congue. +

    +
    +
    + +
    +
    +
      +
    • + HTML5 +
    • +
    • + CSS3 +
    • +
    • + jQuery +
    • +
    • + Photoshop +
    • +
    • + Dreamweaver +
    • +
    +
    +
    +
    +
    +

    + + Customer First +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula + non + dignissim suscipit, neque nunc efficitur felis. +

    +
    +

    + Quality + First +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula + non + dignissim suscipit, neque nunc efficitur felis. +

    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + Services +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Core + Values +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula + non + dignissim suscipit, neque nunc efficitur felis. +

    +
    +

    + Core + Principles +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula + non + dignissim suscipit, neque nunc efficitur felis. +

    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + + +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + Contact +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + + Address +

    +

    + ex nihilo, Inc.
    + Touchdown Dr 1176 +

    +
    +

    + + Telephone +

    +

    + [00] 11 - 76
    + [01] 11 - 76 +

    +
    +

    + + Email +

    +

    + you@yoursite.com +

    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    +

    + Get Social +

    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + + + + + + + +
    + + +
    +
    + +{% endblock %} diff --git a/templates/include/_header.html b/templates/include/_header.html new file mode 100644 index 0000000..442ba38 --- /dev/null +++ b/templates/include/_header.html @@ -0,0 +1,23 @@ +{% load static %} + + + Beyhan Oğur + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/include/_js.html b/templates/include/_js.html new file mode 100644 index 0000000..07f8e7f --- /dev/null +++ b/templates/include/_js.html @@ -0,0 +1,5 @@ +{% load static %} + + + + \ No newline at end of file diff --git a/templates/index-single-image-dark-rain.html b/templates/index-single-image-dark-rain.html new file mode 100644 index 0000000..406bf38 --- /dev/null +++ b/templates/index-single-image-dark-rain.html @@ -0,0 +1,564 @@ + + + + + + + + + + Shared on THEMELOCK.COM - + The Outskirts || Responsive Coming Soon Page + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    + Newsletter sign up +
    +

    + Subscribe today to receive the latest news +

    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +

    +
    + +
    +
    +
    + Subscribe +
    +
    +
    + +
    + +
    +
      + +
    • + 00 +

      + Seconds +

      +
    • + +
    • + 00 +

      + Days +

      +
    • +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + About +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +

    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce dictum pharetra + congue. +

    +
    +
    + +
    +
    +
      +
    • + HTML5 +
    • +
    • + CSS3 +
    • +
    • + jQuery +
    • +
    • + Photoshop +
    • +
    • + Dreamweaver +
    • +
    +
    +
    +
    +
    +

    + Customer First +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula non dignissim suscipit, neque nunc efficitur felis. +

    +
    +

    + Quality First +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula non dignissim suscipit, neque nunc efficitur felis. +

    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + Services +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Core Values +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula non dignissim suscipit, neque nunc efficitur felis. +

    +
    +

    + Core Principles +

    +

    + Suspendisse ut feugiat orci, in laoreet augue. Aliquam ultricies, ligula non dignissim suscipit, neque nunc efficitur felis. +

    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + Photos +

    +
    + +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + Contact +

    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +

    + Address +

    +

    + ex nihilo, Inc.
    + Touchdown Dr 1176 +

    +
    +

    + Telephone +

    +

    + [00] 11 - 76
    + [01] 11 - 76 +

    +
    +

    + Email +

    +

    + you@yoursite.com +

    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    +

    + Get Social +

    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    + + + + + + + +
    + + +
    +
    + + + + + + + \ No newline at end of file diff --git a/templates/layouts/app.html b/templates/layouts/app.html new file mode 100644 index 0000000..ec5805c --- /dev/null +++ b/templates/layouts/app.html @@ -0,0 +1,16 @@ +{% load static %} + + + + + + + + {% include 'include/_header.html' %} + + {% block content %} + + {% endblock %} + {% include 'include/_js.html' %} + + \ No newline at end of file diff --git a/test_github.sh b/test_github.sh new file mode 100644 index 0000000..1746085 --- /dev/null +++ b/test_github.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# GitHub OAuth Test Script +# Usage: ./test_github.sh + +if [ -z "$1" ]; then + echo "❌ Access token gerekli!" + echo "" + echo "Kullanım: ./test_github.sh " + echo "" + echo "Personal Access Token almak için:" + echo "1. https://github.com/settings/tokens" + echo "2. Generate new token (classic)" + echo "3. Scopes: user, user:email" + echo "4. Token'ı kopyala" + exit 1 +fi + +ACCESS_TOKEN="$1" + +echo "⚫ GitHub OAuth Test" +echo "====================" +echo "" +echo "📤 Request gönderiliyor..." +echo "" + +curl -X POST http://localhost:8000/api/v1/auth/social/github/ \ + -H "Content-Type: application/json" \ + -d "{\"access_token\":\"$ACCESS_TOKEN\"}" \ + | python -m json.tool + +echo "" +echo "====================" + diff --git a/test_google.sh b/test_google.sh new file mode 100644 index 0000000..1b7b70f --- /dev/null +++ b/test_google.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Google OAuth Test Script +# Usage: ./test_google.sh + +if [ -z "$1" ]; then + echo "❌ Access token gerekli!" + echo "" + echo "Kullanım: ./test_google.sh " + echo "" + echo "Token almak için:" + echo "1. https://developers.google.com/oauthplayground/" + echo "2. Settings → Use your own OAuth credentials" + echo "3. Client ID: 915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com" + echo "4. Client Secret: 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" + echo "5. Scopes: userinfo.email, userinfo.profile" + echo "6. Authorize → Exchange code for tokens" + echo "7. Access token'ı kopyala" + exit 1 +fi + +ACCESS_TOKEN="$1" + +echo "🔵 Google OAuth Test" +echo "====================" +echo "" +echo "📤 Request gönderiliyor..." +echo "" + +curl -X POST http://localhost:8000/api/v1/auth/social/google-oauth2/ \ + -H "Content-Type: application/json" \ + -d "{\"access_token\":\"$ACCESS_TOKEN\"}" \ + | python -m json.tool + +echo "" +echo "====================" + diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/admin.py b/utils/admin.py new file mode 100644 index 0000000..ac9d0db --- /dev/null +++ b/utils/admin.py @@ -0,0 +1,22 @@ +from django.contrib import admin + +# Register your models here. + + +from .models import JsonToType + + +@admin.register(JsonToType) +class JsonToTypeAdmin(admin.ModelAdmin): + list_display = ( + 'id', + 'user', + 'title', + 'json_data', + 'type_data', + 'created_at', + 'updated_at', + 'is_active', + ) + list_filter = ('user', 'created_at', 'updated_at', 'is_active') + date_hierarchy = 'created_at' diff --git a/utils/apps.py b/utils/apps.py new file mode 100644 index 0000000..83e83de --- /dev/null +++ b/utils/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UtilsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'utils' diff --git a/utils/migrations/0001_initial.py b/utils/migrations/0001_initial.py new file mode 100644 index 0000000..dd10404 --- /dev/null +++ b/utils/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 5.2.9 on 2025-12-24 19:48 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='JsonToType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=254, verbose_name='Başlık')), + ('json_data', models.JSONField(verbose_name='Json Veri')), + ('type_data', models.TextField(verbose_name='Type Veri')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')), + ('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=False, verbose_name='Yayındamı')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='json_to_type_user', to=settings.AUTH_USER_MODEL, verbose_name='Kullanıcı')), + ], + options={ + 'verbose_name': 'Json To Type', + 'verbose_name_plural': 'Json To Type', + 'db_table': 'json_to_type', + 'ordering': ['-updated_at'], + }, + ), + ] diff --git a/utils/migrations/0002_alter_jsontotype_json_data.py b/utils/migrations/0002_alter_jsontotype_json_data.py new file mode 100644 index 0000000..944b7ba --- /dev/null +++ b/utils/migrations/0002_alter_jsontotype_json_data.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.9 on 2025-12-24 20:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('utils', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='jsontotype', + name='json_data', + field=models.JSONField(unique=True, verbose_name='Json Veri'), + ), + ] diff --git a/utils/migrations/0003_alter_jsontotype_type_data.py b/utils/migrations/0003_alter_jsontotype_type_data.py new file mode 100644 index 0000000..bcf8c2e --- /dev/null +++ b/utils/migrations/0003_alter_jsontotype_type_data.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.9 on 2025-12-24 20:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('utils', '0002_alter_jsontotype_json_data'), + ] + + operations = [ + migrations.AlterField( + model_name='jsontotype', + name='type_data', + field=models.TextField(unique=True, verbose_name='Type Veri'), + ), + ] diff --git a/utils/migrations/__init__.py b/utils/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/models.py b/utils/models.py new file mode 100644 index 0000000..0c313d7 --- /dev/null +++ b/utils/models.py @@ -0,0 +1,26 @@ +from django.db import models + + +# Create your models here. +class JsonToType(models.Model): + aktif = ( + (True, 'Evet'), + (False, 'Hayır'), + ) + user = models.ForeignKey('accounts.CustomUser', on_delete=models.CASCADE, related_name='json_to_type_user', + verbose_name="Kullanıcı") + title = models.CharField(max_length=254, verbose_name="Başlık") + json_data = models.JSONField(verbose_name="Json Veri", unique=True) + type_data = models.TextField(verbose_name="Type Veri", unique=True) + created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") + updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") + is_active = models.BooleanField(default=False, verbose_name='Yayındamı', choices=aktif) + + class Meta: + ordering = ["-updated_at"] + db_table = 'json_to_type' + verbose_name_plural = "Json To Type" + verbose_name = "Json To Type" + + def __str__(self): + return self.title diff --git a/utils/serializers.py b/utils/serializers.py new file mode 100644 index 0000000..befad8b --- /dev/null +++ b/utils/serializers.py @@ -0,0 +1,10 @@ +from rest_framework import serializers + +from utils.models import JsonToType + + +class JsonToTypeSerializer(serializers.ModelSerializer): + + class Meta: + model = JsonToType + fields = ['id', 'title', 'json_data', 'type_data', 'created_at', 'updated_at','is_active'] diff --git a/utils/tests.py b/utils/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/utils/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/utils/urls.py b/utils/urls.py new file mode 100644 index 0000000..9c78d2e --- /dev/null +++ b/utils/urls.py @@ -0,0 +1,7 @@ +from django.urls import path, include + +from utils.views import JsonToTypeListCreate + +urlpatterns = [ + path('utils/jasontotype/', JsonToTypeListCreate.as_view(), name='jasontotype'), +] diff --git a/utils/views.py b/utils/views.py new file mode 100644 index 0000000..a07beaa --- /dev/null +++ b/utils/views.py @@ -0,0 +1,18 @@ +from django.shortcuts import render +from rest_framework.generics import ListCreateAPIView +from rest_framework.permissions import IsAuthenticated + +from utils.models import JsonToType +from utils.serializers import JsonToTypeSerializer + + +# Create your views here. +class JsonToTypeListCreate(ListCreateAPIView): + permission_classes = [IsAuthenticated] + serializer_class = JsonToTypeSerializer + + def get_queryset(self): + return JsonToType.objects.filter(user=self.request.user, is_active=True).order_by('-updated_at') + + def perform_create(self, serializer): + serializer.save(user=self.request.user)